fix: store gossip signatures in order#267
Conversation
🤖 Kimi Code ReviewThis is a solid change that fixes a critical correctness requirement for XMSS signature aggregation while improving performance. Consensus Correctness ✅
Performance ✅
Code Quality ✅
Minor Observations
No blocking issues found. The PR correctly addresses the order-dependency requirement of XMSS multi-signatures while cleaning up the implementation. Automated review by Kimi (Moonshot AI) · kimi-k2.5 · custom prompt |
Greptile SummaryFixes the regression from #253 by replacing Confidence Score: 5/5Safe to merge — targeted, correct fix with no new risks introduced. The change is minimal and well-scoped: swapping Vec for BTreeMap fixes the ordering regression, the duplicate-suppression logic is preserved via or_insert, and all public API signatures are unchanged. No P1 or P0 findings. No files require special attention.
|
| Filename | Overview |
|---|---|
| crates/storage/src/store.rs | Replaces Vec-based gossip signature storage with BTreeMap keyed by validator_id to enforce ascending iteration order, fixing XMSS aggregation ordering regression; also removes now-redundant GossipSignatureEntry wrapper struct. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Gossip Signature Received\nvalidator_id + ValidatorSignature] --> B[insert_gossip_signature]
B --> C{data_root entry\nexists?}
C -- No --> D[Create GossipDataEntry\nBTreeMap::new]
C -- Yes --> E[Existing GossipDataEntry]
D --> F[entry.or_insert signature\nkeyed by validator_id]
E --> F
F --> G[BTreeMap\nvalidator_id → ValidatorSignature\nauto-sorted ascending]
G --> H[Interval 2: iter_gossip_signatures]
H --> I[Iterate BTreeMap in ascending\nvalidator_id order]
I --> J[XMSS Aggregation\nparticipation bitfield low-to-high]
J --> K[AggregatedSignatureProof]
L[delete_gossip_signatures\nvalidator_id + data_root] --> M[BTreeMap::remove - O log n]
Reviews (1): Last reviewed commit: "fix: store gossip signatures in order" | Re-trigger Greptile
🤖 Codex Code ReviewNo correctness or security findings in this diff. The change in store.rs to store gossip signatures in a Residual risk: this would benefit from a regression test around iter_gossip_signatures() that inserts validators out of order and asserts ascending iteration order, because the correctness here depends on that ordering contract remaining intact. I could not run the Rust tests in this environment: Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
🤖 Claude Code ReviewHere is the review for PR #267: Review: fix: store gossip signatures in orderSummary: This PR correctly fixes a regression from #253 by replacing CorrectnessThe fix is sound. In for (vid, sig) in validator_sigs {
...
sigs.push(sig.clone());
pubkeys.push(pubkey);
ids.push(*vid);
}
Duplicate handlingThe previous check: if !entry.signatures.iter().any(|e| e.validator_id == validator_id) {
entry.signatures.push(...)
}The new code: entry.signatures.entry(validator_id).or_insert(signature);Both implement first-seen-wins semantics. The new form is idiomatic and correct. Performance
For typical committee sizes (tens to low hundreds of validators) these are small absolute wins, but the asymptotic improvement is real. One observation: no test for ordering invariantThere are currently no tests in #[test]
fn gossip_signatures_returned_in_ascending_validator_id_order() {
let mut store = Store::test_store();
let hashed = HashedAttestationData::new(make_att_data(1));
// Insert in reverse order
for vid in [5u64, 2, 8, 0, 3] {
store.insert_gossip_signature(hashed.clone(), vid, make_sig());
}
let snapshot = store.iter_gossip_signatures();
let ids: Vec<u64> = snapshot[0].1.iter().map(|(vid, _)| *vid).collect();
assert_eq!(ids, vec![0, 2, 3, 5, 8]);
}This is a minor suggestion — the fix itself is correct. Code qualityThe doc comment added to Overall: Clean, targeted fix. The change is minimal, correctly addresses the root cause, and improves both correctness and performance. The only suggestion is adding a unit test to lock in the ordering invariant. Automated review by Claude (Anthropic) · sonnet · custom prompt |
This PR fixes a regression added in #253, which unordered gossip transactions, causing errors during aggregation