From c0c83aabc2631a128ef26e2d2df85d801ceb46ef Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 6 Dec 2024 13:44:59 -0600 Subject: [PATCH 1/3] GH-1052 Add tests that verify LIB can be found by fetch_block_by_number and fetch_block_by_id --- unittests/database_tests.cpp | 51 ++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/unittests/database_tests.cpp b/unittests/database_tests.cpp index 6d8ab1b605..83c1fa72fc 100644 --- a/unittests/database_tests.cpp +++ b/unittests/database_tests.cpp @@ -84,6 +84,57 @@ BOOST_AUTO_TEST_SUITE(database_tests) // Check the latest head block match BOOST_TEST(test.fetch_block_by_number(test.head().block_num())->calculate_id() == test.head().id()); + + // Verify LIB can be found + const auto lib_num = test.last_irreversible_block_num(); + auto lib = test.fetch_block_by_number(lib_num); + BOOST_REQUIRE(lib); + auto lib_id = lib->calculate_id(); + BOOST_TEST(lib_num == lib->block_num()); + lib = test.fetch_block_by_id(lib_id); + BOOST_REQUIRE(lib); + BOOST_TEST(lib->calculate_id() == lib_id); + + } FC_LOG_AND_RETHROW() + } + + // Test the block fetching methods on database, fetch_bock_by_id, and fetch_block_by_number + BOOST_AUTO_TEST_CASE_TEMPLATE( get_blocks_no_block_log, T, validating_testers ) { + try { + fc::temp_directory tempdir; + + constexpr bool use_genesis = true; + T test( + tempdir, + [&](controller::config& cfg) { + cfg.blog = eosio::chain::empty_blocklog_config{}; + }, + use_genesis + ); + + // Ensure that future block doesn't exist + const auto nonexisting_future_block_num = test.head().block_num() + 1; + BOOST_TEST(test.fetch_block_by_number(nonexisting_future_block_num) == nullptr); + BOOST_TEST(test.fetch_block_by_id(sha256::hash("xx")) == nullptr); + + test.produce_block(); + + // Previous nonexisting future block should exist now + BOOST_CHECK_NO_THROW(test.fetch_block_by_number(nonexisting_future_block_num)); + // Check the latest head block match + BOOST_TEST(test.fetch_block_by_number(test.head().block_num())->calculate_id() == test.head().id()); + BOOST_TEST(test.fetch_block_by_id(test.head().id())->calculate_id() == test.head().id()); + + // Verify LIB can be found + const auto lib_num = test.last_irreversible_block_num(); + auto lib = test.fetch_block_by_number(lib_num); + BOOST_REQUIRE(lib); + auto lib_id = lib->calculate_id(); + BOOST_TEST(lib_num == lib->block_num()); + lib = test.fetch_block_by_id(lib_id); + BOOST_REQUIRE(lib); + BOOST_TEST(lib->calculate_id() == lib_id); + } FC_LOG_AND_RETHROW() } From 838e885908aaa1f19aff9aaf4433a6f7904e86cb Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 6 Dec 2024 13:45:49 -0600 Subject: [PATCH 2/3] GH-1052 Fix fetch_block_by_number and fetch_block_by_id to return LIB with no block log --- libraries/chain/controller.cpp | 4 ++-- libraries/chain/fork_database.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 161aac3191..3a7eae907f 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -1149,14 +1149,14 @@ struct controller_impl { signed_block_ptr fork_db_fetch_block_by_id( const block_id_type& id ) const { return fork_db.apply([&](const auto& forkdb) { - auto bsp = forkdb.get_block(id); + auto bsp = forkdb.get_block(id, include_root_t::yes); return bsp ? bsp->block : signed_block_ptr{}; }); } signed_block_ptr fork_db_fetch_block_on_best_branch_by_num(uint32_t block_num) const { return fork_db.apply([&](const auto& forkdb) { - auto bsp = forkdb.search_on_head_branch(block_num); + auto bsp = forkdb.search_on_head_branch(block_num, include_root_t::yes); if (bsp) return bsp->block; return signed_block_ptr{}; }); diff --git a/libraries/chain/fork_database.cpp b/libraries/chain/fork_database.cpp index e6f20d204f..f8f4fe39bc 100644 --- a/libraries/chain/fork_database.cpp +++ b/libraries/chain/fork_database.cpp @@ -448,8 +448,8 @@ namespace eosio::chain { BSP fork_database_impl::search_on_branch_impl( const block_id_type& h, uint32_t block_num, include_root_t include_root ) const { if (!root) return {}; - if( include_root == include_root_t::yes && root->id() == h && root->block_num() == block_num ) { - return root; + if( include_root == include_root_t::yes && root->block_num() == block_num ) { + return root; // root is root of every branch, no need to check h } if (block_num <= root->block_num()) return {}; From ee1c477b1702b334748558ba91aa6c7ae1c4f558 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 6 Dec 2024 14:24:17 -0600 Subject: [PATCH 3/3] GH-1052 Verify root exists before accessing id() --- libraries/chain/fork_database.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/chain/fork_database.cpp b/libraries/chain/fork_database.cpp index f8f4fe39bc..fcb83bc20b 100644 --- a/libraries/chain/fork_database.cpp +++ b/libraries/chain/fork_database.cpp @@ -582,7 +582,7 @@ namespace eosio::chain { template BSP fork_database_impl::get_block_impl(const block_id_type& id, include_root_t include_root /* = include_root_t::no */) const { - if( include_root == include_root_t::yes && root->id() == id ) { + if( include_root == include_root_t::yes && root && root->id() == id ) { return root; } auto itr = index.find( id );