From 2a29cee68438e485b101e9a89c907f7a2ea38232 Mon Sep 17 00:00:00 2001 From: Hao Xu Date: Fri, 19 Jun 2026 20:25:58 +0800 Subject: [PATCH] test: add helper to reset chainman and mempool Move the reusable chainman/mempool reset logic from the cmpctblock fuzz target into test util validation helpers. Return the mature coinbase outputs so cmpctblock can keep using them while other callers can ignore the result. --- src/test/fuzz/cmpctblock.cpp | 35 ++---------------------------- src/test/util/validation.cpp | 41 ++++++++++++++++++++++++++++++++++++ src/test/util/validation.h | 8 +++++++ 3 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/test/fuzz/cmpctblock.cpp b/src/test/fuzz/cmpctblock.cpp index ffa67d4bb63..5a67e8d9c96 100644 --- a/src/test/fuzz/cmpctblock.cpp +++ b/src/test/fuzz/cmpctblock.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -26,20 +25,17 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #include #include #include #include -#include #include #include @@ -107,33 +103,6 @@ public: } }; -void ResetChainmanAndMempool(TestingSetup& setup) -{ - GetFakeNodeClock().set(Params().GenesisBlock().Time()); - - bilingual_str error{}; - setup.m_node.mempool.reset(); - setup.m_node.mempool = std::make_unique(MemPoolOptionsForTest(setup.m_node), error); - Assert(error.empty()); - - setup.m_node.chainman.reset(); - setup.m_make_chainman(); - setup.LoadVerifyActivateChainstate(); - - node::BlockCreateOptions options; - options.coinbase_output_script = P2WSH_OP_TRUE; - - g_mature_coinbase.clear(); - - for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) { - COutPoint prevout{MineBlock(setup.m_node, options)}; - if (i < COINBASE_MATURITY) { - LOCK(cs_main); - CAmount subsidy{setup.m_node.chainman->ActiveChainstate().CoinsTip().GetCoin(prevout)->out.nValue}; - g_mature_coinbase.emplace_back(prevout, subsidy); - } - } -} //! Used to run tasks in a std::thread to avoid DEBUG_LOCKORDER false positives. class ImmediateBackgroundTaskRunner : public util::TaskRunnerInterface @@ -155,7 +124,7 @@ void initialize_cmpctblock() g_nBits = Params().GenesisBlock().nBits; // Replace validation_signals before creating chainman and mempool so they use it. testing_setup->m_node.validation_signals = std::make_unique(std::make_unique()); - ResetChainmanAndMempool(*g_setup); + g_mature_coinbase = ResetChainmanAndMempool(*g_setup); } FUZZ_TARGET(cmpctblock, .init = initialize_cmpctblock) @@ -509,6 +478,6 @@ FUZZ_TARGET(cmpctblock, .init = initialize_cmpctblock) if (initial_index_size != end_index_size || initial_sequence != end_sequence) { MakeRandDeterministicDANGEROUS(uint256::ZERO); - ResetChainmanAndMempool(*g_setup); + g_mature_coinbase = ResetChainmanAndMempool(*g_setup); } } diff --git a/src/test/util/validation.cpp b/src/test/util/validation.cpp index 7e09597ea34..61a16657f58 100644 --- a/src/test/util/validation.cpp +++ b/src/test/util/validation.cpp @@ -4,12 +4,25 @@ #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include +#include +#include + using kernel::ChainstateRole; void TestBlockManager::CleanupForFuzzing() @@ -91,3 +104,31 @@ void TestChainstateManager::ResetBestInvalid() { m_best_invalid = nullptr; } + +std::vector> ResetChainmanAndMempool(TestingSetup& setup) +{ + GetFakeNodeClock().set(setup.m_node.chainman->GetParams().GenesisBlock().Time()); + + bilingual_str error{}; + setup.m_node.mempool.reset(); + setup.m_node.mempool = std::make_unique(MemPoolOptionsForTest(setup.m_node), error); + Assert(error.empty()); + + setup.m_node.chainman.reset(); + setup.m_make_chainman(); + setup.LoadVerifyActivateChainstate(); + + node::BlockCreateOptions options; + options.coinbase_output_script = P2WSH_OP_TRUE; + + std::vector> mature_coinbase; + for (int i = 0; i < 2 * COINBASE_MATURITY; ++i) { + COutPoint prevout{MineBlock(setup.m_node, options)}; + if (i < COINBASE_MATURITY) { + LOCK(cs_main); + CAmount subsidy{setup.m_node.chainman->ActiveChainstate().CoinsTip().GetCoin(prevout)->out.nValue}; + mature_coinbase.emplace_back(prevout, subsidy); + } + } + return mature_coinbase; +} diff --git a/src/test/util/validation.h b/src/test/util/validation.h index 1be3f6a64db..87a2d2efe1a 100644 --- a/src/test/util/validation.h +++ b/src/test/util/validation.h @@ -5,12 +5,18 @@ #ifndef BITCOIN_TEST_UTIL_VALIDATION_H #define BITCOIN_TEST_UTIL_VALIDATION_H +#include +#include #include +#include +#include + namespace node { class BlockManager; } class CValidationInterface; +struct TestingSetup; struct TestBlockManager : public node::BlockManager { /** Test-only method to clear internal state for fuzzing */ @@ -41,4 +47,6 @@ public: const CBlockIndex* pindex); }; +std::vector> ResetChainmanAndMempool(TestingSetup& setup); + #endif // BITCOIN_TEST_UTIL_VALIDATION_H