Port leanSpec on_tick and attestation validation changes#135
Port leanSpec on_tick and attestation validation changes#135pablodeymo wants to merge 3 commits intobump-leanspec-commitfrom
Conversation
…lidation Port two validation rules from leanSpec 8b7636b: reject attestations where the head checkpoint is older than the target, and reject attestations where the head checkpoint slot doesn't match the actual block slot. Well-formed attestations already satisfy these, but without them we'd accept malformed ones.
At interval 3, the migration step (interval 4) hasn't run yet, so attestations that entered "known" directly (proposer's own attestation in block body, node's self-attestation) were invisible to the safe target calculation. Merge both pools to avoid undercounting support. No double-counting risk since extract_attestations_from_aggregated_payloads deduplicates by validator ID.
After aggregating committee signatures at interval 2, broadcast the resulting SignedAggregatedAttestation messages to the network. aggregate_committee_signatures and on_tick now return the new aggregates, and BlockChainServer::on_tick publishes them via P2PMessage::PublishAggregatedAttestation. The variant already existed but was never sent from the aggregation path.
🤖 Kimi Code ReviewReview SummaryThis PR improves attestation aggregation and validation logic in the consensus layer. The changes are generally correct and address important edge cases, but there are a few concerns: Issues Found
Positive Aspects
Minor Suggestions
Automated review by Kimi (Moonshot AI) · custom prompt |
🤖 Codex Code ReviewReview Summary Findings
Notes
If you want, I can draft a small dedup strategy that minimizes allocations. Automated review by OpenAI Codex · custom prompt |
Greptile SummaryPorts three behavioral changes from leanSpec
Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| crates/blockchain/src/store.rs | Core logic changes: merges known+new attestation pools in update_safe_target, returns aggregated attestations from aggregate_committee_signatures and on_tick, adds HeadOlderThanTarget and HeadSlotMismatch validation checks and error variants. All changes are well-structured and consistent with existing patterns. |
| crates/blockchain/src/lib.rs | Captures the Vec<SignedAggregatedAttestation> return from store::on_tick and broadcasts each aggregate via the P2P channel using the existing PublishAggregatedAttestation message variant. Error handling uses inspect_err with logging, consistent with surrounding code. |
Sequence Diagram
sequenceDiagram
participant Timer
participant BCS as BlockChainServer
participant Store as store::on_tick
participant Agg as aggregate_committee_signatures
participant ST as update_safe_target
participant P2P as P2P Channel
Timer->>BCS: on_tick(timestamp_ms)
BCS->>Store: on_tick(store, ts, has_proposal, is_aggregator)
Note over Store: Interval 0: accept attestations if proposal
Note over Store: Interval 1: no-op
Store->>Agg: Interval 2: aggregate_committee_signatures(store)
Agg-->>Store: Vec<SignedAggregatedAttestation>
Store->>ST: Interval 3: update_safe_target(store)
Note over ST: Merge known + new pools
Note over ST: compute_lmd_ghost_head with merged attestations
Note over Store: Interval 4: accept_new_attestations
Store-->>BCS: Vec<SignedAggregatedAttestation>
loop For each aggregate
BCS->>P2P: PublishAggregatedAttestation(aggregate)
end
Last reviewed commit: d72c3a3
🤖 Claude Code ReviewHere is the review of PR #135: PR #135 — Port leanSpec on_tick and attestation validation changesOverallThree focused, well-scoped changes that correctly port behavioral updates from leanSpec Change 1 — Stricter attestation validation (
|
Motivation
The leanSpec bump to
8b7636b(#134) introduced several spec changes beyond the signatureserialization fix. This PR ports three remaining behavioral changes to align ethlambda
with the reference implementation:
Description
1. Stricter attestation validation (
validate_attestation_data)Two new validation rules reject malformed attestations:
head.slot >= target.slot, but without this check we'd accept malformed ones.slotfield doesn't match the actual block's slot. This mirrors the existing checks for source and target checkpoints.New
StoreErrorvariants:HeadOlderThanTarget,HeadSlotMismatch.2. Merge attestation pools in
update_safe_targetPreviously,
update_safe_target(called at interval 3) only looked at "new" attestation payloads. However, the migration from "new" to "known" happens at interval 4, and some attestations enter "known" directly without passing through "new":on_blockWithout merging both pools, these attestations were invisible to the safe target calculation, causing it to undercount support. Now both pools are merged before computing the safe target. No double-counting risk since
extract_attestations_from_aggregated_payloadsdeduplicates by validator ID (latest slot wins).3. Broadcast aggregated attestations after aggregation
After aggregating committee signatures at interval 2, the node now broadcasts the resulting
SignedAggregatedAttestationmessages to the network. TheP2PMessage::PublishAggregatedAttestationvariant already existed but was never sent from the aggregation path.Changes:
aggregate_committee_signaturesreturnsVec<SignedAggregatedAttestation>store::on_tickreturnsVec<SignedAggregatedAttestation>BlockChainServer::on_tickpublishes each aggregate via the P2P channelTest call sites (
forkchoice_spectests,signature_spectests) ignore the return value —Vec<T>is not#[must_use], so this compiles without warnings.How to Test
Change 3 (broadcasting) is a runtime behavior validated in devnet testing.
Related Issues
Stacked on #134 (leanSpec bump to
8b7636b).