Skip to content

Conversation

@knst
Copy link
Collaborator

@knst knst commented Jan 14, 2026

Issue being fixed or feature implemented

LoadChainState is aware of EHF Manager and Credit Pool Manager that are constructed outside, but have no meaning without Chain State; and its ownership and life time is controlled by Chain State too.

What was done?

  • EHF Manager (CMNHFManager), Credit Pool Manager (CCreditPoolManager
  • Removed CMNHFManager::ConnectManagers
  • validation of protx transaction is moved from evo/deterministicmns.h to evo/specialtxman.h to break new circular dependencies
  • removed atomic from m_qman in CMNHFManager

TODO: this PR includes some extra refactorings with code move from deterministicmns.h, that's a preparation for move dmnman (CDeterministicMNManager) inside Chain State too. Though, there's too many usages of NodeContext::dmnman all over code base, and many of its usages are not aware about Chain State at the moment; it will requires significant refactoring all over code base and out-of-scope of this PR; will be done in the further PRs with some extra efforts. Also, LLMQContext depends on dmnman; chainhelper depends on llmq-context; dmnman can't be easily moved inside chainhelper without moving llmq-ctx inside, which is out-of-scope of this PR.

$ grep -r node.dmnman src/ -I | wc -l
80

How Has This Been Tested?

Run unit and functional tests, run lint-circular-dependencies.py

Breaking Changes

N/A

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation
  • I have assigned this pull request to a milestone

@knst knst added this to the 23.1 milestone Jan 14, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

Walkthrough

This PR refactors the dependency management and initialization of masternode-related managers in the Dash codebase. The primary changes involve removing CMNHFManager and CCreditPoolManager as standalone components from NodeContext and moving them to be owned members of CChainstateHelper via unique_ptr. Additionally, CEHFSignalsHandler no longer takes CMNHFManager directly but accesses it through ChainstateManager. ProTx validation logic is relocated from deterministicmns to specialtxman. All call sites throughout the codebase are updated to access these managers through the chain helper instead of directly. This centralizes manager lifecycle management within the chainstate helper and simplifies the dependency graph at the node/initialization level.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • UdjinM6
  • PastaPastaPasta
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.51% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The PR description clearly describes the purpose of moving EHF Manager and Credit Pool Manager ownership into ChainState, removing ConnectManagers, moving protx validation, and removing atomic usage.
Title check ✅ Passed The PR title clearly summarizes the main refactoring objective: moving ownership of mnhfman and cpoolman into CChainstateHelper, which is the core change throughout the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/node/miner.cpp (2)

295-313: Avoid potential null-deref on m_chain_helper.credit_pool_manager in V20 coinbase path.
If credit_pool_manager is ever optional (e.g., certain test setups / partial init), *m_chain_helper.credit_pool_manager will crash. Consider making the invariant explicit before deref.

Proposed fix
                 if (CalcCbTxBestChainlock(m_clhandler, pindexPrev, cbTx.bestCLHeightDiff, cbTx.bestCLSignature)) {
                     LogPrintf("CreateNewBlock() h[%d] CbTx bestCLHeightDiff[%d] CLSig[%s]\n", nHeight, cbTx.bestCLHeightDiff, cbTx.bestCLSignature.ToString());
                 } else {
                     // not an error
                     LogPrintf("CreateNewBlock() h[%d] CbTx failed to find best CL. Inserting null CL\n", nHeight);
                 }
                 BlockValidationState state;
+                CHECK_NONFATAL(m_chain_helper.credit_pool_manager);
                 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()));
                 }

461-475: Document cs_main locking requirement with AssertLockHeld(::cs_main), but remove redundant null checks.

The concern about hidden locking assumptions is valid—addPackageTxs() calls manager methods (credit_pool_manager->GetCreditPool() and ehf_manager->GetSignalsStage()) but only documents mempool.cs as required. Currently invoked under cs_main from CreateNewBlock(), but a future refactor could accidentally drop this lock.

