Skip to content

Conversation

@knst
Copy link
Collaborator

@knst knst commented Dec 16, 2025

Issue being fixed or feature implemented

There are several circular dependencies that may be resolved by using NetHandler interface in CJ

"coinjoin/server -> net_processing -> masternode/active/context -> coinjoin/server"
"coinjoin/server -> net_processing -> coinjoin/server"

This PR is not a part of separation of Network and Consensus code; it's a side quest to break couple circular dependencies. It doesn't block me currently and any conflicting PRs may be merged before this one.
ToDo the same refactoring for coinjoin/client and coinjoin/walletman (out of scope this PR, could be done anytime in the future, but probably a bit more complex than coinjoin/server because need to split CJWalletManager and CJWalletManagerImpl::queueman)

"chainlock/chainlock -> llmq/quorums -> msg_result -> coinjoin/coinjoin -> chainlock/chainlock",
"coinjoin/coinjoin -> instantsend/instantsend -> spork -> msg_result -> coinjoin/coinjoin",

What was done?

Two circular dependencies are resolved.
This PR use NetHandler interface to aggregate network code.

How Has This Been Tested?

Run unit & functional tests.

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 Dec 16, 2025
@github-actions
Copy link

github-actions bot commented Dec 16, 2025

⚠️ Potential Merge Conflicts Detected

This PR has potential conflicts with the following open PRs:

Please coordinate with the authors of these PRs to avoid merge conflicts.

@coderabbitai
Copy link

coderabbitai bot commented Dec 16, 2025

Walkthrough

The CCoinJoinServer was converted into a NetHandler-backed component: its constructor now accepts PeerManagerInternal* and replaces PeerManager usage with m_peer_manager. ProcessMessage and ProcessDSQUEUE now return void and use m_peer_manager for relays and misbehavior/erase calls. DoMaintenance was renamed to Schedule(CScheduler&) and periodic execution moved to a scheduler. New NetHandler overrides AlreadyHave and ProcessGetData were added. ActiveContext and init wiring were updated to construct and bind a CCoinJoinServer instance; PeerManagerInternal and net_processing gained DSQ/transaction relay hooks and external-handler invocation points.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Init as init.cpp
    participant PMI as PeerManagerInternal / PeerManagerImpl
    participant CJS as CCoinJoinServer (NetHandler)
    participant AC as ActiveContext
    participant NP as net_processing (handler registry)
    participant Conn as CConnman

    Init->>PMI: provide PeerManagerInternal*
    Init->>CJS: construct CCoinJoinServer(peer_manager, ...)
    Init->>AC: construct ActiveContext(..., CCoinJoinServer&)
    AC->>CJS: bind m_cj_server reference
    Init->>NP: AddExtraHandler(CJS)
    NP->>CJS: incoming message -> ProcessMessage(msg)
    CJS->>PMI: RelayDSQ / RelayInv / PeerMisbehaving / PeerEraseObjectRequest
    PMI->>Conn: send relayed network messages
    NP->>CJS: query AlreadyHave / ProcessGetData when handling getdata
    CJS->>NP: trigger PeerRelayDSQ / PeerRelayTransaction via PeerManagerInternal
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • src/coinjoin/server.cpp & src/coinjoin/server.h (NetHandler integration, API changes, new helpers, locking/peer erase semantics)
    • src/init.cpp (construction order, AddExtraHandler registration)
    • src/masternode/active/context.h & .cpp (constructor signature and lifetime changes from unique_ptr to reference)
    • src/net_processing.h & .cpp (PeerManagerInternal interface additions, external handler invocation)
    • Cross-cutting call sites (rpc changes, tests, lint updates)

Possibly related PRs

Suggested reviewers

  • PastaPastaPasta
  • UdjinM6
  • kwvg

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.62% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main objective of the PR: refactoring to break circular dependencies in coinjoin/server.
Description check ✅ Passed The description clearly explains the issue being fixed (circular dependencies), what was done (using NetHandler interface), and test results.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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: 1

Caution

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

⚠️ Outside diff range comments (1)
src/coinjoin/server.cpp (1)

48-61: Remove redundant return statement.

Line 55 uses return ProcessDSQUEUE(...) but ProcessDSQUEUE now returns void (line 129). The return keyword is redundant and should be removed for clarity.

Apply this diff:

     } else if (msg_type == NetMsgType::DSQUEUE) {
-        return ProcessDSQUEUE(peer.GetId(), vRecv);
+        ProcessDSQUEUE(peer.GetId(), vRecv);
     } else if (msg_type == NetMsgType::DSVIN) {
🧹 Nitpick comments (1)
src/net_processing.cpp (1)

2353-2372: DSQ AlreadyHave delegation to CJWalletManager and NetHandlers looks consistent

The DSQ branch now:

  • Checks m_cj_walletman->hasQueue() first, and
  • Falls through to m_handlers via handler->AlreadyHave(inv) returning std::optional<bool>.

This preserves the “first handler that knows, decides” semantics and cleanly routes DSQ knowledge to CoinJoin-related components without re-introducing direct coinjoin/server dependencies. Returning false when no handler claims the object is appropriate so DSQ can be requested when relevant. Just ensure NetHandler implementations return std::nullopt (not false) for unrelated inv.types so they don’t accidentally suppress other handlers.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 123ee5e and 7d821b43070a22e8c69fa921ab0264841384361a.

📒 Files selected for processing (9)
  • src/coinjoin/server.cpp (30 hunks)
  • src/coinjoin/server.h (4 hunks)
  • src/init.cpp (1 hunks)
  • src/masternode/active/context.cpp (1 hunks)
  • src/masternode/active/context.h (2 hunks)
  • src/net_processing.cpp (6 hunks)
  • src/net_processing.h (3 hunks)
  • src/rpc/coinjoin.cpp (1 hunks)
  • test/lint/lint-circular-dependencies.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
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/rpc/coinjoin.cpp
  • src/masternode/active/context.h
  • src/init.cpp
  • src/net_processing.h
  • src/coinjoin/server.cpp
  • src/net_processing.cpp
  • src/coinjoin/server.h
  • src/masternode/active/context.cpp
src/{masternode,evo}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • src/masternode/active/context.h
  • src/masternode/active/context.cpp
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/masternode/active/context.h
  • src/coinjoin/server.cpp
  • src/coinjoin/server.h
  • src/masternode/active/context.cpp
src/{masternode,llmq}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • src/masternode/active/context.h
  • src/masternode/active/context.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/masternode/active/context.h
  • src/coinjoin/server.cpp
  • src/coinjoin/server.h
  • src/masternode/active/context.cpp
src/coinjoin/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Files:

  • src/coinjoin/server.cpp
  • src/coinjoin/server.h
🧠 Learnings (21)
📓 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: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.
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
📚 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/rpc/coinjoin.cpp
  • test/lint/lint-circular-dependencies.py
  • src/masternode/active/context.h
  • src/init.cpp
  • src/net_processing.h
  • src/coinjoin/server.cpp
  • src/net_processing.cpp
  • src/coinjoin/server.h
  • src/masternode/active/context.cpp
📚 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/rpc/coinjoin.cpp
  • src/masternode/active/context.h
  • src/init.cpp
  • src/masternode/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/masternode/active/context.h
  • src/init.cpp
  • src/masternode/active/context.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/masternode/active/context.h
  • src/coinjoin/server.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/masternode/active/context.h
  • src/net_processing.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/masternode/active/context.h
  • src/init.cpp
  • src/net_processing.h
  • src/net_processing.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}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features

