fix: write compact-size count in QuorumSnapshot encode#796
Conversation
`QuorumSnapshot::consensus_encode` wrote the active-members bitset without the leading compact-size bit count that `consensus_decode` reads (and that Dash Core's `DYNBITSET(activeQuorumMembers)` serializes), so encode and decode were asymmetric and any re-serialized `QuorumSnapshot` desynced on decode. This never surfaced because the only consensus-encode path for the type is serializing an outgoing `QRInfo` response (`message.rs`), which an SPV client never produces, and the only existing test was decode-only. Adds a round-trip test.
📝 WalkthroughWalkthroughUpdated ChangesQuorumSnapshot Encoding Fix
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
dash/src/network/message_qrinfo.rs (1)
319-320: ⚡ Quick winPin the wire format in the test.
Roundtrip covers internal symmetry, but it would still pass if encode and decode drifted together. Please also assert that the serialized bytes include the compact-size member count before the bitset so this regression stays directly covered.
🧪 Proposed test hardening
let bytes = serialize(&snapshot); + assert_eq!( + &bytes[..5], + &[1, 0, 0, 0, 10], + "wire format must include the active_quorum_members compact-size count", + ); let decoded: QuorumSnapshot = deserialize(&bytes).expect("deserialize QuorumSnapshot");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@dash/src/network/message_qrinfo.rs` around lines 319 - 320, The current test only roundtrips via serialize/deserialize (serialize(&snapshot) and deserialize(&bytes)), but to pin the wire format you must also assert the serialized bytes contain the compact-size encoded member count immediately before the bitset; compute the compact-size encoding for snapshot.members.len() (same encoding used elsewhere in this module), then after calling serialize(&snapshot) assert that the byte sequence for that compact-size integer appears at the expected location right before the bitset payload in bytes (or assert bytes.windows(n).position(...) yields an index such that the subsequent bytes match the bitset), so the test fails if the member-count encoding or ordering drifts.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@dash/src/network/message_qrinfo.rs`:
- Around line 319-320: The current test only roundtrips via
serialize/deserialize (serialize(&snapshot) and deserialize(&bytes)), but to pin
the wire format you must also assert the serialized bytes contain the
compact-size encoded member count immediately before the bitset; compute the
compact-size encoding for snapshot.members.len() (same encoding used elsewhere
in this module), then after calling serialize(&snapshot) assert that the byte
sequence for that compact-size integer appears at the expected location right
before the bitset payload in bytes (or assert bytes.windows(n).position(...)
yields an index such that the subsequent bytes match the bitset), so the test
fails if the member-count encoding or ordering drifts.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 861b72d3-9bda-4086-a808-d3f74e619a77
📒 Files selected for processing (1)
dash/src/network/message_qrinfo.rs
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## dev #796 +/- ##
=======================================
Coverage 72.55% 72.56%
=======================================
Files 322 322
Lines 71006 71019 +13
=======================================
+ Hits 51518 51532 +14
+ Misses 19488 19487 -1
|
QuorumSnapshot::consensus_encodewrote the active-members bitset without the leading compact-size bit count thatconsensus_decodereads (and that Dash Core'sDYNBITSET(activeQuorumMembers)serializes), so encode and decode were asymmetric and any re-serializedQuorumSnapshotdesynced on decode.This never surfaced because the only consensus-encode path for the type is serializing an outgoing
QRInforesponse (message.rs), which an SPV client never produces, and the only existing test was decode-only. Adds a round-trip test.Summary by CodeRabbit
Bug Fixes
Tests