However, the managers are initialized as const std::unique_ptr fields in CChainstateHelper and cannot be null, making CHECK_NONFATAL redundant. Add only:

 void BlockAssembler::addPackageTxs(const CTxMemPool& mempool, int& nPackagesSelected, int& nDescendantsUpdated, const CBlockIndex* const pindexPrev)
 {
     AssertLockHeld(mempool.cs);
+    AssertLockHeld(::cs_main);

This documents the implicit assumption without false null-safety checks.

🤖 Fix all issues with AI agents
In `@src/evo/specialtxman.cpp`:
- Around line 761-785: CheckService currently asserts on
NetInfoStatus::BadInput, ::Duplicate and ::MaxLimit leaving no return in
non-debug builds; change those assert branches to return
state.Invalid(TxValidationResult::TX_BAD_SPECIAL, "<appropriate-error>") with
distinct error strings (e.g. "bad-protx-netinfo-badinput",
"bad-protx-netinfo-duplicate", "bad-protx-netinfo-maxlimit") so every
NetInfoStatus path returns a deterministic validation failure; ensure the final
assert(false) is removed and all enum cases map to a return to avoid undefined
behavior for peer-supplied data in the CheckService template.

In `@test/lint/lint-circular-dependencies.py`:
- Around line 38-46: The EXPECTED_CIRCULAR_DEPENDENCIES allowlist contains six
stale evo/* entries that the lint tool reports as no longer present; remove the
following strings from the list: "evo/chainhelper -> evo/creditpool ->
validation -> evo/chainhelper", "evo/deterministicmns -> evo/providertx ->
validation -> evo/deterministicmns", "evo/deterministicmns -> evo/providertx ->
validation -> txmempool -> evo/deterministicmns", "evo/netinfo -> evo/providertx
-> evo/netinfo", "evo/netinfo -> evo/providertx -> validation -> txmempool ->
evo/netinfo", and "evo/providertx -> validation -> txmempool -> evo/providertx"
from the EXPECTED_CIRCULAR_DEPENDENCIES array so the allowlist matches the lint
output.
🧹 Nitpick comments (3)
src/evo/specialtxman.cpp (1)

857-912: Minor: tighten semantics around gsl::not_null + fix misleading comment.

  • GetValidatedPayload(..., gsl::not_null<const CBlockIndex*> ...) implies non-null, but some later code paths still treat pindexPrev as optional (e.g., if (pindexPrev) in callers). Consider removing the redundant null-check branches to reduce confusion.
  • In IsVersionChangeValid(), the ExtAddr comment mentions ProRegTx, but this helper is only used by update txs here; consider adjusting the comment to reflect actual call sites.
src/test/util/setup_common.cpp (1)

144-147: Use Assert(node.evodb.get()) before dereferencing.

This wrapper dereferences *node.evodb without the usual Assert(...) guard used for other NodeContext members. If any test harness constructs NodeContext without evodb, this becomes a crash.

Proposed fix
-    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,
+    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, *Assert(node.evodb.get()),
                         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);
src/evo/specialtxman.h (1)

93-104: New CheckPro*Tx declarations are OK; consider scoping to reduce global namespace pollution.

These declarations match the implementations and help decouple deterministicmns from validation plumbing. If feasible later, consider scoping them (e.g., a dedicated namespace or making them static/member utilities) to keep the header’s global surface smaller.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7482956 and 71abb3c.

📒 Files selected for processing (24)
  • src/active/context.cpp
  • src/active/context.h
  • src/evo/chainhelper.cpp
  • src/evo/chainhelper.h
  • src/evo/deterministicmns.cpp
  • src/evo/deterministicmns.h
  • src/evo/mnhftx.cpp
  • src/evo/mnhftx.h
  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
  • src/init.cpp
  • src/llmq/context.h
  • src/llmq/ehf_signals.cpp
  • src/llmq/ehf_signals.h
  • src/node/chainstate.cpp
  • src/node/chainstate.h
  • src/node/context.h
  • src/node/miner.cpp
  • src/node/miner.h
  • src/rpc/blockchain.cpp
  • src/rpc/rawtransaction.cpp
  • src/test/evo_deterministicmns_tests.cpp
  • src/test/util/setup_common.cpp
  • test/lint/lint-circular-dependencies.py
💤 Files with no reviewable changes (5)
  • src/node/miner.h
  • src/node/context.h
  • src/llmq/context.h
  • src/evo/deterministicmns.cpp
  • src/evo/deterministicmns.h
🧰 Additional context used
📓 Path-based instructions (10)
src/**/*.{cpp,h,hpp,cc}

📄 CodeRabbit inference engine (CLAUDE.md)

Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1

Files:

  • src/test/evo_deterministicmns_tests.cpp
  • src/node/miner.cpp
  • src/llmq/ehf_signals.h
  • src/active/context.h
  • src/rpc/blockchain.cpp
  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
  • src/evo/chainhelper.cpp
  • src/evo/chainhelper.h
  • src/llmq/ehf_signals.cpp
  • src/test/util/setup_common.cpp
  • src/init.cpp
  • src/rpc/rawtransaction.cpp
  • src/evo/mnhftx.cpp
  • src/node/chainstate.cpp
  • src/evo/mnhftx.h
  • src/node/chainstate.h
  • src/active/context.cpp
src/{test,wallet/test}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Unit tests in src/test/ and src/wallet/test/ must use Boost::Test framework

Files:

  • src/test/evo_deterministicmns_tests.cpp
  • src/test/util/setup_common.cpp
src/node/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

NodeContext must be extended with Dash-specific managers for each subsystem during initialization

Files:

  • src/node/miner.cpp
  • src/node/chainstate.cpp
  • src/node/chainstate.h
src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data

Files:

  • src/llmq/ehf_signals.h
  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
  • src/evo/chainhelper.cpp
  • src/evo/chainhelper.h
  • src/llmq/ehf_signals.cpp
  • src/evo/mnhftx.cpp
  • src/evo/mnhftx.h
src/{masternode,llmq}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

BLS integration must be used for cryptographic foundation of advanced masternode features

Files:

  • src/llmq/ehf_signals.h
  • src/llmq/ehf_signals.cpp
src/llmq/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

src/llmq/**/*.{cpp,h}: LLMQ quorums must support multiple configurations (50/60, 400/60, 400/85) for different services (ChainLocks, InstantSend, governance voting)
InstantSend implementation must provide distributed key generation for secure transaction locking with quorum consensus
ChainLocks implementation must prevent reorganizations and provide block finality through 51% attack prevention

Files:

  • src/llmq/ehf_signals.h
  • src/llmq/ehf_signals.cpp
src/{masternode,llmq,evo,coinjoin,governance}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Use unordered_lru_cache for efficient caching with LRU eviction in Dash-specific data structures

Files:

  • src/llmq/ehf_signals.h
  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
  • src/evo/chainhelper.cpp
  • src/evo/chainhelper.h
  • src/llmq/ehf_signals.cpp
  • src/evo/mnhftx.cpp
  • src/evo/mnhftx.h
src/{masternode,evo}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Masternode lists must use immutable data structures (Immer library) for thread safety

Files:

  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
  • src/evo/chainhelper.cpp
  • src/evo/chainhelper.h
  • src/evo/mnhftx.cpp
  • src/evo/mnhftx.h
src/evo/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Special transactions use payload serialization routines defined in src/evo/specialtx.h and must include appropriate special transaction types (ProRegTx, ProUpServTx, ProUpRegTx, ProUpRevTx)

Files:

  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
  • src/evo/chainhelper.cpp
  • src/evo/chainhelper.h
  • src/evo/mnhftx.cpp
  • src/evo/mnhftx.h
src/node/chainstate.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Chainstate initialization must be separated into dedicated src/node/chainstate.* files

Files:

  • src/node/chainstate.cpp
  • src/node/chainstate.h
🧠 Learnings (36)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request `#6543` is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:247-250
Timestamp: 2025-07-29T14:32:48.369Z
Learning: In PR `#6761`, kwvg acknowledged a null pointer check issue in ChainLockSigner::Cleanup() method but deferred it to follow-up, consistent with the pattern of avoiding scope creep in refactoring PRs.
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (`#6718`), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/node/chainstate.{cpp,h} : Chainstate initialization must be separated into dedicated src/node/chainstate.* files
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/node/**/*.{cpp,h} : NodeContext must be extended with Dash-specific managers for each subsystem during initialization
Learnt from: kwvg
Repo: dashpay/dash PR: 6838
File: src/active/context.cpp:29-33
Timestamp: 2025-10-03T11:20:37.475Z
Learning: In Dash codebase, NodeContext (src/node/context.h) serves only as a container with trivial c/d-tors; member lifetime is explicitly managed via reset() calls in the shutdown sequence (src/init.cpp), not by declaration order. For example, active_ctx.reset() is called before DashChainstateSetupClose handles llmq_ctx teardown, ensuring proper destruction order regardless of declaration order in the struct.
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq,evo,coinjoin,governance}/**/*.{cpp,h} : Use unordered_lru_cache for efficient caching with LRU eviction in Dash-specific data structures
Learnt from: knst
Repo: dashpay/dash PR: 7008
File: src/masternode/sync.h:17-18
Timestamp: 2025-11-25T10:53:37.523Z
Learning: The file src/masternode/sync.h containing `CMasternodeSync` is misnamed and misplaced—it has nothing to do with "masternode" functionality. It should eventually be renamed to `NodeSyncing` or `NodeSyncStatus` and moved to src/node/sync.h as a future refactoring.
Learnt from: knst
Repo: dashpay/dash PR: 7008
File: src/masternode/sync.h:17-18
Timestamp: 2025-11-25T10:53:37.523Z
Learning: In Dash Core, `DEFAULT_SYNC_MEMPOOL` belongs with node synchronization logic (currently in src/masternode/sync.h) rather than with validation logic in src/validation.h, even though other mempool-related constants are in validation.h. The constant is conceptually tied to sync functionality, not validation.
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6933
File: src/llmq/utils.cpp:284-298
Timestamp: 2025-11-04T18:24:27.241Z
Learning: In consensus-critical code (such as quorum formation, block validation, or deployment activation logic), do not suggest changes to the logic itself even if the implementation appears theoretically incorrect or off-by-one. Consensus rules, once deployed on the Dash network, must be preserved exactly to avoid network forks. Refactoring PRs should maintain perfect behavioral equivalence. Only suggest logic changes if explicitly accompanied by a DIP (Dash Improvement Proposal) or if the maintainer indicates the consensus rule needs to be changed with appropriate activation logic.
📚 Learning: 2025-01-07T18:50:44.838Z
Learnt from: knst
Repo: dashpay/dash PR: 6511
File: src/evo/deterministicmns.cpp:1369-1373
Timestamp: 2025-01-07T18:50:44.838Z
Learning: The functions `MigrateDBIfNeeded` and `MigrateDBIfNeeded2` in `src/evo/deterministicmns.cpp` are temporary and will be removed in a future version. Refactoring suggestions for these functions should be avoided.

