fix: handle pruned justified root in compute_lmd_ghost_head#137
fix: handle pruned justified root in compute_lmd_ghost_head#137pablodeymo merged 1 commit intomainfrom
Conversation
When finalization advances, prune_live_chain removes entries with slot < finalized_slot. If the justified checkpoint root (e.g. genesis at slot 0) has been pruned, the unchecked blocks[&start_root] index panics with "no entry found for key". Replace the panicking index with blocks.get() and return start_root as fallback when it's absent from the live chain. This matches the existing early-return for empty blocks and keeps the head at the justified root until more blocks are available.
🤖 Kimi Code ReviewSecurity & Correctness IssuesFile:
Performance & Style
Correctness Question
Automated review by Kimi (Moonshot AI) · custom prompt |
🤖 Codex Code ReviewFindings
No other changes in this PR. Overall the edit is small and readable, but the silent fallback is a consensus-risky behavior change unless explicitly intended. Automated review by OpenAI Codex · custom prompt |
Greptile SummaryFixes a panic in Changes:
Impact:
Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| crates/blockchain/fork_choice/src/lib.rs | Replaced panicking dictionary access with safe .get() that returns start_root when justified checkpoint has been pruned from LiveChain - prevents crash during devnet operation |
Last reviewed commit: 9569a1c
🤖 Claude Code ReviewNow I have everything I need to produce the review. PR #137 Review:
|
Motivation
ethlambda crashes during devnet operation when
compute_lmd_ghost_headperforms an unchecked dictionary access (blocks[&start_root]) and thestart_root(justified checkpoint root) has already been pruned from theLiveChaintable.Crash sequence:
prune_live_chain(finalized_slot)removes entries withslot < finalized_slot— genesis (slot 0) is prunedupdate_head()callscompute_lmd_ghost_head(store.latest_justified().root, &blocks, ...)blocks(fromget_live_chain()) no longer contains the genesis rootblocks[&start_root].0—"no entry found for key"Both
update_headandupdate_safe_targetinstore.rsare affected since they both callcompute_lmd_ghost_head.Description
Replace the panicking index
blocks[&start_root].0withblocks.get(&start_root)and returnstart_rootas a fallback when it is absent from the live chain.Rationale: If the justified checkpoint root is not in the live chain, fork choice cannot traverse beyond it. Returning
start_rootis the safe fallback — it matches the existing early-return behavior forblocks.is_empty()(line 16–18) and ensures the head stays at the justified root until more blocks are available. Normal operation (justified root present in LiveChain) is unaffected since.get()returnsSomeand destructures identically.How to test
The fix only changes the error case — when
start_rootis absent fromblocks, which currently panics.