Applied to files:

  • src/masternode/active/context.h
  • src/init.cpp
  • src/net_processing.h
  • src/coinjoin/server.cpp
  • src/net_processing.cpp
  • src/coinjoin/server.h
  • src/masternode/active/context.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/governance/**/*.{cpp,h} : Governance implementation must support governance objects (proposals, triggers, superblock management) and on-chain voting with tallying

Applied to files:

  • src/masternode/active/context.h
  • src/masternode/active/context.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/masternode/active/context.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/masternode/active/context.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/masternode/active/context.h
📚 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/masternode/active/context.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/**/*.{cpp,h} : NodeContext must be extended with Dash-specific managers for each subsystem during initialization

Applied to files:

  • 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/{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/net_processing.h
  • src/net_processing.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/{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/net_processing.h
  • src/net_processing.cpp
  • src/masternode/active/context.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} : ChainLocks implementation must prevent reorganizations and provide block finality through 51% attack prevention

Applied to files:

  • src/net_processing.cpp
  • src/masternode/active/context.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/chainstate.{cpp,h} : Chainstate initialization must be separated into dedicated src/node/chainstate.* files

Applied to files:

  • src/net_processing.cpp
  • src/masternode/active/context.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/net_processing.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/net_processing.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} : InstantSend implementation must provide distributed key generation for secure transaction locking with quorum consensus

Applied to files:

  • src/net_processing.cpp
  • src/masternode/active/context.cpp
🧬 Code graph analysis (1)
src/coinjoin/server.h (3)
src/coinjoin/server.cpp (9)
  • CCoinJoinServer (27-44)
  • CCoinJoinServer (46-46)
  • ProcessGetData (953-962)
  • ProcessGetData (953-953)
  • inv (372-372)
  • AlreadyHave (947-951)
  • AlreadyHave (947-947)
  • Schedule (923-935)
  • Schedule (923-923)
src/coinjoin/coinjoin.h (1)
  • CCoinJoinBaseManager (322-351)
src/net_processing.h (3)
  • NetHandler (73-97)
  • NetHandler (77-80)
  • std (91-91)
🪛 Cppcheck (2.18.0)
src/masternode/active/context.cpp

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

(preprocessorErrorDirective)

⏰ 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: arm-linux-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: win64-build / Build source
  • GitHub Check: Lint / Run linters
🔇 Additional comments (22)
src/net_processing.h (3)

28-28: LGTM!

Forward declaration is appropriately added for the ProcessGetData method signature.


66-67: Interface extension properly supports dependency breaking.

The pure virtual methods PeerRelayTransaction() and PeerRelayDSQ() appropriately extend PeerManagerInternal to provide relay functionality for CoinJoin components without requiring the full PeerManager interface. Both methods are correctly implemented in PeerManagerImpl with proper lock annotations, allowing CCoinJoinServer to depend on the narrower PeerManagerInternal* interface instead of a full PeerManager& dependency.


86-94: [rewritten review comment text]
[classification tag]

src/net_processing.cpp (4)

44-46: CoinJoin include switch to shared header looks fine

Switching to <coinjoin/coinjoin.h> cleanly decouples net_processing from the server-specific header and aligns with the new NetHandler-based integration. No issues spotted.


2986-3003: DSQ getdata handling and NetHandler fallback are correctly ordered

For MSG_DSQ:

  • You first consult m_cj_walletman->getQueueFromHash() and, if present, respond with DSQUEUE.
  • Only if push is still false do you iterate m_handlers and let external NetHandlers attempt ProcessGetData.

This avoids double responses, keeps wallet-driven DSQ serving as a fast path, and lets CoinJoin server (or other handlers) take over when the wallet has no queue entry. The generic m_handlers loop for any inv type is also guarded via push so only one handler responds. No locking or flow-control issues seen.


649-656: New PeerRelayDSQ/PeerRelayTransaction hooks match existing relay contracts

Adding PeerRelayDSQ and PeerRelayTransaction to the PeerManagerInternal interface, with the same lock annotations as the existing relay methods, gives NetHandlers a clear, symmetric way to trigger DSQ and tx relay without coupling to concrete PeerManagerImpl. The signatures and annotations are consistent with RelayDSQ / RelayTransaction.


6584-6592: Thin forwarding implementations for PeerRelay keep behaviour centralized*

PeerRelayDSQ and PeerRelayTransaction simply forward to RelayDSQ(queue) and RelayTransaction(txid), so all relay behaviour (including filters, DSQ preference handling, etc.) remains in the existing methods. This avoids duplication and ensures external NetHandlers use the same relay path as core code.

src/coinjoin/server.h (2)

28-28: LGTM: NetHandler inheritance enables dependency decoupling.

The addition of NetHandler as a base class is the key change that breaks the circular dependency by allowing CCoinJoinServer to be managed through a polymorphic interface in net_processing without direct coupling.


97-106: Constructor and interface changes are consistent with NetHandler.

The constructor signature taking PeerManagerInternal* and the virtual method overrides (ProcessMessage, ProcessGetData, AlreadyHave, Schedule) correctly implement the NetHandler interface as shown in the relevant code snippets from src/net_processing.h.

src/rpc/coinjoin.cpp (1)

468-468: LGTM: Access pattern updated for reference member.

The change from pointer dereference (cj_server->) to reference access (m_cj_server.) correctly reflects the updated ActiveContext member type. Based on learnings, when node.active_ctx is non-null, its members are guaranteed to be initialized, so this access is safe.