Applied to files:

  • src/test/evo_deterministicmns_tests.cpp
  • src/test/util/setup_common.cpp
  • src/init.cpp
📚 Learning: 2025-11-13T20:02:55.480Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6969
File: src/evo/deterministicmns.h:441-479
Timestamp: 2025-11-13T20:02:55.480Z
Learning: In `src/evo/deterministicmns.h`, the `internalId` field in `CDeterministicMN` and the `mnInternalIdMap` in `CDeterministicMNList` are non-deterministic and used only for internal bookkeeping and efficient lookups. Different nodes can assign different internalIds to the same masternode depending on their sync history. Methods like `IsEqual()` intentionally ignore internalId mappings and only compare consensus-critical deterministic fields (proTxHash, collateral, state, etc.).

Applied to files:

  • src/test/evo_deterministicmns_tests.cpp
  • src/node/miner.cpp
  • src/evo/chainhelper.h
  • src/init.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/evo/**/*.{cpp,h} : Special transactions use payload serialization routines defined in src/evo/specialtx.h and must include appropriate special transaction types (ProRegTx, ProUpServTx, ProUpRegTx, ProUpRevTx)

Applied to files:

  • src/test/evo_deterministicmns_tests.cpp
  • src/node/miner.cpp
  • src/rpc/blockchain.cpp
  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
  • src/test/util/setup_common.cpp
  • src/init.cpp
  • src/rpc/rawtransaction.cpp
  • src/node/chainstate.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/evo/evodb/**/*.{cpp,h} : Evolution Database (CEvoDb) must handle masternode snapshots, quorum state, governance objects with efficient differential updates for masternode lists

