134 lines
No EOL
4.5 KiB
C++
134 lines
No EOL
4.5 KiB
C++
#include <graphene/chain/sidechain_evaluator.hpp>
|
|
#include <graphene/chain/bitcoin_transaction_object.hpp>
|
|
#include <graphene/chain/info_for_used_vin_object.hpp>
|
|
#include <graphene/chain/bitcoin_address_object.hpp>
|
|
|
|
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<bitcoin_transaction_index>().indices().get<by_transaction_id>();
|
|
const auto& btc_addr_idx = d.get_index_type<bitcoin_address_index>().indices().get<by_address>();
|
|
const auto& vins_info_idx = d.get_index_type<info_for_used_vin_index>().indices().get<by_id>();
|
|
const auto& vouts_info_idx = d.get_index_type<info_for_vout_index>().indices().get<by_id>();
|
|
|
|
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<bitcoin_transaction_index>().indices().get<by_transaction_id>();
|
|
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<info_for_used_vin_index>().indices().get<by_id>();
|
|
const auto& vouts_info_idx = d.get_index_type<info_for_vout_index>().indices().get<by_id>();
|
|
|
|
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<sidechain::by_hash>( btc_obj.transaction_id );
|
|
if( trx_approvals.valid() ) {
|
|
d.bitcoin_confirmations.remove<sidechain::by_hash>( btc_obj.transaction_id );
|
|
}
|
|
|
|
d.remove( btc_obj );
|
|
}
|
|
|
|
std::vector<uint64_t> bitcoin_issue_evaluator::get_amounts_to_issue( std::vector<info_for_used_vin_id_type> vins_id )
|
|
{
|
|
database& d = db();
|
|
const auto& vins_info_idx = d.get_index_type<info_for_used_vin_index>().indices().get<by_id>();
|
|
|
|
std::vector<uint64_t> 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<account_id_type> bitcoin_issue_evaluator::get_accounts_to_issue( std::vector<info_for_used_vin_id_type> vins_id )
|
|
{
|
|
database& d = db();
|
|
const auto& btc_addr_idx = d.get_index_type<bitcoin_address_index>().indices().get<by_address>();
|
|
const auto& vins_info_idx = d.get_index_type<info_for_used_vin_index>().indices().get<by_id>();
|
|
|
|
std::vector<account_id_type> 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
|