fix(forkchoice): use only "new" pool for safe target (leanSpec #680)#316
fix(forkchoice): use only "new" pool for safe target (leanSpec #680)#316MegaRedHand wants to merge 1 commit intomainfrom
Conversation
Safe target is an availability signal: it must reflect votes received in the current slot, not historical knowledge. The migration step that moves attestations from "new" into "known" runs at interval 4, strictly after safe-target computation at interval 3, and 3sf-mini chose that ordering deliberately. Counting "known" would let a node keep advancing its safe target on stale evidence (block-included attestations, previously migrated gossip, self-attestations) even when live participation has collapsed: exactly the failure mode safe target is supposed to prevent. Mirrors leanSpec PR #680 and aligns with zeam (PR #779) and the Ream reference implementation. Drops the now-unused extract_latest_all_attestations helper from the store.
🤖 Kimi Code ReviewOverall Assessment: This is a correct and important consensus-layer security fix implementing the 3sf-mini (3-slot finality) specification correctly. The change prevents a liveness attack where nodes could advance safe targets using stale attestations. Detailed Feedback1. Consensus Correctness (Critical)File: The comment addition correctly explains the subtle distinction between availability and durable knowledge signals. The logic change from
Verification: Ensure 2. Code CleanupFile: Safe removal of dead code. The Suggestion: Verify no other crates or test files reference this removed method. If it exists in integration tests, those tests should be updated to reflect the correct 3sf-mini behavior. 3. Documentation QualityFile: Excellent inline documentation. The reference to "leanSpec PR #680" provides traceability to the specification change. The explanation of why counting "known" would be dangerous is clear and aids future maintainers. 4. PerformancePositive: Eliminates double-locking ( 5. Minor SuggestionsLine 121 ( let attestations = store.extract_latest_new_attestations();Consider adding a debug assertion or comment confirming this returns only interval-3 (current slot) attestations, reinforcing the invariant for future readers. Line 118 ( ConclusionNo blocking issues. This PR correctly implements the availability-signal semantics required by 3sf-mini and removes the vulnerable merged-pool logic. The security fix is well-documented and the code is clean. Automated review by Kimi (Moonshot AI) · kimi-k2.5 · custom prompt |
Greptile SummaryThis PR ports leanSpec #680 by changing Confidence Score: 5/5This PR is safe to merge — the change is small, well-motivated by the spec, and the removed helper has no remaining call sites. Two-file, single-concept change with a clear spec rationale. The removed extract_latest_all_attestations helper is confirmed unused across the codebase. All other callers of extract_latest_known_attestations and extract_latest_new_attestations are unaffected. No logic errors or regressions identified. No files require special attention.
|
| Filename | Overview |
|---|---|
| crates/blockchain/src/store.rs | Swaps extract_latest_all_attestations() for extract_latest_new_attestations() in update_safe_target; adds a detailed docstring explaining the interval-3/4 ordering and the availability-signal rationale. |
| crates/storage/src/store.rs | Removes the now-unused extract_latest_all_attestations helper; extract_latest_known_attestations and extract_latest_new_attestations are still present and used by other call sites. |
Sequence Diagram
sequenceDiagram
participant Gossip as Gossip
participant New as new pool
participant Known as known pool
participant FC as update_safe_target (interval 3)
participant Promote as promote new->known (interval 4)
Gossip->>New: "attestations arrive"
FC->>New: "extract_latest_new_attestations()"
New-->>FC: "current-slot votes only"
FC->>FC: "compute_lmd_ghost_head() => safe_target"
Promote->>New: "drain new pool"
Promote->>Known: "insert into known pool"
Note over Known: "historical attestations now in known"
Reviews (1): Last reviewed commit: "fix(forkchoice): use only "new" pool for..." | Re-trigger Greptile
🤖 Claude Code ReviewPR #316 Review:
|
🤖 Codex Code ReviewFindings
I didn’t see another concrete bug in the diff itself. I couldn’t run the Rust test suite here because Cargo needs network/write access for the Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
Summary
Ports leanSpec PR #680 into ethlambda.
update_safe_targetnow reads onlylatest_new_attestationsinstead of merging thenewandknownpools.Rationale
Safe target is an availability signal, not a durable-knowledge signal. The
new -> knownmigration step runs at interval 4, strictly after safe-target computation at interval 3, and 3sf-mini chose that ordering deliberately:newrepresent the current slot's online view.knownis historical: block-included attestations, gossip migrated in earlier slots, self-attestations stored locally without traversing gossipsub.knownwould let a node keep advancing its safe target on stale evidence even when live participation has collapsed, which is exactly the failure mode safe target is supposed to prevent.Aligns with zeam (PR #779) and the Ream reference implementation.
Changes
crates/blockchain/src/store.rs(update_safe_target): swapextract_latest_all_attestations()forextract_latest_new_attestations(). Docstring rewritten around the interval-3 / interval-4 ordering and the availability framing.crates/storage/src/store.rs: drop the now-unusedextract_latest_all_attestationshelper.Notes
LEAN_SPEC_COMMIT_HASHis bumped, the regeneratedtest_safe_target_*fixtures should validate the new behavior end-to-end. (Today the fixture'ssafeTargetSlot/safeTargetRootLabelchecks are silently ignored by our spec-test runner because those fields are not yet wired intoStoreChecks.)Test plan
cargo build --workspacecargo clippy --workspace --all-targets -- -D warningscargo fmt --allcargo test --workspace --release-- 323 passed, 6 ignoredcargo test -p ethlambda-blockchain --release --test forkchoice_spectests-- 70 passed