fix(consensus): require multiplicity-correct MN payment matching after v24#7377
fix(consensus): require multiplicity-correct MN payment matching after v24#7377thepastaclaw wants to merge 2 commits into
Conversation
…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.
|
This pull request has conflicts, please rebase. |
✅ No Merge Conflicts DetectedThis PR currently has no conflicts with other open PRs. |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
The current |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
WalkthroughAdded Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant TransactionValidation as CMNPaymentsProcessor::IsTransactionValid
participant DeploymentState as Consensus::DEPLOYMENT_V24
participant MatchingHelper as FindUnmatchedMasternodePayment
participant Logger as LogPrintf
TransactionValidation->>DeploymentState: DeploymentActiveAfter(...)
DeploymentState-->>TransactionValidation: strict_match flag
TransactionValidation->>MatchingHelper: compare expected payouts vs txNew.vout
MatchingHelper-->>TransactionValidation: unmatched index or -1
alt unmatched payout
TransactionValidation->>Logger: log expected payout and failure
end
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
✅ Review complete (commit 4600b46) |
thepastaclaw
left a comment
There was a problem hiding this comment.
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.
|
Addressed the review suggestion in Local checks run: |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Code Review
The prior finding about registering src/test/masternode_payments_tests.cpp in test/util/data/non-backported.txt is fixed at line 67 by commit 4600b46. No new in-scope defects were introduced. The only remaining observation is a stylistic nit about squashing the one-line follow-up commit into its parent for a cleaner permanent history; split among the commit-history agents and not a defect.
💬 1 nitpick(s)
|
CI diagnosis for the current red The upstream dependency jobs did build the depends packages successfully, but their cache-save step could not write the cache: The later source jobs then fail on the missing exact cache key: So the PR branch is proper as-is; these failures are a GitHub Actions cache-permission/cache-availability issue for this fork run, not an issue in the masternode payment matching changes. I am leaving the branch untouched. |
|
@PastaPastaPasta @UdjinM6 this is ready for human Core review from the code side. I diagnosed the red source-build jobs: they fail before compiling Dash because the depends cache could not be saved/restored for the fork run, while the PR branch itself remains mergeable and the change has completed self-review/CodeRabbit. Leaving the branch untouched unless review finds an actual code issue. |
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_V24and pre-v24 validation keeps thelegacy behavior.
What was done?
existence-only mode or strict multiplicity-correct mode.
CMNPaymentsProcessor::IsTransactionValidto use strict matchingonly after
DEPLOYMENT_V24is active.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: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 instructionsthrough local Claude against
upstream/develop..HEAD; it returnedRecommendation: shipwith no significant findings.Breaking Changes
This is a consensus tightening after
DEPLOYMENT_V24: post-v24 blocks mustinclude a distinct coinbase output for each expected masternode payment output,
including duplicate expected outputs. Pre-v24 behavior is intentionally
unchanged.
Checklist: