From 072343f43123dbe62ada5fc6ee2ade0db38a1d2e Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 7 Jan 2026 14:13:16 +0700 Subject: [PATCH 1/9] refactor: drop CActiveMasternodeManager from chain state and LLMQContext (3/3) --- src/llmq/context.h | 1 - src/node/chainstate.h | 1 - 2 files changed, 2 deletions(-) diff --git a/src/llmq/context.h b/src/llmq/context.h index 1e2e84e25a0e..7a8f9329ed7b 100644 --- a/src/llmq/context.h +++ b/src/llmq/context.h @@ -9,7 +9,6 @@ #include -class CActiveMasternodeManager; class CBLSWorker; class ChainstateManager; class CDeterministicMNManager; diff --git a/src/node/chainstate.h b/src/node/chainstate.h index 0022b7637d87..14a52c588762 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -11,7 +11,6 @@ #include #include -class CActiveMasternodeManager; class CChainstateHelper; class CCreditPoolManager; class CDeterministicMNManager; From c53ee0117bdb861a08ac563d9b3553017af020bf Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 14 Jan 2026 00:31:58 +0700 Subject: [PATCH 2/9] refactor: move initialization of ehf manager from init.cpp to chainhelper --- src/active/context.cpp | 4 ++-- src/active/context.h | 2 +- src/evo/chainhelper.cpp | 8 +++++--- src/evo/chainhelper.h | 4 +++- src/init.cpp | 7 ++----- src/llmq/ehf_signals.cpp | 15 +++++++-------- src/llmq/ehf_signals.h | 6 ++---- src/node/chainstate.cpp | 24 +++++++++--------------- src/node/chainstate.h | 4 ---- src/node/context.h | 2 -- src/node/miner.cpp | 5 ++--- src/node/miner.h | 2 -- src/rpc/blockchain.cpp | 2 +- src/test/util/setup_common.cpp | 8 ++------ src/validation.cpp | 6 ++++++ src/validation.h | 3 +++ 16 files changed, 45 insertions(+), 57 deletions(-) diff --git a/src/active/context.cpp b/src/active/context.cpp index d025c61b6149..217c39e76a88 100644 --- a/src/active/context.cpp +++ b/src/active/context.cpp @@ -25,7 +25,7 @@ ActiveContext::ActiveContext(CBLSWorker& bls_worker, ChainstateManager& chainman, CConnman& connman, CDeterministicMNManager& dmnman, CGovernanceManager& govman, - CMasternodeMetaMan& mn_metaman, CMNHFManager& mnhfman, CSporkManager& sporkman, + CMasternodeMetaMan& mn_metaman, CSporkManager& sporkman, CTxMemPool& mempool, llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, llmq::CQuorumBlockProcessor& qblockman, llmq::CQuorumManager& qman, llmq::CQuorumSnapshotManager& qsnapman, llmq::CSigningManager& sigman, @@ -41,7 +41,7 @@ ActiveContext::ActiveContext(CBLSWorker& bls_worker, ChainstateManager& chainman shareman{std::make_unique(connman, chainman.ActiveChainstate(), sigman, peerman, *nodeman, qman, sporkman)}, gov_signer{std::make_unique(connman, dmnman, govman, *nodeman, chainman, mn_sync)}, - ehf_sighandler{std::make_unique(chainman, mnhfman, sigman, *shareman, qman)}, + ehf_sighandler{std::make_unique(chainman, sigman, *shareman, qman)}, qman_handler{std::make_unique(bls_worker, connman, dmnman, qman, qsnapman, *nodeman, chainman, mn_sync, sporkman, sync_map, quorums_recovery, quorums_watch)}, cl_signer{std::make_unique(chainman.ActiveChainstate(), clhandler, sigman, *shareman, diff --git a/src/active/context.h b/src/active/context.h index c147ed7ea6ff..bd7eeab6a399 100644 --- a/src/active/context.h +++ b/src/active/context.h @@ -63,7 +63,7 @@ struct ActiveContext final : public CValidationInterface { ActiveContext& operator=(const ActiveContext&) = delete; explicit ActiveContext(CBLSWorker& bls_worker, ChainstateManager& chainman, CConnman& connman, CDeterministicMNManager& dmnman, CGovernanceManager& govman, CMasternodeMetaMan& mn_metaman, - CMNHFManager& mnhfman, CSporkManager& sporkman, CTxMemPool& mempool, + CSporkManager& sporkman, CTxMemPool& mempool, llmq::CChainLocksHandler& clhandler, llmq::CInstantSendManager& isman, llmq::CQuorumBlockProcessor& qblockman, llmq::CQuorumManager& qman, llmq::CQuorumSnapshotManager& qsnapman, llmq::CSigningManager& sigman, PeerManager& peerman, diff --git a/src/evo/chainhelper.cpp b/src/evo/chainhelper.cpp index 9c11fc4e6a3c..866df1f9a3c3 100644 --- a/src/evo/chainhelper.cpp +++ b/src/evo/chainhelper.cpp @@ -7,21 +7,23 @@ #include #include +#include #include #include #include #include -CChainstateHelper::CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, - CMNHFManager& mnhfman, CGovernanceManager& govman, llmq::CInstantSendManager& isman, +CChainstateHelper::CChainstateHelper(CEvoDB& evodb, CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, + CGovernanceManager& govman, llmq::CInstantSendManager& isman, llmq::CQuorumBlockProcessor& qblockman, llmq::CQuorumSnapshotManager& qsnapman, const ChainstateManager& chainman, const Consensus::Params& consensus_params, const CMasternodeSync& mn_sync, const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman) : isman{isman}, clhandler{clhandler}, + ehf_manager{std::make_unique(evodb, chainman)}, mn_payments{std::make_unique(dmnman, govman, chainman, consensus_params, mn_sync, sporkman)}, - special_tx{std::make_unique(cpoolman, dmnman, mnhfman, qblockman, qsnapman, chainman, + special_tx{std::make_unique(cpoolman, dmnman, *ehf_manager, qblockman, qsnapman, chainman, consensus_params, clhandler, qman)} {} diff --git a/src/evo/chainhelper.h b/src/evo/chainhelper.h index 66bee994652f..925659b7ec07 100644 --- a/src/evo/chainhelper.h +++ b/src/evo/chainhelper.h @@ -10,6 +10,7 @@ class CCreditPoolManager; class CDeterministicMNManager; +class CEvoDB; class ChainstateManager; class CMNHFManager; class CMNPaymentsProcessor; @@ -39,7 +40,7 @@ class CChainstateHelper CChainstateHelper() = delete; CChainstateHelper(const CChainstateHelper&) = delete; CChainstateHelper& operator=(const CChainstateHelper&) = delete; - explicit CChainstateHelper(CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CMNHFManager& mnhfman, + explicit CChainstateHelper(CEvoDB& evodb, CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, CGovernanceManager& govman, llmq::CInstantSendManager& isman, llmq::CQuorumBlockProcessor& qblockman, llmq::CQuorumSnapshotManager& qsnapman, const ChainstateManager& chainman, const Consensus::Params& consensus_params, @@ -59,6 +60,7 @@ class CChainstateHelper bool ShouldInstantSendRejectConflicts() const; public: + const std::unique_ptr ehf_manager; const std::unique_ptr mn_payments; const std::unique_ptr special_tx; }; diff --git a/src/init.cpp b/src/init.cpp index 6e79ed5b0d21..e8b7d0166689 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -87,7 +87,6 @@ #include #include #include -#include #include #include #include @@ -401,9 +400,8 @@ void PrepareShutdown(NodeContext& node) chainstate->ResetCoinsViews(); } } - DashChainstateSetupClose(node.chain_helper, node.cpoolman, node.dmnman, node.mnhf_manager, node.llmq_ctx, + DashChainstateSetupClose(node.chain_helper, node.cpoolman, node.dmnman, node.llmq_ctx, Assert(node.mempool.get())); - node.mnhf_manager.reset(); node.evodb.reset(); } for (const auto& client : node.chain_clients) { @@ -2002,7 +2000,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) node.cpoolman, node.dmnman, node.evodb, - node.mnhf_manager, node.llmq_ctx, Assert(node.mempool.get()), args.GetDataDirNet(), @@ -2201,7 +2198,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } // Will init later in ThreadImport node.active_ctx = std::make_unique(*node.llmq_ctx->bls_worker, chainman, *node.connman, *node.dmnman, *node.govman, *node.mn_metaman, - *node.mnhf_manager, *node.sporkman, *node.mempool, *node.llmq_ctx->clhandler, *node.llmq_ctx->isman, + *node.sporkman, *node.mempool, *node.llmq_ctx->clhandler, *node.llmq_ctx->isman, *node.llmq_ctx->quorum_block_processor, *node.llmq_ctx->qman, *node.llmq_ctx->qsnapman, *node.llmq_ctx->sigman, *node.peerman, *node.mn_sync, operator_sk, sync_map, dash_db_params, quorums_recovery, quorums_watch); RegisterValidationInterface(node.active_ctx.get()); diff --git a/src/llmq/ehf_signals.cpp b/src/llmq/ehf_signals.cpp index 394f325c4297..5df646d1388a 100644 --- a/src/llmq/ehf_signals.cpp +++ b/src/llmq/ehf_signals.cpp @@ -7,20 +7,19 @@ #include #include #include -#include // g_txindex -#include -#include - #include +#include // g_txindex #include #include #include +#include +#include +#include namespace llmq { -CEHFSignalsHandler::CEHFSignalsHandler(ChainstateManager& chainman, CMNHFManager& mnhfman, CSigningManager& sigman, +CEHFSignalsHandler::CEHFSignalsHandler(ChainstateManager& chainman, CSigningManager& sigman, CSigSharesManager& shareman, const CQuorumManager& qman) : m_chainman(chainman), - mnhfman(mnhfman), sigman(sigman), shareman(shareman), qman(qman) @@ -37,7 +36,7 @@ void CEHFSignalsHandler::UpdatedBlockTip(const CBlockIndex* const pindexNew) { if (!DeploymentActiveAfter(pindexNew, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return; - const auto ehfSignals = mnhfman.GetSignalsStage(pindexNew); + const auto ehfSignals = m_chainman.GetSignalsStage(pindexNew); for (const auto& deployment : Params().GetConsensus().vDeployments) { // Skip deployments that do not use dip0023 if (!deployment.useEHF) continue; @@ -93,7 +92,7 @@ MessageProcessingResult CEHFSignalsHandler::HandleNewRecoveredSig(const CRecover } MessageProcessingResult ret; - const auto ehfSignals = mnhfman.GetSignalsStage(WITH_LOCK(::cs_main, return m_chainman.ActiveTip())); + const auto ehfSignals = m_chainman.GetSignalsStage(WITH_LOCK(::cs_main, return m_chainman.ActiveTip())); MNHFTxPayload mnhfPayload; for (const auto& deployment : Params().GetConsensus().vDeployments) { // skip deployments that do not use dip0023 or that have already been mined diff --git a/src/llmq/ehf_signals.h b/src/llmq/ehf_signals.h index cc9893061dca..cb3b32b16251 100644 --- a/src/llmq/ehf_signals.h +++ b/src/llmq/ehf_signals.h @@ -12,7 +12,6 @@ class CBlockIndex; class ChainstateManager; -class CMNHFManager; namespace llmq { class CQuorumManager; @@ -23,7 +22,6 @@ class CEHFSignalsHandler : public CRecoveredSigsListener { private: ChainstateManager& m_chainman; - CMNHFManager& mnhfman; CSigningManager& sigman; CSigSharesManager& shareman; const CQuorumManager& qman; @@ -34,8 +32,8 @@ class CEHFSignalsHandler : public CRecoveredSigsListener mutable Mutex cs; std::set ids GUARDED_BY(cs); public: - explicit CEHFSignalsHandler(ChainstateManager& chainman, CMNHFManager& mnhfman, CSigningManager& sigman, - CSigSharesManager& shareman, const CQuorumManager& qman); + explicit CEHFSignalsHandler(ChainstateManager& chainman, CSigningManager& sigman, CSigSharesManager& shareman, + const CQuorumManager& qman); ~CEHFSignalsHandler(); diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index e60eaace5630..ef2f07796700 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -44,7 +44,6 @@ std::optional LoadChainstate(bool fReset, std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& evodb, - std::unique_ptr& mnhf_manager, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, const fs::path& data_dir, @@ -74,9 +73,6 @@ std::optional LoadChainstate(bool fReset, evodb.reset(); evodb = std::make_unique(util::DbWrapperParams{.path = data_dir, .memory = dash_dbs_in_memory, .wipe = fReset || fReindexChainState}); - mnhf_manager.reset(); - mnhf_manager = std::make_unique(*evodb, chainman); - chainman.InitializeChainstate(mempool, *evodb, chain_helper); chainman.m_total_coinstip_cache = nCoinCacheUsage; chainman.m_total_coinsdb_cache = nCoinDBCache; @@ -88,7 +84,7 @@ std::optional LoadChainstate(bool fReset, pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, block_tree_db_in_memory, fReset)); DashChainstateSetup(chainman, govman, mn_metaman, mn_sync, sporkman, chain_helper, cpoolman, - dmnman, evodb, mnhf_manager, llmq_ctx, mempool, data_dir, dash_dbs_in_memory, + dmnman, evodb, llmq_ctx, mempool, data_dir, dash_dbs_in_memory, /*llmq_dbs_wipe=*/fReset || fReindexChainState, bls_threads, max_recsigs_age, consensus_params); if (fReset) { @@ -197,7 +193,7 @@ std::optional LoadChainstate(bool fReset, } } - if (!mnhf_manager->ForceSignalDBUpdate()) { + if (!chain_helper->ehf_manager->ForceSignalDBUpdate()) { return ChainstateLoadingError::ERROR_UPGRADING_SIGNALS_DB; } @@ -218,7 +214,6 @@ void DashChainstateSetup(ChainstateManager& chainman, std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& evodb, - std::unique_ptr& mnhf_manager, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, const fs::path& data_dir, @@ -243,27 +238,26 @@ void DashChainstateSetup(ChainstateManager& chainman, util::DbWrapperParams{.path = data_dir, .memory = llmq_dbs_in_memory, .wipe = llmq_dbs_wipe}, bls_threads, max_recsigs_age); mempool->ConnectManagers(dmnman.get(), llmq_ctx->isman.get()); - // Enable CMNHFManager::{Process, Undo}Block - mnhf_manager->ConnectManagers(llmq_ctx->qman.get()); - chain_helper.reset(); - chain_helper = std::make_unique(*cpoolman, *dmnman, *mnhf_manager, govman, *(llmq_ctx->isman), *(llmq_ctx->quorum_block_processor), + chain_helper = std::make_unique(*evodb, *cpoolman, *dmnman, govman, *(llmq_ctx->isman), *(llmq_ctx->quorum_block_processor), *(llmq_ctx->qsnapman), chainman, consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), *(llmq_ctx->qman)); + + // TODO: drop ConnectManagers completely from here + // qman should not be needed for Process/Undo block because validation & processing are 2 different stages + // Enable CMNHFManager::{Process, Undo}Block + chain_helper->ehf_manager->ConnectManagers(llmq_ctx->qman.get()); + } void DashChainstateSetupClose(std::unique_ptr& chain_helper, std::unique_ptr& cpoolman, std::unique_ptr& dmnman, - std::unique_ptr& mnhf_manager, std::unique_ptr& llmq_ctx, CTxMemPool* mempool) { chain_helper.reset(); - if (mnhf_manager) { - mnhf_manager->DisconnectManagers(); - } llmq_ctx.reset(); cpoolman.reset(); mempool->DisconnectManagers(); diff --git a/src/node/chainstate.h b/src/node/chainstate.h index 14a52c588762..ac6c65b6c68c 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -19,7 +19,6 @@ class CGovernanceManager; class ChainstateManager; class CMasternodeMetaMan; class CMasternodeSync; -class CMNHFManager; class CSporkManager; class CTxMemPool; struct LLMQContext; @@ -87,7 +86,6 @@ std::optional LoadChainstate(bool fReset, std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& evodb, - std::unique_ptr& mnhf_manager, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, const fs::path& data_dir, @@ -118,7 +116,6 @@ void DashChainstateSetup(ChainstateManager& chainman, std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& evodb, - std::unique_ptr& mnhf_manager, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, const fs::path& data_dir, @@ -131,7 +128,6 @@ void DashChainstateSetup(ChainstateManager& chainman, void DashChainstateSetupClose(std::unique_ptr& chain_helper, std::unique_ptr& cpoolman, std::unique_ptr& dmnman, - std::unique_ptr& mnhf_manager, std::unique_ptr& llmq_ctx, CTxMemPool* mempool); diff --git a/src/node/context.h b/src/node/context.h index f2d1bdbb9722..0246484fd68d 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -30,7 +30,6 @@ class CNetFulfilledRequestManager; class CScheduler; class CSporkManager; class CTxMemPool; -class CMNHFManager; class NetGroupManager; class PeerManager; struct ActiveContext; @@ -91,7 +90,6 @@ struct NodeContext { std::unique_ptr govman; std::unique_ptr mn_metaman; std::unique_ptr mn_sync; - std::unique_ptr mnhf_manager; std::unique_ptr netfulfilledman; std::unique_ptr sporkman; //! Dash contexts diff --git a/src/node/miner.cpp b/src/node/miner.cpp index a90b88ba3613..607207276ca2 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -29,8 +29,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -75,7 +75,6 @@ BlockAssembler::BlockAssembler(CChainState& chainstate, const NodeContext& node, m_chain_helper(chainstate.ChainHelper()), m_chainstate(chainstate), m_evoDb(*Assert(node.evodb)), - m_mnhfman(*Assert(node.mnhf_manager)), m_clhandler(*Assert(Assert(node.llmq_ctx)->clhandler)), m_isman(*Assert(Assert(node.llmq_ctx)->isman)), chainparams(params), @@ -473,7 +472,7 @@ void BlockAssembler::addPackageTxs(const CTxMemPool& mempool, int& nPackagesSele } // This map with signals is used only to find duplicates - std::unordered_map signals = m_mnhfman.GetSignalsStage(pindexPrev); + std::unordered_map signals = m_chain_helper.ehf_manager->GetSignalsStage(pindexPrev); // mapModifiedTx will store sorted packages after they are modified // because some of their txs are already in the block diff --git a/src/node/miner.h b/src/node/miner.h index eea4d69884bd..a6f289f2806f 100644 --- a/src/node/miner.h +++ b/src/node/miner.h @@ -25,7 +25,6 @@ class CChainstateHelper; class CConnman; class CCreditPoolManager; class CEvoDB; -class CMNHFManager; class CScript; struct LLMQContext; @@ -171,7 +170,6 @@ class BlockAssembler CChainstateHelper& m_chain_helper; CChainState& m_chainstate; CEvoDB& m_evoDb; - CMNHFManager& m_mnhfman; llmq::CChainLocksHandler& m_clhandler; llmq::CInstantSendManager& m_isman; const CChainParams& chainparams; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 203e20da3ba2..a6f15fd38f57 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1549,7 +1549,7 @@ RPCHelpMan getblockchaininfo() const CBlockIndex& tip{*CHECK_NONFATAL(active_chainstate.m_chain.Tip())}; const int height{tip.nHeight}; - const auto ehfSignals{CHECK_NONFATAL(node.mnhf_manager)->GetSignalsStage(&tip)}; + const auto ehfSignals{chainman.GetSignalsStage(&tip)}; UniValue obj(UniValue::VOBJ); if (args.IsArgSet("-devnet")) { diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 5c1aa4543124..cefd370f9424 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include @@ -144,14 +143,14 @@ void DashChainstateSetup(ChainstateManager& chainman, const Consensus::Params& consensus_params) { DashChainstateSetup(chainman, *Assert(node.govman.get()), *Assert(node.mn_metaman.get()), *Assert(node.mn_sync.get()), - *Assert(node.sporkman.get()), node.chain_helper, node.cpoolman, node.dmnman, node.evodb, node.mnhf_manager, + *Assert(node.sporkman.get()), node.chain_helper, node.cpoolman, node.dmnman, node.evodb, node.llmq_ctx, Assert(node.mempool.get()), node.args->GetDataDirNet(), llmq_dbs_in_memory, llmq_dbs_wipe, llmq::DEFAULT_BLSCHECK_THREADS, llmq::DEFAULT_MAX_RECOVERED_SIGS_AGE, consensus_params); } void DashChainstateSetupClose(NodeContext& node) { - DashChainstateSetupClose(node.chain_helper, node.cpoolman, node.dmnman, node.mnhf_manager, node.llmq_ctx, + DashChainstateSetupClose(node.chain_helper, node.cpoolman, node.dmnman, node.llmq_ctx, Assert(node.mempool.get())); } @@ -284,7 +283,6 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve m_node.chainman = std::make_unique(chainparams); m_node.chainman->m_blockman.m_block_tree_db = std::make_unique(m_cache_sizes.block_tree_db, true); - m_node.mnhf_manager = std::make_unique(*m_node.evodb, *m_node.chainman); m_node.mn_sync = std::make_unique(std::make_unique(*m_node.connman, *m_node.netfulfilledman)); m_node.govman = std::make_unique(*m_node.mn_metaman, *m_node.netfulfilledman, *m_node.chainman, m_node.dmnman, *m_node.mn_sync); @@ -302,7 +300,6 @@ ChainTestingSetup::~ChainTestingSetup() GetMainSignals().UnregisterBackgroundSignalScheduler(); m_node.govman.reset(); m_node.mn_sync.reset(); - m_node.mnhf_manager.reset(); m_node.chainman.reset(); m_node.mempool.reset(); m_node.fee_estimator.reset(); @@ -327,7 +324,6 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vectorGetDataDirNet(), diff --git a/src/validation.cpp b/src/validation.cpp index 95629b462cf1..46136a4cdfef 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -6066,6 +6067,11 @@ bool ChainstateManager::IsQuorumTypeEnabled(const Consensus::LLMQType llmqType, assert(false); } +std::unordered_map ChainstateManager::GetSignalsStage(const CBlockIndex* const pindexPrev) +{ + return m_active_chainstate->ChainHelper().ehf_manager->GetSignalsStage(pindexPrev); +} + void ChainstateManager::MaybeRebalanceCaches() { AssertLockHeld(::cs_main); diff --git a/src/validation.h b/src/validation.h index 9301ad4c78fd..a50d5add617e 100644 --- a/src/validation.h +++ b/src/validation.h @@ -1082,6 +1082,9 @@ class ChainstateManager std::optional optDIP0024IsActive = std::nullopt, std::optional optHaveDIP0024Quorums = std::nullopt) const; + // TODO: move it inside ActiveChainstate (active_chainsate is CChainState) + std::unordered_map GetSignalsStage(const CBlockIndex* const pindexPrev); + ~ChainstateManager(); }; From 7339760e243564feb524b037498b83c3c3a06982 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 14 Jan 2026 01:39:06 +0700 Subject: [PATCH 3/9] refactor: re-connect ehf manager to fix new circular dependencies --- src/evo/chainhelper.cpp | 4 ++++ src/evo/chainhelper.h | 4 ++++ src/llmq/ehf_signals.cpp | 6 ++++-- src/rpc/blockchain.cpp | 3 ++- src/validation.cpp | 6 ------ src/validation.h | 3 --- test/lint/lint-circular-dependencies.py | 2 +- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/evo/chainhelper.cpp b/src/evo/chainhelper.cpp index 866df1f9a3c3..ec7ef456e8f1 100644 --- a/src/evo/chainhelper.cpp +++ b/src/evo/chainhelper.cpp @@ -63,3 +63,7 @@ bool CChainstateHelper::RemoveConflictingISLockByTx(const CTransaction& tx) bool CChainstateHelper::ShouldInstantSendRejectConflicts() const { return isman.RejectConflictingBlocks(); } +std::unordered_map CChainstateHelper::GetSignalsStage(const CBlockIndex* const pindexPrev) +{ + return ehf_manager->GetSignalsStage(pindexPrev); +} diff --git a/src/evo/chainhelper.h b/src/evo/chainhelper.h index 925659b7ec07..538933ac3ca5 100644 --- a/src/evo/chainhelper.h +++ b/src/evo/chainhelper.h @@ -7,7 +7,9 @@ #include #include +#include +class CBlockIndex; class CCreditPoolManager; class CDeterministicMNManager; class CEvoDB; @@ -59,6 +61,8 @@ class CChainstateHelper bool RemoveConflictingISLockByTx(const CTransaction& tx); bool ShouldInstantSendRejectConflicts() const; + std::unordered_map GetSignalsStage(const CBlockIndex* const pindexPrev); + public: const std::unique_ptr ehf_manager; const std::unique_ptr mn_payments; diff --git a/src/llmq/ehf_signals.cpp b/src/llmq/ehf_signals.cpp index 5df646d1388a..726d615d46d7 100644 --- a/src/llmq/ehf_signals.cpp +++ b/src/llmq/ehf_signals.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include // g_txindex #include @@ -36,7 +37,7 @@ void CEHFSignalsHandler::UpdatedBlockTip(const CBlockIndex* const pindexNew) { if (!DeploymentActiveAfter(pindexNew, Params().GetConsensus(), Consensus::DEPLOYMENT_V20)) return; - const auto ehfSignals = m_chainman.GetSignalsStage(pindexNew); + const auto ehfSignals = m_chainman.ActiveChainstate().ChainHelper().ehf_manager->GetSignalsStage(pindexNew); for (const auto& deployment : Params().GetConsensus().vDeployments) { // Skip deployments that do not use dip0023 if (!deployment.useEHF) continue; @@ -92,7 +93,8 @@ MessageProcessingResult CEHFSignalsHandler::HandleNewRecoveredSig(const CRecover } MessageProcessingResult ret; - const auto ehfSignals = m_chainman.GetSignalsStage(WITH_LOCK(::cs_main, return m_chainman.ActiveTip())); + const auto ehfSignals = m_chainman.ActiveChainstate().ChainHelper().ehf_manager->GetSignalsStage( + WITH_LOCK(::cs_main, return m_chainman.ActiveTip())); MNHFTxPayload mnhfPayload; for (const auto& deployment : Params().GetConsensus().vDeployments) { // skip deployments that do not use dip0023 or that have already been mined diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index a6f15fd38f57..46a7a6c184b0 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -1549,7 +1550,7 @@ RPCHelpMan getblockchaininfo() const CBlockIndex& tip{*CHECK_NONFATAL(active_chainstate.m_chain.Tip())}; const int height{tip.nHeight}; - const auto ehfSignals{chainman.GetSignalsStage(&tip)}; + const auto ehfSignals{active_chainstate.ChainHelper().GetSignalsStage(&tip)}; UniValue obj(UniValue::VOBJ); if (args.IsArgSet("-devnet")) { diff --git a/src/validation.cpp b/src/validation.cpp index 46136a4cdfef..95629b462cf1 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -53,7 +53,6 @@ #include #include #include -#include #include #include #include @@ -6067,11 +6066,6 @@ bool ChainstateManager::IsQuorumTypeEnabled(const Consensus::LLMQType llmqType, assert(false); } -std::unordered_map ChainstateManager::GetSignalsStage(const CBlockIndex* const pindexPrev) -{ - return m_active_chainstate->ChainHelper().ehf_manager->GetSignalsStage(pindexPrev); -} - void ChainstateManager::MaybeRebalanceCaches() { AssertLockHeld(::cs_main); diff --git a/src/validation.h b/src/validation.h index a50d5add617e..9301ad4c78fd 100644 --- a/src/validation.h +++ b/src/validation.h @@ -1082,9 +1082,6 @@ class ChainstateManager std::optional optDIP0024IsActive = std::nullopt, std::optional optHaveDIP0024Quorums = std::nullopt) const; - // TODO: move it inside ActiveChainstate (active_chainsate is CChainState) - std::unordered_map GetSignalsStage(const CBlockIndex* const pindexPrev); - ~ChainstateManager(); }; diff --git a/test/lint/lint-circular-dependencies.py b/test/lint/lint-circular-dependencies.py index 53f961367958..afbee5f4bd2d 100755 --- a/test/lint/lint-circular-dependencies.py +++ b/test/lint/lint-circular-dependencies.py @@ -38,7 +38,7 @@ "consensus/tx_verify -> evo/assetlocktx -> llmq/commitment -> validation -> consensus/tx_verify", "consensus/tx_verify -> evo/assetlocktx -> llmq/commitment -> validation -> txmempool -> consensus/tx_verify", "evo/assetlocktx -> llmq/commitment -> validation -> txmempool -> evo/assetlocktx", - "evo/chainhelper -> evo/specialtxman -> validation -> evo/chainhelper", + "evo/chainhelper -> evo/mnhftx -> validation -> evo/chainhelper", "evo/deterministicmns -> validation -> evo/deterministicmns", "evo/deterministicmns -> validation -> txmempool -> evo/deterministicmns", "evo/netinfo -> evo/providertx -> evo/netinfo", From e0125250b4455e5ee6ea255e9edb7749c6ab4ff9 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 14 Jan 2026 01:59:22 +0700 Subject: [PATCH 4/9] refactor: drop atomic from evo/mnhftx --- src/evo/chainhelper.cpp | 2 +- src/evo/mnhftx.cpp | 25 +++++-------------------- src/evo/mnhftx.h | 26 ++------------------------ src/node/chainstate.cpp | 6 ------ 4 files changed, 8 insertions(+), 51 deletions(-) diff --git a/src/evo/chainhelper.cpp b/src/evo/chainhelper.cpp index ec7ef456e8f1..09eef1093824 100644 --- a/src/evo/chainhelper.cpp +++ b/src/evo/chainhelper.cpp @@ -21,7 +21,7 @@ CChainstateHelper::CChainstateHelper(CEvoDB& evodb, CCreditPoolManager& cpoolman const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman) : isman{isman}, clhandler{clhandler}, - ehf_manager{std::make_unique(evodb, chainman)}, + ehf_manager{std::make_unique(evodb, chainman, qman)}, mn_payments{std::make_unique(dmnman, govman, chainman, consensus_params, mn_sync, sporkman)}, special_tx{std::make_unique(cpoolman, dmnman, *ehf_manager, qblockman, qsnapman, chainman, consensus_params, clhandler, qman)} diff --git a/src/evo/mnhftx.cpp b/src/evo/mnhftx.cpp index 8f4fa535c4f1..9c9db691acae 100644 --- a/src/evo/mnhftx.cpp +++ b/src/evo/mnhftx.cpp @@ -43,9 +43,10 @@ CMutableTransaction MNHFTxPayload::PrepareTx() const return tx; } -CMNHFManager::CMNHFManager(CEvoDB& evoDb, const ChainstateManager& chainman) : +CMNHFManager::CMNHFManager(CEvoDB& evoDb, const ChainstateManager& chainman, const llmq::CQuorumManager& qman) : m_evoDb(evoDb), - m_chainman{chainman} + m_chainman{chainman}, + m_qman{qman} { assert(globalInstance == nullptr); globalInstance = this; @@ -202,11 +203,9 @@ static bool extractSignals(const ChainstateManager& chainman, const llmq::CQuoru std::optional CMNHFManager::ProcessBlock(const CBlock& block, const CBlockIndex* const pindex, bool fJustCheck, BlockValidationState& state) { - auto qman = Assert(m_qman.load(std::memory_order_acquire)); - try { std::vector new_signals; - if (!extractSignals(m_chainman, *qman, block, pindex, new_signals, state)) { + if (!extractSignals(m_chainman, m_qman, block, pindex, new_signals, state)) { // state is set inside extractSignals return std::nullopt; } @@ -253,11 +252,9 @@ std::optional CMNHFManager::ProcessBlock(const CBlock& bl bool CMNHFManager::UndoBlock(const CBlock& block, const CBlockIndex* const pindex) { - auto qman = Assert(m_qman.load(std::memory_order_acquire)); - std::vector excluded_signals; BlockValidationState state; - if (!extractSignals(m_chainman, *qman, block, pindex, excluded_signals, state)) { + if (!extractSignals(m_chainman, m_qman, block, pindex, excluded_signals, state)) { LogPrintf("CMNHFManager::%s: failed to extract signals\n", __func__); return false; } @@ -370,18 +367,6 @@ void CMNHFManager::AddSignal(const CBlockIndex* const pindex, int bit) AddToCache(signals, pindex); } -void CMNHFManager::ConnectManagers(gsl::not_null qman) -{ - // Do not allow double-initialization - assert(m_qman.load(std::memory_order_acquire) == nullptr); - m_qman.store(qman, std::memory_order_release); -} - -void CMNHFManager::DisconnectManagers() -{ - m_qman.store(nullptr, std::memory_order_release); -} - bool CMNHFManager::ForceSignalDBUpdate() { // force ehf signals db update diff --git a/src/evo/mnhftx.h b/src/evo/mnhftx.h index 2f399412c24c..9653a7823020 100644 --- a/src/evo/mnhftx.h +++ b/src/evo/mnhftx.h @@ -16,7 +16,6 @@ #include #include -#include #include class BlockValidationState; @@ -91,7 +90,7 @@ class CMNHFManager : public AbstractEHFManager private: CEvoDB& m_evoDb; const ChainstateManager& m_chainman; - std::atomic m_qman{nullptr}; + const llmq::CQuorumManager& m_qman; static constexpr size_t MNHFCacheSize = 1000; Mutex cs_cache; @@ -102,15 +101,12 @@ class CMNHFManager : public AbstractEHFManager CMNHFManager() = delete; CMNHFManager(const CMNHFManager&) = delete; CMNHFManager& operator=(const CMNHFManager&) = delete; - explicit CMNHFManager(CEvoDB& evoDb, const ChainstateManager& chainman); + explicit CMNHFManager(CEvoDB& evoDb, const ChainstateManager& chainman, const llmq::CQuorumManager& qman); ~CMNHFManager(); /** * Every new block should be processed when Tip() is updated by calling of CMNHFManager::ProcessBlock. * This function actually does only validate EHF transaction for this block and update internal caches/evodb state - * - * @pre Caller must ensure that LLMQContext has been initialized and the llmq::CQuorumManager pointer has been - * set by calling ConnectManagers() for this CMNHFManager instance */ std::optional ProcessBlock(const CBlock& block, const CBlockIndex* const pindex, bool fJustCheck, BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(!cs_cache); @@ -119,9 +115,6 @@ class CMNHFManager : public AbstractEHFManager * Every undo block should be processed when Tip() is updated by calling of CMNHFManager::UndoBlock * This function actually does nothing at the moment, because status of ancestor block is already known. * Although it should be still called to do some sanity checks - * - * @pre Caller must ensure that LLMQContext has been initialized and the llmq::CQuorumManager pointer has been - * set by calling ConnectManagers() for this CMNHFManager instance */ bool UndoBlock(const CBlock& block, const CBlockIndex* const pindex) EXCLUSIVE_LOCKS_REQUIRED(!cs_cache); @@ -133,21 +126,6 @@ class CMNHFManager : public AbstractEHFManager */ void AddSignal(const CBlockIndex* const pindex, int bit) EXCLUSIVE_LOCKS_REQUIRED(!cs_cache); - /** - * Set llmq::CQuorumManager pointer. - * - * Separated from constructor to allow LLMQContext to use CMNHFManager in read-only capacity. - * Required to mutate state. - */ - void ConnectManagers(gsl::not_null qman); - - /** - * Reset llmq::CQuorumManager pointer. - * - * @pre Must be called before LLMQContext (containing llmq::CQuorumManager) is destroyed. - */ - void DisconnectManagers(); - bool ForceSignalDBUpdate() EXCLUSIVE_LOCKS_REQUIRED(::cs_main, !cs_cache); private: diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index ef2f07796700..a772135d13a1 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -242,12 +242,6 @@ void DashChainstateSetup(ChainstateManager& chainman, chain_helper = std::make_unique(*evodb, *cpoolman, *dmnman, govman, *(llmq_ctx->isman), *(llmq_ctx->quorum_block_processor), *(llmq_ctx->qsnapman), chainman, consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), *(llmq_ctx->qman)); - - // TODO: drop ConnectManagers completely from here - // qman should not be needed for Process/Undo block because validation & processing are 2 different stages - // Enable CMNHFManager::{Process, Undo}Block - chain_helper->ehf_manager->ConnectManagers(llmq_ctx->qman.get()); - } void DashChainstateSetupClose(std::unique_ptr& chain_helper, From 0370287676587bc66a15055a8f7bb526bad4ced2 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 14 Jan 2026 02:30:56 +0700 Subject: [PATCH 5/9] refactor: move CCreditPool inside chain-state helper --- src/evo/chainhelper.cpp | 18 ++++++++++-------- src/evo/chainhelper.h | 13 +++++++------ src/init.cpp | 3 +-- src/node/chainstate.cpp | 12 ++---------- src/node/chainstate.h | 4 ---- src/node/context.h | 2 -- src/node/miner.cpp | 5 ++--- src/node/miner.h | 2 -- src/rpc/rawtransaction.cpp | 9 +++++---- src/test/util/setup_common.cpp | 6 ++---- test/lint/lint-circular-dependencies.py | 2 +- 11 files changed, 30 insertions(+), 46 deletions(-) diff --git a/src/evo/chainhelper.cpp b/src/evo/chainhelper.cpp index 09eef1093824..4a2ac546e8b7 100644 --- a/src/evo/chainhelper.cpp +++ b/src/evo/chainhelper.cpp @@ -7,24 +7,26 @@ #include #include +#include #include #include #include #include #include -CChainstateHelper::CChainstateHelper(CEvoDB& evodb, CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, - CGovernanceManager& govman, llmq::CInstantSendManager& isman, - llmq::CQuorumBlockProcessor& qblockman, llmq::CQuorumSnapshotManager& qsnapman, - const ChainstateManager& chainman, const Consensus::Params& consensus_params, - const CMasternodeSync& mn_sync, const CSporkManager& sporkman, - const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman) : +CChainstateHelper::CChainstateHelper(CEvoDB& evodb, CDeterministicMNManager& dmnman, CGovernanceManager& govman, + llmq::CInstantSendManager& isman, llmq::CQuorumBlockProcessor& qblockman, + llmq::CQuorumSnapshotManager& qsnapman, const ChainstateManager& chainman, + const Consensus::Params& consensus_params, const CMasternodeSync& mn_sync, + const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler, + const llmq::CQuorumManager& qman) : isman{isman}, clhandler{clhandler}, ehf_manager{std::make_unique(evodb, chainman, qman)}, + credit_pool_manager{std::make_unique(evodb, chainman)}, mn_payments{std::make_unique(dmnman, govman, chainman, consensus_params, mn_sync, sporkman)}, - special_tx{std::make_unique(cpoolman, dmnman, *ehf_manager, qblockman, qsnapman, chainman, - consensus_params, clhandler, qman)} + special_tx{std::make_unique(*credit_pool_manager, dmnman, *ehf_manager, qblockman, qsnapman, + chainman, consensus_params, clhandler, qman)} {} CChainstateHelper::~CChainstateHelper() = default; diff --git a/src/evo/chainhelper.h b/src/evo/chainhelper.h index 538933ac3ca5..45dfcedc96d2 100644 --- a/src/evo/chainhelper.h +++ b/src/evo/chainhelper.h @@ -42,12 +42,12 @@ class CChainstateHelper CChainstateHelper() = delete; CChainstateHelper(const CChainstateHelper&) = delete; CChainstateHelper& operator=(const CChainstateHelper&) = delete; - explicit CChainstateHelper(CEvoDB& evodb, CCreditPoolManager& cpoolman, CDeterministicMNManager& dmnman, - CGovernanceManager& govman, llmq::CInstantSendManager& isman, - llmq::CQuorumBlockProcessor& qblockman, llmq::CQuorumSnapshotManager& qsnapman, - const ChainstateManager& chainman, const Consensus::Params& consensus_params, - const CMasternodeSync& mn_sync, const CSporkManager& sporkman, - const llmq::CChainLocksHandler& clhandler, const llmq::CQuorumManager& qman); + explicit CChainstateHelper(CEvoDB& evodb, CDeterministicMNManager& dmnman, CGovernanceManager& govman, + llmq::CInstantSendManager& isman, llmq::CQuorumBlockProcessor& qblockman, + llmq::CQuorumSnapshotManager& qsnapman, const ChainstateManager& chainman, + const Consensus::Params& consensus_params, const CMasternodeSync& mn_sync, + const CSporkManager& sporkman, const llmq::CChainLocksHandler& clhandler, + const llmq::CQuorumManager& qman); ~CChainstateHelper(); /** Passthrough functions to CChainLocksHandler */ @@ -65,6 +65,7 @@ class CChainstateHelper public: const std::unique_ptr ehf_manager; + const std::unique_ptr credit_pool_manager; const std::unique_ptr mn_payments; const std::unique_ptr special_tx; }; diff --git a/src/init.cpp b/src/init.cpp index e8b7d0166689..7a2ca65192d7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -400,7 +400,7 @@ void PrepareShutdown(NodeContext& node) chainstate->ResetCoinsViews(); } } - DashChainstateSetupClose(node.chain_helper, node.cpoolman, node.dmnman, node.llmq_ctx, + DashChainstateSetupClose(node.chain_helper, node.dmnman, node.llmq_ctx, Assert(node.mempool.get())); node.evodb.reset(); } @@ -1997,7 +1997,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) *node.mn_sync, *node.sporkman, node.chain_helper, - node.cpoolman, node.dmnman, node.evodb, node.llmq_ctx, diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index a772135d13a1..831ac63f708a 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -41,7 +40,6 @@ std::optional LoadChainstate(bool fReset, CMasternodeSync& mn_sync, CSporkManager& sporkman, std::unique_ptr& chain_helper, - std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& llmq_ctx, @@ -83,7 +81,7 @@ std::optional LoadChainstate(bool fReset, pblocktree.reset(); pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, block_tree_db_in_memory, fReset)); - DashChainstateSetup(chainman, govman, mn_metaman, mn_sync, sporkman, chain_helper, cpoolman, + DashChainstateSetup(chainman, govman, mn_metaman, mn_sync, sporkman, chain_helper, dmnman, evodb, llmq_ctx, mempool, data_dir, dash_dbs_in_memory, /*llmq_dbs_wipe=*/fReset || fReindexChainState, bls_threads, max_recsigs_age, consensus_params); @@ -211,7 +209,6 @@ void DashChainstateSetup(ChainstateManager& chainman, CMasternodeSync& mn_sync, CSporkManager& sporkman, std::unique_ptr& chain_helper, - std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& llmq_ctx, @@ -227,9 +224,6 @@ void DashChainstateSetup(ChainstateManager& chainman, dmnman.reset(); dmnman = std::make_unique(*evodb, mn_metaman); - cpoolman.reset(); - cpoolman = std::make_unique(*evodb, chainman); - if (llmq_ctx) { llmq_ctx->Stop(); } @@ -239,13 +233,12 @@ void DashChainstateSetup(ChainstateManager& chainman, bls_threads, max_recsigs_age); mempool->ConnectManagers(dmnman.get(), llmq_ctx->isman.get()); chain_helper.reset(); - chain_helper = std::make_unique(*evodb, *cpoolman, *dmnman, govman, *(llmq_ctx->isman), *(llmq_ctx->quorum_block_processor), + chain_helper = std::make_unique(*evodb, *dmnman, govman, *(llmq_ctx->isman), *(llmq_ctx->quorum_block_processor), *(llmq_ctx->qsnapman), chainman, consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), *(llmq_ctx->qman)); } void DashChainstateSetupClose(std::unique_ptr& chain_helper, - std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& llmq_ctx, CTxMemPool* mempool) @@ -253,7 +246,6 @@ void DashChainstateSetupClose(std::unique_ptr& chain_helper, { chain_helper.reset(); llmq_ctx.reset(); - cpoolman.reset(); mempool->DisconnectManagers(); dmnman.reset(); } diff --git a/src/node/chainstate.h b/src/node/chainstate.h index ac6c65b6c68c..39e976cd4947 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -12,7 +12,6 @@ #include class CChainstateHelper; -class CCreditPoolManager; class CDeterministicMNManager; class CEvoDB; class CGovernanceManager; @@ -83,7 +82,6 @@ std::optional LoadChainstate(bool fReset, CMasternodeSync& mn_sync, CSporkManager& sporkman, std::unique_ptr& chain_helper, - std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& llmq_ctx, @@ -113,7 +111,6 @@ void DashChainstateSetup(ChainstateManager& chainman, CMasternodeSync& mn_sync, CSporkManager& sporkman, std::unique_ptr& chain_helper, - std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& evodb, std::unique_ptr& llmq_ctx, @@ -126,7 +123,6 @@ void DashChainstateSetup(ChainstateManager& chainman, const Consensus::Params& consensus_params); void DashChainstateSetupClose(std::unique_ptr& chain_helper, - std::unique_ptr& cpoolman, std::unique_ptr& dmnman, std::unique_ptr& llmq_ctx, CTxMemPool* mempool); diff --git a/src/node/context.h b/src/node/context.h index 0246484fd68d..80e6aa2a3b3e 100644 --- a/src/node/context.h +++ b/src/node/context.h @@ -16,7 +16,6 @@ class CActiveMasternodeManager; class AddrMan; class CBlockPolicyEstimator; class CConnman; -class CCreditPoolManager; class CDeterministicMNManager; class CDSTXManager; class CChainstateHelper; @@ -81,7 +80,6 @@ struct NodeContext { std::unique_ptr scheduler; std::function rpc_interruption_point = [] {}; //! Dash managers - std::unique_ptr cpoolman; std::unique_ptr cj_walletman; std::unique_ptr dstxman; std::unique_ptr evodb; diff --git a/src/node/miner.cpp b/src/node/miner.cpp index 607207276ca2..ecab8b97c481 100644 --- a/src/node/miner.cpp +++ b/src/node/miner.cpp @@ -71,7 +71,6 @@ BlockAssembler::Options::Options() BlockAssembler::BlockAssembler(CChainState& chainstate, const NodeContext& node, const CTxMemPool* mempool, const CChainParams& params, const Options& options) : m_blockman(chainstate.m_blockman), - m_cpoolman(*Assert(node.cpoolman)), m_chain_helper(chainstate.ChainHelper()), m_chainstate(chainstate), m_evoDb(*Assert(node.evodb)), @@ -305,7 +304,7 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc LogPrintf("CreateNewBlock() h[%d] CbTx failed to find best CL. Inserting null CL\n", nHeight); } BlockValidationState state; - const auto creditPoolDiff = GetCreditPoolDiffForBlock(m_cpoolman, m_blockman, m_qman, *pblock, pindexPrev, chainparams.GetConsensus(), blockSubsidy, state); + const auto creditPoolDiff = GetCreditPoolDiffForBlock(*m_chain_helper.credit_pool_manager, m_blockman, m_qman, *pblock, pindexPrev, chainparams.GetConsensus(), blockSubsidy, state); if (creditPoolDiff == std::nullopt) { throw std::runtime_error(strprintf("%s: GetCreditPoolDiffForBlock failed: %s", __func__, state.ToString())); } @@ -467,7 +466,7 @@ void BlockAssembler::addPackageTxs(const CTxMemPool& mempool, int& nPackagesSele // duplicates of indexes. There's used `BlockSubsidy` equaled to 0 std::optional creditPoolDiff; if (DeploymentActiveAfter(pindexPrev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_V20)) { - CCreditPool creditPool = m_cpoolman.GetCreditPool(pindexPrev); + CCreditPool creditPool = m_chain_helper.credit_pool_manager->GetCreditPool(pindexPrev); creditPoolDiff.emplace(std::move(creditPool), pindexPrev, chainparams.GetConsensus(), 0); } diff --git a/src/node/miner.h b/src/node/miner.h index a6f289f2806f..221a9c5de29d 100644 --- a/src/node/miner.h +++ b/src/node/miner.h @@ -23,7 +23,6 @@ class CBlockIndex; class CChainParams; class CChainstateHelper; class CConnman; -class CCreditPoolManager; class CEvoDB; class CScript; struct LLMQContext; @@ -166,7 +165,6 @@ class BlockAssembler int64_t m_lock_time_cutoff; BlockManager& m_blockman; - CCreditPoolManager& m_cpoolman; CChainstateHelper& m_chain_helper; CChainState& m_chainstate; CEvoDB& m_evoDb; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 5db203c01832..a1d984ae2cd4 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -637,7 +638,7 @@ static RPCHelpMan getassetunlockstatuses() const CTxMemPool& mempool = EnsureMemPool(node); const LLMQContext& llmq_ctx = EnsureLLMQContext(node); const ChainstateManager& chainman = EnsureChainman(node); - + CCreditPoolManager& cpoolman = *chainman.ActiveChainstate().ChainHelper().credit_pool_manager; UniValue result_arr(UniValue::VARR); const UniValue str_indexes = request.params[0].get_array(); if (str_indexes.size() > 100) { @@ -663,7 +664,7 @@ static RPCHelpMan getassetunlockstatuses() if (nSpecificCoreHeight.value() < 0 || nSpecificCoreHeight.value() > chainman.ActiveChain().Height()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Block height out of range"); } - poolCL = std::make_optional(CHECK_NONFATAL(node.cpoolman)->GetCreditPool(chainman.ActiveChain()[nSpecificCoreHeight.value()])); + poolCL = std::make_optional(cpoolman.GetCreditPool(chainman.ActiveChain()[nSpecificCoreHeight.value()])); } else { const auto pBlockIndexBestCL = [&]() -> const CBlockIndex* { @@ -682,12 +683,12 @@ static RPCHelpMan getassetunlockstatuses() // We need in 2 credit pools: at tip of chain and on best CL to know if tx is mined or chainlocked // Sometimes that's two different blocks, sometimes not and we need to initialize 2nd creditPoolManager poolCL = pBlockIndexBestCL ? - std::make_optional(node.cpoolman->GetCreditPool(pBlockIndexBestCL)) : + std::make_optional(cpoolman.GetCreditPool(pBlockIndexBestCL)) : std::nullopt; poolOnTip = [&]() -> std::optional { if (pTipBlockIndex != pBlockIndexBestCL) { - return std::make_optional(node.cpoolman->GetCreditPool(pTipBlockIndex)); + return std::make_optional(cpoolman.GetCreditPool(pTipBlockIndex)); } return std::nullopt; }(); diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index cefd370f9424..27386413face 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include @@ -143,14 +142,14 @@ void DashChainstateSetup(ChainstateManager& chainman, const Consensus::Params& consensus_params) { DashChainstateSetup(chainman, *Assert(node.govman.get()), *Assert(node.mn_metaman.get()), *Assert(node.mn_sync.get()), - *Assert(node.sporkman.get()), node.chain_helper, node.cpoolman, node.dmnman, node.evodb, + *Assert(node.sporkman.get()), node.chain_helper, node.dmnman, node.evodb, node.llmq_ctx, Assert(node.mempool.get()), node.args->GetDataDirNet(), llmq_dbs_in_memory, llmq_dbs_wipe, llmq::DEFAULT_BLSCHECK_THREADS, llmq::DEFAULT_MAX_RECOVERED_SIGS_AGE, consensus_params); } void DashChainstateSetupClose(NodeContext& node) { - DashChainstateSetupClose(node.chain_helper, node.cpoolman, node.dmnman, node.llmq_ctx, + DashChainstateSetupClose(node.chain_helper, node.dmnman, node.llmq_ctx, Assert(node.mempool.get())); } @@ -321,7 +320,6 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector evo/assetlocktx -> llmq/commitment -> validation -> consensus/tx_verify", "consensus/tx_verify -> evo/assetlocktx -> llmq/commitment -> validation -> txmempool -> consensus/tx_verify", "evo/assetlocktx -> llmq/commitment -> validation -> txmempool -> evo/assetlocktx", - "evo/chainhelper -> evo/mnhftx -> validation -> evo/chainhelper", + "evo/chainhelper -> evo/creditpool -> validation -> evo/chainhelper", "evo/deterministicmns -> validation -> evo/deterministicmns", "evo/deterministicmns -> validation -> txmempool -> evo/deterministicmns", "evo/netinfo -> evo/providertx -> evo/netinfo", From d8fab4788cdb01cea70a1e6b585ae4ac71a440c6 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 14 Jan 2026 15:15:07 +0700 Subject: [PATCH 6/9] chore: add TODO to drop circular dependency of mnhftx and validation.h --- src/evo/mnhftx.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/evo/mnhftx.h b/src/evo/mnhftx.h index 9653a7823020..db4541d0cc2c 100644 --- a/src/evo/mnhftx.h +++ b/src/evo/mnhftx.h @@ -89,6 +89,11 @@ class CMNHFManager : public AbstractEHFManager { private: CEvoDB& m_evoDb; + // TODO: move its functionallity of ProcessBlock, UndoBlock to specialtxman; + // it will help to drop dependency on m_chainman, m_qman here (and validation.h) + // Secondly, store in database active EHF signals not for each block; + // but quite opposite: keep only hash of block where signal is added. + // TODO: implement migration to a new format const ChainstateManager& m_chainman; const llmq::CQuorumManager& m_qman; From e5aec25ae88a86b4aa84406ccc7abc0533ac8aa0 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 14 Jan 2026 15:20:46 +0700 Subject: [PATCH 7/9] refactor: unwrap CEvoDB from unique_ptr when calling DashChainstateSetup --- src/node/chainstate.cpp | 10 +++++----- src/node/chainstate.h | 2 +- src/test/util/setup_common.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index 831ac63f708a..69abeee2833a 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -82,7 +82,7 @@ std::optional LoadChainstate(bool fReset, pblocktree.reset(new CBlockTreeDB(nBlockTreeDBCache, block_tree_db_in_memory, fReset)); DashChainstateSetup(chainman, govman, mn_metaman, mn_sync, sporkman, chain_helper, - dmnman, evodb, llmq_ctx, mempool, data_dir, dash_dbs_in_memory, + dmnman, *evodb, llmq_ctx, mempool, data_dir, dash_dbs_in_memory, /*llmq_dbs_wipe=*/fReset || fReindexChainState, bls_threads, max_recsigs_age, consensus_params); if (fReset) { @@ -210,7 +210,7 @@ void DashChainstateSetup(ChainstateManager& chainman, CSporkManager& sporkman, std::unique_ptr& chain_helper, std::unique_ptr& dmnman, - std::unique_ptr& evodb, + CEvoDB& evodb, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, const fs::path& data_dir, @@ -222,18 +222,18 @@ void DashChainstateSetup(ChainstateManager& chainman, { // Same logic as pblocktree dmnman.reset(); - dmnman = std::make_unique(*evodb, mn_metaman); + dmnman = std::make_unique(evodb, mn_metaman); if (llmq_ctx) { llmq_ctx->Stop(); } llmq_ctx.reset(); - llmq_ctx = std::make_unique(*dmnman, *evodb, sporkman, *mempool, chainman, mn_sync, + llmq_ctx = std::make_unique(*dmnman, evodb, sporkman, *mempool, chainman, mn_sync, util::DbWrapperParams{.path = data_dir, .memory = llmq_dbs_in_memory, .wipe = llmq_dbs_wipe}, bls_threads, max_recsigs_age); mempool->ConnectManagers(dmnman.get(), llmq_ctx->isman.get()); chain_helper.reset(); - chain_helper = std::make_unique(*evodb, *dmnman, govman, *(llmq_ctx->isman), *(llmq_ctx->quorum_block_processor), + chain_helper = std::make_unique(evodb, *dmnman, govman, *(llmq_ctx->isman), *(llmq_ctx->quorum_block_processor), *(llmq_ctx->qsnapman), chainman, consensus_params, mn_sync, sporkman, *(llmq_ctx->clhandler), *(llmq_ctx->qman)); } diff --git a/src/node/chainstate.h b/src/node/chainstate.h index 39e976cd4947..bd88ab863286 100644 --- a/src/node/chainstate.h +++ b/src/node/chainstate.h @@ -112,7 +112,7 @@ void DashChainstateSetup(ChainstateManager& chainman, CSporkManager& sporkman, std::unique_ptr& chain_helper, std::unique_ptr& dmnman, - std::unique_ptr& evodb, + CEvoDB& evodb, std::unique_ptr& llmq_ctx, CTxMemPool* mempool, const fs::path& data_dir, diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 27386413face..6ccf69f310b1 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -142,7 +142,7 @@ void DashChainstateSetup(ChainstateManager& chainman, const Consensus::Params& consensus_params) { DashChainstateSetup(chainman, *Assert(node.govman.get()), *Assert(node.mn_metaman.get()), *Assert(node.mn_sync.get()), - *Assert(node.sporkman.get()), node.chain_helper, node.dmnman, node.evodb, + *Assert(node.sporkman.get()), node.chain_helper, node.dmnman, *node.evodb, node.llmq_ctx, Assert(node.mempool.get()), node.args->GetDataDirNet(), llmq_dbs_in_memory, llmq_dbs_wipe, llmq::DEFAULT_BLSCHECK_THREADS, llmq::DEFAULT_MAX_RECOVERED_SIGS_AGE, consensus_params); } From 3e8831a832e8da90b4e294387f7b082beacaf444 Mon Sep 17 00:00:00 2001 From: Konstantin Akimov Date: Wed, 14 Jan 2026 15:40:38 +0700 Subject: [PATCH 8/9] refactor: code move only; validation of protx transactions are moved from detemrinisticmns to specialtxman --- src/evo/deterministicmns.cpp | 468 ----------------------- src/evo/deterministicmns.h | 14 - src/evo/specialtxman.cpp | 484 +++++++++++++++++++++++- src/evo/specialtxman.h | 12 + src/test/evo_deterministicmns_tests.cpp | 1 + test/lint/lint-circular-dependencies.py | 4 +- 6 files changed, 491 insertions(+), 492 deletions(-) diff --git a/src/evo/deterministicmns.cpp b/src/evo/deterministicmns.cpp index aa97f67de072..ac89530dc6ee 100644 --- a/src/evo/deterministicmns.cpp +++ b/src/evo/deterministicmns.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -24,7 +23,6 @@ #include #include