test/lint/lint-circular-dependencies.py (1)

35-35: Circular dependency changes align with PR objectives.

The newly expected cycle coinjoin/coinjoin -> ... -> net_processing -> coinjoin/coinjoin reflects the architectural change where CoinJoin server functionality is now integrated via the NetHandler interface. This successfully removes the coinjoin/server -> net_processing cycles mentioned in the PR objectives.

src/masternode/active/context.h (2)

43-46: Constructor signature updated to accept CCoinJoinServer reference.

The removal of dstxman and mn_metaman parameters and addition of CCoinJoinServer& cj_server aligns with the refactoring where CCoinJoinServer now internally manages its own dependencies rather than having them passed through ActiveContext.


58-58: Changed from pointer to reference member for type safety.

The change from cj_server pointer to CCoinJoinServer& m_cj_server reference provides stronger guarantees: the member must be initialized at construction time and cannot be null. This aligns with the retrieved learning that "if ActiveContext is non-null, its members (including cj_server) are guaranteed to be initialized."

src/init.cpp (2)

2202-2203: NetInstantSend and NetSigning handlers are correctly registered unconditionally.

These handlers process network-wide messages (ISDLOCK and QSIGREC) that all nodes must receive and validate, not just masternodes. The isdlock message produced by the locking process is relayed to the entire Dash network. Regular nodes need these handlers to track locked transactions and maintain consensus state. Masternode-specific functionality (like lock creation) is properly isolated within the if (node.mn_activeman) block via ActiveContext and CCoinJoinServer.


2205-2210: Correct the shutdown order concern: peerman (owning cj_server) is destroyed before active_ctx.

The review correctly identifies a lifetime management issue. In PrepareShutdown() at line 96, node.peerman.reset() destroys the CCoinJoinServer before line 140 where node.active_ctx.reset() destroys the ActiveContext that holds a reference to it.

However, this is mitigated by the shutdown sequence: the RPC server is stopped at lines 63-66 (before peerman.reset()), preventing any RPC calls from accessing m_cj_server. Additionally, ActiveContext::~ActiveContext() (lines 41-45) does not dereference m_cj_server—it only disconnects signers via llmq_ctx.

While the dangling reference is fragile design, it poses no practical safety issue given the current shutdown ordering and cleanup code. Consider reordering peerman.reset() to occur after active_ctx.reset() (line 140) for defensive robustness.

src/masternode/active/context.cpp (1)

19-25: LGTM! Clean dependency injection refactor.

The constructor changes successfully break the circular dependency by accepting CCoinJoinServer& as an external dependency rather than constructing it internally. The initialization is correct.

src/coinjoin/server.cpp (6)

27-31: LGTM! Constructor aligns with NetHandler integration.

The updated constructor correctly integrates CCoinJoinServer into the NetHandler framework by accepting PeerManagerInternal* and initializing the base class.


137-137: LGTM! Consistent peer manager integration.

All usages of m_peer_manager methods (PeerEraseObjectRequest, PeerMisbehaving, PeerRelayDSQ, PeerRelayInv, PeerRelayTransaction) are correctly migrated from the previous m_peerman member, aligning with the PeerManagerInternal interface.

Also applies to: 142-142, 147-147, 156-156, 190-190, 206-206, 373-373, 485-485, 532-532, 753-753


923-935: LGTM! Clean scheduler integration.

The Schedule method correctly integrates with CScheduler for recurring maintenance tasks. The lambda captures this safely, includes appropriate sync and shutdown guards, and calls the expected maintenance methods on a one-second interval.


947-951: LGTM! Correct NetHandler integration.

The AlreadyHave method correctly implements the NetHandler interface for DSQ inventory handling, returning std::nullopt for non-DSQ types and delegating to HasQueue for MSG_DSQ.


953-962: LGTM! Correct GetData handling.

The ProcessGetData method correctly implements the NetHandler interface for DSQ GetData requests, returning false for non-DSQ types or missing entries, and successfully responding with the DSQUEUE message when found.


276-277: Modern C++ pattern: inline variable declaration.

The use of if (int entries = GetEntriesCount(); entries != 0) is a clean C++17 init-statement pattern that limits the scope of the entries variable.

@knst knst force-pushed the refactor-peermanager-handlers-cj branch from 7d821b4 to d88585d Compare December 17, 2025 10:16
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: 1

🧹 Nitpick comments (1)
src/net_processing.cpp (1)

2353-2372: DSQ AlreadyHave NetHandler integration is sound; consider documenting “first handler wins”

The new MSG_DSQ case correctly:

  • Short‑circuits via m_cj_walletman->hasQueue() when available, and
  • Falls back to iterating m_handlers and using the first handler that returns a non‑empty std::optional<bool>.

This achieves the goal of removing the direct coinjoin/server dependency while keeping AlreadyHave fast and side‑effect free.

One thing to consider: right now the semantics are “first handler that knows this inv type decides”. If you ever introduce multiple handlers for the same inv type, later handlers will never be consulted. A short comment or assertion around handler registration (e.g., “at most one handler per inv type”) would make this contract explicit and avoid subtle future bugs.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d821b43070a22e8c69fa921ab0264841384361a and d88585d5b438817a04b146cce3034f117c7df50b.

📒 Files selected for processing (9)
  • src/coinjoin/server.cpp (18 hunks)
  • src/coinjoin/server.h (4 hunks)
  • src/init.cpp (1 hunks)
  • src/masternode/active/context.cpp (1 hunks)
  • src/masternode/active/context.h (2 hunks)
  • src/net_processing.cpp (6 hunks)
  • src/net_processing.h (3 hunks)
  • src/rpc/coinjoin.cpp (1 hunks)
  • test/lint/lint-circular-dependencies.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/net_processing.h
  • src/rpc/coinjoin.cpp
  • test/lint/lint-circular-dependencies.py
🧰 Additional context used
📓 Path-based instructions (6)
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/masternode/active/context.cpp
  • src/net_processing.cpp
  • src/coinjoin/server.h
  • src/masternode/active/context.h
  • src/init.cpp
  • src/coinjoin/server.cpp
src/{masternode,evo}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • src/masternode/active/context.cpp
  • src/masternode/active/context.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/masternode/active/context.cpp
  • src/coinjoin/server.h
  • src/masternode/active/context.h
  • src/coinjoin/server.cpp
