fix(net): bound quorum data response vectors - #7416
Conversation
|
Caution Review failedThe pull request is closed. Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📥 CommitsReviewing files that changed from the base of the PR and between ecf49885bcbb40fd09bd81de95edf54d3996e2fe and a286e0e. 📒 Files selected for processing (2)
WalkthroughQDATA processing now bounds verification-vector and encrypted-contribution deserialization using quorum-derived expected counts, rejects mismatches, and marks the peer misbehaving. Functional tests isolate malformed-payload cases, cover invalid vector and contribution lengths, and craft inconsistent CompactSize declarations for both sections. Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Peer
participant NetQuorum
participant QuorumState
Peer->>NetQuorum: Send malformed QDATA
NetQuorum->>QuorumState: Read expected vector counts
NetQuorum->>NetQuorum: Decode and validate sections
NetQuorum->>Peer: Apply misbehavior score and disconnect
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 a286e0e) |
✅ No Merge Conflicts DetectedThis PR currently has no conflicts with other open PRs. |
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
Source: reviewers claude/general=opus(failed), codex/general=gpt-5.5(completed), claude/dash-core-commit-history=opus(failed), codex/dash-core-commit-history=gpt-5.5(completed); verifier=gpt-5.5
The PR matches its stated goal of rejecting quorum-data vectors with unexpected element counts before deserialization work continues. I verified one in-scope portability regression in the new helper: the braced initialization from ReadCompactSize() is ill-formed on 32-bit size_t builds, and this repository still defines i686 depends hosts.
Verified Findings
- [BLOCKING]
src/llmq/net_quorum.cpp:34: Fix narrowing initialization on 32-bit builds
ReadCompactSize() returns uint64_t, but this new helper list-initializes a size_t from that value. On targets where size_t is 32-bit, list initialization rejects the uint64_t-to-size_t conversion as narrowing at compile time, so this breaks supported i686-style builds even though ReadCompactSize() range-checks vector sizes against MAX_SIZE. Use an explicit cast after the range-checked read.
Note: posted as a COMMENT review because GitHub does not allow approving/requesting changes on my own PR via the normal review event.
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
Addressed the self-review finding about 32-bit Commit: Validation:
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Code Review
Source: reviewers claude/general=opus(failed), codex/general=gpt-5.5, claude/dash-core-commit-history=opus(failed), codex/dash-core-commit-history=gpt-5.5; verifier=gpt-5.5
Prior findings: prior-1 is fixed; src/llmq/net_quorum.cpp:34 now explicitly casts the ReadCompactSize() result to size_t, removing the 32-bit narrowing build failure. New findings in latest delta: one commit-history hygiene issue remains because the latest commit is a one-line fixup for code introduced by the previous PR commit.
Prior Finding Reconciliation
- FIXED: Fix narrowing initialization on 32-bit builds — Fixed in commit 9df78f0c6a4;
ReadCompactSize(stream)is now wrapped instatic_cast<size_t>()before initialization atsrc/llmq/net_quorum.cpp:34.
Carried-Forward Prior Findings
None.
New Findings In Latest Delta
- [SUGGESTION]
<commit:9df78f0c6a4>: Squash the one-line corrective commit
Commit 9df78f0c6a4 only changes the helper introduced by d452f3db84c from the narrowingsize_tinitialization to the corrected explicit cast. This is a review-fix commit for the same logical change, and Dash PR commits land in permanent history without squash merging, so leaving it separate records an intermediate unshipped version ingit logandgit blame. Squash 9df78f0c6a4 into d452f3db84c so the QDATA hardening lands as one corrected logical commit.
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 `<commit:9df78f0c6a4>`:
- [SUGGESTION] <commit:9df78f0c6a4>:1: Squash the one-line corrective commit
Commit 9df78f0c6a4 only changes the helper introduced by d452f3db84c from the narrowing `size_t` initialization to the corrected explicit cast. This is a review-fix commit for the same logical change, and Dash PR commits land in permanent history without squash merging, so leaving it separate records an intermediate unshipped version in `git log` and `git blame`. Squash 9df78f0c6a4 into d452f3db84c so the QDATA hardening lands as one corrected logical commit.
9df78f0 to
4157ce5
Compare
|
@coderabbitai review |
|
Squashed the one-line corrective commit into the original QDATA vector-bound commit. The new head is Validation after rewrite:
|
✅ Action performedReview finished.
|
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
Source: reviewers claude/general=opus(failed), codex/general=gpt-5.5(completed), claude/dash-core-commit-history=opus(failed), codex/dash-core-commit-history=gpt-5.5(completed); verifier=gpt-5.5
Prior reconciliation: prior-commit-history-1 is FIXED because the current stack at 4157ce53e6ae2b41ced3d1217bca0a0970d151d2 contains one non-merge commit, fix: bound quorum data response vectors, and the separate one-line corrective commit is no longer in the current branch history. Carried-forward prior findings: none. New findings in latest delta 9df78f0c6a477bd9a3d92fbd3e07e79c39d72537..4157ce53e6ae2b41ced3d1217bca0a0970d151d2: none; the tree delta is empty, and the cumulative PR diff's exact-size QDATA checks match the sender-side quorum vector shapes.
GitHub does not allow PastaClaw to approve their own PR, so this is posted as a COMMENT review rather than an APPROVE review.
Prior Reconciliation:
- FIXED: Squash the one-line corrective commit — Fixed in the new head: the current PR stack is a single non-merge commit, and the prior corrective commit
9df78f0c6a4 fix: avoid qdata vector size narrowingis not present in the current branch history.
Carried-forward prior findings: None.
New findings in latest delta:
None.
|
CI failure triage for the old This PR's current head is |
PastaPastaPasta
left a comment
There was a problem hiding this comment.
utACK 4157ce53e6ae2b41ced3d1217bca0a0970d151d2
UdjinM6
left a comment
There was a problem hiding this comment.
utACK 4157ce53e6ae2b41ced3d1217bca0a0970d151d2
knst
left a comment
There was a problem hiding this comment.
over-complicated ; see clarification below
c64ac8c
4157ce5 to
c64ac8c
Compare
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@kwvg Yes—the defensive effect does not depend on accepting a payload larger than The peer controls the CompactSize element count independently of the bytes that follow it. A small QDATA payload can therefore declare, for example, 1,000 BLS elements and omit the elements. With ordinary vector deserialization, the receiver starts element decoding and reaches a stream-underrun exception; that exception is logged by the outer message loop and does not reach the QDATA score-100 path. With the bounded helper, the declared count is compared with the known quorum threshold/member count first, so it is rejected and scored before any element decode. The amended head |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a286e0e7eb
ℹ️ 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".
|
@coderabbitai review Follow-up status: #7416 merged at a286e0e before the corrected branch head f2e577a was pushed. The fix is preserved on the source branch but is not in merge commit 5260466 and needs a separate follow-up. |
✅ Action performedReview finished.
|
🧩 Analysis chain🏁 Script executed: #!/bin/bash
gh pr view 7416 --repo dashpay/dash --json state,mergeCommit,mergedAt,baseRefName,headRefName,commits --jq '{state, mergeCommit, mergedAt, baseRefName, headRefName}'
echo "---"
gh api repos/dashpay/dash/pulls/7416/commits --jq '.[].sha' | tail -5
echo "---merge commit parents---"
gh api repos/dashpay/dash/commits/52604668ed7 --jq '.parents[].sha' 2>/dev/null || echo "not found"Length of output: 882
Since the merge already happened, there's nothing further for me to review on this closed PR. If you'd like, I can open a follow-up GitHub issue on ✅ Action performedReview finished.
|
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
Source: orchestrator openai/gpt-5.6-sol/high (orchestration-only); reviewers codex/general=gpt-5.6-sol, sonnet5/general=claude-sonnet-5, codex/dash-core-commit-history=gpt-5.6-sol, sonnet5/dash-core-commit-history=claude-sonnet-5; verifier=claude-sonnet-5 (verifier-sonnet5-7416-1783709714).
PR #7416 at head a286e0e introduces pre-decode bounds checks for the two QDATA vectors, but the intended full-ban protection is bypassed for wire counts above MAX_SIZE. The carried-forward prior finding is STILL VALID: it was fixed at unpublished checkpoint 50e177d9 and then reverted along with its boundary coverage. No distinct new latest-delta or additional cumulative findings were identified; commit-history hygiene is clean.
🔴 1 blocking
🤖 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/llmq/net_quorum.cpp`:
- [BLOCKING] src/llmq/net_quorum.cpp:205-295: Oversized QDATA vector counts throw past the intended full-ban path at both call sites
At current head, UnserializeVectorWithMaxSize (src/serialize.h:978-988) calls ReadCompactSize(s) with default range_check=true. Counts above MAX_SIZE throw before either QDATA expected-size check and its PeerMisbehaving(..., 100) full-ban branch. The exception reaches src/net_processing.cpp:5752, whose catch only logs it, leaving the authenticated peer connected even though ValidateDataResponse already consumed the request. Both data-mask fields are affected. The unpublished 50e177d9 checkpoint fixed this with range_check=false and a full-width comparison, but a286e0e7 removes that fix and weakens the MAX_SIZE+1 functional cases to count 1000, so the bypass is again untested. Impact is MNAuth-gated and element decoding remains bounded, but the PR's documented full-ban policy is bypassed.
af6a0fd feat(serialize): add bounded-vector deserialization primitives (PastaClaw) Pull request description: ## Issue being fixed or feature implemented Network messages often have protocol-specific vector limits below the generic serialization limit. Callers need to enforce those limits before vector allocation and element decoding, without changing the wire format. ## What was done? - Factor the existing batched vector element decoder into a shared internal helper. - Add `UnserializeVectorWithMaxSize` for runtime bounds. - Add `LIMITED_VECTOR` / `LimitedVectorFormatter` for compile-time bounds in `READWRITE` declarations. - Keep serialization byte-for-byte compatible with ordinary vectors; only deserialization is bounded. - Compare CompactSize counts before narrowing or allocating, including counts at and above `MAX_SIZE`. ## Stacked adopters Each consumer remains a separate command-specific PR: - dashpay#7416 — quorum-data response vectors - dashpay#7418 — LLMQ signing message vectors - dashpay#7419 — CoinJoin message vectors - dashpay#7438 — SPORK signature vector Reviewing dashpay#7439 first leaves each child PR with only its protocol-specific policy, punishment, and regression tests. ## How Has This Been Tested? - `src/test/test_dash --run_test=serialize_tests` - Exact and over-limit boundaries, zero limits, custom element formatters, `MAX_SIZE` and `MAX_SIZE + 1` declarations, 64-bit CompactSize counts, wire compatibility, and rejection before element decode are covered. ## Breaking Changes None. Existing vector serialization and deserialization behavior is unchanged. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] 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 Top commit has no ACKs. Tree-SHA512: 61e4183a5a2a173254f3105d30969704c2c53dac3ce421f0b3e8e989bc87ec1a94d2757944694db219802403a668d7460943d507ab7948db30b97145d57f26d6
a286e0e fix: bound quorum data response vectors (PastaClaw) Pull request description: Depends on dashpay#7439. Please review only the final command-specific commit here. ## Issue being fixed or feature implemented Quorum-data responses carry verification-vector and encrypted-contribution vectors whose expected sizes are known from the requested quorum. This hardens QDATA processing by checking the serialized vector count before allocating, deserializing, or processing those vectors. This path is MNAuth/request-gated and is intentionally handled separately from unauthenticated public vector intake. ## What was done? - Read QDATA verification vectors with the requested quorum threshold as the maximum. - Read encrypted contributions with the number of valid quorum members as the maximum. - Require exact semantic counts and penalize mismatches before decrypt/aggregate work. - Extend functional coverage for undersized, oversized, and allocation-amplifying CompactSize declarations. The reusable bounded-vector serialization primitives are introduced separately in dashpay#7439. ## How Has This Been Tested? - `test/functional/p2p_quorum_data.py` ## Breaking Changes None. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] 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) ACKs for top commit: kwvg: Code near identical to past utACK (see [diff](https://github.com/dashpay/dash/compare/ecf49885bcbb40fd09bd81de95edf54d3996e2fe..a286e0e7eb4fd63eb65f05f5deefd5a2c4c43f55)) --- utACK a286e0e Tree-SHA512: 1d217cff7096f0dbad736e98be91e6b4eac154ae7ca0512cb3200f448b3152485d89f3f13a5d36617d7e4122aac2ed521f79ccd6ca787c0e8fafb200cb3cf118
af6a0fd feat(serialize): add bounded-vector deserialization primitives (PastaClaw) Pull request description: ## Issue being fixed or feature implemented Network messages often have protocol-specific vector limits below the generic serialization limit. Callers need to enforce those limits before vector allocation and element decoding, without changing the wire format. ## What was done? - Factor the existing batched vector element decoder into a shared internal helper. - Add `UnserializeVectorWithMaxSize` for runtime bounds. - Add `LIMITED_VECTOR` / `LimitedVectorFormatter` for compile-time bounds in `READWRITE` declarations. - Keep serialization byte-for-byte compatible with ordinary vectors; only deserialization is bounded. - Compare CompactSize counts before narrowing or allocating, including counts at and above `MAX_SIZE`. ## Stacked adopters Each consumer remains a separate command-specific PR: - dashpay#7416 — quorum-data response vectors - dashpay#7418 — LLMQ signing message vectors - dashpay#7419 — CoinJoin message vectors - dashpay#7438 — SPORK signature vector Reviewing dashpay#7439 first leaves each child PR with only its protocol-specific policy, punishment, and regression tests. ## How Has This Been Tested? - `src/test/test_dash --run_test=serialize_tests` - Exact and over-limit boundaries, zero limits, custom element formatters, `MAX_SIZE` and `MAX_SIZE + 1` declarations, 64-bit CompactSize counts, wire compatibility, and rejection before element decode are covered. ## Breaking Changes None. Existing vector serialization and deserialization behavior is unchanged. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] 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 Top commit has no ACKs. Tree-SHA512: 61e4183a5a2a173254f3105d30969704c2c53dac3ce421f0b3e8e989bc87ec1a94d2757944694db219802403a668d7460943d507ab7948db30b97145d57f26d6
a286e0e fix: bound quorum data response vectors (PastaClaw) Pull request description: Depends on dashpay#7439. Please review only the final command-specific commit here. ## Issue being fixed or feature implemented Quorum-data responses carry verification-vector and encrypted-contribution vectors whose expected sizes are known from the requested quorum. This hardens QDATA processing by checking the serialized vector count before allocating, deserializing, or processing those vectors. This path is MNAuth/request-gated and is intentionally handled separately from unauthenticated public vector intake. ## What was done? - Read QDATA verification vectors with the requested quorum threshold as the maximum. - Read encrypted contributions with the number of valid quorum members as the maximum. - Require exact semantic counts and penalize mismatches before decrypt/aggregate work. - Extend functional coverage for undersized, oversized, and allocation-amplifying CompactSize declarations. The reusable bounded-vector serialization primitives are introduced separately in dashpay#7439. ## How Has This Been Tested? - `test/functional/p2p_quorum_data.py` ## Breaking Changes None. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] 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) ACKs for top commit: kwvg: Code near identical to past utACK (see [diff](https://github.com/dashpay/dash/compare/ecf49885bcbb40fd09bd81de95edf54d3996e2fe..a286e0e7eb4fd63eb65f05f5deefd5a2c4c43f55)) --- utACK a286e0e Tree-SHA512: 1d217cff7096f0dbad736e98be91e6b4eac154ae7ca0512cb3200f448b3152485d89f3f13a5d36617d7e4122aac2ed521f79ccd6ca787c0e8fafb200cb3cf118
…lization 8f0b813 fix(governance): bound vote signature deserialization (PastaClaw) Pull request description: Uses the shared bounded-vector deserialization primitive merged in dashpay#7439. ## Motivation Governance vote signatures were deserialized through the generic byte-vector path. A peer could declare a very large signature length, causing allocation before the stream reported truncation. The outer message-processing catch did not score or disconnect the peer, allowing repeated malformed messages. ## Changes - bound network governance-vote signature reads to 96 bytes before allocation - require one of the two structurally valid encodings: 65-byte compact ECDSA or 96-byte BLS - score malformed or truncated governance vote messages with 100 misbehavior points - preserve disk, hash, and outbound serialization behavior - add focused unit coverage ## Testing - `./src/test/test_dash --run_test=governance_vote_wire_tests` (4/4 tests) - `./src/test/test_dash --run_test=serialize_tests` (10/10 tests) - `test/lint/lint-python.py` Tree-SHA512: backported to v23.1.x by cherry-picking 8f0b813 (applies cleanly). Backport note for v23.1.8 ------------------------- This was missing from the original v23.1.8 branch while its test follow-up dashpay#7450 ("test: make governance vote fixtures wire-valid", 915566d) was already included. That ordering was inverted: dashpay#7450 exists solely to adapt the dashpay#7442 governance-inv fixtures to the bound that dashpay#7440 introduces. Verified by removing dashpay#7450's SetSignature() line and rebuilding: without dashpay#7440 present the fixtures pass regardless, and re-adding dashpay#7440 reproduces exactly the six governance_inv_tests failures dashpay#7450's description cites. So the branch was shipping the compensating test change for a hardening fix it did not have, leaving CGovernanceVote::vchSig unbounded on the network path. The prerequisite dashpay#7439 (LIMITED_VECTOR) is already present via 099b99d, as are the sibling bounding backports dashpay#7416/dashpay#7418/dashpay#7419/dashpay#7438/dashpay#7444, so this restores the intended set rather than widening release scope. Reported-by: UdjinM6 Co-Authored-By: Claude <noreply@anthropic.com>
af6a0fd feat(serialize): add bounded-vector deserialization primitives (PastaClaw) Pull request description: ## Issue being fixed or feature implemented Network messages often have protocol-specific vector limits below the generic serialization limit. Callers need to enforce those limits before vector allocation and element decoding, without changing the wire format. ## What was done? - Factor the existing batched vector element decoder into a shared internal helper. - Add `UnserializeVectorWithMaxSize` for runtime bounds. - Add `LIMITED_VECTOR` / `LimitedVectorFormatter` for compile-time bounds in `READWRITE` declarations. - Keep serialization byte-for-byte compatible with ordinary vectors; only deserialization is bounded. - Compare CompactSize counts before narrowing or allocating, including counts at and above `MAX_SIZE`. ## Stacked adopters Each consumer remains a separate command-specific PR: - dashpay#7416 — quorum-data response vectors - dashpay#7418 — LLMQ signing message vectors - dashpay#7419 — CoinJoin message vectors - dashpay#7438 — SPORK signature vector Reviewing dashpay#7439 first leaves each child PR with only its protocol-specific policy, punishment, and regression tests. ## How Has This Been Tested? - `src/test/test_dash --run_test=serialize_tests` - Exact and over-limit boundaries, zero limits, custom element formatters, `MAX_SIZE` and `MAX_SIZE + 1` declarations, 64-bit CompactSize counts, wire compatibility, and rejection before element decode are covered. ## Breaking Changes None. Existing vector serialization and deserialization behavior is unchanged. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] 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 Top commit has no ACKs. Tree-SHA512: 61e4183a5a2a173254f3105d30969704c2c53dac3ce421f0b3e8e989bc87ec1a94d2757944694db219802403a668d7460943d507ab7948db30b97145d57f26d6 (cherry picked from commit 9474fc5)
Backport of dashpay#7416 (upstream merge 5260466, cherry-picked with -m1). v23.1.x adaptations: develop's QDATA handling lives in src/llmq/net_quorum.cpp, which does not exist on this branch. The verification-vector bound is applied to the identical code in CQuorumManager::ProcessMessage (src/llmq/quorumsman.cpp) and the encrypted-contributions bound to QuorumParticipant::ProcessContribQDATA (src/active/quorums.cpp). Both report the violation as 'return MisbehavingError{100, ...}' through this branch's MessageProcessingResult flow instead of develop's m_peer_manager->PeerMisbehaving(...), matching the surrounding error handling. The functional test change applied cleanly and is unchanged from upstream. (cherry picked from commit 52604668ed7965936a0e9af9e2ab21b04ecfe087)
af6a0fd feat(serialize): add bounded-vector deserialization primitives (PastaClaw) Pull request description: ## Issue being fixed or feature implemented Network messages often have protocol-specific vector limits below the generic serialization limit. Callers need to enforce those limits before vector allocation and element decoding, without changing the wire format. ## What was done? - Factor the existing batched vector element decoder into a shared internal helper. - Add `UnserializeVectorWithMaxSize` for runtime bounds. - Add `LIMITED_VECTOR` / `LimitedVectorFormatter` for compile-time bounds in `READWRITE` declarations. - Keep serialization byte-for-byte compatible with ordinary vectors; only deserialization is bounded. - Compare CompactSize counts before narrowing or allocating, including counts at and above `MAX_SIZE`. ## Stacked adopters Each consumer remains a separate command-specific PR: - dashpay#7416 — quorum-data response vectors - dashpay#7418 — LLMQ signing message vectors - dashpay#7419 — CoinJoin message vectors - dashpay#7438 — SPORK signature vector Reviewing dashpay#7439 first leaves each child PR with only its protocol-specific policy, punishment, and regression tests. ## How Has This Been Tested? - `src/test/test_dash --run_test=serialize_tests` - Exact and over-limit boundaries, zero limits, custom element formatters, `MAX_SIZE` and `MAX_SIZE + 1` declarations, 64-bit CompactSize counts, wire compatibility, and rejection before element decode are covered. ## Breaking Changes None. Existing vector serialization and deserialization behavior is unchanged. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] 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 Top commit has no ACKs. Tree-SHA512: 61e4183a5a2a173254f3105d30969704c2c53dac3ce421f0b3e8e989bc87ec1a94d2757944694db219802403a668d7460943d507ab7948db30b97145d57f26d6 (cherry picked from commit 9474fc5)
Backport of dashpay#7416 (upstream merge 5260466, cherry-picked with -m1). v23.1.x adaptations: develop's QDATA handling lives in src/llmq/net_quorum.cpp, which does not exist on this branch. The verification-vector bound is applied to the identical code in CQuorumManager::ProcessMessage (src/llmq/quorumsman.cpp) and the encrypted-contributions bound to QuorumParticipant::ProcessContribQDATA (src/active/quorums.cpp). Both report the violation as 'return MisbehavingError{100, ...}' through this branch's MessageProcessingResult flow instead of develop's m_peer_manager->PeerMisbehaving(...), matching the surrounding error handling. The functional test change applied cleanly and is unchanged from upstream. (cherry picked from commit 52604668ed7965936a0e9af9e2ab21b04ecfe087)
Backport of dashpay#7416 (upstream merge 5260466, cherry-picked with -m1). v23.1.x adaptations: develop's QDATA handling lives in src/llmq/net_quorum.cpp, which does not exist on this branch. The verification-vector bound is applied to the identical code in CQuorumManager::ProcessMessage (src/llmq/quorumsman.cpp) and the encrypted-contributions bound to QuorumParticipant::ProcessContribQDATA (src/active/quorums.cpp). Both report the violation as 'return MisbehavingError{100, ...}' through this branch's MessageProcessingResult flow instead of develop's m_peer_manager->PeerMisbehaving(...), matching the surrounding error handling. The functional test change applied cleanly and is unchanged from upstream. (cherry picked from commit 52604668ed7965936a0e9af9e2ab21b04ecfe087)
af6a0fd feat(serialize): add bounded-vector deserialization primitives (PastaClaw) Pull request description: ## Issue being fixed or feature implemented Network messages often have protocol-specific vector limits below the generic serialization limit. Callers need to enforce those limits before vector allocation and element decoding, without changing the wire format. ## What was done? - Factor the existing batched vector element decoder into a shared internal helper. - Add `UnserializeVectorWithMaxSize` for runtime bounds. - Add `LIMITED_VECTOR` / `LimitedVectorFormatter` for compile-time bounds in `READWRITE` declarations. - Keep serialization byte-for-byte compatible with ordinary vectors; only deserialization is bounded. - Compare CompactSize counts before narrowing or allocating, including counts at and above `MAX_SIZE`. ## Stacked adopters Each consumer remains a separate command-specific PR: - dashpay#7416 — quorum-data response vectors - dashpay#7418 — LLMQ signing message vectors - dashpay#7419 — CoinJoin message vectors - dashpay#7438 — SPORK signature vector Reviewing dashpay#7439 first leaves each child PR with only its protocol-specific policy, punishment, and regression tests. ## How Has This Been Tested? - `src/test/test_dash --run_test=serialize_tests` - Exact and over-limit boundaries, zero limits, custom element formatters, `MAX_SIZE` and `MAX_SIZE + 1` declarations, 64-bit CompactSize counts, wire compatibility, and rejection before element decode are covered. ## Breaking Changes None. Existing vector serialization and deserialization behavior is unchanged. ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] 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 Top commit has no ACKs. Tree-SHA512: 61e4183a5a2a173254f3105d30969704c2c53dac3ce421f0b3e8e989bc87ec1a94d2757944694db219802403a668d7460943d507ab7948db30b97145d57f26d6 (cherry picked from commit 9474fc5)
Backport of dashpay#7416 (upstream merge 5260466, cherry-picked with -m1). v23.1.x adaptations: develop's QDATA handling lives in src/llmq/net_quorum.cpp, which does not exist on this branch. The verification-vector bound is applied to the identical code in CQuorumManager::ProcessMessage (src/llmq/quorumsman.cpp) and the encrypted-contributions bound to QuorumParticipant::ProcessContribQDATA (src/active/quorums.cpp). Both report the violation as 'return MisbehavingError{100, ...}' through this branch's MessageProcessingResult flow instead of develop's m_peer_manager->PeerMisbehaving(...), matching the surrounding error handling. The functional test change applied cleanly and is unchanged from upstream. (cherry picked from commit 52604668ed7965936a0e9af9e2ab21b04ecfe087)
24920a0 chore: prepare v23.1.8 release (pasta) 2194248 Merge #7348: fix: penalize oversized notfound messages (pasta) f5c72c3 Merge #7347: fix: punish invalid dstx messages (pasta) 550caf7 Merge #7465: fix(qt): handle pixel-sized fonts when scaling widgets (pasta) e203710 Merge #7419: fix(net): bound CoinJoin message vector intake (pasta) 5f5b960 Merge #7418: fix(net): bound signing message vector intake (Pasta) 7cc2cca Merge #7450: test: make governance vote fixtures wire-valid (Pasta) f011c80 Merge #7440: fix(net): bound governance vote signature deserialization (Pasta) 4b4d96a Merge #7442: fix(net): authorize governance inv responses via the net-layer per-peer request tracker (Pasta) f855b13 Merge #7444: fix(net): bound bloom message vectors before allocation (Pasta) 5b5c6fb Merge #7415: fix: bound pending sig share queue (Pasta) 9bbe808 Merge #7416: fix(net): bound quorum data response vectors (Pasta) da42f50 Merge #7424: fix: bound ChainLock seen cache (Pasta) 5b310df Merge #7438: fix: bound SPORK signature deserialization (Pasta) e118d0c Merge #7259: fix: dangling point to cj client (Pasta) 9921621 Merge #7439: refactor: add bounded vector deserialization (Pasta) 89bdf7c Merge #7414: fix(net): throttle per-object governance vote sync requests (Pasta) 44c396d Merge #7402: fix: bound pending recovered sig queue to prevent remote OOM (Pasta) 05cfe27 Merge #7351: fix: limit signing share sessions per peer (pasta) 3ef3a5b Merge #7408: fix: bound DKG contribution blob intake (pasta) 0ea6532 Merge #7387: test: migrate governance inv cache coverage to unit tests (Pasta) 8ffdf7f Merge #7398: backport: compact block relay hardening (bitcoin#26898, bitcoin#27626, bitcoin#27743, bitcoin#26969, bitcoin#29412, bitcoin#32646, bitcoin#33296) (Pasta) 2915142 backport: bitcoin#27608 - p2p: Avoid prematurely clearing download state for other peers (PastaClaw) 90b5473 Merge #7396: fix: run of circular-dependencies with python3.15 (Pasta) b003cdc Merge #7395: ci: update GitHub Actions pins for Node 24 (pasta) 97c3dd1 Merge #7394: fix: stabilize par help text in manpages (pasta) 8f8616b Merge #7372: backport: bitcoin#32693: depends: fix cmake compatibility error for freetype (pasta) 48f72be Merge #7360: fix: empty platformP2PPort deprecated field in protx listdiff results (pasta) a8cccff Merge #7298: fix(qt): keep PoSe score visible when hiding banned masternodes (pasta) Pull request description: Release PR for Dash Core v23.1.8, a patch release on top of v23.1.7. Fast-forwards from `v23.1.x` (currently at `chore: prepare v23.1.7 release`), 29 commits, no merge commits, no conflicts. ## Contents Backports of PRs already reviewed and merged on `develop`: `#7259` `#7347` `#7348` `#7351` `#7298` `#7360` `#7372` `#7387` `#7394` `#7395` `#7396` `#7398` `#7402` `#7408` `#7414` `#7415` `#7416` `#7418` `#7419` `#7424` `#7438` `#7439` `#7440` `#7442` `#7444` `#7450` `#7465` Plus `backport: bitcoin#27608`, a single commit taken from Dash #7237 because #7398's compact-block hardening depends on it. The rest of that v0.26 batch is intentionally not included on v23.1.x. The commit is byte-identical to its reviewed counterpart inside #7237. And release preparation: version bump, regenerated man pages, release notes, archived 23.1.7 notes. ## Note for reviewers: this branch was rebuilt An earlier revision of this PR was discarded and the branch rebuilt from scratch. Review comments on the previous revision point at commits that no longer exist, though the feedback itself was carried over (see below). The reason: several commits titled `Merge #NNNN` in the earlier revision contained substantial code that exists nowhere upstream — apparently written from a description of each PR rather than ported from its diff. For example, `feature_llmq_simplepose.py` is byte-identical between v23.1.7 and `develop`, yet the earlier `Merge #7408` rewrote 66 lines of it; `test/functional/p2p_governance_invs.py` does not exist on `develop` at all, yet had grown from 62 to 148 lines. That mislabeling matters because a commit titled `Merge #NNNN` invites less scrutiny, not more. It also had consequences: the earlier revision was **missing #7440 entirely**, and contained eleven consecutive commits that did not compile (code written against newer upstream APIs this branch does not have — `Misbehaving(Peer&)`, and `PeerIsBanned` used five commits before it was declared). Every commit on this branch has now been diffed against its upstream merge commit. Where a backport differs, it is because v23.1.x predates an upstream refactor and the change had to be applied to the pre-refactor file — for example #7418 and #7438 patch `signing_shares.cpp` / `spork.cpp` where upstream patches `net_signing.cpp` / `net_processing.cpp`. ## Dropped from this branch - **#7350** (`net: don't lock cs_main while reading blocks`) — dropped on review feedback. It is a 110-line lock-structure refactor of `ProcessGetBlockData` with no measured benefit, and it would add avoidable churn to the eventual master→develop merge-back. Nothing on this branch depends on it: #7398's compact-block work precedes it, and the remaining 14 commits replay with zero conflicts once it is removed. Thanks @knst. ## Added after the initial review pass - **#7351** (`fix: limit signing share sessions per peer`) — cherry-picked as a single commit and placed before #7402, matching upstream's merge order. The include block additionally carries `<ranges>`: upstream's diff adds only `<algorithm>` because develop already had it, whereas v23.1.x did not and the backported `GetSessionCount()` / `GetAnnouncementSessionCount()` use `std::ranges::count_if`. - **#7465** (`fix(qt): handle pixel-sized fonts when scaling widgets`) — cherry-picked from the five upstream commits. `optiontests.cpp` additionally includes `qt/guiutil_font.h`, because `fontsLoaded()` and `updateFonts()` are declared there on v23.1.x while develop declares them in `qt/guiutil.h`, which is all the upstream test includes. Two further backports were added later and applied without any adaptation -- their diffs are byte-for-byte identical to upstream: - **#7347** (`fix: punish invalid dstx messages`) - **#7348** (`fix: penalize oversized notfound messages`) ## Adaptations worth flagging - **#7360** — upstream gates `platformP2PPort` / `platformHTTPPort` in `protx listdiff` behind `IsServiceDeprecatedRPCEnabled()`. On 23.x those deprecated fields are deliberately not enforced through gating (see `bbcd9d543e6`), so shipping the gate as-is would silently drop two fields that v23.1.7 always returned. Changed to `if (true)` with a comment, per review feedback, keeping the block aligned with `develop`. The substantive fix from #7360 — reading the live port from `netInfo` instead of the always-zero scalar — is retained. - **#7415** — the pending-map caps (`MAX_PENDING_SIG_SHARES_PER_NODE`, `MAX_PENDING_SIG_SHARES_TOTAL`) are backported. The additional bound upstream places on batches awaiting verification is not, because it guards a condition that does not exist here: upstream's dispatcher pushes one task per batch inside an inner loop, whereas v23.1.x pushes a single looping worker per 10 ms tick. There is no unbounded task queue to bound. - **Man pages** — regenerated without the `lock` debug category, which only exists under `DEBUG_LOCKCONTENTION` and so is absent from release binaries. Thanks @UdjinM6 for catching this. ## Known CI failure macOS jobs are expected to fail. `actions/upload-artifact@v6` rejects filenames containing `:`, and the Xcode SDK ships Perl man pages with `::` in the name. A release-branch-only workaround existed on the earlier revision but was dropped as it corresponds to no upstream PR. This is accepted for this release. ## Testing - Every commit through #7465 compiles individually (verified for 27 of the 29; the three additions below were verified at the tip) — verified individually, not just at the tip. - Full build clean; no new warnings. - Unit tests pass. - Functional tests pass: `feature_llmq_signing` (both variants), `feature_llmq_chainlocks`, `feature_llmq_dkgerrors`, `feature_llmq_is_cl_conflicts`, `p2p_instantsend`, `feature_dip3_deterministicmns` (both wallet types), `rpc_coinjoin`. - Qt unit tests pass (32 cases, run under the `cocoa` platform plugin so the pixel-sized font regression from #7465 actually executes rather than self-skipping). - Lint: one pre-existing `lint-cppcheck-dash` failure, identical on v23.1.7, in files this branch does not touch. Top commit has no ACKs. Tree-SHA512: 0fa469c9a33820aa85fbb8b90c5877409d09490f746f1300b05ceda470a600765f900bec42e5aad5d90a2d46b44e28c20e44dc4a8fe719553a072298069eaec4
Depends on #7439. Please review only the final command-specific commit here.
Issue being fixed or feature implemented
Quorum-data responses carry verification-vector and encrypted-contribution vectors whose expected sizes are known from the requested quorum. This hardens QDATA processing by checking the serialized vector count before allocating, deserializing, or processing those vectors.
This path is MNAuth/request-gated and is intentionally handled separately from unauthenticated public vector intake.
What was done?
The reusable bounded-vector serialization primitives are introduced separately in #7439.
How Has This Been Tested?
test/functional/p2p_quorum_data.pyBreaking Changes
None.
Checklist: