diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index f5a58e5a19..a8212fbbb2 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -828,6 +828,13 @@ struct controller_impl { map< account_name, map > apply_handlers; unordered_map< builtin_protocol_feature_t, std::function, enum_hash > protocol_feature_activation_handlers; + signal block_start; + signal accepted_block_header; + signal accepted_block; + signal irreversible_block; + signal)> applied_transaction; + signal voted_block; + int64_t set_proposed_producers( vector producers ); int64_t set_proposed_producers_legacy( vector producers ); @@ -865,7 +872,7 @@ struct controller_impl { }); } - const producer_authority_schedule* head_pending_schedule_auth_legacy() { + const producer_authority_schedule* head_pending_schedule_auth_legacy() const { return fork_db.apply(overloaded{ [](const fork_database_legacy_t& forkdb) -> const producer_authority_schedule* { return forkdb.chain_head->pending_schedule_auth(); @@ -1103,7 +1110,7 @@ struct controller_impl { set_activation_handler(); set_activation_handler(); - self.irreversible_block.connect([this](const block_signal_params& t) { + irreversible_block.connect([this](const block_signal_params& t) { const auto& [ block, id] = t; wasmif.current_lib(block->block_num()); }); @@ -1162,7 +1169,7 @@ struct controller_impl { if (auto dm_logger = get_deep_mind_logger(false)) { if (trx && is_onblock(*t)) dm_logger->on_onblock(*trx); - dm_logger->on_applied_transaction(self.head_block_num() + 1, t); + dm_logger->on_applied_transaction(head_block_num() + 1, t); } } @@ -1206,7 +1213,7 @@ struct controller_impl { apply_block( br, *bitr, controller::block_status::complete, trx_meta_cache_lookup{} ); } - emit( self.irreversible_block, std::tie((*bitr)->block, (*bitr)->id()) ); + emit( irreversible_block, std::tie((*bitr)->block, (*bitr)->id()) ); // blog.append could fail due to failures like running out of space. // Do it before commit so that in case it throws, DB can be rolled back. @@ -1321,7 +1328,7 @@ struct controller_impl { // if the irreverible log is played without undo sessions enabled, we need to sync the // revision ordinal to the appropriate expected value here. - if( self.skip_db_sessions( controller::block_status::irreversible ) ) + if( skip_db_sessions( controller::block_status::irreversible ) ) db.set_revision( head->block_num() ); } else { ilog( "no irreversible blocks need to be replayed" ); @@ -1551,7 +1558,6 @@ struct controller_impl { } ~controller_impl() { - thread_pool.stop(); pending.reset(); //only log this not just if configured to, but also if initialization made it to the point we'd log the startup too if(okay_to_print_integrity_hash_on_stop && conf.integrity_hash_on_stop) @@ -1569,11 +1575,6 @@ struct controller_impl { void clear_all_undo() { // Rewind the database to the last irreversible block db.undo_all(); - /* - FC_ASSERT(db.revision() == self.head_block_num(), - "Chainbase revision does not match head block num", - ("rev", db.revision())("head_block", self.head_block_num())); - */ } void add_contract_tables_to_snapshot( const snapshot_writer_ptr& snapshot ) const { @@ -1944,13 +1945,13 @@ struct controller_impl { // Deliver onerror action containing the failed deferred transaction directly back to the sender. etrx.actions.emplace_back( vector{{gtrx.sender, config::active_name}}, onerror( gtrx.sender_id, gtrx.packed_trx.data(), gtrx.packed_trx.size() ) ); - if( self.is_builtin_activated( builtin_protocol_feature_t::no_duplicate_deferred_id ) ) { + if( is_builtin_activated( builtin_protocol_feature_t::no_duplicate_deferred_id ) ) { etrx.expiration = time_point_sec(); etrx.ref_block_num = 0; etrx.ref_block_prefix = 0; } else { - etrx.expiration = time_point_sec{self.pending_block_time() + fc::microseconds(999'999)}; // Round up to nearest second to avoid appearing expired - etrx.set_reference_block( self.head_block_id() ); + etrx.expiration = time_point_sec{pending_block_time() + fc::microseconds(999'999)}; // Round up to nearest second to avoid appearing expired + etrx.set_reference_block( head_block_id() ); } transaction_checktime_timer trx_timer(timer); @@ -2062,11 +2063,11 @@ struct controller_impl { { try { auto start = fc::time_point::now(); - const bool validating = !self.is_speculative_block(); + const bool validating = !is_speculative_block(); EOS_ASSERT( !validating || explicit_billed_cpu_time, transaction_exception, "validating requires explicit billing" ); maybe_session undo_session; - if ( !self.skip_db_sessions() ) + if ( !skip_db_sessions() ) undo_session = maybe_session(db); auto gtrx = generated_transaction(gto); @@ -2082,9 +2083,9 @@ struct controller_impl { fc::datastream ds( gtrx.packed_trx.data(), gtrx.packed_trx.size() ); // check delay_until only before disable_deferred_trxs_stage_1 is activated. - if( !self.is_builtin_activated( builtin_protocol_feature_t::disable_deferred_trxs_stage_1 ) ) { - EOS_ASSERT( gtrx.delay_until <= self.pending_block_time(), transaction_exception, "this transaction isn't ready", - ("gtrx.delay_until",gtrx.delay_until)("pbt",self.pending_block_time()) ); + if( !is_builtin_activated( builtin_protocol_feature_t::disable_deferred_trxs_stage_1 ) ) { + EOS_ASSERT( gtrx.delay_until <= pending_block_time(), transaction_exception, "this transaction isn't ready", + ("gtrx.delay_until",gtrx.delay_until)("pbt",pending_block_time()) ); } signed_transaction dtrx; @@ -2098,12 +2099,12 @@ struct controller_impl { // can only be retired as expired, and it can be retired as expired // regardless of whether its delay_util or expiration times have been reached. transaction_trace_ptr trace; - if( self.is_builtin_activated( builtin_protocol_feature_t::disable_deferred_trxs_stage_1 ) || gtrx.expiration < self.pending_block_time() ) { + if( is_builtin_activated( builtin_protocol_feature_t::disable_deferred_trxs_stage_1 ) || gtrx.expiration < pending_block_time() ) { trace = std::make_shared(); trace->id = gtrx.trx_id; - trace->block_num = self.head_block_num() + 1; - trace->block_time = self.pending_block_time(); - trace->producer_block_id = self.pending_producer_block_id(); + trace->block_num = head_block_num() + 1; + trace->block_time = pending_block_time(); + trace->producer_block_id = pending_producer_block_id(); trace->scheduled = true; trace->receipt = push_receipt( gtrx.trx_id, transaction_receipt::expired, billed_cpu_time_us, 0 ); // expire the transaction trace->account_ram_delta = account_delta( gtrx.payer, trx_removal_ram_delta ); @@ -2112,7 +2113,7 @@ struct controller_impl { pending->_block_report.total_elapsed_time += trace->elapsed; pending->_block_report.total_time += trace->elapsed; dmlog_applied_transaction(trace); - emit( self.applied_transaction, std::tie(trace, trx->packed_trx()) ); + emit( applied_transaction, std::tie(trace, trx->packed_trx()) ); undo_session.squash(); return trace; } @@ -2151,7 +2152,7 @@ struct controller_impl { try { trx_context.init_for_deferred_trx( gtrx.published ); - if( trx_context.enforce_whiteblacklist && self.is_speculative_block() ) { + if( trx_context.enforce_whiteblacklist && is_speculative_block() ) { flat_set actors; for( const auto& act : trx->packed_trx()->get_transaction().actions ) { for( const auto& auth : act.authorization ) { @@ -2177,7 +2178,7 @@ struct controller_impl { trace->account_ram_delta = account_delta( gtrx.payer, trx_removal_ram_delta ); dmlog_applied_transaction(trace); - emit( self.applied_transaction, std::tie(trace, trx->packed_trx()) ); + emit( applied_transaction, std::tie(trace, trx->packed_trx()) ); trx_context.squash(); undo_session.squash(); @@ -2221,7 +2222,7 @@ struct controller_impl { trace->account_ram_delta = account_delta( gtrx.payer, trx_removal_ram_delta ); trace->elapsed = fc::time_point::now() - start; dmlog_applied_transaction(trace); - emit( self.applied_transaction, std::tie(trace, trx->packed_trx()) ); + emit( applied_transaction, std::tie(trace, trx->packed_trx()) ); undo_session.squash(); pending->_block_report.total_net_usage += trace->net_usage; if( trace->receipt ) pending->_block_report.total_cpu_usage_us += trace->receipt->cpu_usage_us; @@ -2246,8 +2247,7 @@ struct controller_impl { // hard failure logic if( !validating ) { - auto& rl = self.get_mutable_resource_limits_manager(); - rl.update_account_usage( trx_context.bill_to_accounts, block_timestamp_type(self.pending_block_time()).slot ); + resource_limits.update_account_usage( trx_context.bill_to_accounts, block_timestamp_type(pending_block_time()).slot ); int64_t account_cpu_limit = 0; std::tie( std::ignore, account_cpu_limit, std::ignore, std::ignore ) = trx_context.max_bandwidth_billed_accounts_can_pay( true ); @@ -2260,18 +2260,18 @@ struct controller_impl { } resource_limits.add_transaction_usage( trx_context.bill_to_accounts, cpu_time_to_bill_us, 0, - block_timestamp_type(self.pending_block_time()).slot ); // Should never fail + block_timestamp_type(pending_block_time()).slot ); // Should never fail trace->receipt = push_receipt(gtrx.trx_id, transaction_receipt::hard_fail, cpu_time_to_bill_us, 0); trace->account_ram_delta = account_delta( gtrx.payer, trx_removal_ram_delta ); dmlog_applied_transaction(trace); - emit( self.applied_transaction, std::tie(trace, trx->packed_trx()) ); + emit( applied_transaction, std::tie(trace, trx->packed_trx()) ); undo_session.squash(); } else { dmlog_applied_transaction(trace); - emit( self.applied_transaction, std::tie(trace, trx->packed_trx()) ); + emit( applied_transaction, std::tie(trace, trx->packed_trx()) ); } pending->_block_report.total_net_usage += trace->net_usage; @@ -2321,7 +2321,7 @@ struct controller_impl { transaction_trace_ptr trace; try { auto start = fc::time_point::now(); - const bool check_auth = !self.skip_auth_check() && !trx->implicit() && !trx->is_read_only(); + const bool check_auth = !skip_auth_check() && !trx->implicit() && !trx->is_read_only(); const fc::microseconds sig_cpu_usage = trx->signature_cpu_usage(); if( !explicit_billed_cpu_time ) { @@ -2337,7 +2337,7 @@ struct controller_impl { const signed_transaction& trn = trx->packed_trx()->get_signed_transaction(); transaction_checktime_timer trx_timer(timer); transaction_context trx_context(self, *trx->packed_trx(), trx->id(), std::move(trx_timer), start, trx->get_trx_type()); - if ((bool)subjective_cpu_leeway && self.is_speculative_block()) { + if ((bool)subjective_cpu_leeway && is_speculative_block()) { trx_context.leeway = *subjective_cpu_leeway; } trx_context.block_deadline = block_deadline; @@ -2408,7 +2408,7 @@ struct controller_impl { } dmlog_applied_transaction(trace, &trn); - emit(self.applied_transaction, std::tie(trace, trx->packed_trx())); + emit(applied_transaction, std::tie(trace, trx->packed_trx())); } } @@ -2452,7 +2452,7 @@ struct controller_impl { if (!trx->is_transient()) { dmlog_applied_transaction(trace); - emit(self.applied_transaction, std::tie(trace, trx->packed_trx())); + emit(applied_transaction, std::tie(trace, trx->packed_trx())); pending->_block_report.total_net_usage += trace->net_usage; if( trace->receipt ) pending->_block_report.total_cpu_usage_us += trace->receipt->cpu_usage_us; @@ -2473,7 +2473,7 @@ struct controller_impl { { EOS_ASSERT( !pending, block_validate_exception, "pending block already exists" ); - emit( self.block_start, head_block_num() + 1 ); + emit( block_start, head_block_num() + 1 ); // at block level, no transaction specific logging is possible if (auto dm_logger = get_deep_mind_logger(false)) { @@ -2486,17 +2486,17 @@ struct controller_impl { pending.reset(); }); - EOS_ASSERT( self.skip_db_sessions(s) || db.revision() == head_block_num(), database_exception, + EOS_ASSERT( skip_db_sessions(s) || db.revision() == head_block_num(), database_exception, "db revision is not on par with head block", ("db.revision()", db.revision())("controller_head_block", head_block_num())("fork_db_head_block", fork_db_head_block_num()) ); fork_db.apply( [&](auto& forkdb) { // legacy - maybe_session session = self.skip_db_sessions(s) ? maybe_session() : maybe_session(db); + maybe_session session = skip_db_sessions(s) ? maybe_session() : maybe_session(db); pending.emplace(std::move(session), *forkdb.chain_head, when, confirm_block_count, new_protocol_feature_activations); }, [&](auto& forkdb) { // instant-finality - maybe_session session = self.skip_db_sessions(s) ? maybe_session() : maybe_session(db); + maybe_session session = skip_db_sessions(s) ? maybe_session() : maybe_session(db); building_block_input bbi{forkdb.chain_head->id(), when, forkdb.chain_head->get_scheduled_producer(when).producer_name, new_protocol_feature_activations}; pending.emplace(std::move(session), *forkdb.chain_head, bbi); @@ -2573,7 +2573,7 @@ struct controller_impl { }); } - const auto& gpo = self.get_global_properties(); + const auto& gpo = db.get(); // instant finality uses alternative method for chaning producer schedule bb.apply_legacy([&](building_block::building_block_legacy& bb_legacy) { @@ -2651,7 +2651,7 @@ struct controller_impl { // Update resource limits: resource_limits.process_account_limit_updates(); - const auto& chain_config = self.get_global_properties().configuration; + const auto& chain_config = db.get().configuration; resource_limits.set_block_parameters( { EOS_PERCENT(chain_config.max_block_cpu_usage, chain_config.target_block_cpu_usage_pct), chain_config.max_block_cpu_usage, @@ -2696,14 +2696,14 @@ struct controller_impl { if( s == controller::block_status::incomplete ) { forkdb.add( bsp ); forkdb.mark_valid( bsp ); - emit( self.accepted_block_header, std::tie(bsp->block, bsp->id()) ); + emit( accepted_block_header, std::tie(bsp->block, bsp->id()) ); EOS_ASSERT( bsp == forkdb.head(), fork_database_exception, "committed block did not become the new head in fork database"); } else if (s != controller::block_status::irreversible) { forkdb.mark_valid( bsp ); } forkdb.chain_head = bsp; - emit( self.accepted_block, std::tie(bsp->block, bsp->id()) ); + emit( accepted_block, std::tie(bsp->block, bsp->id()) ); }; fork_db.apply(add_completed_block); @@ -2887,7 +2887,7 @@ struct controller_impl { const bool existing_trxs_metas = !bsp->trxs_metas().empty(); const bool pub_keys_recovered = bsp->is_pub_keys_recovered(); - const bool skip_auth_checks = self.skip_auth_check(); + const bool skip_auth_checks = skip_auth_check(); std::vector> trx_metas; bool use_bsp_cached = false; if( pub_keys_recovered || (skip_auth_checks && existing_trxs_metas) ) { @@ -3032,7 +3032,7 @@ struct controller_impl { // net plugin subscribed this signal. it will broadcast the vote message // on receiving the signal - emit( self.voted_block, vote ); + emit( voted_block, vote ); boost::asio::post(thread_pool.get_executor(), [control=this, vote]() { control->process_vote_message(vote); @@ -3304,7 +3304,7 @@ struct controller_impl { EOS_ASSERT( bsp, block_validate_exception, "null block" ); const auto& b = bsp->block; - if( conf.terminate_at_block > 0 && conf.terminate_at_block <= self.head_block_num()) { + if( conf.terminate_at_block > 0 && conf.terminate_at_block <= head_block_num()) { ilog("Reached configured maximum block ${num}; terminating", ("num", conf.terminate_at_block) ); shutdown(); return; @@ -3314,11 +3314,11 @@ struct controller_impl { if constexpr (std::is_same_v>) forkdb.add( bsp ); - if (self.is_trusted_producer(b->producer)) { + if (is_trusted_producer(b->producer)) { trusted_producer_light_validation = true; }; - emit( self.accepted_block_header, std::tie(bsp->block, bsp->id()) ); + emit( accepted_block_header, std::tie(bsp->block, bsp->id()) ); if( read_mode != db_read_mode::IRREVERSIBLE ) { if constexpr (std::is_same_v>) @@ -3335,7 +3335,7 @@ struct controller_impl { template void replay_push_block( const signed_block_ptr& b, controller::block_status s ) { - self.validate_db_available_size(); + validate_db_available_size(); EOS_ASSERT(!pending, block_validate_exception, "it is not valid to push a block when there is a pending block"); @@ -3344,7 +3344,7 @@ struct controller_impl { EOS_ASSERT( (s == controller::block_status::irreversible || s == controller::block_status::validated), block_validate_exception, "invalid block status for replay" ); - if( conf.terminate_at_block > 0 && conf.terminate_at_block <= self.head_block_num() ) { + if( conf.terminate_at_block > 0 && conf.terminate_at_block <= head_block_num() ) { ilog("Reached configured maximum block ${num}; terminating", ("num", conf.terminate_at_block) ); shutdown(); return; @@ -3365,7 +3365,7 @@ struct controller_impl { forkdb.add(bsp, true); } - emit(self.accepted_block_header, std::tie(bsp->block, bsp->id())); + emit(accepted_block_header, std::tie(bsp->block, bsp->id())); controller::block_report br; if (s == controller::block_status::irreversible) { @@ -3373,9 +3373,9 @@ struct controller_impl { // On replay, log_irreversible is not called and so no irreversible_block signal is emitted. // So emit it explicitly here. - emit(self.irreversible_block, std::tie(bsp->block, bsp->id())); + emit(irreversible_block, std::tie(bsp->block, bsp->id())); - if (!self.skip_db_sessions(s)) { + if (!skip_db_sessions(s)) { db.commit(bsp->block_num()); } } else { @@ -3420,7 +3420,7 @@ struct controller_impl { for( auto itr = branches.second.begin(); itr != branches.second.end(); ++itr ) { pop_block(); } - EOS_ASSERT( self.head_block_id() == branches.second.back()->header.previous, fork_database_exception, + EOS_ASSERT( head_block_id() == branches.second.back()->header.previous, fork_database_exception, "loss of sync between fork_db and chainbase during fork switch" ); // _should_ never fail if( forked_cb ) { @@ -3463,7 +3463,7 @@ struct controller_impl { for( auto itr = applied_itr; itr != branches.first.end(); ++itr ) { pop_block(); } - EOS_ASSERT( self.head_block_id() == branches.second.back()->header.previous, fork_database_exception, + EOS_ASSERT( head_block_id() == branches.second.back()->header.previous, fork_database_exception, "loss of sync between fork_db and chainbase during fork switch reversal" ); // _should_ never fail // re-apply good blocks @@ -3580,7 +3580,7 @@ struct controller_impl { //Look for expired transactions in the deduplication list, and remove them. auto& transaction_idx = db.get_mutable_index(); const auto& dedupe_index = transaction_idx.indices().get(); - auto now = self.is_building_block() ? self.pending_block_time() : (time_point)self.head_block_time(); + auto now = is_building_block() ? pending_block_time() : head_block_time().to_time_point(); const auto total = dedupe_index.size(); uint32_t num_removed = 0; while( (!dedupe_index.empty()) && ( now > dedupe_index.begin()->expiration.to_time_point() ) ) { @@ -3723,22 +3723,6 @@ struct controller_impl { } } - /* - bool should_check_tapos()const { return true; } - - void validate_tapos( const transaction& trx )const { - if( !should_check_tapos() ) return; - - const auto& tapos_block_summary = db.get((uint16_t)trx.ref_block_num); - - //Verify TaPoS block summary has correct ID prefix, and that this block's time is not past the expiration - EOS_ASSERT(trx.verify_reference_block(tapos_block_summary.block_id), invalid_ref_block_exception, - "Transaction's reference block did not match. Is this transaction from a different fork?", - ("tapos_summary", tapos_block_summary)); - } - */ - - /** * At the start of each block we notify the system contract with a transaction that passes in * the block header of the prior block (which is currently our head block) @@ -3749,17 +3733,17 @@ struct controller_impl { on_block_act.account = config::system_account_name; on_block_act.name = "onblock"_n; on_block_act.authorization = vector{{config::system_account_name, config::active_name}}; - on_block_act.data = fc::raw::pack(self.head_block_header()); + on_block_act.data = fc::raw::pack(head_block_header()); signed_transaction trx; trx.actions.emplace_back(std::move(on_block_act)); - if( self.is_builtin_activated( builtin_protocol_feature_t::no_duplicate_deferred_id ) ) { + if( is_builtin_activated( builtin_protocol_feature_t::no_duplicate_deferred_id ) ) { trx.expiration = time_point_sec(); trx.ref_block_num = 0; trx.ref_block_prefix = 0; } else { - trx.expiration = time_point_sec{self.pending_block_time() + fc::microseconds(999'999)}; // Round up to nearest second to avoid appearing expired - trx.set_reference_block( self.head_block_id() ); + trx.expiration = time_point_sec{pending_block_time() + fc::microseconds(999'999)}; // Round up to nearest second to avoid appearing expired + trx.set_reference_block( head_block_id() ); } return trx; @@ -3822,6 +3806,108 @@ struct controller_impl { } bool irreversible_mode() const { return read_mode == db_read_mode::IRREVERSIBLE; } + + bool light_validation_allowed() const { + if (!pending || in_trx_requiring_checks) { + return false; + } + + const auto pb_status = pending->_block_status; + + // in a pending irreversible or previously validated block and we have forcing all checks + const bool consider_skipping_on_replay = + (pb_status == controller::block_status::irreversible || pb_status == controller::block_status::validated) && !conf.force_all_checks; + + // OR in a signed block and in light validation mode + const bool consider_skipping_on_validate = pb_status == controller::block_status::complete && + (conf.block_validation_mode == validation_mode::LIGHT || trusted_producer_light_validation); + + return consider_skipping_on_replay || consider_skipping_on_validate; + } + + + bool skip_auth_check() const { + return light_validation_allowed(); + } + + bool skip_trx_checks() const { + return light_validation_allowed(); + } + + bool skip_db_sessions( controller::block_status bs ) const { + bool consider_skipping = bs == controller::block_status::irreversible; + return consider_skipping + && !conf.disable_replay_opts + && !in_trx_requiring_checks; + } + + bool skip_db_sessions() const { + if (pending) { + return skip_db_sessions(pending->_block_status); + } else { + return false; + } + } + + bool is_trusted_producer( const account_name& producer) const { + return conf.block_validation_mode == validation_mode::LIGHT || conf.trusted_producers.count(producer); + } + + bool is_builtin_activated( builtin_protocol_feature_t f )const { + uint32_t current_block_num = head_block_num(); + + if( pending ) { + ++current_block_num; + } + + return protocol_features.is_builtin_activated( f, current_block_num ); + } + + block_timestamp_type pending_block_timestamp()const { + EOS_ASSERT( pending, block_validate_exception, "no pending block" ); + + return pending->timestamp(); + } + + time_point pending_block_time()const { + return pending_block_timestamp(); + } + + bool is_building_block()const { + return pending.has_value() && !std::holds_alternative(pending->_block_stage); + } + + bool is_speculative_block()const { + if( !pending ) return false; + + return (pending->_block_status == controller::block_status::incomplete || pending->_block_status == controller::block_status::ephemeral ); + } + + std::optional pending_producer_block_id()const { + EOS_ASSERT( pending, block_validate_exception, "no pending block" ); + return pending->_producer_block_id; + } + + void validate_db_available_size() const { + const auto free = db.get_free_memory(); + const auto guard = conf.state_guard_size; + EOS_ASSERT(free >= guard, database_guard_exception, "database free: ${f}, guard size: ${g}", ("f", free)("g",guard)); + } + + const producer_authority_schedule& active_producers()const { + if( !(pending) ) + return head_active_schedule_auth(); + + return pending->active_producers(); + } + + const producer_authority_schedule* pending_producers_legacy()const { + if( !(pending) ) + return head_pending_schedule_auth_legacy(); + + return pending->pending_producers_legacy(); + } + }; /// controller_impl thread_local platform_timer controller_impl::timer; @@ -3873,12 +3959,12 @@ controller::controller( const config& cfg, protocol_feature_set&& pfs, const cha controller::~controller() { my->abort_block(); - /* Shouldn't be needed anymore. - //close fork_db here, because it can generate "irreversible" signal to this controller, - //in case if read-mode == IRREVERSIBLE, we will apply latest irreversible block - //for that we need 'my' to be valid pointer pointing to valid controller_impl. - my->fork_db.close(); - */ + // controller_impl (my) holds a reference to controller (controller_impl.self). + // The self is passed to transaction_context which passes it on to apply_context. + // Currently nothing posted to the thread_pool accesses the `self` reference, but to make + // sure it is safe in case something is added to the thread pool that does access self, + // stop the thread pool before the unique_ptr (my) destructor runs. + my->thread_pool.stop(); } void controller::add_indices() { @@ -4196,13 +4282,11 @@ block_id_type controller::fork_db_head_block_id()const { } block_timestamp_type controller::pending_block_timestamp()const { - EOS_ASSERT( my->pending, block_validate_exception, "no pending block" ); - - return my->pending->timestamp(); + return my->pending_block_timestamp(); } time_point controller::pending_block_time()const { - return pending_block_timestamp(); + return my->pending_block_time(); } uint32_t controller::pending_block_num()const { @@ -4221,8 +4305,7 @@ const block_signing_authority& controller::pending_block_signing_authority() con } std::optional controller::pending_producer_block_id()const { - EOS_ASSERT( my->pending, block_validate_exception, "no pending block" ); - return my->pending->_producer_block_id; + return my->pending_producer_block_id(); } void controller::set_if_irreversible_block_num(uint32_t block_num) { @@ -4346,10 +4429,10 @@ int64_t controller_impl::set_proposed_producers( vector prod } int64_t controller_impl::set_proposed_producers_legacy( vector producers ) { - const auto& gpo = self.get_global_properties(); + const auto& gpo = db.get(); auto cur_block_num = head_block_num() + 1; - if( producers.size() == 0 && self.is_builtin_activated( builtin_protocol_feature_t::disallow_empty_producer_schedule ) ) { + if( producers.size() == 0 && is_builtin_activated( builtin_protocol_feature_t::disallow_empty_producer_schedule ) ) { return -1; } @@ -4367,11 +4450,11 @@ int64_t controller_impl::set_proposed_producers_legacy( vectorproducers.size() == 0 ) { - const auto& active_sch = self.active_producers(); + const auto& active_sch = active_producers(); begin = active_sch.producers.begin(); end = active_sch.producers.end(); sch.version = active_sch.version + 1; @@ -4407,10 +4490,7 @@ vote_status controller::process_vote_message( const vote_message& vote ) { }; const producer_authority_schedule& controller::active_producers()const { - if( !(my->pending) ) - return my->head_active_schedule_auth(); - - return my->pending->active_producers(); + return my->active_producers(); } const producer_authority_schedule& controller::head_active_producers()const { @@ -4418,10 +4498,7 @@ const producer_authority_schedule& controller::head_active_producers()const { } const producer_authority_schedule* controller::pending_producers_legacy()const { - if( !(my->pending) ) - return my->head_pending_schedule_auth_legacy(); - - return my->pending->pending_producers_legacy(); + return my->pending_producers_legacy(); } std::optional controller::proposed_producers_legacy()const { @@ -4440,49 +4517,27 @@ const producer_authority_schedule* controller::next_producers()const { } bool controller::light_validation_allowed() const { - if (!my->pending || my->in_trx_requiring_checks) { - return false; - } - - const auto pb_status = my->pending->_block_status; - - // in a pending irreversible or previously validated block and we have forcing all checks - const bool consider_skipping_on_replay = - (pb_status == block_status::irreversible || pb_status == block_status::validated) && !my->conf.force_all_checks; - - // OR in a signed block and in light validation mode - const bool consider_skipping_on_validate = (pb_status == block_status::complete && - (my->conf.block_validation_mode == validation_mode::LIGHT || my->trusted_producer_light_validation)); - - return consider_skipping_on_replay || consider_skipping_on_validate; + return my->light_validation_allowed(); } - bool controller::skip_auth_check() const { - return light_validation_allowed(); + return my->skip_auth_check(); } bool controller::skip_trx_checks() const { - return light_validation_allowed(); + return my->skip_trx_checks(); } bool controller::skip_db_sessions( block_status bs ) const { - bool consider_skipping = bs == block_status::irreversible; - return consider_skipping - && !my->conf.disable_replay_opts - && !my->in_trx_requiring_checks; + return my->skip_db_sessions( bs ); } bool controller::skip_db_sessions() const { - if (my->pending) { - return skip_db_sessions(my->pending->_block_status); - } else { - return false; - } + return my->skip_db_sessions(); } bool controller::is_trusted_producer( const account_name& producer) const { - return get_validation_mode() == chain::validation_mode::LIGHT || my->conf.trusted_producers.count(producer); + return my->is_trusted_producer( producer ); } bool controller::contracts_console()const { @@ -4549,13 +4604,11 @@ void controller::check_key_list( const public_key_type& key )const { } bool controller::is_building_block()const { - return my->pending.has_value() && !std::holds_alternative(my->pending->_block_stage); + return my->is_building_block(); } bool controller::is_speculative_block()const { - if( !my->pending ) return false; - - return (my->pending->_block_status == block_status::incomplete || my->pending->_block_status == block_status::ephemeral ); + return my->is_speculative_block(); } bool controller::is_ram_billing_in_notify_allowed()const { @@ -4592,16 +4645,7 @@ void controller::validate_tapos( const transaction& trx )const { try { } FC_CAPTURE_AND_RETHROW() } void controller::validate_db_available_size() const { - const auto free = db().get_free_memory(); - const auto guard = my->conf.state_guard_size; - EOS_ASSERT(free >= guard, database_guard_exception, "database free: ${f}, guard size: ${g}", ("f", free)("g",guard)); - - // give a change to chainbase to write some pages to disk if memory becomes scarce. - if (is_write_window()) { - if (auto flushed_pages = mutable_db().check_memory_and_flush_if_needed()) { - ilog("CHAINBASE: flushed ${p} pages to disk to decrease memory pressure", ("p", flushed_pages)); - } - } + return my->validate_db_available_size(); } bool controller::is_protocol_feature_activated( const digest_type& feature_digest )const { @@ -4613,13 +4657,7 @@ bool controller::is_protocol_feature_activated( const digest_type& feature_diges } bool controller::is_builtin_activated( builtin_protocol_feature_t f )const { - uint32_t current_block_num = head_block_num(); - - if( my->pending ) { - ++current_block_num; - } - - return my->protocol_features.is_builtin_activated( f, current_block_num ); + return my->is_builtin_activated( f ); } bool controller::is_known_unexpired_transaction( const transaction_id_type& id) const { @@ -4722,6 +4760,13 @@ std::optional controller::convert_exception_to_error_code( const fc::e return e_ptr->error_code; } +signal& controller::block_start() { return my->block_start; } +signal& controller::accepted_block_header() { return my->accepted_block_header; } +signal& controller::accepted_block() { return my->accepted_block; } +signal& controller::irreversible_block() { return my->irreversible_block; } +signal)>& controller::applied_transaction() { return my->applied_transaction; } +signal& controller::voted_block() { return my->voted_block; } + chain_id_type controller::extract_chain_id(snapshot_reader& snapshot) { chain_snapshot_header header; snapshot.read_section([&header]( auto §ion ){ diff --git a/libraries/chain/fork_database.cpp b/libraries/chain/fork_database.cpp index 6d893b5304..1d6f920178 100644 --- a/libraries/chain/fork_database.cpp +++ b/libraries/chain/fork_database.cpp @@ -27,10 +27,6 @@ namespace eosio::chain { template bool first_preferred( const bs& lhs, const bs& rhs ) { - // dpos_irreversible_blocknum == std::numeric_limits::max() after hotstuff activation - // hotstuff block considered preferred over dpos - // hotstuff blocks compared by block_num as both lhs & rhs dpos_irreversible_blocknum is max uint32_t - // This can be simplified in a future release that assumes hotstuff already activated return std::pair(lhs.irreversible_blocknum(), lhs.block_num()) > std::pair(rhs.irreversible_blocknum(), rhs.block_num()); } diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index 9334f69fff..448ec80468 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -367,12 +367,12 @@ namespace eosio::chain { static std::optional convert_exception_to_error_code( const fc::exception& e ); - signal block_start; - signal accepted_block_header; - signal accepted_block; - signal irreversible_block; - signal)> applied_transaction; - signal voted_block; + signal& block_start(); + signal& accepted_block_header(); + signal& accepted_block(); + signal& irreversible_block(); + signal)>& applied_transaction(); + signal& voted_block(); const apply_handler* find_apply_handler( account_name contract, scope_name scope, action_name act )const; wasm_interface& get_wasm_interface(); diff --git a/libraries/testing/tester.cpp b/libraries/testing/tester.cpp index 60212299e6..fb6e0488d3 100644 --- a/libraries/testing/tester.cpp +++ b/libraries/testing/tester.cpp @@ -339,7 +339,7 @@ namespace eosio { namespace testing { control->add_indices(); if (lambda) lambda(); chain_transactions.clear(); - control->accepted_block.connect([this]( block_signal_params t ){ + control->accepted_block().connect([this]( block_signal_params t ){ const auto& [ block, id ] = t; FC_ASSERT( block ); for( auto receipt : block->transactions ) { diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index 67a48c661e..60e321da27 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1012,12 +1012,12 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) { } ); // relay signals to channels - accepted_block_header_connection = chain->accepted_block_header.connect( + accepted_block_header_connection = chain->accepted_block_header().connect( [this]( const block_signal_params& t ) { accepted_block_header_channel.publish( priority::medium, t ); } ); - accepted_block_connection = chain->accepted_block.connect( [this]( const block_signal_params& t ) { + accepted_block_connection = chain->accepted_block().connect( [this]( const block_signal_params& t ) { const auto& [ block, id ] = t; if (_account_query_db) { _account_query_db->commit_block(block); @@ -1034,7 +1034,7 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) { accepted_block_channel.publish( priority::high, t ); } ); - irreversible_block_connection = chain->irreversible_block.connect( [this]( const block_signal_params& t ) { + irreversible_block_connection = chain->irreversible_block().connect( [this]( const block_signal_params& t ) { const auto& [ block, id ] = t; if (_trx_retry_db) { @@ -1048,7 +1048,7 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) { irreversible_block_channel.publish( priority::low, t ); } ); - applied_transaction_connection = chain->applied_transaction.connect( + applied_transaction_connection = chain->applied_transaction().connect( [this]( std::tuple t ) { const auto& [ trace, ptrx ] = t; if (_account_query_db) { @@ -1067,7 +1067,7 @@ void chain_plugin_impl::plugin_initialize(const variables_map& options) { } ); if (_trx_finality_status_processing || _trx_retry_db) { - block_start_connection = chain->block_start.connect( + block_start_connection = chain->block_start().connect( [this]( uint32_t block_num ) { if (_trx_retry_db) { _trx_retry_db->on_block_start(block_num); diff --git a/plugins/chain_plugin/test/test_account_query_db.cpp b/plugins/chain_plugin/test/test_account_query_db.cpp index cd02c1627a..4bda8dfc5d 100644 --- a/plugins/chain_plugin/test/test_account_query_db.cpp +++ b/plugins/chain_plugin/test/test_account_query_db.cpp @@ -37,7 +37,7 @@ BOOST_FIXTURE_TEST_CASE(newaccount_test, validating_tester) { try { auto aq_db = account_query_db(*control); //link aq_db to the `accepted_block` signal on the controller - auto c2 = control->accepted_block.connect([&](const block_signal_params& t) { + auto c2 = control->accepted_block().connect([&](const block_signal_params& t) { const auto& [ block, id ] = t; aq_db.commit_block( block ); }); @@ -63,7 +63,7 @@ BOOST_FIXTURE_TEST_CASE(updateauth_test, validating_tester) { try { auto aq_db = account_query_db(*control); //link aq_db to the `accepted_block` signal on the controller - auto c = control->accepted_block.connect([&](const block_signal_params& t) { + auto c = control->accepted_block().connect([&](const block_signal_params& t) { const auto& [ block, id ] = t; aq_db.commit_block( block ); }); @@ -98,7 +98,7 @@ BOOST_FIXTURE_TEST_CASE(updateauth_test_multi_threaded, validating_tester) { try auto aq_db = account_query_db(*control); //link aq_db to the `accepted_block` signal on the controller - auto c = control->accepted_block.connect([&](const block_signal_params& t) { + auto c = control->accepted_block().connect([&](const block_signal_params& t) { const auto& [ block, id ] = t; aq_db.commit_block( block ); }); @@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(future_fork_test) { try { auto aq_db = account_query_db(*node_a.control); //link aq_db to the `accepted_block` signal on the controller - auto c = node_a.control->accepted_block.connect([&](const block_signal_params& t) { + auto c = node_a.control->accepted_block().connect([&](const block_signal_params& t) { const auto& [ block, id ] = t; aq_db.commit_block( block ); }); @@ -199,7 +199,7 @@ BOOST_AUTO_TEST_CASE(fork_test) { try { auto aq_db = account_query_db(*node_a.control); //link aq_db to the `accepted_block` signal on the controller - auto c = node_a.control->accepted_block.connect([&](const block_signal_params& t) { + auto c = node_a.control->accepted_block().connect([&](const block_signal_params& t) { const auto& [ block, id ] = t; aq_db.commit_block( block ); }); diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 1b91f21cfe..5111ecb420 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -4392,20 +4392,20 @@ namespace eosio { { chain::controller& cc = chain_plug->chain(); - cc.accepted_block_header.connect( [my = shared_from_this()]( const block_signal_params& t ) { + cc.accepted_block_header().connect( [my = shared_from_this()]( const block_signal_params& t ) { const auto& [ block, id ] = t; my->on_accepted_block_header( block, id ); } ); - cc.accepted_block.connect( [my = shared_from_this()]( const block_signal_params& t ) { + cc.accepted_block().connect( [my = shared_from_this()]( const block_signal_params& t ) { my->on_accepted_block(); } ); - cc.irreversible_block.connect( [my = shared_from_this()]( const block_signal_params& t ) { + cc.irreversible_block().connect( [my = shared_from_this()]( const block_signal_params& t ) { const auto& [ block, id ] = t; my->on_irreversible_block( id, block->block_num() ); } ); - cc.voted_block.connect( [my = shared_from_this()]( const vote_message& vote ) { + cc.voted_block().connect( [my = shared_from_this()]( const vote_message& vote ) { my->on_voted_block(vote); } ); } diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 76d8ba66da..3a30cf8ee3 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -1343,20 +1343,20 @@ void producer_plugin_impl::plugin_startup() { chain.set_node_finalizer_keys(_finalizer_keys); - _accepted_block_connection.emplace(chain.accepted_block.connect([this](const block_signal_params& t) { + _accepted_block_connection.emplace(chain.accepted_block().connect([this](const block_signal_params& t) { const auto& [ block, id ] = t; on_block(block); })); - _accepted_block_header_connection.emplace(chain.accepted_block_header.connect([this](const block_signal_params& t) { + _accepted_block_header_connection.emplace(chain.accepted_block_header().connect([this](const block_signal_params& t) { const auto& [ block, id ] = t; on_block_header(block->producer, block->block_num(), block->timestamp); })); - _irreversible_block_connection.emplace(chain.irreversible_block.connect([this](const block_signal_params& t) { + _irreversible_block_connection.emplace(chain.irreversible_block().connect([this](const block_signal_params& t) { const auto& [ block, id ] = t; on_irreversible_block(block); })); - _block_start_connection.emplace(chain.block_start.connect([this, &chain](uint32_t bs) { + _block_start_connection.emplace(chain.block_start().connect([this, &chain](uint32_t bs) { try { _snapshot_scheduler.on_start_block(bs, chain); } catch (const snapshot_execution_exception& e) { diff --git a/plugins/producer_plugin/test/test_trx_full.cpp b/plugins/producer_plugin/test/test_trx_full.cpp index 51abbf3a3e..1a51570515 100644 --- a/plugins/producer_plugin/test/test_trx_full.cpp +++ b/plugins/producer_plugin/test/test_trx_full.cpp @@ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(producer) { std::deque all_blocks; std::promise empty_blocks_promise; std::future empty_blocks_fut = empty_blocks_promise.get_future(); - auto ab = chain_plug->chain().accepted_block.connect( [&](const chain::block_signal_params& t) { + auto ab = chain_plug->chain().accepted_block().connect( [&](const chain::block_signal_params& t) { const auto& [ block, id ] = t; static int num_empty = std::numeric_limits::max(); all_blocks.push_back( block ); @@ -140,7 +140,7 @@ BOOST_AUTO_TEST_CASE(producer) { num_empty = 10; } } ); - auto bs = chain_plug->chain().block_start.connect( [&]( uint32_t bn ) { + auto bs = chain_plug->chain().block_start().connect( [&]( uint32_t bn ) { } ); std::atomic num_acked = 0; diff --git a/plugins/state_history_plugin/state_history_plugin.cpp b/plugins/state_history_plugin/state_history_plugin.cpp index ba0ae54ea6..a676249a14 100644 --- a/plugins/state_history_plugin/state_history_plugin.cpp +++ b/plugins/state_history_plugin/state_history_plugin.cpp @@ -324,17 +324,17 @@ void state_history_plugin_impl::plugin_initialize(const variables_map& options) chain.set_disable_replay_opts(true); } - applied_transaction_connection.emplace(chain.applied_transaction.connect( + applied_transaction_connection.emplace(chain.applied_transaction().connect( [&](std::tuple t) { on_applied_transaction(std::get<0>(t), std::get<1>(t)); })); accepted_block_connection.emplace( - chain.accepted_block.connect([&](const block_signal_params& t) { + chain.accepted_block().connect([&](const block_signal_params& t) { const auto& [ block, id ] = t; on_accepted_block(block, id); })); block_start_connection.emplace( - chain.block_start.connect([&](uint32_t block_num) { on_block_start(block_num); })); + chain.block_start().connect([&](uint32_t block_num) { on_block_start(block_num); })); auto dir_option = options.at("state-history-dir").as(); std::filesystem::path state_history_dir; diff --git a/plugins/test_control_plugin/test_control_plugin.cpp b/plugins/test_control_plugin/test_control_plugin.cpp index 80543c9942..e06a08de1f 100644 --- a/plugins/test_control_plugin/test_control_plugin.cpp +++ b/plugins/test_control_plugin/test_control_plugin.cpp @@ -32,12 +32,12 @@ class test_control_plugin_impl { void test_control_plugin_impl::connect() { _irreversible_block_connection.emplace( - _chain.irreversible_block.connect( [&]( const chain::block_signal_params& t ) { + _chain.irreversible_block().connect( [&]( const chain::block_signal_params& t ) { const auto& [ block, id ] = t; applied_irreversible_block( id ); } )); _accepted_block_connection = - _chain.accepted_block.connect( [&]( const chain::block_signal_params& t ) { + _chain.accepted_block().connect( [&]( const chain::block_signal_params& t ) { const auto& [ block, id ] = t; accepted_block( id ); } ); diff --git a/plugins/trace_api_plugin/trace_api_plugin.cpp b/plugins/trace_api_plugin/trace_api_plugin.cpp index 8aa7ea9556..4d51e35625 100644 --- a/plugins/trace_api_plugin/trace_api_plugin.cpp +++ b/plugins/trace_api_plugin/trace_api_plugin.cpp @@ -363,21 +363,21 @@ struct trace_api_plugin_impl { auto& chain = app().find_plugin()->chain(); applied_transaction_connection.emplace( - chain.applied_transaction.connect([this](std::tuple t) { + chain.applied_transaction().connect([this](std::tuple t) { emit_killer([&](){ extraction->signal_applied_transaction(std::get<0>(t), std::get<1>(t)); }); })); block_start_connection.emplace( - chain.block_start.connect([this](uint32_t block_num) { + chain.block_start().connect([this](uint32_t block_num) { emit_killer([&](){ extraction->signal_block_start(block_num); }); })); accepted_block_connection.emplace( - chain.accepted_block.connect([this](const chain::block_signal_params& t) { + chain.accepted_block().connect([this](const chain::block_signal_params& t) { emit_killer([&](){ const auto& [ block, id ] = t; extraction->signal_accepted_block(block, id); @@ -385,7 +385,7 @@ struct trace_api_plugin_impl { })); irreversible_block_connection.emplace( - chain.irreversible_block.connect([this](const chain::block_signal_params& t) { + chain.irreversible_block().connect([this](const chain::block_signal_params& t) { const auto& [ block, id ] = t; emit_killer([&](){ extraction->signal_irreversible_block(block->block_num()); diff --git a/tests/test_snapshot_scheduler.cpp b/tests/test_snapshot_scheduler.cpp index 1a560ca079..a03add72bb 100644 --- a/tests/test_snapshot_scheduler.cpp +++ b/tests/test_snapshot_scheduler.cpp @@ -76,7 +76,7 @@ BOOST_AUTO_TEST_CASE(snapshot_scheduler_test) { chain_plugin* chain_plug = app->find_plugin(); plugin_promise.set_value({prod_plug, chain_plug}); - auto bs = chain_plug->chain().block_start.connect([&prod_plug, &at_block_20_promise](uint32_t bn) { + auto bs = chain_plug->chain().block_start().connect([&prod_plug, &at_block_20_promise](uint32_t bn) { if(bn == 20u) at_block_20_promise.set_value(); // catching pending snapshot diff --git a/unittests/api_tests.cpp b/unittests/api_tests.cpp index ab65ff25d2..a25e96f0ad 100644 --- a/unittests/api_tests.cpp +++ b/unittests/api_tests.cpp @@ -889,7 +889,7 @@ BOOST_AUTO_TEST_CASE(light_validation_skip_cfa) try { other.execute_setup_policy( setup_policy::full ); transaction_trace_ptr other_trace; - auto cc = other.control->applied_transaction.connect( [&](std::tuple x) { + auto cc = other.control->applied_transaction().connect( [&](std::tuple x) { auto& t = std::get<0>(x); if( t && t->id == trace->id ) { other_trace = t; @@ -1467,12 +1467,12 @@ void transaction_tests(T& chain) { { chain.produce_blocks(10); transaction_trace_ptr trace; - auto c = chain.control->applied_transaction.connect([&](std::tuple x) { + auto c = chain.control->applied_transaction().connect([&](std::tuple x) { auto& t = std::get<0>(x); if (t && t->receipt && t->receipt->status != transaction_receipt::executed) { trace = t; } } ); signed_block_ptr block; - auto c2 = chain.control->accepted_block.connect([&](block_signal_params t) { + auto c2 = chain.control->accepted_block().connect([&](block_signal_params t) { const auto& [ b, id ] = t; block = b; }); @@ -1652,7 +1652,7 @@ BOOST_AUTO_TEST_CASE(deferred_inline_action_limit) { try { chain2.push_block(block); transaction_trace_ptr trace; - auto c = chain.control->applied_transaction.connect([&](std::tuple x) { + auto c = chain.control->applied_transaction().connect([&](std::tuple x) { auto& t = std::get<0>(x); if (t->scheduled) { trace = t; } } ); @@ -1687,7 +1687,7 @@ BOOST_FIXTURE_TEST_CASE(deferred_transaction_tests, validating_tester_no_disable //schedule { transaction_trace_ptr trace; - auto c = control->applied_transaction.connect([&](std::tuple x) { + auto c = control->applied_transaction().connect([&](std::tuple x) { auto& t = std::get<0>(x); if (t->scheduled) { trace = t; } } ); @@ -1710,7 +1710,7 @@ BOOST_FIXTURE_TEST_CASE(deferred_transaction_tests, validating_tester_no_disable { transaction_trace_ptr trace; uint32_t count = 0; - auto c = control->applied_transaction.connect([&](std::tuple x) { + auto c = control->applied_transaction().connect([&](std::tuple x) { auto& t = std::get<0>(x); if (t && t->scheduled) { trace = t; ++count; } } ); @@ -1736,7 +1736,7 @@ BOOST_FIXTURE_TEST_CASE(deferred_transaction_tests, validating_tester_no_disable { transaction_trace_ptr trace; uint32_t count = 0; - auto c = control->applied_transaction.connect([&](std::tuple x) { + auto c = control->applied_transaction().connect([&](std::tuple x) { auto& t = std::get<0>(x); if (t && t->scheduled) { trace = t; ++count; } } ); @@ -1762,7 +1762,7 @@ BOOST_FIXTURE_TEST_CASE(deferred_transaction_tests, validating_tester_no_disable //schedule and cancel { transaction_trace_ptr trace; - auto c = control->applied_transaction.connect([&](std::tuple x) { + auto c = control->applied_transaction().connect([&](std::tuple x) { auto& t = std::get<0>(x); if (t && t->scheduled) { trace = t; } } ); @@ -1785,7 +1785,7 @@ BOOST_FIXTURE_TEST_CASE(deferred_transaction_tests, validating_tester_no_disable //repeated deferred transactions { vector traces; - auto c = control->applied_transaction.connect([&](std::tuple x) { + auto c = control->applied_transaction().connect([&](std::tuple x) { auto& t = std::get<0>(x); if (t && t->scheduled) { traces.push_back( t ); @@ -3863,7 +3863,7 @@ BOOST_AUTO_TEST_CASE(set_finalizer_test) { try { validating_tester t; uint32_t lib = 0; - t.control->irreversible_block.connect([&](const block_signal_params& t) { + t.control->irreversible_block().connect([&](const block_signal_params& t) { const auto& [ block, id ] = t; lib = block->block_num(); }); @@ -3921,7 +3921,7 @@ void test_finality_transition(const vector& accounts, const base_t validating_tester t; uint32_t lib = 0; - t.control->irreversible_block.connect([&](const block_signal_params& t) { + t.control->irreversible_block().connect([&](const block_signal_params& t) { const auto& [ block, id ] = t; lib = block->block_num(); }); diff --git a/unittests/block_tests.cpp b/unittests/block_tests.cpp index 638aa38a1a..c34aaadb7d 100644 --- a/unittests/block_tests.cpp +++ b/unittests/block_tests.cpp @@ -217,11 +217,11 @@ BOOST_AUTO_TEST_CASE(broadcasted_block_test) signed_block_ptr bcasted_blk_by_prod_node; signed_block_ptr bcasted_blk_by_recv_node; - producer_node.control->accepted_block.connect( [&](block_signal_params t) { + producer_node.control->accepted_block().connect( [&](block_signal_params t) { const auto& [ block, id ] = t; bcasted_blk_by_prod_node = block; }); - receiving_node.control->accepted_block.connect( [&](block_signal_params t) { + receiving_node.control->accepted_block().connect( [&](block_signal_params t) { const auto& [ block, id ] = t; bcasted_blk_by_recv_node = block; }); diff --git a/unittests/chain_tests.cpp b/unittests/chain_tests.cpp index bc2a973e12..dc6a63914c 100644 --- a/unittests/chain_tests.cpp +++ b/unittests/chain_tests.cpp @@ -156,7 +156,7 @@ BOOST_AUTO_TEST_CASE( signal_validated_blocks ) try { signed_block_ptr accepted_block; block_id_type accepted_id; - auto c = chain.control->accepted_block.connect([&](block_signal_params t) { + auto c = chain.control->accepted_block().connect([&](block_signal_params t) { const auto& [ block, id ] = t; auto block_num = block->block_num(); BOOST_CHECK(block); @@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE( signal_validated_blocks ) try { }); signed_block_ptr validated_block; block_id_type validated_id; - auto c2 = validator.control->accepted_block.connect([&](block_signal_params t) { + auto c2 = validator.control->accepted_block().connect([&](block_signal_params t) { const auto& [ block, id ] = t; auto block_num = block->block_num(); BOOST_CHECK(block); diff --git a/unittests/eosio.system_tests.cpp b/unittests/eosio.system_tests.cpp index 9d3905819c..3d2a408f28 100644 --- a/unittests/eosio.system_tests.cpp +++ b/unittests/eosio.system_tests.cpp @@ -1844,7 +1844,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) ); transaction_trace_ptr trace; - control->applied_transaction.connect( + control->applied_transaction().connect( [&]( std::tuple p ) { trace = std::get<0>(p); } ); @@ -2595,7 +2595,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { } transaction_trace_ptr trace; - control->applied_transaction.connect( + control->applied_transaction().connect( [&]( std::tuple p ) { trace = std::get<0>(p); } ); diff --git a/unittests/forked_tests.cpp b/unittests/forked_tests.cpp index 6a79c18a80..8ac11285e0 100644 --- a/unittests/forked_tests.cpp +++ b/unittests/forked_tests.cpp @@ -355,7 +355,7 @@ BOOST_AUTO_TEST_CASE( validator_accepts_valid_blocks ) try { block_id_type first_id; signed_block_header first_header; - auto c = n2.control->accepted_block.connect( [&]( block_signal_params t ) { + auto c = n2.control->accepted_block().connect( [&]( block_signal_params t ) { const auto& [ block, id ] = t; first_block = block; first_id = id; @@ -704,7 +704,7 @@ BOOST_AUTO_TEST_CASE( push_block_returns_forked_transactions ) try { // test forked blocks signal accepted_block in order, required by trace_api_plugin std::vector accepted_blocks; - auto conn = c.control->accepted_block.connect( [&]( block_signal_params t ) { + auto conn = c.control->accepted_block().connect( [&]( block_signal_params t ) { const auto& [ block, id ] = t; accepted_blocks.emplace_back( block ); } ); diff --git a/unittests/producer_schedule_if_tests.cpp b/unittests/producer_schedule_if_tests.cpp index 9d84ded4af..efc3a7856f 100644 --- a/unittests/producer_schedule_if_tests.cpp +++ b/unittests/producer_schedule_if_tests.cpp @@ -52,7 +52,7 @@ BOOST_FIXTURE_TEST_CASE( verify_producer_schedule_after_instant_finality_activat }; uint32_t lib = 0; - control->irreversible_block.connect([&](const block_signal_params& t) { + control->irreversible_block().connect([&](const block_signal_params& t) { const auto& [ block, id ] = t; lib = block->block_num(); }); diff --git a/unittests/protocol_feature_tests.cpp b/unittests/protocol_feature_tests.cpp index bfd6067867..a013de368d 100644 --- a/unittests/protocol_feature_tests.cpp +++ b/unittests/protocol_feature_tests.cpp @@ -414,7 +414,7 @@ BOOST_AUTO_TEST_CASE( replace_deferred_test ) try { c.init( cfg ); transaction_trace_ptr trace; - auto h = c.control->applied_transaction.connect( [&](std::tuple x) { + auto h = c.control->applied_transaction().connect( [&](std::tuple x) { auto& t = std::get<0>(x); if( t && !eosio::chain::is_onblock(*t)) { trace = t; @@ -558,7 +558,7 @@ BOOST_AUTO_TEST_CASE( no_duplicate_deferred_id_test ) try { c2.produce_empty_block( fc::minutes(10) ); transaction_trace_ptr trace0; - auto h2 = c2.control->applied_transaction.connect( [&](std::tuple x) { + auto h2 = c2.control->applied_transaction().connect( [&](std::tuple x) { auto& t = std::get<0>(x); if( t && t->receipt && t->receipt->status == transaction_receipt::expired) { trace0 = t; @@ -576,7 +576,7 @@ BOOST_AUTO_TEST_CASE( no_duplicate_deferred_id_test ) try { const auto& index = c.control->db().get_index(); transaction_trace_ptr trace1; - auto h = c.control->applied_transaction.connect( [&](std::tuple x) { + auto h = c.control->applied_transaction().connect( [&](std::tuple x) { auto& t = std::get<0>(x); if( t && t->receipt && t->receipt->status == transaction_receipt::executed) { trace1 = t; diff --git a/unittests/restart_chain_tests.cpp b/unittests/restart_chain_tests.cpp index c810f50548..913a72902a 100644 --- a/unittests/restart_chain_tests.cpp +++ b/unittests/restart_chain_tests.cpp @@ -60,7 +60,7 @@ class replay_tester : public base_tester { replay_tester(controller::config config, const genesis_state& genesis, OnAppliedTrx&& on_applied_trx) { cfg = config; base_tester::open(make_protocol_feature_set(), genesis.compute_chain_id(), [&genesis,&control=this->control, &on_applied_trx]() { - control->applied_transaction.connect(on_applied_trx); + control->applied_transaction().connect(on_applied_trx); control->startup( [](){}, []() { return false; }, genesis ); }); } diff --git a/unittests/state_history_tests.cpp b/unittests/state_history_tests.cpp index 2c74310248..cac7d5e9e2 100644 --- a/unittests/state_history_tests.cpp +++ b/unittests/state_history_tests.cpp @@ -588,7 +588,7 @@ BOOST_AUTO_TEST_CASE(test_deltas_resources_history) { fc::temp_directory state_history_dir; eosio::state_history::trace_converter log; - c.control->applied_transaction.connect( + c.control->applied_transaction().connect( [&](std::tuple t) { log.add_transaction(std::get<0>(t), std::get<1>(t)); }); @@ -626,12 +626,12 @@ struct state_history_tester : state_history_tester_logs, tester { state_history_tester(const std::filesystem::path& dir, const eosio::state_history_log_config& config) : state_history_tester_logs(dir, config), tester ([this](eosio::chain::controller& control) { - control.applied_transaction.connect( + control.applied_transaction().connect( [&](std::tuple t) { trace_converter.add_transaction(std::get<0>(t), std::get<1>(t)); }); - control.accepted_block.connect([&](block_signal_params t) { + control.accepted_block().connect([&](block_signal_params t) { const auto& [ block, id ] = t; eosio::state_history_log_header header{.magic = eosio::ship_magic(eosio::ship_current_version, 0), .block_id = id, @@ -645,7 +645,7 @@ struct state_history_tester : state_history_tester_logs, tester { eosio::state_history::pack_deltas(buf, control.db(), true); }); }); - control.block_start.connect([this](uint32_t block_num) { + control.block_start().connect([this](uint32_t block_num) { trace_converter.cached_traces.clear(); trace_converter.onblock_trace.reset(); }); diff --git a/unittests/whitelist_blacklist_tests.cpp b/unittests/whitelist_blacklist_tests.cpp index ca4ea88dfb..519682246f 100644 --- a/unittests/whitelist_blacklist_tests.cpp +++ b/unittests/whitelist_blacklist_tests.cpp @@ -492,7 +492,7 @@ BOOST_AUTO_TEST_CASE( actor_blacklist_inline_deferred ) { try { } }; - auto c1 = tester1.chain->control->applied_transaction.connect( log_trxs ); + auto c1 = tester1.chain->control->applied_transaction().connect( log_trxs ); // Disallow inline actions authorized by actor in blacklist BOOST_CHECK_EXCEPTION( tester1.chain->push_action( "alice"_n, "inlinecall"_n, "alice"_n, mvo() @@ -537,7 +537,7 @@ BOOST_AUTO_TEST_CASE( actor_blacklist_inline_deferred ) { try { tester1.actor_blacklist = {"bob"_n, "charlie"_n}; tester1.init(false); - auto c2 = tester1.chain->control->applied_transaction.connect( log_trxs ); + auto c2 = tester1.chain->control->applied_transaction().connect( log_trxs ); num_deferred = tester1.chain->control->db().get_index().size(); BOOST_REQUIRE_EQUAL(1u, num_deferred);