src/{masternode,llmq}/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • src/masternode/active/context.cpp
  • src/masternode/active/context.h
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/masternode/active/context.cpp
  • src/coinjoin/server.h
  • src/masternode/active/context.h
  • src/coinjoin/server.cpp
src/coinjoin/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Files:

  • src/coinjoin/server.h
  • src/coinjoin/server.cpp
🧠 Learnings (22)
📓 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: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.
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: 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.
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
📚 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/masternode/active/context.cpp
  • src/net_processing.cpp
  • src/coinjoin/server.h
  • src/masternode/active/context.h
  • src/init.cpp
  • src/coinjoin/server.cpp
📚 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/masternode/active/context.cpp
  • src/masternode/active/context.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/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features

Applied to files:

  • src/masternode/active/context.cpp
  • src/net_processing.cpp
  • src/coinjoin/server.h
  • src/masternode/active/context.h
  • src/init.cpp
  • src/coinjoin/server.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} : ChainLocks implementation must prevent reorganizations and provide block finality through 51% attack prevention

Applied to files:

  • src/masternode/active/context.cpp
  • src/net_processing.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} : InstantSend implementation must provide distributed key generation for secure transaction locking with quorum consensus

Applied to files:

  • src/masternode/active/context.cpp
  • src/net_processing.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/chainstate.{cpp,h} : Chainstate initialization must be separated into dedicated src/node/chainstate.* files

Applied to files:

  • src/masternode/active/context.cpp
  • src/net_processing.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/governance/**/*.{cpp,h} : Governance implementation must support governance objects (proposals, triggers, superblock management) and on-chain voting with tallying

Applied to files:

  • src/masternode/active/context.cpp
  • src/masternode/active/context.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/masternode/active/context.cpp
  • src/net_processing.cpp
  • src/masternode/active/context.h