Applied to files:

  • src/test/evo_deterministicmns_tests.cpp
  • src/node/miner.cpp
  • src/rpc/blockchain.cpp
  • src/evo/chainhelper.cpp
  • src/evo/chainhelper.h
  • src/test/util/setup_common.cpp
  • src/init.cpp
  • src/rpc/rawtransaction.cpp
  • src/evo/mnhftx.cpp
  • src/node/chainstate.cpp
  • src/evo/mnhftx.h
  • src/node/chainstate.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,txmempool}/**/*.{cpp,h} : Block validation and mempool handling must use extensions to Bitcoin Core mechanisms for special transaction validation and enhanced transaction relay

Applied to files:

  • src/test/evo_deterministicmns_tests.cpp
  • src/node/miner.cpp
  • src/rpc/blockchain.cpp
  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
  • src/evo/chainhelper.h
  • src/test/util/setup_common.cpp
  • src/init.cpp
  • src/rpc/rawtransaction.cpp
  • src/node/chainstate.cpp
  • src/evo/mnhftx.h
  • src/node/chainstate.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : InstantSend implementation must provide distributed key generation for secure transaction locking with quorum consensus

Applied to files:

  • src/test/evo_deterministicmns_tests.cpp
  • src/llmq/ehf_signals.h
  • src/evo/specialtxman.cpp
  • src/llmq/ehf_signals.cpp
  • src/evo/mnhftx.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features

Applied to files:

  • src/test/evo_deterministicmns_tests.cpp
  • src/node/miner.cpp
  • src/llmq/ehf_signals.h
  • src/rpc/blockchain.cpp
  • src/evo/specialtxman.cpp
  • src/test/util/setup_common.cpp
  • src/init.cpp
  • src/rpc/rawtransaction.cpp
  • src/node/chainstate.cpp
  • src/node/chainstate.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/node/chainstate.{cpp,h} : Chainstate initialization must be separated into dedicated src/node/chainstate.* files

Applied to files:

  • src/node/miner.cpp
  • src/rpc/blockchain.cpp
  • src/evo/specialtxman.cpp
  • src/evo/chainhelper.cpp
  • src/evo/chainhelper.h
  • src/test/util/setup_common.cpp
  • src/init.cpp
  • src/rpc/rawtransaction.cpp
  • src/node/chainstate.cpp
  • src/node/chainstate.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/coinjoin/**/*.{cpp,h} : CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Applied to files:

  • src/node/miner.cpp
  • src/test/util/setup_common.cpp
  • src/node/chainstate.cpp
  • src/node/chainstate.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data

Applied to files:

  • src/node/miner.cpp
  • src/rpc/blockchain.cpp
  • src/evo/chainhelper.cpp
  • src/evo/chainhelper.h
  • src/test/util/setup_common.cpp
  • src/init.cpp
  • src/rpc/rawtransaction.cpp
  • src/node/chainstate.cpp
  • src/node/chainstate.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,consensus,net_processing}/**/*.{cpp,h} : ValidationInterface callbacks must be used for event-driven architecture to coordinate subsystems during block/transaction processing

Applied to files:

  • src/node/miner.cpp
  • src/rpc/blockchain.cpp
  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
  • src/llmq/ehf_signals.cpp
  • test/lint/lint-circular-dependencies.py
📚 Learning: 2025-11-04T18:23:28.175Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6933
File: src/governance/classes.cpp:147-154
Timestamp: 2025-11-04T18:23:28.175Z
Learning: In src/governance/classes.cpp, CSuperblock::GetPaymentsLimit intentionally uses synthetic difficulty constants (nBits = 1 for mainnet, powLimit for networks with min difficulty) and simple height-based V20 activation checks instead of actual chain block data. This is by design because superblocks themselves are "synthetic" governance payment blocks, not regular mined blocks.

Applied to files:

  • src/node/miner.cpp
  • src/rpc/rawtransaction.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : LLMQ quorums must support multiple configurations (50/60, 400/60, 400/85) for different services (ChainLocks, InstantSend, governance voting)

Applied to files:

  • src/llmq/ehf_signals.h
  • src/llmq/ehf_signals.cpp
  • src/evo/mnhftx.cpp
  • src/evo/mnhftx.h
  • src/node/chainstate.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : ChainLocks implementation must prevent reorganizations and provide block finality through 51% attack prevention

Applied to files:

  • src/llmq/ehf_signals.h
  • src/evo/specialtxman.cpp
  • src/llmq/ehf_signals.cpp
  • src/rpc/rawtransaction.cpp
  • src/evo/mnhftx.h
  • src/node/chainstate.h
📚 Learning: 2024-12-29T17:43:41.755Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6504
File: src/llmq/quorums.cpp:224-224
Timestamp: 2024-12-29T17:43:41.755Z
Learning: The `CQuorumManager` is fully initialized by `LLMQContext`, addressing any concerns about the manager’s initialization sequence.

Applied to files:

  • src/llmq/ehf_signals.h
  • src/evo/mnhftx.cpp
  • src/evo/mnhftx.h
📚 Learning: 2025-10-02T18:29:54.756Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6840
File: src/net_processing.cpp:2882-2886
Timestamp: 2025-10-02T18:29:54.756Z
Learning: Across net_processing.cpp, once LLMQContext (m_llmq_ctx) is asserted non-null, its subcomponents (e.g., isman, qdkgsman, quorum_block_processor) are treated as initialized and used without extra null checks.

Applied to files:

  • src/llmq/ehf_signals.h
  • src/active/context.h
  • src/test/util/setup_common.cpp
  • src/init.cpp
  • src/evo/mnhftx.cpp
  • src/evo/mnhftx.h
  • src/active/context.cpp
