#include #include #include #include namespace graphene { namespace chain { void_result bitcoin_issue_evaluator::do_evaluate( const bitcoin_issue_operation& op ) { database& d = db(); const auto& btc_trx_idx = d.get_index_type().indices().get(); const auto& btc_addr_idx = d.get_index_type().indices().get(); const auto& vins_info_idx = d.get_index_type().indices().get(); const auto& vouts_info_idx = d.get_index_type().indices().get(); FC_ASSERT( op.payer == db().get_sidechain_account_id() ); const auto& btc_itr = btc_trx_idx.find( op.transaction_id ); FC_ASSERT( btc_itr != btc_trx_idx.end() ); for( auto& vin_id : btc_itr->vins ){ FC_ASSERT( vins_info_idx.find( vin_id ) != vins_info_idx.end() ); auto addr_itr = btc_addr_idx.find( vins_info_idx.find( vin_id )->address ); FC_ASSERT( addr_itr != btc_addr_idx.end() ); } for( auto& vout_id : btc_itr->vouts ) FC_ASSERT( vouts_info_idx.find( vout_id ) != vouts_info_idx.end() ); return void_result(); } void_result bitcoin_issue_evaluator::do_apply( const bitcoin_issue_operation& op ) { database& d = db(); const auto& btc_trx_idx = d.get_index_type().indices().get(); const auto& btc_obj = *btc_trx_idx.find( op.transaction_id ); add_issue( btc_obj ); d.pw_vout_manager.confirm_vout( btc_obj.pw_vin ); clear_btc_transaction_information( btc_obj ); return void_result(); } void bitcoin_issue_evaluator::add_issue( const bitcoin_transaction_object& btc_obj ) { database& d = db(); const auto& accounts_to_issue = get_accounts_to_issue( btc_obj.vins ); const auto& amounts_to_issue = get_amounts_to_issue( btc_obj.vins ); bool skip_fee_old = trx_state->skip_fee; bool skip_fee_schedule_check_old = trx_state->skip_fee_schedule_check; trx_state->skip_fee = true; trx_state->skip_fee_schedule_check = true; for( size_t i = 0; i < accounts_to_issue.size(); i++ ){ asset_issue_operation issue_op; issue_op.issuer = d.get_sidechain_account_id(); issue_op.asset_to_issue = asset( amounts_to_issue[i], d.get_sidechain_asset_id() ); issue_op.issue_to_account = accounts_to_issue[i]; d.apply_operation( *trx_state, issue_op ); } trx_state->skip_fee = skip_fee_old; trx_state->skip_fee_schedule_check = skip_fee_schedule_check_old; } void bitcoin_issue_evaluator::clear_btc_transaction_information( const bitcoin_transaction_object& btc_obj ) { database& d = db(); const auto& vins_info_idx = d.get_index_type().indices().get(); const auto& vouts_info_idx = d.get_index_type().indices().get(); for( auto& vin_id : btc_obj.vins ) { auto vin_itr = vins_info_idx.find( vin_id ); d.remove( *vin_itr ); } for( auto& vout_id : btc_obj.vouts ) { auto vout_itr = vouts_info_idx.find( vout_id ); d.remove( *vout_itr ); } auto trx_approvals = d.bitcoin_confirmations.find( btc_obj.transaction_id ); if( trx_approvals.valid() ) { d.bitcoin_confirmations.remove( btc_obj.transaction_id ); } d.remove( btc_obj ); } std::vector bitcoin_issue_evaluator::get_amounts_to_issue( std::vector vins_id ) { database& d = db(); const auto& vins_info_idx = d.get_index_type().indices().get(); std::vector result; for( auto& id : vins_id ) { auto vin_itr = vins_info_idx.find( id ); result.push_back( vin_itr->out.amount ); } return result; } std::vector bitcoin_issue_evaluator::get_accounts_to_issue( std::vector vins_id ) { database& d = db(); const auto& btc_addr_idx = d.get_index_type().indices().get(); const auto& vins_info_idx = d.get_index_type().indices().get(); std::vector result; for( auto& id : vins_id ) { auto vin_itr = vins_info_idx.find( id ); auto addr_itr = btc_addr_idx.find( vin_itr->address ); result.push_back( addr_itr->owner ); } return result; } } } // graphene::chain