Skip to content

fix: punish invalid dstx messages#7347

Open
thepastaclaw wants to merge 2 commits into
dashpay:developfrom
thepastaclaw:fix/dstx-unknown-mn-cost
Open

fix: punish invalid dstx messages#7347
thepastaclaw wants to merge 2 commits into
dashpay:developfrom
thepastaclaw:fix/dstx-unknown-mn-cost

Conversation

@thepastaclaw

Copy link
Copy Markdown

fix: punish invalid dstx messages

Issue being fixed or feature implemented

Invalid CoinJoin broadcast transaction (dstx) messages can return early from
validation without applying the same peer-accounting consequence used by other
invalid P2P messages.

This hardens DSTX handling by making invalid validation results contribute a low
misbehavior score while preserving benign early returns for duplicate or
otherwise non-error DSTX cases.

What was done?

  • Apply a low misbehavior score when DSTX validation returns an invalid/error
    result.
  • Preserve existing behavior for successful validation and benign early-return
    cases.
  • Add P2P test framework serialization for dstx messages.
  • Add a focused functional test covering invalid DSTX peer accounting.

How Has This Been Tested?

Tested on macOS arm64.

  • git diff --check
  • python3 -m py_compile test/functional/p2p_dstx.py test/functional/test_framework/messages.py
  • Configured with depends config.site, --without-gui, --disable-bench,
    and --disable-fuzz-binary
  • make -j8 src/dashd
  • test/functional/p2p_dstx.py --tmpdir=/tmp/dash_func_dstx
  • test/functional/p2p_dstx.py --tmpdir=/tmp/dash_func_dstx_2

Breaking Changes

None.

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

@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: efa87a00-18bb-495b-94b3-28fb5cb48490

📥 Commits

Reviewing files that changed from the base of the PR and between e4f814a and da0ea55.

📒 Files selected for processing (2)
  • src/net_processing.cpp
  • test/functional/p2p_dstx.py

Walkthrough

Adds CCoinJoinBroadcastTx/msg_dstx test wire types, adjusts DSTX validation so missing masternode is treated as non-invalid, updates ProcessMessage to punish peers when ValidateDSTX reports an invalid DSTX early-exit, and adds a P2P functional test (registered in the base suite) that verifies non-punishment for unknown-masternode DSTX and punishment for structurally invalid DSTX.

Sequence Diagram

sequenceDiagram
  participant Peer as P2P Peer
  participant ProcessMsg as PeerManagerImpl::ProcessMessage
  participant ValidateDSTX as ValidateDSTX
  participant Misbehave as Misbehaving
  Peer->>ProcessMsg: recv "dstx" message
  ProcessMsg->>ValidateDSTX: validate DSTX
  alt Missing masternode (no punishment)
    ValidateDSTX-->>ProcessMsg: bDoReturn=true, bRet=true
    ProcessMsg-->>Peer: ignore without penalty
  else Invalid DSTX (punish)
    ValidateDSTX-->>ProcessMsg: bDoReturn=true, bRet=false
    ProcessMsg->>Misbehave: Misbehaving(pfrom, 10, "invalid dstx")
    Misbehave-->>ProcessMsg: score recorded
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • UdjinM6
  • PastaPastaPasta
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'fix: punish invalid dstx messages' directly and clearly describes the main change: applying misbehavior scoring to invalid DSTX validation results, which is the core objective of the changeset.
Description check ✅ Passed The PR description is comprehensive and directly related to the changeset, explaining the issue being fixed, what was done, testing performed, and verification steps taken.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Infer (1.2.0)
src/net_processing.cpp

src/net_processing.cpp:6:10: error: 'net_processing.h' file not found with include; use "quotes" instead
6 | #include <net_processing.h>
| ^~~~~~~~~~~~~~~~~~
| "net_processing.h"
In file included from src/net_processing.cpp:6:
src/net_processing.h:9:10: error: 'net.h' file not found with include; use "quotes" instead
9 | #include <net.h>
| ^~~~~~~
| "net.h"
In file included from src/net_processing.cpp:6:
In file included from src/net_processing.h:9:
src/net.h:9:10: error: 'bip324.h' file not found with include; use "quotes" instead
9 | #include <bip324.h>
| ^~~~~~~~~~
| "bip324.h"
In file included from src/net_processing.cpp:6:
In file included from src/net_processing.h:9:
In file included from src/net.h:9:
src/bip324.h:12:10: error: 'crypto/chacha20.h' file not found with include; use "quotes" instead
12 | #include <crypto/chacha20.h>
|