📚 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/masternode/active/context.cpp
  • src/masternode/active/context.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/{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/net_processing.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,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/net_processing.cpp
  • src/masternode/active/context.h
  • src/init.cpp
  • src/coinjoin/server.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/net_processing.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/net_processing.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/masternode/active/context.h
📚 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/masternode/active/context.h
  • src/coinjoin/server.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/masternode/active/context.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/masternode/active/context.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/masternode/active/context.h
📚 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/masternode/active/context.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/**/*.{cpp,h} : NodeContext must be extended with Dash-specific managers for each subsystem during initialization

Applied to files:

  • src/init.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/coinjoin/server.cpp
🪛 Cppcheck (2.18.0)
src/masternode/active/context.cpp

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

(preprocessorErrorDirective)

🔇 Additional comments (18)
src/masternode/active/context.cpp (1)

19-39: LGTM! Clean refactor to external CCoinJoinServer ownership.

The constructor correctly accepts CCoinJoinServer by reference and initializes m_cj_server in the member initializer list. This cleanly breaks the circular dependency by externalizing server ownership.

src/masternode/active/context.h (1)

43-46: LGTM! Reference member correctly replaces unique_ptr ownership.

The change from const std::unique_ptr<CCoinJoinServer> cj_server to CCoinJoinServer& m_cj_server correctly implements external ownership while maintaining access. Reference members must be initialized in the constructor (verified in context.cpp line 25) and can't be reassigned, which enforces the single-binding contract.

The public reference allows external access (e.g., rpc/coinjoin.cpp) while clearly indicating ActiveContext doesn't own the server.

Also applies to: 58-58

src/init.cpp (1)

2202-2210: Verify lifetime safety: m_cj_server reference becomes dangling between peerman and active_ctx destruction.

The CCoinJoinServer is created with a reference passed to ActiveContext, then ownership is moved to peerman via AddExtraHandler. This creates a subtle lifetime dependency:

  1. Line 2210: Ownership transferred to peerman's handler list
  2. PrepareShutdown line 325: node.peerman.reset() destroys the CCoinJoinServer
  3. PrepareShutdown line 369: node.active_ctx.reset() destroys ActiveContext, which holds a now-dangling reference to m_cj_server

Currently safe because ActiveContext destructor (context.cpp lines 41-45) doesn't access m_cj_server. However, this design is brittle—future modifications to the destructor could introduce use-after-free bugs.

Consider one of these solutions:

  1. Reset active_ctx before peerman in PrepareShutdown to make the dependency explicit
  2. Document this lifetime constraint clearly in ActiveContext
  3. Use a weak_ptr or optional reference to make the dangling reference explicit
⛔ Skipped due to learnings
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.
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: 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.
src/coinjoin/server.h (4)

10-10: LGTM: Include updated to support NetHandler integration.

The switch from msg_result.h to net_processing.h aligns with the new NetHandler base class and the removal of MessageProcessingResult return types.


28-28: LGTM: NetHandler inheritance breaks circular dependencies.

This inheritance is central to the PR's goal of breaking circular dependencies between coinjoin/server and net_processing by providing a well-defined interface for network message handling.


97-100: LGTM: Constructor signature updated for NetHandler integration.

Adding PeerManagerInternal* peer_manager as the first parameter enables NetHandler initialization and provides access to network processing functionality without creating circular dependencies.


103-106: LGTM: Public API updated to match NetHandler interface.

The changes reflect the net-centric design:

  • ProcessMessage now returns void with error handling via PeerMisbehaving
  • ProcessGetData and AlreadyHave expose DSQ inventory handling
  • Schedule replaces DoMaintenance for recurring tasks
src/coinjoin/server.cpp (7)

14-15: LGTM: Includes added for new functionality.

The new includes support ProcessGetData (netmessagemaker.h) and Schedule (scheduler.h) methods.


27-31: LGTM: Constructor properly initializes NetHandler.

The constructor correctly accepts PeerManagerInternal* peer_manager and passes it to the NetHandler base class initializer, enabling network message handling without circular dependencies.


48-61: LGTM: ProcessMessage refactored to void return type.

The method now handles errors inline via peer misbehaving calls instead of returning status codes. The early return pattern (line 50, 55) is appropriate for the new design.


129-143: LGTM: ProcessDSQUEUE refactored with early returns.

The conversion to early returns for validation failures is consistent and improves readability. The use of m_peer_manager for misbehaving reports and relay operations is correct (note: line 188-206 has a separate critical issue).

Also applies to: 144-187, 192-207


372-372: LGTM: Relay calls updated to use m_peer_manager.

All relay operations (PeerRelayInv, PeerRelayTransaction, PeerRelayDSQ) now use m_peer_manager instead of the removed m_peerman, consistent with the NetHandler integration.

Also applies to: 485-485, 530-530, 740-740


900-912: LGTM: Schedule method implements recurring maintenance tasks.

The method correctly schedules CheckForCompleteQueue, CheckPool, and CheckTimeout on a 1-second interval with appropriate guards for blockchain sync status and shutdown requests.


924-939: LGTM: AlreadyHave and ProcessGetData expose DSQ inventory handling.

These NetHandler overrides correctly:

  • Filter for MSG_DSQ inventory type
  • Delegate to existing queue management methods (HasQueue, GetQueueFromHash)
  • Integrate DSQ handling into the network layer
src/net_processing.cpp (4)

44-46: Include swap to coinjoin/coinjoin.h looks appropriate

Switching to #include <coinjoin/coinjoin.h> here is consistent with the new NetHandler‑based integration (CCoinJoin types, DSTX validation) and helps decouple net_processing from the concrete server implementation. No issues from a dependency or layering perspective.


2986-3003: DSQ GETDATA handling refactor matches new abstraction; verify handler expectations

The DSQ branch in ProcessGetData now:

  • Serves DSQ from m_cj_walletman->getQueueFromHash() when available, and
  • Delegates to each NetHandler::ProcessGetData until one returns true, otherwise falls back to NOTFOUND.

This is consistent with the new AlreadyHave behavior and keeps wallet/server responsibilities nicely separated. It also ensures peers don’t hang waiting for DSQ, since unhandled requests still land in vNotFound.

Just ensure that:

  • NetHandler implementations of ProcessGetData are safe to call under this function’s locking preconditions (no cs_main held, peer.m_getdata_requests_mutex held by caller), and
  • They return true iff they fully handled the request (including any responses or NOTFOUND), so push reflects “request was served”.

Functionally this looks correct and aligned with the PR’s intent.


655-657: New PeerManagerInternal relay hooks are minimal and consistent

Adding PeerRelayDSQ and PeerRelayTransaction to PeerManagerInternal gives NetHandlers an explicit way to trigger network relay without depending on concrete PeerManagerImpl internals. The lock annotations mirror the existing relay APIs and fit cleanly into the interface surface.


6584-6592: PeerRelayDSQ / PeerRelayTransaction wrappers are correct

These implementations just forward to RelayDSQ and RelayTransaction, preserving existing relay semantics while exposing them through the internal interface. Lock annotations line up with the underlying methods, and there’s no additional state or complexity introduced.

@knst knst force-pushed the refactor-peermanager-handlers-cj branch from deffce0 to 75a9ea2 Compare December 17, 2025 18:06
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: 0

🧹 Nitpick comments (1)
src/net_processing.cpp (1)

2353-2372: DSQ handling in AlreadyHave looks correct; consider clarifying NetHandler contract

The new MSG_DSQ branch:

  • Checks m_cj_walletman->hasQueue(inv.hash) first, which is a cheap local “have-it” check.
  • Then iterates m_handlers, using std::optional<bool> from handler->AlreadyHave(inv) and treating std::nullopt as “handler not interested”, while honoring the first concrete true/false.
  • Falls back to false (we do not already have the DSQ), which is appropriate for a known type that we want to request if no component owns it.

Behavior-wise this keeps DSQ out of the generic “unknown → already have” path and lets external handlers (e.g. CoinJoin server NetHandler) participate without creating new dependencies.

One small improvement: it might be worth adding a brief comment to the NetHandler interface (or here) explicitly stating that AlreadyHave() must return std::nullopt when a handler does not own a given CInv type, otherwise a handler that always returns false would short‑circuit others.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between deffce0595a7a9e7f1cbb584271830f0edac7280 and 75a9ea23d5116b8490fbe2ee7484988495a96e7e.

📒 Files selected for processing (9)
  • src/coinjoin/server.cpp (18 hunks)
  • src/coinjoin/server.h (4 hunks)
  • src/init.cpp (1 hunks)
  • src/masternode/active/context.cpp (1 hunks)
  • src/masternode/active/context.h (2 hunks)
  • src/net_processing.cpp (6 hunks)
  • src/net_processing.h (3 hunks)
  • src/rpc/coinjoin.cpp (1 hunks)
  • test/lint/lint-circular-dependencies.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/lint/lint-circular-dependencies.py
🧰 Additional context used
📓 Path-based instructions (6)
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/init.cpp
  • src/rpc/coinjoin.cpp
  • src/net_processing.h
  • src/coinjoin/server.h
  • src/masternode/active/context.cpp
  • src/coinjoin/server.cpp
  • src/net_processing.cpp
  • src/masternode/active/context.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/coinjoin/server.h
  • src/masternode/active/context.cpp
  • src/coinjoin/server.cpp
  • src/masternode/active/context.h
src/coinjoin/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Files:

  • src/coinjoin/server.h
  • src/coinjoin/server.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/coinjoin/server.h
  • src/masternode/active/context.cpp
  • src/coinjoin/server.cpp
  • src/masternode/active/context.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/masternode/active/context.cpp
  • src/masternode/active/context.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/masternode/active/context.cpp
  • src/masternode/active/context.h
🧠 Learnings (23)
📓 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: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.
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
📚 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/init.cpp
  • src/rpc/coinjoin.cpp
  • src/masternode/active/context.cpp
  • src/masternode/active/context.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/init.cpp
  • src/rpc/coinjoin.cpp
  • src/net_processing.h
  • src/coinjoin/server.h
  • src/masternode/active/context.cpp
  • src/coinjoin/server.cpp
  • src/net_processing.cpp
  • src/masternode/active/context.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/init.cpp
  • src/net_processing.h
  • src/net_processing.cpp
  • src/masternode/active/context.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/**/*.{cpp,h} : NodeContext must be extended with Dash-specific managers for each subsystem during initialization

Applied to files:

  • src/init.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/init.cpp
  • src/masternode/active/context.cpp
  • src/masternode/active/context.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/init.cpp
  • src/net_processing.h
  • src/coinjoin/server.h
  • src/masternode/active/context.cpp
  • src/coinjoin/server.cpp
  • src/net_processing.cpp
  • src/masternode/active/context.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/net_processing.h
  • src/masternode/active/context.cpp
  • src/net_processing.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/net_processing.h
  • src/masternode/active/context.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/masternode/active/context.cpp
  • src/net_processing.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} : InstantSend implementation must provide distributed key generation for secure transaction locking with quorum consensus

