Information storage for inputs and outputs
This commit is contained in:
parent
381946bab7
commit
d18e36d459
10 changed files with 566 additions and 1 deletions
|
|
@ -10,3 +10,4 @@ add_subdirectory( utilities )
|
|||
add_subdirectory( app )
|
||||
add_subdirectory( plugins )
|
||||
add_subdirectory( wallet )
|
||||
add_subdirectory( sidechain )
|
||||
|
|
|
|||
|
|
@ -117,7 +117,8 @@ add_library( graphene_chain
|
|||
)
|
||||
|
||||
add_dependencies( graphene_chain build_hardfork_hpp )
|
||||
target_link_libraries( graphene_chain fc graphene_db )
|
||||
#target_link_libraries( graphene_chain fc graphene_db )
|
||||
target_link_libraries( graphene_chain fc graphene_db sidechain )
|
||||
target_include_directories( graphene_chain
|
||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" )
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@
|
|||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
#include <graphene/chain/info_for_vout_object.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
// C++ requires that static class variables declared and initialized
|
||||
|
|
@ -301,6 +303,8 @@ void database::initialize_indexes()
|
|||
//add_index< primary_index<distributed_dividend_balance_object_index > >();
|
||||
add_index< primary_index<pending_dividend_payout_balance_for_holder_object_index > >();
|
||||
add_index< primary_index<total_distributed_dividend_balance_object_index > >();
|
||||
|
||||
add_index< primary_index<info_for_vout_index > >();
|
||||
}
|
||||
|
||||
void database::init_genesis(const genesis_state_type& genesis_state)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
|
||||
#include <graphene/chain/protocol/types.hpp>
|
||||
#include <graphene/db/generic_index.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
class info_for_vout_object : public abstract_object<info_for_vout_object>
|
||||
{
|
||||
public:
|
||||
static const uint8_t space_id = protocol_ids;
|
||||
static const uint8_t type_id = info_for_vout_object_type;
|
||||
|
||||
struct comparer {
|
||||
bool operator()( const info_for_vout_object& lhs, const info_for_vout_object& rhs ) const {
|
||||
if( lhs.created != rhs.created )
|
||||
return lhs.created < rhs.created;
|
||||
return lhs.id < rhs.id;
|
||||
}
|
||||
};
|
||||
|
||||
info_for_vout_id_type get_id()const { return id; }
|
||||
|
||||
account_id_type payer;
|
||||
// btc::payment_type addr_type;
|
||||
std::string data;
|
||||
uint64_t amount;
|
||||
|
||||
bool created = false;
|
||||
};
|
||||
|
||||
struct by_created;
|
||||
struct by_id_and_not_created;
|
||||
|
||||
typedef boost::multi_index_container<
|
||||
info_for_vout_object,
|
||||
indexed_by<
|
||||
ordered_unique< tag< by_id >, member< object, object_id_type, &object::id > >,
|
||||
ordered_non_unique< tag< by_created >, member< info_for_vout_object, bool, &info_for_vout_object::created > >,
|
||||
ordered_non_unique<tag<by_id_and_not_created>, identity< info_for_vout_object >, info_for_vout_object::comparer >
|
||||
>
|
||||
> info_for_vout_multi_index_container;
|
||||
typedef generic_index<info_for_vout_object, info_for_vout_multi_index_container> info_for_vout_index;
|
||||
|
||||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT_DERIVED( graphene::chain::info_for_vout_object, (graphene::chain::object), (payer)(data)(amount)(created) )
|
||||
|
||||
|
|
@ -145,6 +145,7 @@ namespace graphene { namespace chain {
|
|||
betting_market_group_object_type,
|
||||
betting_market_object_type,
|
||||
bet_object_type,
|
||||
info_for_vout_object_type,
|
||||
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
|
||||
};
|
||||
|
||||
|
|
@ -202,6 +203,7 @@ namespace graphene { namespace chain {
|
|||
class betting_market_group_object;
|
||||
class betting_market_object;
|
||||
class bet_object;
|
||||
class info_for_vout_object;
|
||||
|
||||
typedef object_id< protocol_ids, account_object_type, account_object> account_id_type;
|
||||
typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type;
|
||||
|
|
@ -228,6 +230,7 @@ namespace graphene { namespace chain {
|
|||
typedef object_id< protocol_ids, betting_market_group_object_type, betting_market_group_object> betting_market_group_id_type;
|
||||
typedef object_id< protocol_ids, betting_market_object_type, betting_market_object> betting_market_id_type;
|
||||
typedef object_id< protocol_ids, bet_object_type, bet_object> bet_id_type;
|
||||
typedef object_id< protocol_ids, info_for_vout_object_type, info_for_vout_object> info_for_vout_id_type;
|
||||
|
||||
// implementation types
|
||||
class global_property_object;
|
||||
|
|
@ -402,6 +405,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
|
|||
(betting_market_group_object_type)
|
||||
(betting_market_object_type)
|
||||
(bet_object_type)
|
||||
(info_for_vout_object_type)
|
||||
(OBJECT_TYPE_COUNT)
|
||||
)
|
||||
FC_REFLECT_ENUM( graphene::chain::impl_object_type,
|
||||
|
|
|
|||
7
libraries/sidechain/CMakeLists.txt
Normal file
7
libraries/sidechain/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
file( GLOB SOURCES "*.cpp" )
|
||||
file( GLOB HEADERS "include/*.hpp" )
|
||||
|
||||
add_library( sidechain STATIC ${SOURCES} ${HEADERS} )
|
||||
|
||||
target_link_libraries( sidechain ${Boost_LIBRARIES} fc graphene_chain )
|
||||
target_include_directories( sidechain PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
|
||||
115
libraries/sidechain/include/sidechain/input_withdrawal_info.hpp
Normal file
115
libraries/sidechain/include/sidechain/input_withdrawal_info.hpp
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
|
||||
#include <sidechain/thread_safe_index.hpp>
|
||||
#include <fc/crypto/sha256.hpp>
|
||||
|
||||
#include <graphene/chain/info_for_vout_object.hpp>
|
||||
#include <graphene/chain/protocol/types.hpp>
|
||||
|
||||
using boost::multi_index_container;
|
||||
using namespace boost::multi_index;
|
||||
using info_for_vout = graphene::chain::info_for_vout_object;
|
||||
|
||||
namespace graphene { namespace chain { class database; } }
|
||||
|
||||
namespace sidechain {
|
||||
|
||||
struct prev_out
|
||||
{
|
||||
std::string hash_tx;
|
||||
uint32_t n_vout;
|
||||
uint64_t amount;
|
||||
};
|
||||
|
||||
struct info_for_vin
|
||||
{
|
||||
info_for_vin() = default;
|
||||
|
||||
info_for_vin( const prev_out& _out, const std::string& _address, std::vector<char> _script = std::vector<char>() ) :
|
||||
id( count_id_info_for_vin++ ), out( _out ), address( _address ), script( _script ) {
|
||||
identifier = fc::sha256::hash( out.hash_tx + std::to_string( out.n_vout ) );
|
||||
}
|
||||
|
||||
struct comparer {
|
||||
bool operator() ( const info_for_vin& lhs, const info_for_vin& rhs ) const;
|
||||
};
|
||||
|
||||
static uint64_t count_id_info_for_vin;
|
||||
uint64_t id;
|
||||
|
||||
fc::sha256 identifier;
|
||||
|
||||
prev_out out;
|
||||
std::string address;
|
||||
std::vector<char> script;
|
||||
|
||||
bool created = false;
|
||||
};
|
||||
|
||||
struct by_id;
|
||||
struct by_identifier;
|
||||
struct by_id_and_not_created;
|
||||
|
||||
using info_for_vin_index = boost::multi_index_container<info_for_vin,
|
||||
indexed_by<
|
||||
ordered_unique<tag<by_id>, member<info_for_vin, uint64_t, &info_for_vin::id>>,
|
||||
ordered_unique<tag<by_identifier>, member<info_for_vin, fc::sha256, &info_for_vin::identifier>>,
|
||||
ordered_non_unique<tag<by_id_and_not_created>, identity< info_for_vin >, info_for_vin::comparer >
|
||||
>
|
||||
>;
|
||||
|
||||
class input_withdrawal_info
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
using iterator_id_vin = typename info_for_vin_index::template index<by_id>::type::iterator;
|
||||
using iterator_id_vout = typename graphene::chain::info_for_vout_index::index_type::template index<graphene::chain::by_id>::type::iterator;
|
||||
|
||||
|
||||
input_withdrawal_info( graphene::chain::database& _db ) : db( _db ) {}
|
||||
|
||||
|
||||
void insert_info_for_vin( const prev_out& out, const std::string& address, std::vector<char> script = std::vector<char>() );
|
||||
|
||||
void modify_info_for_vin( const info_for_vin& obj, const std::function<void( info_for_vin& e )>& func );
|
||||
|
||||
void mark_as_used_vin( const info_for_vin& obj );
|
||||
|
||||
void remove_info_for_vin( const info_for_vin& obj );
|
||||
|
||||
std::pair<bool, input_withdrawal_info::iterator_id_vin> find_info_for_vin( uint64_t id );
|
||||
|
||||
size_t size_info_for_vins() { return info_for_vins.size(); }
|
||||
|
||||
std::vector<info_for_vin> get_info_for_vins();
|
||||
|
||||
|
||||
void insert_info_for_vout( const graphene::chain::account_id_type& payer, /*ayment_type addr_type,*/ const std::string& data, const uint64_t& amount );
|
||||
|
||||
void mark_as_used_vout( const graphene::chain::info_for_vout_object& obj );
|
||||
|
||||
void remove_info_for_vout( const info_for_vout& obj );
|
||||
|
||||
std::pair<bool, input_withdrawal_info::iterator_id_vout> find_info_for_vout( uint64_t id );
|
||||
|
||||
size_t size_info_for_vouts();
|
||||
|
||||
std::vector<info_for_vout> get_info_for_vouts();
|
||||
|
||||
private:
|
||||
|
||||
graphene::chain::database& db;
|
||||
|
||||
thread_safe_index<info_for_vin_index> info_for_vins;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
63
libraries/sidechain/include/sidechain/thread_safe_index.hpp
Normal file
63
libraries/sidechain/include/sidechain/thread_safe_index.hpp
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace sidechain {
|
||||
|
||||
struct by_id;
|
||||
|
||||
template<class T1>
|
||||
class thread_safe_index {
|
||||
|
||||
public:
|
||||
|
||||
using iterator = typename T1::iterator;
|
||||
using iterator_id = typename T1::template index<by_id>::type::iterator;
|
||||
|
||||
std::pair<iterator,bool> insert( const typename T1::value_type& value ) {
|
||||
std::lock_guard<std::recursive_mutex> locker( lock );
|
||||
return data.insert( value );
|
||||
}
|
||||
|
||||
void modify( const typename T1::value_type& obj, const std::function<void( typename T1::value_type& e)>& func ) {
|
||||
std::lock_guard<std::recursive_mutex> locker( lock );
|
||||
data.modify( data.iterator_to(obj), [&func]( typename T1::value_type& obj ) { func(obj); } );
|
||||
}
|
||||
|
||||
void remove( const typename T1::value_type& obj ) {
|
||||
std::lock_guard<std::recursive_mutex> locker( lock );
|
||||
data.erase( data.iterator_to( obj ) );
|
||||
}
|
||||
|
||||
size_t size() {
|
||||
std::lock_guard<std::recursive_mutex> locker( lock );
|
||||
return data.size();
|
||||
}
|
||||
|
||||
std::pair<bool, iterator_id> find( uint64_t id ) {
|
||||
std::lock_guard<std::recursive_mutex> locker( lock );
|
||||
auto& index = data.template get<by_id>();
|
||||
auto it = index.find( id );
|
||||
if( it != index.end() ) {
|
||||
return std::make_pair(true, it);
|
||||
}
|
||||
return std::make_pair(false, it);
|
||||
}
|
||||
|
||||
template<class T2>
|
||||
void safe_for(std::function<void(typename T1::template index<T2>::type::iterator itr1,
|
||||
typename T1::template index<T2>::type::iterator itr2)> func) {
|
||||
std::lock_guard<std::recursive_mutex> locker( lock );
|
||||
auto& index = data.template get<T2>();
|
||||
func(index.begin(), index.end());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::recursive_mutex lock;
|
||||
|
||||
T1 data;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
122
libraries/sidechain/input_withdrawal_info.cpp
Normal file
122
libraries/sidechain/input_withdrawal_info.cpp
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
#include <sidechain/input_withdrawal_info.hpp>
|
||||
#include <graphene/chain/database.hpp>
|
||||
|
||||
namespace sidechain {
|
||||
|
||||
uint64_t info_for_vin::count_id_info_for_vin = 0;
|
||||
|
||||
bool info_for_vin::comparer::operator() ( const info_for_vin& lhs, const info_for_vin& rhs ) const
|
||||
{
|
||||
if( lhs.created != rhs.created ) {
|
||||
return lhs.created < rhs.created;
|
||||
}
|
||||
return lhs.id < rhs.id;
|
||||
}
|
||||
|
||||
void input_withdrawal_info::insert_info_for_vin( const prev_out& out, const std::string& address, std::vector<char> script )
|
||||
{
|
||||
info_for_vins.insert( info_for_vin( out, address, script ) );
|
||||
}
|
||||
|
||||
void input_withdrawal_info::modify_info_for_vin( const info_for_vin& obj, const std::function<void( info_for_vin& e )>& func )
|
||||
{
|
||||
info_for_vins.modify( obj, func );
|
||||
}
|
||||
|
||||
void input_withdrawal_info::mark_as_used_vin( const info_for_vin& obj )
|
||||
{
|
||||
info_for_vins.modify( obj, [&]( info_for_vin& o ) {
|
||||
o.created = true;
|
||||
} );
|
||||
}
|
||||
|
||||
void input_withdrawal_info::remove_info_for_vin( const info_for_vin& obj )
|
||||
{
|
||||
info_for_vins.remove( obj );
|
||||
}
|
||||
|
||||
std::pair<bool, input_withdrawal_info::iterator_id_vin> input_withdrawal_info::find_info_for_vin( uint64_t id )
|
||||
{
|
||||
return info_for_vins.find( id );
|
||||
}
|
||||
|
||||
std::vector<info_for_vin> input_withdrawal_info::get_info_for_vins()
|
||||
{
|
||||
std::vector<info_for_vin> result;
|
||||
|
||||
info_for_vins.safe_for<by_id_and_not_created>( [&]( info_for_vin_index::index<by_id_and_not_created>::type::iterator itr_b,
|
||||
info_for_vin_index::index<by_id_and_not_created>::type::iterator itr_e )
|
||||
{
|
||||
for( size_t i = 0; itr_b != itr_e && i < 5 && !itr_b->created; i++ ) { // 5 amount vins to bitcoin transaction
|
||||
info_for_vin vin;
|
||||
vin.identifier = itr_b->identifier;
|
||||
vin.out.hash_tx = itr_b->out.hash_tx;
|
||||
vin.out.n_vout = itr_b->out.n_vout;
|
||||
vin.out.amount = itr_b->out.amount;
|
||||
vin.address = itr_b->address;
|
||||
// vin.script = get account address, from the address get the script
|
||||
|
||||
result.push_back( vin );
|
||||
++itr_b;
|
||||
}
|
||||
} );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void input_withdrawal_info::insert_info_for_vout( const graphene::chain::account_id_type& payer, /*ayment_type addr_type,*/ const std::string& data, const uint64_t& amount )
|
||||
{
|
||||
db.create<graphene::chain::info_for_vout_object>([&](graphene::chain::info_for_vout_object& obj) {
|
||||
obj.payer = payer;
|
||||
// obj.addr_type = addr_type;
|
||||
obj.data = data;
|
||||
obj.amount = amount;
|
||||
});
|
||||
}
|
||||
|
||||
void input_withdrawal_info::mark_as_used_vout( const graphene::chain::info_for_vout_object& obj )
|
||||
{
|
||||
db.modify<graphene::chain::info_for_vout_object>( obj, [&]( graphene::chain::info_for_vout_object& o ) {
|
||||
o.created = true;
|
||||
});
|
||||
}
|
||||
|
||||
void input_withdrawal_info::remove_info_for_vout( const info_for_vout& obj )
|
||||
{
|
||||
db.remove( obj );
|
||||
}
|
||||
|
||||
std::pair<bool, input_withdrawal_info::iterator_id_vout> input_withdrawal_info::find_info_for_vout( uint64_t id )
|
||||
{
|
||||
const auto& info_for_vout_idx = db.get_index_type<graphene::chain::info_for_vout_index>().indices().get< graphene::chain::by_id >();
|
||||
auto itr = info_for_vout_idx.find( graphene::chain::info_for_vout_id_type( id ) );
|
||||
return std::make_pair( itr != info_for_vout_idx.end(), itr );
|
||||
}
|
||||
|
||||
size_t input_withdrawal_info::size_info_for_vouts()
|
||||
{
|
||||
const auto& info_for_vout_idx = db.get_index_type<graphene::chain::info_for_vout_index>().indices().get< graphene::chain::by_id >();
|
||||
return info_for_vout_idx.size();
|
||||
}
|
||||
|
||||
std::vector<info_for_vout> input_withdrawal_info::get_info_for_vouts()
|
||||
{
|
||||
std::vector<info_for_vout> result;
|
||||
|
||||
const auto& info_for_vout_idx = db.get_index_type<graphene::chain::info_for_vout_index>().indices().get< graphene::chain::by_id_and_not_created >();
|
||||
auto itr = info_for_vout_idx.begin();
|
||||
for(size_t i = 0; i < 5 && itr != info_for_vout_idx.end() && !itr->created; i++) {
|
||||
info_for_vout vout;
|
||||
vout.payer = itr->payer;
|
||||
// vout.addr_type = itr->addr_type;
|
||||
vout.data = itr->data;
|
||||
vout.amount = itr->amount;
|
||||
|
||||
result.push_back( vout );
|
||||
++itr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
200
tests/tests/input_withdrawal_info_tests.cpp
Normal file
200
tests/tests/input_withdrawal_info_tests.cpp
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
#include <boost/test/unit_test.hpp>
|
||||
#include <sidechain/input_withdrawal_info.hpp>
|
||||
#include "../common/database_fixture.hpp"
|
||||
|
||||
using namespace graphene::chain;
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE( input_withdrawal_info_tests, database_fixture )
|
||||
|
||||
BOOST_AUTO_TEST_CASE( input_withdrawal_info_insert_vin_test ) {
|
||||
sidechain::input_withdrawal_info infos( db );
|
||||
sidechain::prev_out out = { "1", 1, 13 };
|
||||
infos.insert_info_for_vin( out, "addr1", { 0x01, 0x02, 0x03 } );
|
||||
BOOST_CHECK( infos.size_info_for_vins() == 1 );
|
||||
|
||||
sidechain::info_for_vin::count_id_info_for_vin = 0;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( input_withdrawal_info_many_insert_vin_test ) {
|
||||
sidechain::input_withdrawal_info infos( db );
|
||||
for( size_t i = 1; i <= 10; i++ ) {
|
||||
sidechain::prev_out out = { std::to_string( i ), static_cast<uint32_t>( i ), static_cast< uint64_t >( i ) };
|
||||
infos.insert_info_for_vin( out, "addr" + std::to_string( i ), { 0x01, 0x02, 0x03 } );
|
||||
}
|
||||
BOOST_CHECK( infos.size_info_for_vins() == 10 );
|
||||
|
||||
sidechain::info_for_vin::count_id_info_for_vin = 0;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( input_withdrawal_info_id_test ) {
|
||||
sidechain::input_withdrawal_info infos( db );
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
sidechain::prev_out out = { std::to_string( i ), static_cast<uint32_t>( i ), static_cast< uint64_t >( i ) };
|
||||
infos.insert_info_for_vin( out, "addr" + std::to_string( i ), { 0x01, 0x02, 0x03 } );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).first );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->id == i );
|
||||
}
|
||||
|
||||
sidechain::info_for_vin::count_id_info_for_vin = 0;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( input_withdrawal_info_check_data_test ) {
|
||||
sidechain::input_withdrawal_info infos( db );
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
sidechain::prev_out out = { std::to_string( i ), static_cast<uint32_t>( i ), static_cast< uint64_t >( i ) };
|
||||
infos.insert_info_for_vin( out, "addr" + std::to_string( i ), { 0x01, 0x02, 0x03 } );
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).first );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->id == i );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.hash_tx == std::to_string( i ) );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.n_vout == i );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.amount == i );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->address == "addr" + std::to_string( i ) );
|
||||
std::vector<char> script = { 0x01, 0x02, 0x03 };
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->script == script );
|
||||
}
|
||||
|
||||
sidechain::info_for_vin::count_id_info_for_vin = 0;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( input_withdrawal_info_modify_test ) {
|
||||
sidechain::input_withdrawal_info infos( db );
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
sidechain::prev_out out = { std::to_string( i ), static_cast<uint32_t>( i ), static_cast< uint64_t >( i ) };
|
||||
infos.insert_info_for_vin( out, "addr" + std::to_string( i ), { 0x01, 0x02, 0x03 } );
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
if( i % 2 == 0 ) {
|
||||
auto iter = infos.find_info_for_vin( static_cast< uint64_t >( i ) );
|
||||
BOOST_CHECK( iter.first );
|
||||
infos.modify_info_for_vin( *iter.second, [&]( sidechain::info_for_vin& obj ) {
|
||||
obj.out.hash_tx = std::to_string( i + 1 );
|
||||
obj.out.n_vout = i + 1;
|
||||
obj.out.amount = i + 1;
|
||||
obj.address = "addr" + std::to_string( i ) + std::to_string( i );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
if( i % 2 == 0 ) {
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).first );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->id == i );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.hash_tx == std::to_string( i + 1 ) );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.n_vout == i + 1 );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.amount == i + 1 );
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->address == "addr" + std::to_string( i ) + std::to_string( i ) );
|
||||
std::vector<char> script = { 0x01, 0x02, 0x03 };
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->script == script );
|
||||
}
|
||||
}
|
||||
|
||||
sidechain::info_for_vin::count_id_info_for_vin = 0;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( input_withdrawal_info_remove_vin_test ) {
|
||||
sidechain::input_withdrawal_info infos( db );
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
sidechain::prev_out out = { std::to_string( i ), static_cast<uint32_t>( i ), static_cast< uint64_t >( i ) };
|
||||
infos.insert_info_for_vin( out, "addr" + std::to_string( i ), { 0x01, 0x02, 0x03 } );
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
if( i % 2 == 0 ) {
|
||||
auto iter = infos.find_info_for_vin( static_cast< uint64_t >( i ) );
|
||||
BOOST_CHECK( iter.first );
|
||||
infos.remove_info_for_vin( *iter.second );
|
||||
}
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
if( i % 2 == 0 ) {
|
||||
BOOST_CHECK( !infos.find_info_for_vin( static_cast< uint64_t >( i ) ).first );
|
||||
} else {
|
||||
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).first );
|
||||
}
|
||||
}
|
||||
|
||||
sidechain::info_for_vin::count_id_info_for_vin = 0;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( input_withdrawal_info_get_info_for_vins_test ) {
|
||||
sidechain::input_withdrawal_info infos( db );
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
sidechain::prev_out out = { std::to_string( i ), static_cast<uint32_t>( i ), static_cast< uint64_t >( i ) };
|
||||
infos.insert_info_for_vin( out, "addr" + std::to_string( i ), { 0x01, 0x02, 0x03 } );
|
||||
}
|
||||
|
||||
const auto& vins = infos.get_info_for_vins();
|
||||
BOOST_CHECK( vins.size() == 5 ); // 5 amount vins to bitcoin transaction
|
||||
|
||||
for( size_t i = 0; i < 7; i++ ) {
|
||||
auto iter = infos.find_info_for_vin( static_cast< uint64_t >( i ) );
|
||||
infos.mark_as_used_vin( *iter.second );
|
||||
}
|
||||
|
||||
const auto& vins2 = infos.get_info_for_vins();
|
||||
BOOST_CHECK( vins2.size() == 3 );
|
||||
|
||||
sidechain::info_for_vin::count_id_info_for_vin = 0;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( input_withdrawal_info_insert_vout_test ) {
|
||||
sidechain::input_withdrawal_info infos( db );
|
||||
infos.insert_info_for_vout( account_id_type(), "1", 1 );
|
||||
BOOST_CHECK( infos.size_info_for_vouts() == 1 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( input_withdrawal_info_many_insert_vout_test ) {
|
||||
sidechain::input_withdrawal_info infos( db );
|
||||
for( size_t i = 1; i <= 10; i++ ) {
|
||||
infos.insert_info_for_vout( account_id_type(i), std::to_string( i ), static_cast<uint64_t>( i ) );
|
||||
}
|
||||
BOOST_CHECK( infos.size_info_for_vouts() == 10 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( input_withdrawal_info_remove_vout_test ) {
|
||||
sidechain::input_withdrawal_info infos( db );
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
infos.insert_info_for_vout( account_id_type(i), std::to_string( i ), static_cast<uint64_t>( i ) );
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
if( i % 2 == 0 ) {
|
||||
auto iter = infos.find_info_for_vout( static_cast< uint64_t >( i ) );
|
||||
BOOST_CHECK( iter.first );
|
||||
infos.remove_info_for_vout( *iter.second );
|
||||
}
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
if( i % 2 == 0 ) {
|
||||
BOOST_CHECK( !infos.find_info_for_vout( static_cast< uint64_t >( i ) ).first );
|
||||
} else {
|
||||
BOOST_CHECK( infos.find_info_for_vout( static_cast< uint64_t >( i ) ).first );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( input_withdrawal_info_get_info_for_vouts_test ) {
|
||||
sidechain::input_withdrawal_info infos( db );
|
||||
for( size_t i = 0; i < 10; i++ ) {
|
||||
infos.insert_info_for_vout( account_id_type(i), std::to_string( i ), static_cast<uint64_t>( i ) );
|
||||
}
|
||||
|
||||
const auto& vouts = infos.get_info_for_vouts();
|
||||
BOOST_CHECK( vouts.size() == 5 ); // 5 amount vouts to bitcoin transaction
|
||||
|
||||
for( size_t i = 0; i < 7; i++ ) {
|
||||
auto iter = infos.find_info_for_vout( static_cast< uint64_t >( i ) );
|
||||
infos.mark_as_used_vout( *iter.second );
|
||||
}
|
||||
|
||||
const auto& vouts2 = infos.get_info_for_vouts();
|
||||
BOOST_CHECK( vouts2.size() == 3 );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
Loading…
Reference in a new issue