From a9ca86cab24740b2948b7a1ecf56d0cf917d2b67 Mon Sep 17 00:00:00 2001 From: Anton Shkinder Date: Fri, 8 Feb 2019 13:19:04 +0300 Subject: [PATCH] Added creation of bitcoin revert proposals --- .../chain/bitcoin_transaction_evaluator.cpp | 56 ++++++++++--------- libraries/chain/db_block.cpp | 5 ++ libraries/chain/db_sidechain.cpp | 33 +++++++++++ .../chain/include/graphene/chain/database.hpp | 1 + .../chain/protocol/bitcoin_transaction.hpp | 19 +++++-- .../bitcoin_transaction_confirmations.hpp | 4 +- 6 files changed, 86 insertions(+), 32 deletions(-) diff --git a/libraries/chain/bitcoin_transaction_evaluator.cpp b/libraries/chain/bitcoin_transaction_evaluator.cpp index b8174b44..00b22b3d 100644 --- a/libraries/chain/bitcoin_transaction_evaluator.cpp +++ b/libraries/chain/bitcoin_transaction_evaluator.cpp @@ -221,15 +221,17 @@ void_result bitcoin_transaction_revert_evaluator::do_evaluate( const bitcoin_tra const auto& vouts_info_idx = d.get_index_type().indices().get(); const auto& vins_info_idx = d.get_index_type().indices().get(); - const auto& btc_itr = btc_trx_idx.find( op.transaction_id ); - FC_ASSERT( btc_itr != btc_trx_idx.end() ); + for( auto trx_info: op.transactions_info ) { + const auto& btc_itr = btc_trx_idx.find( trx_info.transaction_id ); + FC_ASSERT( btc_itr != btc_trx_idx.end() ); - for( const auto& vout_id : btc_itr->vouts ) { - FC_ASSERT( vouts_info_idx.find( vout_id ) != vouts_info_idx.end() ); - } - - for( const auto& vout_id : btc_itr->vins ) { - FC_ASSERT( vins_info_idx.find( vout_id ) != vins_info_idx.end() ); + for( const auto& vout_id : btc_itr->vouts ) { + FC_ASSERT( vouts_info_idx.find( vout_id ) != vouts_info_idx.end() ); + } + + for( const auto& vout_id : btc_itr->vins ) { + FC_ASSERT( vins_info_idx.find( vout_id ) != vins_info_idx.end() ); + } } return void_result(); @@ -243,27 +245,29 @@ void_result bitcoin_transaction_revert_evaluator::do_apply( const bitcoin_transa const auto& vouts_info_idx = d.get_index_type().indices().get(); const auto& vins_info_idx = d.get_index_type().indices().get(); - const auto& btc_trx_obj = *btc_trx_idx.find( op.transaction_id ); - - for( const auto& vout_id : btc_trx_obj.vouts ) { - const auto& vout_obj = *vouts_info_idx.find( vout_id ); - d.modify( vout_obj, [&]( info_for_vout_object& obj ){ - obj.used = false; - }); - } - - for( const auto& vin_id : btc_trx_obj.vins ) { - const auto& vin_obj = *vins_info_idx.find( vin_id ); - if( op.valid_vins.count( fc::sha256 ( vin_obj.out.hash_tx ) ) ) { - d.modify( vin_obj, [&]( info_for_used_vin_object& obj ){ - obj.resend = true; + for( auto trx_info: op.transactions_info ) { + const auto& btc_trx_obj = *btc_trx_idx.find( trx_info.transaction_id ); + + for( const auto& vout_id : btc_trx_obj.vouts ) { + const auto& vout_obj = *vouts_info_idx.find( vout_id ); + d.modify( vout_obj, [&]( info_for_vout_object& obj ){ + obj.used = false; }); - } else { - d.remove( vin_obj ); } + + for( const auto& vin_id : btc_trx_obj.vins ) { + const auto& vin_obj = *vins_info_idx.find( vin_id ); + if( trx_info.valid_vins.count( fc::sha256 ( vin_obj.out.hash_tx ) ) ) { + d.modify( vin_obj, [&]( info_for_used_vin_object& obj ){ + obj.resend = true; + }); + } else { + d.remove( vin_obj ); + } + } + d.bitcoin_confirmations.remove( trx_info.transaction_id ); + d.remove( btc_trx_obj ); } - d.bitcoin_confirmations.remove( op.transaction_id ); - d.remove( btc_trx_obj ); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index 35d5f78a..42c7e327 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -427,6 +427,11 @@ signed_block database::_generate_block( if( iss_op.valid() ) { _pending_tx.insert( _pending_tx.begin(), create_signed_transaction( block_signing_private_key, *iss_op ) ); } + + auto revert_op = create_bitcoin_revert_proposals( witness_obj ); + if( revert_op.valid() ) { + _pending_tx.insert( _pending_tx.begin(), create_signed_transaction( block_signing_private_key, *revert_op ) ); + } } send_btc_tx_flag = false; diff --git a/libraries/chain/db_sidechain.cpp b/libraries/chain/db_sidechain.cpp index 46014115..aef371a8 100644 --- a/libraries/chain/db_sidechain.cpp +++ b/libraries/chain/db_sidechain.cpp @@ -335,4 +335,37 @@ fc::optional database::create_bitcoin_issue_proposals( const witness_ return fc::optional(); } +fc::optional database::create_bitcoin_revert_proposals( const witness_object& current_witness ) +{ + using iter_by_missing = btc_tx_confirmations_index::index::type::iterator; + std::vector trx_info; + + bitcoin_confirmations.safe_for([&]( iter_by_missing itr_b, iter_by_missing itr_e ){ + for(auto iter = itr_b; iter != itr_e; iter++) { + if( !iter->missing ) return; + + const auto& btc_trx_idx = get_index_type().indices().get(); + const auto& btc_tx = btc_trx_idx.find( iter->transaction_id ); + if( btc_tx == btc_trx_idx.end() ) continue; + trx_info.push_back( revert_trx_info( iter->transaction_id, iter->valid_vins ) ); + } + }); + + if( trx_info.size() ) { + bitcoin_transaction_revert_operation revert_op; + revert_op.payer = get_sidechain_account_id(); + revert_op.transactions_info = trx_info; + + proposal_create_operation proposal_op; + proposal_op.fee_paying_account = current_witness.witness_account; + proposal_op.proposed_ops.push_back( op_wrapper( revert_op ) ); + uint32_t lifetime = ( get_global_properties().parameters.block_interval * get_global_properties().active_witnesses.size() ) * 3; + proposal_op.expiration_time = time_point_sec( head_block_time().sec_since_epoch() + lifetime ); + + return fc::optional( proposal_op ); + } + + return fc::optional(); +} + } } \ No newline at end of file diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index e5d15cd5..9ef282b7 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -545,6 +545,7 @@ namespace graphene { namespace chain { fc::optional create_bitcoin_issue_proposals( const witness_object& current_witness ); + fc::optional create_bitcoin_revert_proposals( const witness_object& current_witness ); fc::signal send_btc_tx; diff --git a/libraries/chain/include/graphene/chain/protocol/bitcoin_transaction.hpp b/libraries/chain/include/graphene/chain/protocol/bitcoin_transaction.hpp index 137ac882..654b2fcb 100644 --- a/libraries/chain/include/graphene/chain/protocol/bitcoin_transaction.hpp +++ b/libraries/chain/include/graphene/chain/protocol/bitcoin_transaction.hpp @@ -48,6 +48,15 @@ namespace graphene { namespace chain { share_type calculate_fee( const fee_parameters_type& k )const { return 0; } }; + struct revert_trx_info + { + revert_trx_info() = default; + revert_trx_info( fc::sha256 trx_id, std::set< fc::sha256 > vins ): transaction_id( trx_id ), valid_vins( vins ) {} + + fc::sha256 transaction_id; + std::set< fc::sha256 > valid_vins; + }; + struct bitcoin_transaction_revert_operation : public base_operation { struct fee_parameters_type { @@ -55,11 +64,10 @@ namespace graphene { namespace chain { uint32_t price_per_kbyte = 0; }; - asset fee; - account_id_type payer; + asset fee; + account_id_type payer; - fc::sha256 transaction_id; - std::set< fc::sha256 > valid_vins; + std::vector< revert_trx_info > transactions_info; account_id_type fee_payer()const { return payer; } @@ -75,5 +83,6 @@ FC_REFLECT( graphene::chain::bitcoin_transaction_send_operation, (fee)(payer)(vi FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation::fee_parameters_type, (fee)(price_per_kbyte) ) FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation, (fee)(payer)(proposal_id)(signatures) ) +FC_REFLECT( graphene::chain::revert_trx_info, (transaction_id)(valid_vins) ) FC_REFLECT( graphene::chain::bitcoin_transaction_revert_operation::fee_parameters_type, (fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::bitcoin_transaction_revert_operation, (fee)(payer)(transaction_id)(valid_vins) ) +FC_REFLECT( graphene::chain::bitcoin_transaction_revert_operation, (fee)(payer)(transactions_info) ) diff --git a/libraries/sidechain/include/sidechain/bitcoin_transaction_confirmations.hpp b/libraries/sidechain/include/sidechain/bitcoin_transaction_confirmations.hpp index 89e4f20d..bd06f91f 100644 --- a/libraries/sidechain/include/sidechain/bitcoin_transaction_confirmations.hpp +++ b/libraries/sidechain/include/sidechain/bitcoin_transaction_confirmations.hpp @@ -47,11 +47,13 @@ struct bitcoin_transaction_confirmations struct by_hash; struct by_confirmed_and_not_used; +struct by_missing_first; using btc_tx_confirmations_index = boost::multi_index_container, member>, - ordered_non_unique, identity< bitcoin_transaction_confirmations >, bitcoin_transaction_confirmations::comparer > + ordered_non_unique, identity< bitcoin_transaction_confirmations >, bitcoin_transaction_confirmations::comparer >, + ordered_non_unique, member, std::greater> > >;