Skip to content

fix(consensus): require multiplicity-correct MN payment matching after v24#7377

Open
thepastaclaw wants to merge 1 commit into
dashpay:developfrom
thepastaclaw:fix-v24-mn-payment-multiplicity
Open

fix(consensus): require multiplicity-correct MN payment matching after v24#7377
thepastaclaw wants to merge 1 commit into
dashpay:developfrom
thepastaclaw:fix-v24-mn-payment-multiplicity

Conversation

@thepastaclaw

Copy link
Copy Markdown

Issue being fixed or feature implemented

Masternode payment validation currently checks each expected coinbase output with
existence-only matching. If the expected masternode payments contain duplicate
CTxOuts, one actual coinbase output can satisfy multiple expected payments.

This matters after the v24 multi-payout reward-share changes because duplicate
expected outputs can be valid when multiple owner shares resolve to the same
amount and script. Since this tightens consensus validation, the stricter
matching is gated behind DEPLOYMENT_V24 and pre-v24 validation keeps the
legacy behavior.

What was done?

  • Added a masternode payment matching helper that can run in legacy
    existence-only mode or strict multiplicity-correct mode.
  • Switched CMNPaymentsProcessor::IsTransactionValid to use strict matching
    only after DEPLOYMENT_V24 is active.
  • Added focused unit tests covering duplicate expected payments, legacy
    behavior, empty expected payments, missing outputs, and exact amount matching.

How Has This Been Tested?

Ran locally on macOS in
/Users/claw/Projects/dash/worktrees/fix-v24-mn-payment-multiplicity:

./src/test/test_dash --run_test=masternode_payments_tests
./src/test/test_dash --run_test=governance_superblock_tests

Both passed.

Also ran the pre-PR review gate command with the explicit branch ref:

code-review dashpay/dash upstream/develop fix-v24-mn-payment-multiplicity "v24-gated multiplicity-correct masternode payment matching"

The wrapper built the correct 4-file diff, but the Codex reviewer backend failed
with 401 Unauthorized. As a fallback, I ran the same code-reviewer instructions
through local Claude against upstream/develop..HEAD; it returned
Recommendation: ship with no significant findings.

Breaking Changes

This is a consensus tightening after DEPLOYMENT_V24: post-v24 blocks must
include a distinct coinbase output for each expected masternode payment output,
including duplicate expected outputs. Pre-v24 behavior is intentionally
unchanged.

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 (for repository code-owners and collaborators only)

…r v24

CMNPaymentsProcessor::IsTransactionValid previously checked each expected masternode coinbase output with std::ranges::any_of, which made matching existence-only: a single actual output could satisfy multiple identical expected outputs. With multi-payout reward shares, expected outputs can legitimately include duplicates, so this mismatch is consensus-relevant.

Gate the stricter matching behind DEPLOYMENT_V24 to avoid tightening historical validation. After v24 activation, every expected output must be matched by a distinct actual output; pre-v24 retains the legacy existence-only behaviour.

Extract the matching into FindUnmatchedMasternodePayment so it can be unit-tested directly, and add focused regression coverage in masternode_payments_tests, including the duplicate-expected case that motivates the fix.
@github-actions

Copy link
Copy Markdown

This pull request has conflicts, please rebase.

@github-actions

Copy link
Copy Markdown

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

@thepastaclaw

Copy link
Copy Markdown
Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 25, 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.

@thepastaclaw

Copy link
Copy Markdown
Author

The current check_merge failure appears unrelated to this PR branch. The job fast-forwarded PR #7377 onto develop successfully:\n\ntext\nUpdating 8c9f166a3..93be20423\nFast-forward\n\n\nIt failed afterward while checking whether develop can fast-forward into master:\n\ntext\ngit checkout master\ngit merge --ff-only base_branch\nfatal: Not possible to fast-forward, aborting.\n\n\nSo the branch itself is mergeable into develop; this looks like the current repo-level developmaster relationship, not a conflict introduced by this PR.

@coderabbitai

coderabbitai Bot commented Jun 25, 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: b693deb2-0cd9-43cb-acbf-e4688bab60fc

📥 Commits

Reviewing files that changed from the base of the PR and between 8c9f166 and 93be204.

📒 Files selected for processing (4)
  • src/Makefile.test.include
  • src/masternode/payments.cpp
  • src/masternode/payments.h
  • src/test/masternode_payments_tests.cpp

Walkthrough

Added FindUnmatchedMasternodePayment to compare expected and actual masternode payout outputs with optional strict multiplicity. CMNPaymentsProcessor::IsTransactionValid now uses strict matching after Consensus::DEPLOYMENT_V24 activation and logs the unmatched payout on failure. Added a unit test file and included it in BITCOIN_TESTS.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • dashpay/dash#7362: Threads is_v24 into superblock validation and applies distinct-output checking for duplicate payments, which matches the V24-gated matching change here.

Suggested reviewers

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

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% 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 title accurately summarizes the consensus change to require multiplicity-correct masternode payment matching after v24.
Description check ✅ Passed The description matches the implemented changes, including the new helper, v24-gated strict matching, and added tests.
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

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.

@thepastaclaw thepastaclaw marked this pull request as ready for review June 25, 2026 22:20
@thepastaclaw

thepastaclaw commented Jun 25, 2026

Copy link
Copy Markdown
Author

✅ Review complete (commit 93be204)

@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

Verified one non-blocking in-scope issue: the PR adds a Dash-specific unit test but does not register it in the Dash-only non-backported file list used by local lint gates. Coverage was degraded because the required ACP Claude/Codex reviewer sessions failed authentication; this review is based on native Codex reviewer outputs plus direct source inspection.

🟡 1 suggestion(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 `test/util/data/non-backported.txt`:
- [SUGGESTION] test/util/data/non-backported.txt:68: Register the new masternode payment test for Dash-only linting
  This PR adds `src/test/masternode_payments_tests.cpp`, but none of the existing patterns in `test/util/data/non-backported.txt` match that file. Both `.github/workflows/clang-diff-format.yml` and `test/lint/lint-cppcheck-dash.py` build their Dash-specific file lists from this data file, so the new test is skipped by those Dash-only format/cppcheck gates unless it is listed here.

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