From 2aa4e73ccdc12c5b8359f9fa9c0d8ae4f5c4927d Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 25 Feb 2022 22:16:49 -0600 Subject: [PATCH] Limit input transaction dedup time --- libraries/chain/controller.cpp | 23 +++++++++++++------ .../chain/include/eosio/chain/controller.hpp | 3 ++- plugins/producer_plugin/producer_plugin.cpp | 4 ++-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 6789092c38..6d006a8172 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -1597,7 +1597,8 @@ struct controller_impl { uint16_t confirm_block_count, const vector& new_protocol_feature_activations, controller::block_status s, - const std::optional& producer_block_id ) + const std::optional& producer_block_id, + const fc::time_point& deadline ) { EOS_ASSERT( !pending, block_validate_exception, "pending block already exists" ); @@ -1745,7 +1746,7 @@ struct controller_impl { elog( "on block transaction failed due to unknown exception" ); } - clear_expired_input_transactions(); + clear_expired_input_transactions(deadline); update_producers_authority(); } @@ -1946,7 +1947,7 @@ struct controller_impl { const auto& new_protocol_feature_activations = bsp->get_new_protocol_feature_activations(); auto producer_block_id = b->id(); - start_block( b->timestamp, b->confirmed, new_protocol_feature_activations, s, producer_block_id); + start_block( b->timestamp, b->confirmed, new_protocol_feature_activations, s, producer_block_id, fc::time_point::maximum() ); const bool existing_trxs_metas = !bsp->trxs_metas().empty(); const bool pub_keys_recovered = bsp->is_pub_keys_recovered(); @@ -2317,14 +2318,21 @@ struct controller_impl { } - void clear_expired_input_transactions() { + void clear_expired_input_transactions(const fc::time_point& deadline) { //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.pending_block_time(); + const auto total = dedupe_index.size(); + uint32_t num_removed = 0; while( (!dedupe_index.empty()) && ( now > fc::time_point(dedupe_index.begin()->expiration) ) ) { transaction_idx.remove(*dedupe_index.begin()); + ++num_removed; + if( deadline <= fc::time_point::now() ) { + break; + } } + dlog("removed ${n} expired transactions of the ${t} input dedup list", ("n", num_removed)("t", total)); } bool sender_avoids_whitelist_blacklist_enforcement( account_name sender )const { @@ -2711,12 +2719,13 @@ void controller::start_block( block_timestamp_type when, uint16_t confirm_block_ } my->start_block( when, confirm_block_count, new_protocol_feature_activations, - block_status::incomplete, std::optional() ); + block_status::incomplete, std::optional(), fc::time_point::maximum() ); } void controller::start_block( block_timestamp_type when, uint16_t confirm_block_count, - const vector& new_protocol_feature_activations ) + const vector& new_protocol_feature_activations, + const fc::time_point& deadline ) { validate_db_available_size(); @@ -2725,7 +2734,7 @@ void controller::start_block( block_timestamp_type when, } my->start_block( when, confirm_block_count, new_protocol_feature_activations, - block_status::incomplete, std::optional() ); + block_status::incomplete, std::optional(), deadline ); } block_state_ptr controller::finalize_block( const signer_callback_type& signer_callback ) { diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index c07e085903..14b121f1c6 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -136,7 +136,8 @@ namespace eosio { namespace chain { */ void start_block( block_timestamp_type time, uint16_t confirm_block_count, - const vector& new_protocol_feature_activations ); + const vector& new_protocol_feature_activations, + const fc::time_point& deadline = fc::time_point::maximum() ); /** * @return transactions applied in aborted block diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index 8a25f7bea2..43bbb2fb1a 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -1514,6 +1514,7 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { const fc::time_point now = fc::time_point::now(); const fc::time_point block_time = calculate_pending_block_time(); + const fc::time_point preprocess_deadline = calculate_block_deadline(block_time); const pending_block_mode previous_pending_mode = _pending_block_mode; _pending_block_mode = pending_block_mode::producing; @@ -1660,12 +1661,11 @@ producer_plugin_impl::start_block_result producer_plugin_impl::start_block() { } } - chain.start_block( block_time, blocks_to_confirm, features_to_activate ); + chain.start_block( block_time, blocks_to_confirm, features_to_activate, preprocess_deadline ); } LOG_AND_DROP(); if( chain.is_building_block() ) { const auto& pending_block_signing_authority = chain.pending_block_signing_authority(); - const fc::time_point preprocess_deadline = calculate_block_deadline(block_time); if (_pending_block_mode == pending_block_mode::producing && pending_block_signing_authority != scheduled_producer.authority) { elog("Unexpected block signing authority, reverting to speculative mode! [expected: \"${expected}\", actual: \"${actual\"", ("expected", scheduled_producer.authority)("actual", pending_block_signing_authority));