fix: skip one signature aggregation jobs#483
Conversation
🤖 Codex Code ReviewFindings
No other issues stood out in this small diff, but I would add a regression test for “single gossip attestation becomes a pending proof and affects fork-choice-visible state.” Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
🤖 Kimi Code ReviewOverall Assessment: The change correctly optimizes aggregation by skipping redundant operations on single signatures. The logic is sound and safe. Specific Feedback:
Suggestion (Optional): if raw_ids.len() + children.len() < 2 {
return None;
}However, the explicit separation may be intentional for future extensibility (e.g., different thresholds for raw vs. aggregated signatures). Verdict: LGTM. The optimization is correct and prevents unnecessary cryptographic operations. Automated review by Kimi (Moonshot AI) · kimi-k2.5 · custom prompt |
Greptile SummaryThis PR changes when aggregation jobs are built for small input groups. The main change is:
Confidence Score: 4/5The single-signature aggregation path can leave gossip signatures unconsumed.
crates/blockchain/src/aggregation.rs
|
| Filename | Overview |
|---|---|
| crates/blockchain/src/aggregation.rs | Adds an early return in build_job that suppresses job creation for a single raw signature with no child aggregate. |
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
crates/blockchain/src/aggregation.rs:213-215
**Single Signature Stays Unconsumed**
When a gossip group has exactly one raw validator signature and no child aggregate, this branch returns before `keys_to_delete` is built. The caller treats `None` as no aggregation job, so the previous path that produced an aggregate and deleted the consumed gossip signature is skipped, leaving that single-signer attestation unpromoted and still present in the gossip store.
Reviews (1): Last reviewed commit: "fix: skip aggregation when there's only ..." | Re-trigger Greptile
🤖 Claude Code ReviewReview: fix: skip aggregation when there's only a single signature (PR #483)Diff: 1. Possible vote-loss / liveness concern — please confirm against intended semantics
With this change, an attestation-data group that ends up with exactly one raw gossip signature and zero reusable child proofs is dropped from Before this PR, that lone signature would still go through Please confirm this matches leanSpec's reference behavior (i.e., that the spec also discards genuinely-unaggregatable singleton votes rather than admitting them as trivial 1-of-1 proofs) rather than this being an unintended side effect of trying to avoid wasted aggregation work. 2. The two skip conditions can be merged into one, simpler checkThe new logic at if raw_ids.is_empty() && children.len() < 2 {
return None;
}
if children.is_empty() && raw_ids.len() <= 1 {
return None;
}is exactly equivalent to: if children.len() + raw_ids.len() < 2 {
return None;
}(verified by case enumeration over 3.
|
🗒️ Description / Motivation
build_job(crates/blockchain/src/aggregation.rs) already skipped aggregation when there was nothing at all to do (no raw signatures and fewer than 2 children), but it missed one case: exactly one raw gossip signature with no children to merge it with.That job still went to the worker and ran the full
aggregate_mixedleanVM/XMSS proving pipeline, just to wrap a single signature into a 1-participantTypeOneMultiSignature. That proof is no smaller or cheaper to verify than the raw signature it wraps, so the proving cost was paid for zero compression benefit, every interval-2 tick, for every attestation-data root that happened to have only one signer so far (e.g. early in a slot, before other votes arrive).aggregate_mixed's own doc comment already calls this out for the "lone child" case ("A lone child is already a valid Type-1; further aggregation is wasted work") but the equivalent "lone raw signature" case wasn't covered.Aggregation runs on a tight
AGGREGATION_DEADLINEbudget shared across all groups in a session, so every wasted proof is time taken away from groups that actually need it.What Changed
crates/blockchain/src/aggregation.rs:build_jobnow also returnsNonewhenchildren.is_empty() && raw_ids.len() <= 1, skipping job creation for a lone, companion-less raw signature.Correctness / Behavior Guarantees
gossip_signaturesbuffer (it's never added tokeys_to_delete), so it's reconsidered on the next interval-2 tick once a companion signature or mergeable proof shows up for the same attestation data. It remains subject to the buffer's existing FIFO eviction and finalization pruning, same as before.Tests Added / Run
cargo test -p ethlambda-blockchain --release(incl.forkchoice_spectestssignature-aggregation cases) — all passing.Related Issues / PRs
✅ Verification Checklist
make fmt— cleanmake lint(clippy with-D warnings) — cleancargo test --workspace --release— all passing