Applied to files:

  • src/masternode/active/context.cpp
  • src/net_processing.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/chainstate.{cpp,h} : Chainstate initialization must be separated into dedicated src/node/chainstate.* files

Applied to files:

  • src/masternode/active/context.cpp
  • src/net_processing.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/governance/**/*.{cpp,h} : Governance implementation must support governance objects (proposals, triggers, superblock management) and on-chain voting with tallying

Applied to files:

  • src/masternode/active/context.cpp
  • src/masternode/active/context.h
📚 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/coinjoin/server.cpp
📚 Learning: 2025-07-29T14:32:48.369Z
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.

Applied to files:

  • src/coinjoin/server.cpp
📚 Learning: 2025-11-04T18:24:27.241Z
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.

Applied to files:

  • src/coinjoin/server.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/coinjoin/server.cpp
  • src/masternode/active/context.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/net_processing.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/net_processing.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/net_processing.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/masternode/active/context.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/masternode/active/context.h
📚 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/masternode/active/context.h
🧬 Code graph analysis (3)
src/init.cpp (2)
src/interfaces/node.h (2)
  • node (42-44)
  • node (417-417)
src/init.h (1)
  • node (23-25)
src/coinjoin/server.h (1)
src/net_processing.h (3)
  • NetHandler (73-97)
  • NetHandler (77-80)
  • std (91-91)
src/net_processing.cpp (5)
src/node/interfaces.cpp (6)
  • txid (1063-1068)
  • txid (1063-1063)
  • txid (1069-1075)
  • txid (1069-1069)
  • txid (1084-1089)
  • txid (1084-1084)
src/coinjoin/server.cpp (1)
  • inv (372-372)
src/instantsend/net_instantsend.cpp (1)
  • inv (191-191)
src/llmq/dkgsession.cpp (4)
  • inv (301-301)
  • inv (608-608)
  • inv (819-819)
  • inv (1174-1174)
src/init.cpp (1)
  • handler (496-496)
🪛 Cppcheck (2.18.0)
src/masternode/active/context.cpp

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

(preprocessorErrorDirective)

⏰ 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_multiprocess-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: win64-build / Build source
🔇 Additional comments (21)
src/coinjoin/server.h (5)

10-10: LGTM: Include change aligns with NetHandler usage.

The switch from msg_result.h to net_processing.h is appropriate since the class now inherits from NetHandler and uses PeerManagerInternal.


28-28: LGTM: NetHandler inheritance breaks circular dependency.

The addition of NetHandler as a base class follows the pattern introduced to break circular dependencies between coinjoin/server and net_processing.


97-100: LGTM: Constructor updated for NetHandler initialization.

The addition of PeerManagerInternal* peer_manager as the first parameter correctly initializes the NetHandler base class, which provides access to peer management functionality.


103-106: LGTM: NetHandler overrides correctly implement the interface.

All four method overrides properly match the NetHandler interface:

  • ProcessMessage: Changed to void return for internal error handling
  • ProcessGetData: Handles CoinJoin-specific inventory requests
  • AlreadyHave: Checks for MSG_DSQ inventory
  • Schedule: Replaces DoMaintenance for periodic tasks

87-87: Verify error handling after void return change.

The change from [[nodiscard]] MessageProcessingResult to void correctly shifts error handling to internal calls. Confirmed:

  1. Call site at line 55 properly handles void return without capturing a result
  2. Error handling is properly internalized via m_peer_manager->PeerMisbehaving() calls for invalid denominations (score 10), null identifiers (score 100), invalid masternode (score 10), and signature failures (score 10)
src/net_processing.h (3)

28-28: LGTM: Forward declaration supports ProcessGetData signature.

The CNetMsgMaker forward declaration is properly added to support the new ProcessGetData method signature.


66-67: LGTM: New relay methods support handler callbacks.

The addition of PeerRelayTransaction and PeerRelayDSQ to PeerManagerInternal allows NetHandler implementations (like CCoinJoinServer) to trigger relay operations, properly breaking the circular dependency.


86-94: LGTM: Well-designed handler delegation pattern.

The new NetHandler methods use appropriate patterns:

  • AlreadyHave returns std::optional<bool> to distinguish "not my responsibility" (nullopt) from "I handle this" (true/false)
  • ProcessGetData returns bool to indicate whether data was pushed
  • Clear comments explain the delegation semantics

This design allows multiple handlers to coexist and properly delegate responsibility.

src/net_processing.cpp (3)

44-46: Include switch to coinjoin/coinjoin.h is appropriate

Using the aggregate CoinJoin header here is consistent with the NetHandler-based refactor and helps avoid the previous circular dependency on coinjoin/server.h. No issues spotted.


655-656: PeerRelayDSQ/PeerRelayTransaction wrappers are correctly wired

The new PeerRelayDSQ and PeerRelayTransaction overrides cleanly delegate to RelayDSQ and RelayTransaction, and their lock annotations match the underlying methods (no extra locking requirements introduced). This gives NetHandler implementations a narrow, well-scoped way to trigger relays without exposing more of PeerManagerImpl.

Also applies to: 6584-6592


2986-3003: DSQ GETDATA path and NetHandler delegation preserve semantics

For MSG_DSQ getdata requests you now:

  • Try m_cj_walletman->getQueueFromHash(inv.hash) and, if present, send DSQUEUE immediately and mark push = true.
  • Then iterate m_handlers and let the first handler that returns true from ProcessGetData claim the request, for any supported inv type.
  • Only append to vNotFound when push remained false, so objects handled by either wallet or handlers won’t trigger NOTFOUND.

This keeps DSQ responses local when the wallet has the queue, and moves CoinJoin server / other NetHandler responses behind the generic extension hook without changing NOTFOUND behavior. Locking is also consistent: ProcessGetData is called with peer.m_getdata_requests_mutex held and cs_main excluded, and the new calls respect that.

No issues from a net-processing perspective.

src/rpc/coinjoin.cpp (1)

468-468: LGTM!

The member access correctly reflects the transition from cj_server unique_ptr to m_cj_server reference. Based on learnings, when active_ctx is non-null, its members are guaranteed to be initialized, so no additional null-check is needed.

src/init.cpp (2)

2202-2203: LGTM!

Registration of NetInstantSend and NetSigning handlers before ActiveContext creation is appropriate and follows the established pattern.


2205-2210: Shutdown order is safe; no use-after-free risk.