📚 Learning: 2025-01-02T21:50:00.967Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6504
File: src/llmq/context.cpp:42-43
Timestamp: 2025-01-02T21:50:00.967Z
Learning: LLMQContext manages concurrency for the `CInstantSendManager`. Previously, this was handled globally; now it's handled as a class member in `LLMQContext`, but the concurrency control remains consistent.

Applied to files:

  • src/llmq/ehf_signals.h
  • src/evo/mnhftx.h
📚 Learning: 2025-12-22T15:42:48.595Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In C++/Qt codebases, use fail-fast asserts in setters to enforce invariants (e.g., ensuring internal maps contain necessary keys). Prefer assert() for programmer errors that should be caught in development and debugging, rather than defensive runtime checks with fallbacks. This helps catch invariant violations early during development. Apply to header and source files where invariant-driven state mutations occur, especially in setters like SetWeightBold/SetWeightNormal that assume established relationships or preconditions.

Applied to files:

  • src/llmq/ehf_signals.h
  • src/active/context.h
  • src/evo/specialtxman.h
  • src/evo/chainhelper.h
  • src/evo/mnhftx.h
  • src/node/chainstate.h
📚 Learning: 2025-10-02T18:29:54.756Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6840
File: src/net_processing.cpp:2882-2886
Timestamp: 2025-10-02T18:29:54.756Z
Learning: In src/net_processing.cpp, if ActiveContext (m_active_ctx) is non-null, its members (including cj_server) are guaranteed to be initialized; call sites can safely dereference m_active_ctx->cj_server without an additional null-check.

Applied to files:

  • src/active/context.h
  • src/active/context.cpp
📚 Learning: 2025-10-03T11:20:37.475Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6838
File: src/active/context.cpp:29-33
Timestamp: 2025-10-03T11:20:37.475Z
Learning: In Dash codebase, NodeContext (src/node/context.h) serves only as a container with trivial c/d-tors; member lifetime is explicitly managed via reset() calls in the shutdown sequence (src/init.cpp), not by declaration order. For example, active_ctx.reset() is called before DashChainstateSetupClose handles llmq_ctx teardown, ensuring proper destruction order regardless of declaration order in the struct.

Applied to files:

  • src/active/context.h
  • src/test/util/setup_common.cpp
  • src/init.cpp
  • src/node/chainstate.cpp
  • src/node/chainstate.h
  • src/active/context.cpp
📚 Learning: 2025-12-02T12:59:28.247Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 7026
File: src/rpc/evo.cpp:1713-1799
Timestamp: 2025-12-02T12:59:28.247Z
Learning: In the Dash codebase, CChain::operator[] has built-in safe bounds checking. Accessing chainman.ActiveChain()[height] is safe even if height exceeds the current chain height, as the operator will handle bounds checking internally. There is no need to manually check chain height before using the [] operator on CChain.

Applied to files:

  • src/rpc/blockchain.cpp
  • src/rpc/rawtransaction.cpp
📚 Learning: 2025-06-06T11:53:09.094Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6665
File: src/evo/providertx.h:82-82
Timestamp: 2025-06-06T11:53:09.094Z
Learning: In ProTx serialization code (SERIALIZE_METHODS), version checks should use hardcoded maximum flags (/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true) rather than deployment-based flags. This is because serialization code should be able to deserialize any structurally valid ProTx up to the maximum version the code knows how to handle, regardless of current consensus validity. Validation code, not serialization code, is responsible for checking whether a ProTx version is consensus-valid based on deployment status.

Applied to files:

  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
📚 Learning: 2025-07-09T15:02:26.899Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6729
File: src/evo/deterministicmns.cpp:1313-1316
Timestamp: 2025-07-09T15:02:26.899Z
Learning: In Dash's masternode transaction validation, `IsVersionChangeValid()` is only called by transaction types that update existing masternode entries (like `ProUpServTx`, `ProUpRegTx`, `ProUpRevTx`), not by `ProRegTx` which creates new entries. This means validation logic in `IsVersionChangeValid()` only applies to the subset of transaction types that actually call it, not all masternode transaction types.

Applied to files:

  • src/evo/specialtxman.cpp
  • src/evo/specialtxman.h
📚 Learning: 2025-06-16T17:59:55.669Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6665
File: src/evo/deterministicmns.cpp:1284-1287
Timestamp: 2025-06-16T17:59:55.669Z
Learning: In Dash masternode ProRegTx validation, platform ports (platformHTTPPort and platformP2PPort) are mandatory and must be non-zero, while netInfo (ipAndPort) is optional. This means that even if an empty netInfo returns 0 from GetPrimary().GetPort(), it won't cause false positives in port duplication checks since platform ports cannot be 0.

Applied to files:

  • src/evo/specialtxman.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq,evo,coinjoin,governance}/**/*.{cpp,h} : Use unordered_lru_cache for efficient caching with LRU eviction in Dash-specific data structures

Applied to files:

  • src/evo/chainhelper.h
  • src/test/util/setup_common.cpp
  • src/init.cpp
  • src/node/chainstate.cpp
  • src/node/chainstate.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo}/**/*.{cpp,h} : Masternode lists must use immutable data structures (Immer library) for thread safety

Applied to files:

  • src/evo/chainhelper.h
  • src/init.cpp
  • src/node/chainstate.h
📚 Learning: 2025-06-09T16:43:20.996Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (`#6718`), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.

Applied to files:

  • src/test/util/setup_common.cpp
