diff --git a/libraries/app/impacted.cpp b/libraries/app/impacted.cpp index f0ee0e2d..9c72ca0c 100644 --- a/libraries/app/impacted.cpp +++ b/libraries/app/impacted.cpp @@ -298,7 +298,11 @@ struct get_impacted_account_visitor { _impacted.insert( op.payer ); } - void operator()( const bitcoin_issue_operation& op ) + void operator()( const bitcoin_issue_operation& op ) + { + _impacted.insert( op.payer ); + } + void operator()( const bitcoin_transaction_revert_operation& op ) { _impacted.insert( op.payer ); } diff --git a/libraries/chain/bitcoin_transaction_evaluator.cpp b/libraries/chain/bitcoin_transaction_evaluator.cpp index f86429f7..43613115 100644 --- a/libraries/chain/bitcoin_transaction_evaluator.cpp +++ b/libraries/chain/bitcoin_transaction_evaluator.cpp @@ -212,4 +212,59 @@ bool bitcoin_transaction_sign_evaluator::check_sigs( const bytes& key_data, cons return true; } +void_result bitcoin_transaction_revert_evaluator::do_evaluate( const bitcoin_transaction_revert_operation& op ) +{ try { + + database& d = db(); + const auto& btc_trx_idx = d.get_index_type().indices().get(); + 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( 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(); +} FC_CAPTURE_AND_RETHROW( (op) ) } + +void_result bitcoin_transaction_revert_evaluator::do_apply( const bitcoin_transaction_revert_operation& op ) +{ try { + + database& d = db(); + const auto& btc_trx_idx = d.get_index_type().indices().get(); + 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; + }); + } else { + d.remove( vin_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_init.cpp b/libraries/chain/db_init.cpp index 6009314f..b6442190 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -253,6 +253,7 @@ void database::initialize_evaluators() register_evaluator(); register_evaluator(); register_evaluator(); + register_evaluator(); } void database::initialize_indexes() diff --git a/libraries/chain/db_notify.cpp b/libraries/chain/db_notify.cpp index 1baa8ffc..f0c02a12 100644 --- a/libraries/chain/db_notify.cpp +++ b/libraries/chain/db_notify.cpp @@ -289,6 +289,10 @@ struct get_impacted_account_visitor { _impacted.insert( op.payer ); } + void operator()( const bitcoin_transaction_revert_operation& op ) + { + _impacted.insert( op.payer ); + } }; void operation_get_impacted_accounts( const operation& op, flat_set& result ) diff --git a/libraries/chain/include/graphene/chain/bitcoin_transaction_evaluator.hpp b/libraries/chain/include/graphene/chain/bitcoin_transaction_evaluator.hpp index d2d29d77..973a5fcf 100644 --- a/libraries/chain/include/graphene/chain/bitcoin_transaction_evaluator.hpp +++ b/libraries/chain/include/graphene/chain/bitcoin_transaction_evaluator.hpp @@ -40,4 +40,16 @@ public: }; +class bitcoin_transaction_revert_evaluator : public evaluator +{ + +public: + + typedef bitcoin_transaction_revert_operation operation_type; + + void_result do_evaluate( const bitcoin_transaction_revert_operation& op ); + + void_result do_apply( const bitcoin_transaction_revert_operation& op ); +}; + } } // graphene::chain \ No newline at end of file diff --git a/libraries/chain/include/graphene/chain/info_for_used_vin_object.hpp b/libraries/chain/include/graphene/chain/info_for_used_vin_object.hpp index abd4ff67..5da7314b 100644 --- a/libraries/chain/include/graphene/chain/info_for_used_vin_object.hpp +++ b/libraries/chain/include/graphene/chain/info_for_used_vin_object.hpp @@ -20,6 +20,8 @@ class info_for_used_vin_object : public abstract_object valid_vins; + + + account_id_type fee_payer()const { return payer; } + void validate()const {} + share_type calculate_fee( const fee_parameters_type& k )const { return k.fee; } + }; + } } // graphene::chain FC_REFLECT( graphene::chain::bitcoin_transaction_send_operation::fee_parameters_type, (fee)(price_per_kbyte) ) @@ -56,3 +74,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::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) ) diff --git a/libraries/chain/include/graphene/chain/protocol/operations.hpp b/libraries/chain/include/graphene/chain/protocol/operations.hpp index b1496973..f9fc8b73 100644 --- a/libraries/chain/include/graphene/chain/protocol/operations.hpp +++ b/libraries/chain/include/graphene/chain/protocol/operations.hpp @@ -138,7 +138,8 @@ namespace graphene { namespace chain { bitcoin_address_create_operation, bitcoin_transaction_send_operation, bitcoin_transaction_sign_operation, - bitcoin_issue_operation + bitcoin_issue_operation, + bitcoin_transaction_revert_operation > operation; /// @} // operations group