The code safely handles the CCoinJoinServer lifetime. RPC is stopped at line 55 before peerman.reset() at line 86, eliminating access to m_cj_server through the RPC handler. Additionally, ActiveContext::Stop() (line 58) and ~ActiveContext() do not access m_cj_server, so the dangling reference after peerman destruction poses no risk before active_ctx is destroyed at line 130.

Likely an incorrect or invalid review comment.

src/masternode/active/context.cpp (1)

19-39: LGTM!

The constructor correctly accepts CCoinJoinServer& and binds it to m_cj_server. The destructor and Stop() method only interact with LLMQ-related members, not m_cj_server, which addresses potential lifetime concerns during shutdown.

src/masternode/active/context.h (1)

43-58: LGTM!

The transition from std::unique_ptr<CCoinJoinServer> to CCoinJoinServer& is consistent with the dependency injection refactoring goal. The deleted copy operations appropriately prevent copying a class with reference members.

src/coinjoin/server.cpp (5)

27-44: LGTM!

Constructor correctly initializes the NetHandler base class with peer_manager and removes the old m_peerman reference in favor of the inherited m_peer_manager pointer.


48-61: LGTM!

The conversion to void return type is correct. All message handling paths either return early or delegate to specific handlers.


129-207: LGTM!

ProcessDSQUEUE correctly handles all error paths with early returns after calling PeerMisbehaving. The previously flagged issues (unused ret variable and missing return after signature validation failure) have been addressed.


925-939: LGTM!

The AlreadyHave and ProcessGetData implementations follow the NetHandler interface pattern correctly. AlreadyHave returns std::nullopt for non-DSQ inventory types, allowing other handlers to respond.


901-913: The Schedule method is properly invoked via PeerManager::ScheduleHandlers. The CCoinJoinServer is registered as an extra handler at initialization, stored in the m_handlers vector, and ScheduleHandlers correctly iterates through all registered handlers calling their Schedule methods. The implementation at lines 901-913 correctly encapsulates the periodic maintenance logic with proper guard checks for blockchain sync and shutdown state.

@knst knst force-pushed the refactor-peermanager-handlers-cj branch from 75a9ea2 to a56c106 Compare December 17, 2025 19:05
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: 0

🧹 Nitpick comments (1)
src/net_processing.h (1)

89-93: Solid extension points for NetHandler implementations.

These virtual methods elegantly allow NetHandler implementations (like CCoinJoinServer) to participate in inventory management and GETDATA processing without tight coupling to net_processing internals. The default implementations returning false provide safe fallback behavior.

Optional consideration: AlreadyHave could potentially be marked const if implementations only perform read-only checks without modifying internal state. However, this may be intentionally non-const to allow for cache updates or other state management.

-    virtual bool AlreadyHave(const CInv& inv) { return false; }
+    virtual bool AlreadyHave(const CInv& inv) const { return false; }

Only apply this change if all derived implementations can be const-qualified.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75a9ea23d5116b8490fbe2ee7484988495a96e7e and a56c106.

📒 Files selected for processing (5)
  • src/coinjoin/server.cpp (18 hunks)
  • src/coinjoin/server.h (4 hunks)
  • src/net_processing.cpp (6 hunks)
  • src/net_processing.h (3 hunks)
  • test/lint/lint-circular-dependencies.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/lint/lint-circular-dependencies.py
🧰 Additional context used
📓 Path-based instructions (4)
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/net_processing.h
  • src/coinjoin/server.cpp
  • src/net_processing.cpp
  • src/coinjoin/server.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/coinjoin/server.cpp
  • src/coinjoin/server.h
src/coinjoin/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Files:

  • src/coinjoin/server.cpp
  • src/coinjoin/server.h
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/coinjoin/server.cpp
  • src/coinjoin/server.h
🧠 Learnings (16)
📓 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: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.
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
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.
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.
📚 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/net_processing.h
  • src/coinjoin/server.cpp
  • src/net_processing.cpp
  • src/coinjoin/server.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/net_processing.h
  • src/net_processing.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/{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/net_processing.h
  • src/net_processing.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,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/net_processing.h
  • src/net_processing.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/net_processing.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/net_processing.h
  • src/coinjoin/server.cpp
  • src/net_processing.cpp
  • src/coinjoin/server.h
📚 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/coinjoin/server.cpp
📚 Learning: 2025-07-29T14:32:48.369Z
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.

Applied to files:

  • src/coinjoin/server.cpp
📚 Learning: 2025-11-04T18:24:27.241Z
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.

Applied to files:

  • src/coinjoin/server.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/coinjoin/server.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} : ChainLocks implementation must prevent reorganizations and provide block finality through 51% attack prevention

Applied to files:

  • src/net_processing.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/chainstate.{cpp,h} : Chainstate initialization must be separated into dedicated src/node/chainstate.* files

Applied to files:

  • src/net_processing.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/net_processing.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/net_processing.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} : InstantSend implementation must provide distributed key generation for secure transaction locking with quorum consensus

Applied to files:

  • src/net_processing.cpp
🧬 Code graph analysis (2)
src/net_processing.h (1)
src/net_processing.cpp (33)
  • PeerRelayTransaction (6588-6591)
  • PeerRelayTransaction (6588-6588)
  • txid (629-629)
  • txid (656-656)
  • txid (657-657)
  • txid (662-662)
  • txid (665-665)
  • PeerRelayDSQ (6583-6586)
  • PeerRelayDSQ (6583-6583)
  • queue (631-631)
  • queue (655-655)
  • pfrom (613-613)
  • pfrom (634-635)
  • pfrom (750-752)
  • pfrom (761-761)
  • pfrom (769-769)
  • pfrom (772-772)
  • pfrom (774-774)
  • pfrom (776-776)
  • pfrom (872-872)
  • pfrom (1054-1054)
  • inv (627-627)
  • inv (628-628)
  • inv (652-652)
  • inv (653-653)
  • inv (654-654)
  • inv (668-668)
  • inv (674-674)
  • inv (962-962)
  • inv (2406-2406)
  • ProcessGetData (2801-3039)
  • ProcessGetData (2801-2801)
  • msgMaker (2159-2159)
src/coinjoin/server.h (5)
src/coinjoin/server.cpp (9)
  • CCoinJoinServer (27-44)
  • CCoinJoinServer (46-46)
  • ProcessGetData (930-939)
  • ProcessGetData (930-930)
  • inv (372-372)
  • AlreadyHave (925-928)
  • AlreadyHave (925-925)
  • Schedule (901-913)
  • Schedule (901-901)