📚 Learning: 2025-10-28T18:36:40.263Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6923
File: src/test/util/setup_common.cpp:235-251
Timestamp: 2025-10-28T18:36:40.263Z
Learning: In `src/test/util/setup_common.cpp`, the `CEvoDB` instance in `BasicTestingSetup` is constructed with `.memory = true` flag (memory-only mode), so it does not create file handles on disk. This makes the destructor teardown order safe even if `fs::remove_all(m_path_root)` is called before `m_node.evodb.reset()`.

Applied to files:

  • src/test/util/setup_common.cpp
  • src/node/chainstate.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{test,wallet/test}/**/*.{cpp,h} : Unit tests in src/test/ and src/wallet/test/ must use Boost::Test framework

Applied to files:

  • src/test/util/setup_common.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite

Applied to files:

  • src/test/util/setup_common.cpp
  • src/init.cpp
  • src/node/chainstate.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/node/**/*.{cpp,h} : NodeContext must be extended with Dash-specific managers for each subsystem during initialization

Applied to files:

  • src/test/util/setup_common.cpp
  • src/init.cpp
📚 Learning: 2025-08-08T07:01:47.332Z
Learnt from: knst
Repo: dashpay/dash PR: 6805
File: src/wallet/rpc/wallet.cpp:357-357
Timestamp: 2025-08-08T07:01:47.332Z
Learning: In src/wallet/rpc/wallet.cpp, the upgradetohd RPC now returns a UniValue string message (RPCResult::Type::STR) instead of a boolean, including guidance about mnemonic backup and null-character passphrase handling; functional tests have been updated to assert returned strings in several cases.

Applied to files:

  • src/rpc/rawtransaction.cpp
📚 Learning: 2025-05-05T12:45:44.781Z
Learnt from: knst
Repo: dashpay/dash PR: 6658
File: src/evo/creditpool.cpp:177-185
Timestamp: 2025-05-05T12:45:44.781Z
Learning: The GetAncestor() function in CBlockIndex safely handles negative heights by returning nullptr rather than asserting, making it safe to call with potentially negative values.

Applied to files:

  • src/rpc/rawtransaction.cpp
📚 Learning: 2025-08-19T14:57:31.801Z
Learnt from: knst
Repo: dashpay/dash PR: 6692
File: src/llmq/blockprocessor.cpp:217-224
Timestamp: 2025-08-19T14:57:31.801Z
Learning: In PR `#6692`, knst acknowledged a null pointer dereference issue in ProcessBlock() method where LookupBlockIndex may return nullptr but is passed to gsl::not_null, and created follow-up PR `#6789` to address it, consistent with avoiding scope creep in performance-focused PRs.

Applied to files:

  • src/evo/mnhftx.cpp
📚 Learning: 2025-11-25T10:53:37.523Z
Learnt from: knst
Repo: dashpay/dash PR: 7008
File: src/masternode/sync.h:17-18
Timestamp: 2025-11-25T10:53:37.523Z
Learning: The file src/masternode/sync.h containing `CMasternodeSync` is misnamed and misplaced—it has nothing to do with "masternode" functionality. It should eventually be renamed to `NodeSyncing` or `NodeSyncStatus` and moved to src/node/sync.h as a future refactoring.

Applied to files:

  • src/node/chainstate.h
🧬 Code graph analysis (10)
src/node/miner.cpp (2)
src/evo/creditpool.cpp (3)
  • creditPoolDiff (332-332)
  • GetCreditPoolDiffForBlock (325-349)
  • GetCreditPoolDiffForBlock (325-327)
src/evo/creditpool.h (1)
  • pindexPrev (81-109)
src/llmq/ehf_signals.h (1)
src/llmq/ehf_signals.cpp (2)
  • CEHFSignalsHandler (21-29)
  • CEHFSignalsHandler (31-34)
src/evo/specialtxman.cpp (3)
src/evo/netinfo.cpp (2)
  • IsNodeOnMainnet (71-71)
  • IsNodeOnMainnet (71-71)
src/deploymentstatus.h (3)
  • DeploymentActiveAfter (14-18)
  • DeploymentActiveAfter (20-24)
  • DeploymentDIP0003Enforced (53-56)
src/chainparams.cpp (2)
  • Params (1345-1348)
  • Params (1345-1345)
src/evo/specialtxman.h (1)
src/evo/specialtxman.cpp (8)
  • CheckProRegTx (914-1048)
  • CheckProRegTx (914-916)
  • CheckProUpServTx (1050-1127)
  • CheckProUpServTx (1050-1051)
  • CheckProUpRegTx (1129-1201)
  • CheckProUpRegTx (1129-1131)
  • CheckProUpRevTx (1203-1233)
  • CheckProUpRevTx (1203-1204)
src/evo/chainhelper.cpp (2)
src/evo/chainhelper.h (1)
  • CChainstateHelper (35-71)
src/evo/mnhftx.cpp (2)
  • GetSignalsStage (61-92)
  • GetSignalsStage (61-61)
src/evo/chainhelper.h (3)
src/evo/creditpool.cpp (2)
  • CCreditPoolManager (241-245)
  • CCreditPoolManager (247-247)
src/evo/chainhelper.cpp (4)
  • CChainstateHelper (17-30)
  • CChainstateHelper (32-32)
  • GetSignalsStage (68-71)
  • GetSignalsStage (68-68)
src/evo/mnhftx.cpp (4)
  • GetSignalsStage (61-92)
  • GetSignalsStage (61-61)
  • CMNHFManager (46-53)
  • CMNHFManager (55-59)
src/llmq/ehf_signals.cpp (1)
src/llmq/ehf_signals.h (1)
  • CEHFSignalsHandler (21-50)
