From 472b1d4af527fb5e86ffd9b7eb9dba818d594299 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Thu, 8 Feb 2024 14:10:40 -0600 Subject: [PATCH] GH-2125 Optimize fetch_block_branch --- libraries/chain/controller.cpp | 4 +-- libraries/chain/fork_database.cpp | 31 ++++++++++++++----- .../include/eosio/chain/fork_database.hpp | 5 ++- programs/leap-util/actions/blocklog.cpp | 2 +- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index bb46a5058e..c679f8425b 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -1339,13 +1339,13 @@ struct controller_impl { forkdb.reset( *head ); } else if( !except_ptr && !check_shutdown() && forkdb.head() ) { auto head_block_num = head->block_num(); - auto branch = forkdb.fetch_branch( forkdb.head()->id() ); + auto branch = fork_db.fetch_branch_from_head(); int rev = 0; for( auto i = branch.rbegin(); i != branch.rend(); ++i ) { if( check_shutdown() ) break; if( (*i)->block_num() <= head_block_num ) continue; ++rev; - replay_push_block( (*i)->block, controller::block_status::validated ); + replay_push_block( *i, controller::block_status::validated ); } ilog( "${n} reversible blocks replayed", ("n",rev) ); } diff --git a/libraries/chain/fork_database.cpp b/libraries/chain/fork_database.cpp index 1d6f920178..272b88957a 100644 --- a/libraries/chain/fork_database.cpp +++ b/libraries/chain/fork_database.cpp @@ -72,6 +72,7 @@ namespace eosio::chain { void advance_root_impl( const block_id_type& id ); void remove_impl( const block_id_type& id ); branch_type fetch_branch_impl( const block_id_type& h, uint32_t trim_after_block_num ) const; + block_branch_t fetch_block_branch_impl( const block_id_type& h, uint32_t trim_after_block_num ) const; bsp search_on_branch_impl( const block_id_type& h, uint32_t block_num ) const; void mark_valid_impl( const bsp& h ); branch_type_pair fetch_branch_from_impl( const block_id_type& first, const block_id_type& second ) const; @@ -420,6 +421,25 @@ namespace eosio::chain { return result; } + template + block_branch_t + fork_database_t::fetch_block_branch(const block_id_type& h, uint32_t trim_after_block_num) const { + std::lock_guard g(my->mtx); + return my->fetch_block_branch_impl(h, trim_after_block_num); + } + + template + block_branch_t + fork_database_impl::fetch_block_branch_impl(const block_id_type& h, uint32_t trim_after_block_num) const { + block_branch_t result; + for (auto s = get_block_impl(h); s; s = get_block_impl(s->previous())) { + if (s->block_num() <= trim_after_block_num) + result.push_back(s->block); + } + + return result; + } + template bsp fork_database_t::search_on_branch( const block_id_type& h, uint32_t block_num ) const { std::lock_guard g( my->mtx ); @@ -648,15 +668,10 @@ namespace eosio::chain { }); } - std::vector fork_database::fetch_branch_from_head() { - std::vector r; - apply([&](auto& forkdb) { - auto branch = forkdb.fetch_branch(forkdb.head()->id()); - r.reserve(branch.size()); - for (auto& b : branch) - r.push_back(b->block); + block_branch_t fork_database::fetch_branch_from_head() const { + return apply([&](auto& forkdb) { + return forkdb.fetch_block_branch(forkdb.head()->id()); }); - return r; } // do class instantiations diff --git a/libraries/chain/include/eosio/chain/fork_database.hpp b/libraries/chain/include/eosio/chain/fork_database.hpp index c9ad269914..56b17744f9 100644 --- a/libraries/chain/include/eosio/chain/fork_database.hpp +++ b/libraries/chain/include/eosio/chain/fork_database.hpp @@ -10,6 +10,8 @@ namespace eosio::chain { template struct fork_database_impl; + using block_branch_t = deque; + /** * @class fork_database_t * @brief manages light-weight state for all potential unconfirmed forks @@ -85,6 +87,7 @@ namespace eosio::chain { * A block with an id of `h` must exist in the fork database otherwise this method will throw an exception. */ branch_type fetch_branch( const block_id_type& h, uint32_t trim_after_block_num = std::numeric_limits::max() ) const; + block_branch_t fetch_block_branch( const block_id_type& h, uint32_t trim_after_block_num = std::numeric_limits::max() ) const; /** @@ -131,7 +134,7 @@ namespace eosio::chain { void switch_from_legacy(); // see fork_database_t::fetch_branch(forkdb->head()->id()) - std::vector fetch_branch_from_head(); + block_branch_t fetch_branch_from_head() const; template R apply(const F& f) { diff --git a/programs/leap-util/actions/blocklog.cpp b/programs/leap-util/actions/blocklog.cpp index 1807081b59..869d25732f 100644 --- a/programs/leap-util/actions/blocklog.cpp +++ b/programs/leap-util/actions/blocklog.cpp @@ -266,7 +266,7 @@ int blocklog_actions::read_log() { opt->first_block = block_logger.first_block_num(); } - std::vector fork_db_branch; + block_branch_t fork_db_branch; if(std::filesystem::exists(std::filesystem::path(opt->blocks_dir) / config::reversible_blocks_dir_name / config::forkdb_filename)) { ilog("opening fork_db");