src/coinjoin/coinjoin.cpp (2)
  • CCoinJoinBaseManager (125-125)
  • CCoinJoinBaseManager (127-127)
src/coinjoin/coinjoin.h (1)
  • CCoinJoinBaseManager (322-351)
src/net_processing.h (2)
  • NetHandler (73-96)
  • NetHandler (77-80)
src/coinjoin/walletman.cpp (1)
  • connman (33-33)
🪛 GitHub Actions: Clang Diff Format Check
src/coinjoin/server.cpp

[error] 922-922: Clang-format differences detected. Formatting changed in function AlreadyHave. Process completed with exit code 1.

⏰ 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: win64-build / Build source
  • GitHub Check: linux64_nowallet-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: linux64_tsan-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: Lint / Run linters
🔇 Additional comments (18)
src/net_processing.h (2)

28-28: LGTM! Appropriate forward declaration.

The forward declaration of CNetMsgMaker is correctly added to support the new ProcessGetData method signature on line 93, avoiding unnecessary header inclusion and supporting the dependency reduction objectives of this PR.


66-67: Abstraction correctly implements interface for breaking circular dependencies.

The PeerRelayTransaction and PeerRelayDSQ methods provide a clean interface allowing CoinJoin components to relay transactions and DSQ messages through the abstract PeerManagerInternal interface. Implementation is verified: both methods in PeerManagerImpl correctly delegate to their respective RelayTransaction and RelayDSQ methods. Usage is confirmed across three call sites in CCoinJoinServer::ConsumeCollateral and queue processing methods, all properly using m_peer_manager initialized through the NetHandler base class. The signatures, parameter passing by const reference, and method patterns align with existing interface conventions.

src/net_processing.cpp (3)

44-45: Include swap to coinjoin/coinjoin.h is appropriate

The file now only needs CoinJoin core types (e.g. CCoinJoinQueue), not the full server header; this narrows the dependency surface and is consistent with moving server logic behind NetHandler.


2353-2371: DSQ AlreadyHave / GETDATA delegation to handlers looks consistent

The new MSG_DSQ handling in AlreadyHave (wallet check then m_handlers) and in ProcessGetData (wallet getQueueFromHash, then NetHandler::ProcessGetData fallback, else NOTFOUND) cleanly routes DSQ inventory through the new handler abstraction without changing semantics for callers of AlreadyHave/GETDATA. The boolean push gate also ensures only a single producer responds per request.

Also applies to: 2985-3003


655-656: PeerManagerInternal relay hooks correctly forward to existing relay logic

PeerRelayDSQ and PeerRelayTransaction are thin wrappers that just call RelayDSQ / RelayTransaction, preserving existing locking and relay behavior while exposing stable hooks for external NetHandlers. The override signatures and implementations are consistent with the rest of the PeerManagerInternal API.

Also applies to: 6583-6591

src/coinjoin/server.h (5)

10-10: LGTM! Include change aligns with NetHandler integration.

The change from msg_result.h to net_processing.h is correct as CCoinJoinServer now inherits from NetHandler (defined in net_processing.h) and no longer returns MessageProcessingResult.


28-28: LGTM! NetHandler inheritance correctly implemented.

The addition of NetHandler inheritance is consistent with the PR objective to break circular dependencies. The inheritance order (CCoinJoinBaseSession, CCoinJoinBaseManager, NetHandler) is appropriate.


87-87: LGTM! ProcessDSQUEUE signature change is correct.

The signature change to void return and NodeId parameter (instead of CNode&) aligns with the net-centric refactoring. This allows the method to use m_peer_manager for network operations without directly depending on the peer object.


97-100: LGTM! Constructor signature correctly updated.

The constructor now takes PeerManagerInternal* as the first parameter, which is properly passed to the NetHandler base class. This is consistent with the NetHandler pattern shown in the relevant code snippets.


103-106: LGTM! NetHandler override signatures are correct.

All four override methods (ProcessMessage, ProcessGetData, AlreadyHave, Schedule) match the NetHandler base class interface shown in the relevant code snippets. The void return types and parameter lists are appropriate for the net-centric design.

src/coinjoin/server.cpp (8)

27-44: LGTM! Constructor correctly initializes NetHandler.

The constructor properly accepts PeerManagerInternal* and initializes the NetHandler base class. The base class constructor asserts the pointer is non-null, so initialization is safe.


48-61: LGTM! ProcessMessage correctly implements void return flow.

The void return signature matches the NetHandler interface. The early return on Line 50 and the ProcessDSQUEUE call on Line 55 (without capturing a return value) are both correct for the new signature.


129-208: LGTM! ProcessDSQUEUE correctly refactored to void return.

The method correctly handles error cases with m_peer_manager->PeerMisbehaving followed by early returns (Lines 141-142, 146-147, 155-156, 189-190). The success case (Line 206) properly uses m_peer_manager->PeerRelayDSQ. Past review comments about missing returns and unused variables have been addressed.


373-373: LGTM! Peer manager relay calls correctly updated.

All relay operations (PeerRelayInv, PeerRelayTransaction, PeerRelayDSQ) correctly use m_peer_manager from the NetHandler base class. This is consistent with the refactoring to break circular dependencies.

Also applies to: 486-486, 531-531, 741-741


901-913: LGTM! Schedule correctly replaces DoMaintenance.

The Schedule method properly implements the NetHandler interface. The lambda function includes appropriate guards (blockchain sync check and shutdown check) and executes the same maintenance tasks (CheckForCompleteQueue, CheckPool, CheckTimeout) on a 1-second interval. The conversion from DoMaintenance to scheduled execution is clean.


925-928: LGTM! AlreadyHave correctly implements queue lookup.

The implementation correctly returns true if the inventory type is MSG_DSQ and we have the queue, false otherwise. The bool return type (rather than optional) is appropriate as confirmed in past review discussions.


930-939: LGTM! ProcessGetData correctly handles DSQ inventory requests.

The implementation properly handles GETDATA requests for MSG_DSQ inventory. It returns false for non-DSQ types, retrieves the queue, and sends it to the requesting peer using the appropriate network message. The return value correctly indicates whether the request was handled.


924-924: No formatting issues detected in the current code state. The spacing between GetJsonInfo() and AlreadyHave() functions follows standard C++ conventions with a single blank line between function definitions.

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 a56c106

knst and others added 3 commits December 18, 2025 04:19
@PastaPastaPasta PastaPastaPasta merged commit 44a7a8c into dashpay:develop Dec 19, 2025
70 of 75 checks passed
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.

3 participants