Added check_bitcoin_transaction_revert_operation
This commit is contained in:
parent
7428c10414
commit
fa2eff74c2
6 changed files with 152 additions and 18 deletions
|
|
@ -132,6 +132,15 @@ void database::processing_sidechain_proposals( const witness_object& current_wit
|
|||
|
||||
sidechain_proposal_checker checker( *this );
|
||||
|
||||
auto approve_propose = [ & ]( const proposal_id_type& id )
|
||||
{
|
||||
proposal_update_operation puo;
|
||||
puo.fee_paying_account = current_witness.witness_account;
|
||||
puo.proposal = id;
|
||||
puo.active_approvals_to_add = { current_witness.witness_account };
|
||||
_pending_tx.insert( _pending_tx.begin(), create_signed_transaction( private_key, puo ) );
|
||||
};
|
||||
|
||||
for( auto& sidechain_proposal : sidechain_proposal_idx ) {
|
||||
|
||||
const auto& proposal = proposal_idx.find( sidechain_proposal.proposal_id );
|
||||
|
|
@ -143,11 +152,7 @@ void database::processing_sidechain_proposals( const witness_object& current_wit
|
|||
|
||||
switch( sidechain_proposal.proposal_type ) {
|
||||
case sidechain_proposal_type::ISSUE_BTC :{
|
||||
proposal_update_operation puo;
|
||||
puo.fee_paying_account = current_witness.witness_account;
|
||||
puo.proposal = proposal->id;
|
||||
puo.active_approvals_to_add = { current_witness.witness_account };
|
||||
_pending_tx.insert( _pending_tx.begin(), create_signed_transaction( private_key, puo ) );
|
||||
approve_propose( proposal->id );
|
||||
break;
|
||||
}
|
||||
case sidechain_proposal_type::SEND_BTC_TRANSACTION :{
|
||||
|
|
@ -159,7 +164,12 @@ void database::processing_sidechain_proposals( const witness_object& current_wit
|
|||
}
|
||||
break;
|
||||
}
|
||||
case sidechain_proposal_type::RETURN_PBTC_BACK :{}
|
||||
case sidechain_proposal_type::REVERT_BTC_TRANSACTION :{
|
||||
bitcoin_transaction_revert_operation op = proposal->proposed_transaction.operations.back().get<bitcoin_transaction_revert_operation>();
|
||||
if( checker.check_bitcoin_transaction_revert_operation( op ) )
|
||||
approve_propose( proposal->id );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,6 +55,14 @@ namespace graphene { namespace chain {
|
|||
|
||||
fc::sha256 transaction_id;
|
||||
std::set< fc::sha256 > valid_vins;
|
||||
|
||||
bool operator ==( const revert_trx_info& trx_info ){
|
||||
return this->transaction_id == trx_info.transaction_id && this->valid_vins == trx_info.valid_vins;
|
||||
}
|
||||
|
||||
bool operator !=( const revert_trx_info& trx_info ){
|
||||
return this->transaction_id != trx_info.transaction_id || this->valid_vins != trx_info.valid_vins;
|
||||
}
|
||||
};
|
||||
|
||||
struct bitcoin_transaction_revert_operation : public base_operation
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ public:
|
|||
|
||||
bool check_witness_opportunity_to_approve( const witness_object& current_witness, const proposal_object& proposal );
|
||||
|
||||
bool check_bitcoin_transaction_revert_operation( const bitcoin_transaction_revert_operation& op );
|
||||
|
||||
private:
|
||||
|
||||
bool check_info_for_pw_vin( const info_for_vin& info_for_vin );
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ enum class sidechain_proposal_type
|
|||
{
|
||||
ISSUE_BTC,
|
||||
SEND_BTC_TRANSACTION,
|
||||
RETURN_PBTC_BACK
|
||||
REVERT_BTC_TRANSACTION
|
||||
};
|
||||
|
||||
struct prev_out
|
||||
|
|
@ -56,5 +56,5 @@ struct prev_out
|
|||
}
|
||||
|
||||
FC_REFLECT_ENUM( sidechain::payment_type, (NULLDATA)(P2PK)(P2PKH)(P2SH)(P2WPKH)(P2WSH)(P2SH_WPKH)(P2SH_WSH) );
|
||||
FC_REFLECT_ENUM( sidechain::sidechain_proposal_type, (ISSUE_BTC)(SEND_BTC_TRANSACTION)(RETURN_PBTC_BACK) );
|
||||
FC_REFLECT_ENUM( sidechain::sidechain_proposal_type, (ISSUE_BTC)(SEND_BTC_TRANSACTION)(REVERT_BTC_TRANSACTION) );
|
||||
FC_REFLECT( sidechain::prev_out, (hash_tx)(n_vout)(amount) );
|
||||
|
|
|
|||
|
|
@ -57,9 +57,21 @@ bool sidechain_proposal_checker::check_reuse( const operation& op )
|
|||
std::vector<fc::sha256> user_vin_identifiers;
|
||||
std::vector<info_for_vout_id_type> user_vout_ids;
|
||||
|
||||
auto get_bto_tx_info = [ & ]( fc::sha256 trx_id ) {
|
||||
const auto& bto_itr_idx = db.get_index_type<bitcoin_transaction_index>().indices().get<graphene::chain::by_transaction_id>();
|
||||
const auto& bto_itr = bto_itr_idx.find( trx_id );
|
||||
if( bto_itr == bto_itr_idx.end() ) {
|
||||
return false;
|
||||
}
|
||||
pw_vin_identifier = bto_itr->pw_vin;
|
||||
user_vout_ids = bto_itr->vouts;
|
||||
user_vin_identifiers = bto_itr->vins;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if( op.which() == operation::tag<bitcoin_transaction_send_operation>::value ) {
|
||||
bitcoin_transaction_send_operation btc_tx_send_op = op.get<bitcoin_transaction_send_operation>();
|
||||
|
||||
pw_vin_identifier = btc_tx_send_op.pw_vin.identifier;
|
||||
user_vout_ids = btc_tx_send_op.vouts;
|
||||
for( const auto& vin : btc_tx_send_op.vins ) {
|
||||
|
|
@ -67,17 +79,15 @@ bool sidechain_proposal_checker::check_reuse( const operation& op )
|
|||
}
|
||||
} else if ( op.which() == operation::tag<bitcoin_issue_operation>::value ) {
|
||||
bitcoin_issue_operation btc_issue_op = op.get<bitcoin_issue_operation>();
|
||||
const auto& bto_itr_idx = db.get_index_type<bitcoin_transaction_index>().indices().get<graphene::chain::by_transaction_id>();
|
||||
|
||||
for( const auto& id : btc_issue_op.transaction_ids ) {
|
||||
const auto& bto_itr = bto_itr_idx.find( id );
|
||||
if( bto_itr == bto_itr_idx.end() ) {
|
||||
if ( !get_bto_tx_info( id ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
pw_vin_identifier = bto_itr->pw_vin;
|
||||
user_vout_ids = bto_itr->vouts;
|
||||
user_vin_identifiers = bto_itr->vins;
|
||||
} else if ( op.which() == operation::tag<bitcoin_transaction_revert_operation>::value ) {
|
||||
bitcoin_transaction_revert_operation btc_tx_revert_op = op.get<bitcoin_transaction_revert_operation>();
|
||||
for( auto trx_info: btc_tx_revert_op.transactions_info ) {
|
||||
if ( !get_bto_tx_info( trx_info.transaction_id ) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,4 +169,20 @@ bool sidechain_proposal_checker::check_witness_opportunity_to_approve( const wit
|
|||
return is_active_witness() && does_the_witness_have_authority();
|
||||
}
|
||||
|
||||
bool sidechain_proposal_checker::check_bitcoin_transaction_revert_operation( const bitcoin_transaction_revert_operation& op )
|
||||
{
|
||||
const auto& btc_trx_idx = db.get_index_type<bitcoin_transaction_index>().indices().get<by_transaction_id>();
|
||||
|
||||
for( auto trx_info: op.transactions_info )
|
||||
{
|
||||
auto value = db.bitcoin_confirmations.find<sidechain::by_hash>( trx_info.transaction_id );
|
||||
if( !value.valid() ||
|
||||
btc_trx_idx.find( value->transaction_id ) == btc_trx_idx.end() ||
|
||||
trx_info != revert_trx_info( value->transaction_id, value->valid_vins ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return !op.transactions_info.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <graphene/chain/proposal_object.hpp>
|
||||
#include <graphene/chain/proposal_evaluator.hpp>
|
||||
#include <graphene/chain/witness_object.hpp>
|
||||
#include <graphene/chain/bitcoin_transaction_object.hpp>
|
||||
|
||||
using namespace sidechain;
|
||||
|
||||
|
|
@ -244,4 +245,91 @@ BOOST_AUTO_TEST_CASE( not_account_auths_wit_try_to_approve_btc_send_test )
|
|||
BOOST_CHECK( !checker.check_witness_opportunity_to_approve( *itr, *proposal_idx.begin() ) );
|
||||
}
|
||||
|
||||
void create_missing_bto( graphene::chain::database& db, uint32_t amount )
|
||||
{
|
||||
BOOST_REQUIRE( amount < 9 );
|
||||
while( amount-- > 0 ) {
|
||||
std::set<fc::sha256> vins { fc::sha256( std::string( 64,'1' + amount ) ), fc::sha256( std::string( 64,'2' + amount ) ) };
|
||||
sidechain::bitcoin_transaction_confirmations btc_trx_conf ( fc::sha256( std::string( 64,'1' + amount ) ), vins );
|
||||
btc_trx_conf.missing = true;
|
||||
db.bitcoin_confirmations.insert( btc_trx_conf );
|
||||
|
||||
db.create<graphene::chain::bitcoin_transaction_object>( [&]( graphene::chain::bitcoin_transaction_object& obj ){
|
||||
obj.transaction_id = fc::sha256( std::string( 64,'1' + amount ) );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
std::vector< revert_trx_info > get_transactions_info( graphene::chain::database& db, uint32_t amount )
|
||||
{
|
||||
using iter_by_missing = btc_tx_confirmations_index::index<by_missing_first>::type::iterator;
|
||||
std::vector< revert_trx_info > transactions_info;
|
||||
const auto& btc_trx_idx = db.get_index_type<graphene::chain::bitcoin_transaction_index>().indices().get<graphene::chain::by_transaction_id>();
|
||||
BOOST_CHECK_EQUAL( btc_trx_idx.size() , amount );
|
||||
|
||||
db.bitcoin_confirmations.safe_for<by_missing_first>([&]( 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_tx = btc_trx_idx.find( iter->transaction_id );
|
||||
if( btc_tx == btc_trx_idx.end() ) continue;
|
||||
transactions_info.push_back( revert_trx_info( iter->transaction_id, iter->valid_vins ) );
|
||||
}
|
||||
});
|
||||
|
||||
return transactions_info;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( bitcoin_transaction_revert_operation_checker_test )
|
||||
{
|
||||
using namespace graphene::chain;
|
||||
const uint32_t amount = 5;
|
||||
|
||||
create_missing_bto( db, amount );
|
||||
sidechain_proposal_checker checker( db );
|
||||
|
||||
bitcoin_transaction_revert_operation op;
|
||||
|
||||
std::vector< revert_trx_info > transactions_info = get_transactions_info( db, amount );
|
||||
|
||||
op.transactions_info = transactions_info;
|
||||
|
||||
BOOST_CHECK_EQUAL( transactions_info.size(), amount );
|
||||
BOOST_CHECK( checker.check_bitcoin_transaction_revert_operation( op ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( bitcoin_transaction_revert_operation_checker_failed_test )
|
||||
{
|
||||
using namespace graphene::chain;
|
||||
const uint32_t amount = 5;
|
||||
|
||||
create_missing_bto( db, amount );
|
||||
|
||||
std::set<fc::sha256> vins { fc::sha256( std::string( 64,'1' + 6 ) ), fc::sha256( std::string( 64,'1' + 8 ) ) };
|
||||
fc::sha256 trx_id( std::string( 64,'1' + 8 ) );
|
||||
sidechain::bitcoin_transaction_confirmations btc_trx_conf ( trx_id, vins );
|
||||
db.bitcoin_confirmations.insert( btc_trx_conf );
|
||||
db.create<graphene::chain::bitcoin_transaction_object>( [&]( graphene::chain::bitcoin_transaction_object& obj ){
|
||||
obj.transaction_id = fc::sha256( std::string( 64,'1' + 7 ) );
|
||||
} );
|
||||
|
||||
sidechain_proposal_checker checker( db );
|
||||
|
||||
bitcoin_transaction_revert_operation op;
|
||||
std::vector< revert_trx_info > transactions_info = get_transactions_info( db, amount + 1 );
|
||||
|
||||
op.transactions_info = transactions_info;
|
||||
op.transactions_info.push_back( revert_trx_info( trx_id, vins) );
|
||||
|
||||
BOOST_CHECK_EQUAL( op.transactions_info.size(), amount + 1 );
|
||||
BOOST_CHECK( !checker.check_bitcoin_transaction_revert_operation( op ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( no_btc_trx_to_revert_test )
|
||||
{
|
||||
sidechain_proposal_checker checker( db );
|
||||
|
||||
bitcoin_transaction_revert_operation op;
|
||||
BOOST_CHECK( !checker.check_bitcoin_transaction_revert_operation( op ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
|||
Loading…
Reference in a new issue