From d738ad45232436b3f06c8499f42ad4f27532db37 Mon Sep 17 00:00:00 2001 From: pasta Date: Wed, 19 Aug 2026 22:46:11 -0500 Subject: [PATCH] test: reset stale peerman and cj_walletman before chainstate reloads PeerManagerImpl references the mempool, dmnman, isman, clhandler and llmq_ctx; CJWalletManagerImpl references the chainman, dmnman, mempool and isman. LoadVerifyActivateChainstate() recreates llmq_ctx, and since dash#7603 its reindex path also replaces the mempool and those managers, so any SnapshotTestSetup test reloading the chainstate left m_node.peerman and m_node.cj_walletman holding dangling references for the rest of the test. No test uses either object across a reload, so destroy them (clearing connman's raw m_msgproc pointer first) instead of rebuilding them: future use after a reload fails on a null pointer rather than silently reading freed memory. A test that needs them after a reload must rebuild them itself, as AppInitMain constructs them only after the chainstate is loaded. Co-authored-by: Konstantin Akimov --- src/test/util/setup_common.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index e1f6a8efcd52..6d2ebc61c2f4 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -326,6 +326,22 @@ void ChainTestingSetup::LoadVerifyActivateChainstate() { auto& chainman{*Assert(m_node.chainman)}; + // peerman and cj_walletman reference llmq_ctx, the mempool and the Dash + // managers recreated by the reload below. No test uses them across a + // reload: destroy them (clearing connman's raw m_msgproc pointer first) + // so future use after a reload fails on a null pointer instead of + // silently reading freed memory; such a test must rebuild them itself, + // as AppInitMain constructs them only after the chainstate is loaded. + if (m_node.peerman) { + CConnman::Options connman_options; + connman_options.socketEventsMode = ::g_socket_events_mode; + m_node.connman->Init(connman_options); + m_node.peerman.reset(); + } +#ifdef ENABLE_WALLET + m_node.cj_walletman.reset(); +#endif // ENABLE_WALLET + node::ChainstateLoadOptions options{ChainstateLoadOptionsForTest()}; if (options.reindex || options.reindex_chainstate) {