src/test/util/setup_common.cpp (1)
src/node/chainstate.cpp (2)
  • DashChainstateSetupClose (241-251)
  • DashChainstateSetupClose (241-244)
src/node/chainstate.cpp (1)
src/test/util/setup_common.cpp (2)
  • DashChainstateSetup (138-148)
  • DashChainstateSetup (138-142)
src/evo/mnhftx.h (1)
src/evo/mnhftx.cpp (2)
  • CMNHFManager (46-53)
  • CMNHFManager (55-59)
🪛 Cppcheck (2.19.0)
src/evo/specialtxman.cpp

[error] 22-22: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)


[error] 24-24: #error No known always_inline attribute for this platform.

(preprocessorErrorDirective)

src/evo/chainhelper.cpp

[error] 22-22: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)

src/llmq/ehf_signals.cpp

[error] 10-10: failed to evaluate #if condition, undefined function-like macro invocation

(syntaxError)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: win64-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: Lint / Run linters
🔇 Additional comments (32)
src/test/evo_deterministicmns_tests.cpp (1)

10-16: Looks good: test now includes the new ProTx validation home header.
This aligns with the ProTx validation move to evo/specialtxman.* and helps keep the unit tests compiling against the refactor.

src/node/miner.cpp (1)

28-35: Include move looks fine.

src/active/context.h (1)

64-71: Constructor signature is consistent across header, definition, and call site—no issues found.

Header declaration (lines 64–71), definition in src/active/context.cpp (lines 26–33), and the construction site in src/init.cpp (lines 2199–2202) all match exactly. All 21 parameters are passed in the correct order, and the removal of CMNHFManager is properly reflected everywhere (only a forward declaration remains, no orphaned member references).

src/rpc/blockchain.cpp (1)

19-20: No actionable issues. The GetSignalsStage() call is safe and performant:

  • Lock-safe: Annotated with EXCLUSIVE_LOCKS_REQUIRED(!cs_cache), ensuring proper lock design. Calling under cs_main does not conflict with the lock contract.
  • Performance: Implementation is lightweight (block traversal and consensus checks via GetForBlock() and GetAncestor() calls), with no file I/O or expensive operations.
src/evo/specialtxman.cpp (3)

7-29: New includes look reasonable; watch for avoidable coupling.

No issues spotted with the added headers in this file; they appear required for the moved validation code.


787-827: Confirm MainParams() usage is intended for non-mainnet validation.

CheckPlatformFields() uses MainParams() for some “port must not equal core port” checks even when not on mainnet. That may be intentional, but it’s easy to accidentally bake in mainnet defaults for test/dev networks.

Suggested verification:

  • confirm which networks these rules are consensus-enforced on (mainnet-only vs all nets)
  • confirm NetInfoInterface::GetPrimary().GetPort() behavior when netInfo is empty and how that interacts with these checks

914-1233: Per-type ProTx validation entry points look cleanly separated.

The CheckPro*Tx() split + shared helpers is a good direction for breaking circular deps and centralizing validation entry points. Once CheckService() is hardened (above), the rest of these flows look consistent with the existing structure (payload parse → trivial validity → semantic checks → inputsHash → sig).

src/init.cpp (2)

403-405: Verify shutdown ordering inside DashChainstateSetupClose() vs CTxMemPool::DisconnectManagers().

Given DashChainstateSetupClose() now resets llmq_ctx internally (per snippet), please confirm mempool->DisconnectManagers() doesn’t touch llmq-owned objects after llmq_ctx.reset(). If it does, reorder to disconnect before resetting llmq.


2199-2202: ActiveContext construction update looks consistent with the refactor intent.

Call-site update aligns with removing direct mnhf_manager plumbing from init.

src/test/util/setup_common.cpp (1)

152-154: Wrapper update looks fine; keep the teardown invariants explicit.

Given tests often mutate init/teardown sequences, keeping this wrapper minimal is good.

src/evo/mnhftx.h (1)

92-99: Fix typo in TODO comment on line 92: "functionallity" → "functionality"

This is a simple spelling error in the TODO block.

Likely an incorrect or invalid review comment.

src/evo/chainhelper.cpp (3)

10-11: LGTM: Required includes added for manager ownership.

The includes for creditpool.h and mnhftx.h are necessary since CChainstateHelper now owns and constructs these manager instances directly.


17-30: LGTM: Constructor correctly initializes owned managers.

The constructor properly:

  1. Accepts CEvoDB& evodb to construct the managers internally
  2. Initializes ehf_manager and credit_pool_manager via std::make_unique before special_tx which depends on them
  3. Passes dereferenced managers to CSpecialTxProcessor

The initializer list order matches the member declaration order in the header, which is correct C++ practice.


68-71: Remove this suggestion—the method cannot be const.

The GetSignalsStage methods in both CMNHFManager and CChainstateHelper are intentionally non-const. The abstract base class in versionbits.h explicitly documents: "This member function is not const because it calls non-const GetFromCache()." The implementation calls GetForBlock(), which requires access to non-const cache operations. Making these methods const would violate the virtual interface contract and break the implementation.

Likely an incorrect or invalid review comment.

src/evo/chainhelper.h (3)

10-15: LGTM: Forward declarations and includes properly added.

The additions support the new public API:

  • <unordered_map> for GetSignalsStage return type
  • CBlockIndex forward declaration for the method parameter
  • CEvoDB forward declaration for the constructor parameter

45-50: LGTM: Constructor signature simplified by internalizing manager dependencies.

