void network_broadcast_api::broadcast_transaction_with_callback(confirmation_callback cb, const signed_transaction& trx) { trx.validate(); _callbacks[trx.id()] = cb; _app.chain_database()->push_transaction(trx); _app.p2p_node()->broadcast_transaction(trx); }
void network_broadcast_api::broadcast_transaction(const signed_transaction& trx) { trx.validate(); _app.chain_database()->push_transaction(trx); _app.p2p_node()->broadcast_transaction(trx); }
processed_transaction database::_apply_transaction(const signed_transaction& trx) { try { uint32_t skip = get_node_properties().skip_flags; if( true || !(skip&skip_validate) ) /* issue #505 explains why this skip_flag is disabled */ trx.validate(); auto& trx_idx = get_mutable_index_type<transaction_index>(); const chain_id_type& chain_id = get_chain_id(); auto trx_id = trx.id(); FC_ASSERT( (skip & skip_transaction_dupe_check) || trx_idx.indices().get<by_trx_id>().find(trx_id) == trx_idx.indices().get<by_trx_id>().end() ); transaction_evaluation_state eval_state(this); const chain_parameters& chain_parameters = get_global_properties().parameters; eval_state._trx = &trx; if( !(skip & (skip_transaction_signatures | skip_authority_check) ) ) { auto get_active = [&]( account_id_type id ) { return &id(*this).active; }; auto get_owner = [&]( account_id_type id ) { return &id(*this).owner; }; trx.verify_authority( chain_id, get_active, get_owner, get_global_properties().parameters.max_authority_depth ); } //Skip all manner of expiration and TaPoS checking if we're on block 1; It's impossible that the transaction is //expired, and TaPoS makes no sense as no blocks exist. if( BOOST_LIKELY(head_block_num() > 0) ) { if( !(skip & skip_tapos_check) ) { const auto& tapos_block_summary = block_summary_id_type( trx.ref_block_num )(*this); //Verify TaPoS block summary has correct ID prefix, and that this block's time is not past the expiration FC_ASSERT( trx.ref_block_prefix == tapos_block_summary.block_id._hash[1] ); } fc::time_point_sec now = head_block_time(); FC_ASSERT( trx.expiration <= now + chain_parameters.maximum_time_until_expiration, "", ("trx.expiration",trx.expiration)("now",now)("max_til_exp",chain_parameters.maximum_time_until_expiration)); FC_ASSERT( now <= trx.expiration, "", ("now",now)("trx.exp",trx.expiration) ); } //Insert transaction into unique transactions database. if( !(skip & skip_transaction_dupe_check) ) { create<transaction_object>([&](transaction_object& transaction) { transaction.trx_id = trx_id; transaction.trx = trx; }); } eval_state.operation_results.reserve(trx.operations.size()); //Finally process the operations processed_transaction ptrx(trx); _current_op_in_trx = 0; for( const auto& op : ptrx.operations ) { eval_state.operation_results.emplace_back(apply_operation(eval_state, op)); ++_current_op_in_trx; } ptrx.operation_results = std::move(eval_state.operation_results); //Make sure the temp account has no non-zero balances const auto& index = get_index_type<account_balance_index>().indices().get<by_account_asset>(); auto range = index.equal_range( boost::make_tuple( GRAPHENE_TEMP_ACCOUNT ) ); std::for_each(range.first, range.second, [](const account_balance_object& b) { FC_ASSERT(b.balance == 0); }); return ptrx; } FC_CAPTURE_AND_RETHROW( (trx) ) }