From f22d61855bc4b2bb33dfa353fbeb6cf3ef6bc5be Mon Sep 17 00:00:00 2001 From: Alexander Suslikov Date: Mon, 28 Jan 2019 11:18:22 +0300 Subject: [PATCH] Added sidechain_proposal_object creation, changed thread_safe_index and input_withdrawal_info --- .../graphene/chain/proposal_evaluator.hpp | 14 +++++ libraries/chain/proposal_evaluator.cpp | 33 +++++++++++ .../sidechain/input_withdrawal_info.hpp | 6 +- .../include/sidechain/thread_safe_index.hpp | 10 ++-- libraries/sidechain/input_withdrawal_info.cpp | 8 +-- tests/tests/input_withdrawal_info_tests.cpp | 57 +++++++++++-------- 6 files changed, 91 insertions(+), 37 deletions(-) diff --git a/libraries/chain/include/graphene/chain/proposal_evaluator.hpp b/libraries/chain/include/graphene/chain/proposal_evaluator.hpp index bf6fc547..ca1bed39 100644 --- a/libraries/chain/include/graphene/chain/proposal_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/proposal_evaluator.hpp @@ -29,6 +29,20 @@ #include namespace graphene { namespace chain { + + class sidechain_hardfork_visitor + { + public: + typedef void result_type; + database& db; + + sidechain_hardfork_visitor( database& _db ) : db(_db) {} + + template + void operator()( const T &v, const proposal_id_type prop_id ) const {} + + void operator()( const bitcoin_transaction_send_operation &v, const proposal_id_type prop_id ); + }; class proposal_create_evaluator : public evaluator { diff --git a/libraries/chain/proposal_evaluator.cpp b/libraries/chain/proposal_evaluator.cpp index a6640ea4..d19ee541 100644 --- a/libraries/chain/proposal_evaluator.cpp +++ b/libraries/chain/proposal_evaluator.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -142,6 +143,30 @@ struct proposal_operation_hardfork_visitor } }; +void sidechain_hardfork_visitor::operator()( const bitcoin_transaction_send_operation &v, const proposal_id_type prop_id ) +{ + db.create([&]( sidechain_proposal_object& sch_prop ) { + sch_prop.proposal_type = sidechain::sidechain_proposal_type::SEND_BTC_TRANSACTION; + sch_prop.proposal_id = prop_id; + }); + + for( auto& vin : v.vins ) { + auto itr = db.i_w_info.find_info_for_vin( vin.identifier ); + if( !itr.first ) + continue; + db.i_w_info.mark_as_used_vin( *itr.second ); + } + + for( auto& vout : v.vouts ) { + auto itr = db.i_w_info.find_info_for_vout( vout ); + FC_ASSERT( itr.first, "info_for_vout_object don't exist." ); + db.i_w_info.mark_as_used_vout( *itr.second ); + } + + fc::sha256 hashid = fc::sha256::hash(v.transaction.vin[0].prevout.hash.str() + std::to_string(v.transaction.vin[0].prevout.n)); + db.pw_vout_manager.use_latest_vout( hashid ); +} + void_result proposal_create_evaluator::do_evaluate(const proposal_create_operation& o) { try { const database& d = db(); @@ -157,6 +182,12 @@ void_result proposal_create_evaluator::do_evaluate(const proposal_create_operati FC_ASSERT( !o.review_period_seconds || fc::seconds(*o.review_period_seconds) < (o.expiration_time - d.head_block_time()), "Proposal review period must be less than its overall lifetime." ); + bool pbtc_op = o.proposed_ops[0].op.which() == operation::tag::value; + + if( d.is_sidechain_fork_needed() && pbtc_op ) { + FC_THROW( "Currently the operation is unavailable." ); + } + { // If we're dealing with the committee authority, make sure this transaction has a sufficient review period. flat_set auths; @@ -196,6 +227,7 @@ void_result proposal_create_evaluator::do_evaluate(const proposal_create_operati object_id_type proposal_create_evaluator::do_apply(const proposal_create_operation& o) { try { database& d = db(); + sidechain_hardfork_visitor sidechain_vtor( d ); const proposal_object& proposal = d.create([&](proposal_object& proposal) { _proposed_trx.expiration = o.expiration_time; @@ -220,6 +252,7 @@ object_id_type proposal_create_evaluator::do_apply(const proposal_create_operati std::inserter(proposal.required_active_approvals, proposal.required_active_approvals.begin())); }); + sidechain_vtor( o.proposed_ops[0].op, proposal.id ); return proposal.id; } FC_CAPTURE_AND_RETHROW( (o) ) } diff --git a/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp b/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp index 57724028..0126f6f2 100644 --- a/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp +++ b/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp @@ -60,7 +60,7 @@ class input_withdrawal_info public: - using iterator_id_vin = typename info_for_vin_index::template index::type::iterator; + using iterator_identifier_vin = typename info_for_vin_index::template index::type::iterator; using iterator_id_vout = typename graphene::chain::info_for_vout_index::index_type::template index::type::iterator; @@ -75,7 +75,7 @@ public: void remove_info_for_vin( const info_for_vin& obj ); - std::pair find_info_for_vin( uint64_t id ); + std::pair find_info_for_vin( fc::sha256 identifier ); size_t size_info_for_vins() { return info_for_vins.size(); } @@ -88,7 +88,7 @@ public: void remove_info_for_vout( const info_for_vout& obj ); - std::pair find_info_for_vout( uint64_t id ); + std::pair find_info_for_vout( graphene::chain::info_for_vout_id_type id ); size_t size_info_for_vouts(); diff --git a/libraries/sidechain/include/sidechain/thread_safe_index.hpp b/libraries/sidechain/include/sidechain/thread_safe_index.hpp index c4fdbda9..6c0e1d7d 100644 --- a/libraries/sidechain/include/sidechain/thread_safe_index.hpp +++ b/libraries/sidechain/include/sidechain/thread_safe_index.hpp @@ -4,7 +4,7 @@ namespace sidechain { -struct by_id; +struct by_identifier; template class thread_safe_index { @@ -12,7 +12,7 @@ class thread_safe_index { public: using iterator = typename T1::iterator; - using iterator_id = typename T1::template index::type::iterator; + using iterator_identifier = typename T1::template index::type::iterator; std::pair insert( const typename T1::value_type& value ) { std::lock_guard locker( lock ); @@ -34,10 +34,10 @@ public: return data.size(); } - std::pair find( uint64_t id ) { + std::pair find( fc::sha256 identifier ) { std::lock_guard locker( lock ); - auto& index = data.template get(); - auto it = index.find( id ); + auto& index = data.template get(); + auto it = index.find( identifier ); if( it != index.end() ) { return std::make_pair(true, it); } diff --git a/libraries/sidechain/input_withdrawal_info.cpp b/libraries/sidechain/input_withdrawal_info.cpp index 866f442c..a5023574 100644 --- a/libraries/sidechain/input_withdrawal_info.cpp +++ b/libraries/sidechain/input_withdrawal_info.cpp @@ -35,9 +35,9 @@ void input_withdrawal_info::remove_info_for_vin( const info_for_vin& obj ) info_for_vins.remove( obj ); } -std::pair input_withdrawal_info::find_info_for_vin( uint64_t id ) +std::pair input_withdrawal_info::find_info_for_vin( fc::sha256 identifier ) { - return info_for_vins.find( id ); + return info_for_vins.find( identifier ); } std::vector input_withdrawal_info::get_info_for_vins() @@ -86,10 +86,10 @@ void input_withdrawal_info::remove_info_for_vout( const info_for_vout& obj ) db.remove( obj ); } -std::pair input_withdrawal_info::find_info_for_vout( uint64_t id ) +std::pair input_withdrawal_info::find_info_for_vout( graphene::chain::info_for_vout_id_type id ) { const auto& info_for_vout_idx = db.get_index_type().indices().get< graphene::chain::by_id >(); - auto itr = info_for_vout_idx.find( graphene::chain::info_for_vout_id_type( id ) ); + auto itr = info_for_vout_idx.find( id ); return std::make_pair( itr != info_for_vout_idx.end(), itr ); } diff --git a/tests/tests/input_withdrawal_info_tests.cpp b/tests/tests/input_withdrawal_info_tests.cpp index 38f087d2..48ae4fe0 100644 --- a/tests/tests/input_withdrawal_info_tests.cpp +++ b/tests/tests/input_withdrawal_info_tests.cpp @@ -36,8 +36,9 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_id_test ) for( size_t i = 0; i < 10; i++ ) { prev_out out = { std::to_string( i ), static_cast( 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 ); + auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).first ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->id == i ); } info_for_vin::count_id_info_for_vin = 0; @@ -52,14 +53,15 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_check_data_test ) } 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 ) ); + auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).first ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->id == i ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.hash_tx == std::to_string( i ) ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.n_vout == i ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.amount == i ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->address == "addr" + std::to_string( i ) ); std::vector script = { 0x01, 0x02, 0x03 }; - BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->script == script ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->script == script ); } info_for_vin::count_id_info_for_vin = 0; @@ -75,7 +77,8 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_modify_test ) for( size_t i = 0; i < 10; i++ ) { if( i % 2 == 0 ) { - auto iter = infos.find_info_for_vin( static_cast< uint64_t >( i ) ); + auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) ); + auto iter = infos.find_info_for_vin( identifier ); BOOST_CHECK( iter.first ); infos.modify_info_for_vin( *iter.second, [&]( info_for_vin& obj ) { obj.out.hash_tx = std::to_string( i + 1 ); @@ -88,14 +91,15 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_modify_test ) 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 ) ); + auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).first ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->id == i ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.hash_tx == std::to_string( i + 1 ) ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.n_vout == i + 1 ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.amount == i + 1 ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->address == "addr" + std::to_string( i ) + std::to_string( i ) ); std::vector script = { 0x01, 0x02, 0x03 }; - BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->script == script ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).second->script == script ); } } @@ -112,17 +116,19 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_remove_vin_test ) for( size_t i = 0; i < 10; i++ ) { if( i % 2 == 0 ) { - auto iter = infos.find_info_for_vin( static_cast< uint64_t >( i ) ); + auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) ); + auto iter = infos.find_info_for_vin( identifier ); BOOST_CHECK( iter.first ); infos.remove_info_for_vin( *iter.second ); } } for( size_t i = 0; i < 10; i++ ) { + auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( 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( identifier ).first ); } else { - BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).first ); + BOOST_CHECK( infos.find_info_for_vin( identifier ).first ); } } @@ -141,7 +147,8 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_get_info_for_vins_test ) 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 ) ); + auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) ); + auto iter = infos.find_info_for_vin( identifier ); infos.mark_as_used_vin( *iter.second ); } @@ -176,7 +183,7 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_remove_vout_test ) for( size_t i = 0; i < 10; i++ ) { if( i % 2 == 0 ) { - auto iter = infos.find_info_for_vout( static_cast< uint64_t >( i ) ); + auto iter = infos.find_info_for_vout( graphene::chain::info_for_vout_id_type(i) ); BOOST_CHECK( iter.first ); infos.remove_info_for_vout( *iter.second ); } @@ -184,9 +191,9 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_remove_vout_test ) 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 ); + BOOST_CHECK( !infos.find_info_for_vout( graphene::chain::info_for_vout_id_type(i) ).first ); } else { - BOOST_CHECK( infos.find_info_for_vout( static_cast< uint64_t >( i ) ).first ); + BOOST_CHECK( infos.find_info_for_vout( graphene::chain::info_for_vout_id_type(i) ).first ); } } } @@ -202,7 +209,7 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_get_info_for_vouts_test ) 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 ) ); + auto iter = infos.find_info_for_vout( graphene::chain::info_for_vout_id_type(i) ); infos.mark_as_used_vout( *iter.second ); }