From 5aa15df60c49aacd3b3dafe13a4ceded9cec07cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Sat, 22 Aug 2026 20:03:05 -0700 Subject: [PATCH 1/2] test: expose missing index crash checkpoint `index_unclean_shutdown` previously checked only that each index could reopen and start background sync after the simulated crash. An empty index at height 0 satisfies both checks, so the test could pass without preserving any pre-crash checkpoint. Assert the current reopened height before background sync to make the false positive explicit. --- src/test/baseindex_tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/baseindex_tests.cpp b/src/test/baseindex_tests.cpp index 553b07ee7d8..96f41ae118b 100644 --- a/src/test/baseindex_tests.cpp +++ b/src/test/baseindex_tests.cpp @@ -145,6 +145,7 @@ BOOST_FIXTURE_TEST_CASE(index_unclean_shutdown, TestChain100Setup) auto index{make_index(m_node)}; BOOST_REQUIRE(index->Init()); // Make sure the index can be loaded. + BOOST_CHECK_EQUAL(index->GetSummary().best_block_height, 0); // TODO: Establish and reload a pre-crash commit BOOST_REQUIRE(index->StartBackgroundSync()); index->Stop(); } From 7ea36e985a900b2291ce549e468f6baab5324dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C5=91rinc?= Date: Sat, 22 Aug 2026 20:04:23 -0700 Subject: [PATCH 2/2] test: preserve index crash test state Flush the chainstate at the current tip and drain its notification before registering any index. This lets each end-of-sync `Commit()` persist the pre-crash height and keeps the setup callback out of the simulated crash window. Replace the TODO-marked `0` expectation with the captured tip height. The check runs before background sync, so rebuilding cannot hide a missing checkpoint. --- src/test/baseindex_tests.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/test/baseindex_tests.cpp b/src/test/baseindex_tests.cpp index 96f41ae118b..4e9a03a1856 100644 --- a/src/test/baseindex_tests.cpp +++ b/src/test/baseindex_tests.cpp @@ -108,11 +108,15 @@ BOOST_FIXTURE_TEST_CASE(baseindex_no_commit_ahead_of_flush, TestChain100Setup) } // Test shutdown between BlockConnected and ChainStateFlushed notifications, -// make sure index is not corrupted and is able to reload. +// make sure index is not corrupted and reloads at the last committed height. BOOST_FIXTURE_TEST_CASE(index_unclean_shutdown, TestChain100Setup) { Chainstate& chainstate = Assert(m_node.chainman)->ActiveChainstate(); const CChainParams& params = Params(); + const int tip_height{WITH_LOCK(cs_main, return chainstate.m_chain.Height())}; + chainstate.ForceFlushStateToDisk(); + // Drain the notification before registering any index. + m_node.chain->context()->validation_signals->SyncWithValidationInterfaceQueue(); for (const auto& [index_name, make_index] : INDEX_FACTORIES) { BOOST_TEST_INFO_SCOPE(index_name); { @@ -144,8 +148,8 @@ BOOST_FIXTURE_TEST_CASE(index_unclean_shutdown, TestChain100Setup) { auto index{make_index(m_node)}; BOOST_REQUIRE(index->Init()); - // Make sure the index can be loaded. - BOOST_CHECK_EQUAL(index->GetSummary().best_block_height, 0); // TODO: Establish and reload a pre-crash commit + // Make sure the index reloads from the pre-crash commit. + BOOST_CHECK_EQUAL(index->GetSummary().best_block_height, tip_height); BOOST_REQUIRE(index->StartBackgroundSync()); index->Stop(); }