... [truncated 2200 characters] ...

__CTrans.CTrans_funct.get_clang_stmt_trans in file "src/clang/cTrans.ml" (inlined), line 5395, characters 4-69
Called from ClangFrontend__CTrans.CTrans_funct.get_custom_stmt_trans in file "src/clang/cTrans.ml", line 5401, characters 8-55
Called from ClangFrontend__CTrans.CTrans_funct.exec_trans_instrs.exec_trans_instrs_rev in file "src/clang/cTrans.ml" (inlined), line 5365, characters 28-54
Called from ClangFrontend__CTrans.CTrans_funct.exec_trans_instrs in file "src/clang/cTrans.ml" (inlined), line 5389, characters 6-70
Called from ClangFrontend__CTrans.CTrans_funct.instructions_trans in file "src/clang/cTrans.ml", line 5451, characters 25-68
Called from ClangFrontend__CFrontend_decl.CFrontend_decl_funct.add_method.f in file "src/clang/cFrontend_decl.ml", line 48, characters 12-91
Called


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.

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

@thepastaclaw thepastaclaw marked this pull request as ready for review June 9, 2026 03:38
@thepastaclaw

thepastaclaw commented Jun 9, 2026

Copy link
Copy Markdown
Author

✅ Review complete (commit da0ea55)

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e4f814a849

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/net_processing.cpp
Comment on lines +4673 to +4674
if (!bRet) {
Misbehaving(pfrom.GetId(), 10, "invalid dstx");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid penalizing unverifiable DSTX relays

When this node is out of IBD but its active tip does not yet include the masternode that signed the DSTX, ValidateDSTX searches only the current tip and 23 ancestors and returns {false, true} from the “Can't find masternode” path. This new !bRet branch therefore increments the peer's misbehavior score for a DSTX that may be valid from the relaying peer's newer chain view, turning a local inability to verify into punishment; consider distinguishing unverifiable/unknown-masternode cases from structural or signature failures before calling Misbehaving.

Useful? React with 👍 / 👎.

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Code Review

The PR correctly applies a small misbehavior score (10) only on the invalid/error early-return paths of ValidateDSTX, leaving benign duplicate and mixing-rate-limited cases untouched. The new functional test exercises the unknown-masternode error path with a matching Python serializer for the dstx message. Two non-blocking observations: the !dmn path can rarely punish honest peers whose MN list is briefly stale, and only one of the three error paths is covered by the test.

🟡 1 suggestion(s) | 💬 1 nitpick(s)

1 additional finding(s) omitted (not in diff).

🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.

In `src/net_processing.cpp`:
- [SUGGESTION] src/net_processing.cpp:3584-3587: `!dmn` path can punish honest peers when local MN list is briefly stale
  This change routes all three `{false, true}` returns from ValidateDSTX through `Misbehaving(..., 10, "invalid dstx")`, including the `!dmn` branch at lines 3584-3587. The 24-block lookback at lines 3565-3582 already mitigates short staleness, but an honest relayer can still trip this case during reorgs, slow validation, or restart catch-up shortly after IBD when the receiving node's deterministic MN list is more than 24 blocks behind the broadcaster's registration. Score 10 keeps the impact bounded (discouragement threshold is 100), but a well-connected peer that forwards multiple valid DSTXes against a stale node could still accumulate score over time. Unlike `!IsValidStructure()` and bad-signature, which are unambiguous protocol violations, missing-MN can be a benign timing artifact. Consider treating `!dmn` like the `!IsValidForMixingTxes` branch (`{true, true}`), or gating the punishment with `m_mn_sync.IsBlockchainSynced()`, so only structural and signature failures are punished.

Comment thread test/functional/p2p_dstx.py
@thepastaclaw

Copy link
Copy Markdown
Author

Addressed the automated review feedback in da0ea55f6d: unknown-masternode DSTX relays are now treated as unverifiable/non-punishable, while structurally invalid DSTX still triggers the peer misbehavior path.

Validation:

  • make -C src -j8 dashd
  • test/functional/p2p_dstx.py --timeout-factor=2
  • automated-system review for da0ea55f6d: no significant issues, recommendation: ship

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

@thepastaclaw Thanks for the detailed update! The distinction between unverifiable (unknown masternode) and structurally invalid DSTX is a solid design choice — it avoids false positives while still hardening against malformed messages. Triggering a review of the latest changes now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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.

1 participant