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( app )
|
||||||
add_subdirectory( plugins )
|
add_subdirectory( plugins )
|
||||||
add_subdirectory( wallet )
|
add_subdirectory( wallet )
|
||||||
|
add_subdirectory( sidechain )
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,8 @@ add_library( graphene_chain
|
||||||
)
|
)
|
||||||
|
|
||||||
add_dependencies( graphene_chain build_hardfork_hpp )
|
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
|
target_include_directories( graphene_chain
|
||||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" )
|
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_BINARY_DIR}/include" )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,8 @@
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
|
#include <graphene/chain/info_for_vout_object.hpp>
|
||||||
|
|
||||||
namespace graphene { namespace chain {
|
namespace graphene { namespace chain {
|
||||||
|
|
||||||
// C++ requires that static class variables declared and initialized
|
// 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<distributed_dividend_balance_object_index > >();
|
||||||
add_index< primary_index<pending_dividend_payout_balance_for_holder_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<total_distributed_dividend_balance_object_index > >();
|
||||||
|
|
||||||
|
add_index< primary_index<info_for_vout_index > >();
|
||||||
}
|
}
|
||||||
|
|
||||||
void database::init_genesis(const genesis_state_type& genesis_state)
|
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_group_object_type,
|
||||||
betting_market_object_type,
|
betting_market_object_type,
|
||||||
bet_object_type,
|
bet_object_type,
|
||||||
|
info_for_vout_object_type,
|
||||||
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
|
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_group_object;
|
||||||
class betting_market_object;
|
class betting_market_object;
|
||||||
class bet_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, account_object_type, account_object> account_id_type;
|
||||||
typedef object_id< protocol_ids, asset_object_type, asset_object> asset_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_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, 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, 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
|
// implementation types
|
||||||
class global_property_object;
|
class global_property_object;
|
||||||
|
|
@ -402,6 +405,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
|
||||||
(betting_market_group_object_type)
|
(betting_market_group_object_type)
|
||||||
(betting_market_object_type)
|
(betting_market_object_type)
|
||||||
(bet_object_type)
|
(bet_object_type)
|
||||||
|
(info_for_vout_object_type)
|
||||||
(OBJECT_TYPE_COUNT)
|
(OBJECT_TYPE_COUNT)
|
||||||
)
|
)
|
||||||
FC_REFLECT_ENUM( graphene::chain::impl_object_type,
|
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