The constructor now takes CEvoDB& evodb and constructs ehf_manager/credit_pool_manager internally, reducing the external dependency surface. This aligns with the PR objective of moving ownership into CChainstateHelper.


64-68: Public const unique_ptr members expose managers appropriately.

The const qualifier on the unique_ptr members prevents reassignment while still allowing read access and method calls on the managed objects. This is a reasonable pattern for exposing owned resources.

Minor: Consider whether GetSignalsStage should be const (see related comment in chainhelper.cpp).

src/active/context.cpp (1)

26-43: LGTM: CMNHFManager dependency removed from ActiveContext.

The constructor signature and CEHFSignalsHandler initialization correctly remove the mnhfman parameter. This aligns with the refactor moving EHF manager access through the chain helper pathway. The CEHFSignalsHandler will now obtain EHF signals via ChainstateManager rather than a direct reference.

src/node/chainstate.cpp (4)

84-86: LGTM: LoadChainstate correctly passes evodb to setup.

The call to DashChainstateSetup now passes *evodb (dereferenced) instead of separate manager pointers. This reflects the API change where managers are now constructed internally by CChainstateHelper.


194-196: LGTM: Signal DB update accessed through chain helper.

ForceSignalDBUpdate is now correctly accessed via chain_helper->ehf_manager, reflecting the new ownership model where CMNHFManager is owned by CChainstateHelper.


206-238: LGTM: DashChainstateSetup signature and implementation simplified.

The function now:

  1. Takes CEvoDB& by reference (appropriate since caller owns the evodb lifetime)
  2. Constructs dmnman, llmq_ctx, and chain_helper using the evodb reference
  3. No longer manages cpoolman or mnhf_manager separately since they're owned by chain_helper

The initialization order (dmnmanllmq_ctxchain_helper) is correct since chain_helper depends on components from llmq_ctx.


241-251: Destruction order is correct and safe.

The current order (chain_helper → llmq_ctx → mempool → dmnman) correctly handles the dependency: chain_helper holds raw references to llmq_ctx-owned components (isman and clhandler), so destroying chain_helper first ensures it no longer accesses these references before their owners are destroyed. The ehf_manager and credit_pool_manager owned by chain_helper are not accessed by llmq_ctx.

src/node/chainstate.h (2)

14-23: LGTM: Forward declarations cleaned up.

The removed forward declarations for CCreditPoolManager and CMNHFManager correctly reflect that these types are no longer part of the public API signatures. They're now internal to CChainstateHelper.


108-128: LGTM: API signatures simplified.

The header changes correctly reflect:

  1. DashChainstateSetup now takes CEvoDB& by reference instead of unique_ptr
  2. DashChainstateSetupClose no longer requires cpoolman or mnhf_manager parameters

This API simplification aligns with the PR objective of internalizing manager ownership within CChainstateHelper. As per coding guidelines, chainstate initialization is properly separated in these dedicated files.

src/rpc/rawtransaction.cpp (1)

49-56: Include looks fine; just watch dependency creep.
Adding <evo/chainhelper.h> is consistent with the refactor, but it does broaden RPC compile-time dependencies. Given this PR already updated lint-circular-dependencies.py, this is probably intended.

src/llmq/ehf_signals.h (1)

34-37: Ctor signature simplification is consistent with the new ownership model.
This aligns the handler with chainstate-owned EHF manager access and reduces plumbing through callers.

src/evo/mnhftx.cpp (3)

204-212: ProcessBlock wiring to m_qman looks correct.
This keeps the verification path explicit and avoids pointer/atomic indirection.


253-260: UndoBlock wiring to m_qman looks correct.
Same comment as ProcessBlock—cleaner and easier to reason about.


46-53: Good refactor. Storing const llmq::CQuorumManager& as a member eliminates the need for connect/disconnect handlers. The lifetime guarantee is sound: LLMQContext is initialized before CChainstateHelper (which owns CMNHFManager), and destroyed after it, ensuring the referenced CQuorumManager outlives CMNHFManager throughout its lifetime.

src/llmq/ehf_signals.cpp (3)

7-29: Ctor + include updates are consistent with the new access path.
Signature matches src/llmq/ehf_signals.h and removes the old direct manager dependency.


84-100: ehf_manager access is safe and consistent across the codebase.

The ehf_manager is a const std::unique_ptr<CMNHFManager> member initialized in the constructor and cannot be null. The access pattern used in HandleNewRecoveredSig matches the pattern throughout the codebase (miner.cpp, chainstate.cpp) without null checks, indicating this is intentional design. No preprocessor or cppcheck warnings were identified for this file in the current configuration.


36-49: No blocking issue identified; ehf_manager lifecycle is properly managed.

The ehf_manager is initialized via std::make_unique in the ChainHelper constructor and cannot be null. The ChainHelper() accessor includes an assert guard, and the CEHFSignalsHandler properly manages listener registration/unregistration through RAII (constructor registers, destructor unregisters). The code is safe as-is and poses no crashing risk.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 71abb3c

nit: PR title is a bit confusing - consider s/ChainState/CChainstateHelper/

@knst knst changed the title refactor: move ownerships of mnhfman, cpoolman inside ChainState where it belongs to refactor: move ownerships of mnhfman, cpoolman inside Chain State where it belongs to Jan 16, 2026
@knst knst changed the title refactor: move ownerships of mnhfman, cpoolman inside Chain State where it belongs to refactor: move ownerships of mnhfman, cpoolman inside CChainstateHelper where it belongs to Jan 16, 2026
@knst knst requested a review from UdjinM6 January 16, 2026 15:46
Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 71abb3c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants