Document on_block() validate-then-mutate structure and resolve stale TODOs#154
Document on_block() validate-then-mutate structure and resolve stale TODOs#154pablodeymo wants to merge 2 commits intomainfrom
Conversation
🤖 Kimi Code ReviewReview SummaryThe PR improves documentation and clarifies the two-phase validation approach in Critical Issues
Security Concerns
Code Quality
Suggested Fixes// Move state mutation after all validation
let state_root = block.state_root;
// Don't modify post_state here - do it after validation
// After all validation passes:
post_state.latest_block_header.state_root = state_root;
// Then proceed with mutationsConsider wrapping the entire mutation phase in a transaction or implementing rollback mechanisms for critical failures. Automated review by Kimi (Moonshot AI) · custom prompt |
🤖 Codex Code ReviewNo functional changes detected — this diff only updates comments in Notes:
Given the above, I have no requested changes. The PR looks good from a code‑review perspective. Automated review by OpenAI Codex · custom prompt |
Greptile SummaryThis PR makes documentation-only improvements to
All changes are comments-only with zero executable code modifications. The explanations are technically accurate and improve code maintainability. Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| crates/blockchain/src/store.rs | Documentation-only changes that clarify the validate-then-mutate structure and remove three incorrect TODOs, replacing them with accurate explanations of protocol behavior |
Last reviewed commit: 4122c73
🤖 Claude Code ReviewI have everything I need. Here is the review: PR 154 Review: Document
|
|
Superseded by #157 |
Summary
on_block()that was previously implicitContext
This is a follow-up to the investigation started in #113 by @MegaRedHand (which addresses #78). That PR proposed extracting signature verification from
on_block()into a separateprecheck_block_signatures()function called earlier in the pipeline. Four automated reviewers flagged a critical issue: removingverify_signatures()fromon_block()means any caller that forgets to callprecheck_block_signatures()first can import blocks without cryptographic validation. There are 3 call sites foron_block()(productionprocess_block(), and 2 test files), and only 1 would get the precheck.During this rework, we also attempted the two other TODOs in the function: rejecting blocks when block body or proposer attestations fail validation. Both turned out to be incorrect — forkchoice spec tests revealed that attestation validation failures are normal and expected:
source.slot > target.slotwhen the attesting validator's justified checkpoint (source) advanced past their chosen target. 3 spec tests (test_reorg_on_newly_justified_slot,test_all_validators_attest_in_single_aggregation,test_multiple_specs_same_target_merge_into_one) exercise this exact scenario.The current warn-and-skip behavior (
let _ = on_attestation(...)) is the correct design.Changes
crates/blockchain/src/store.rs(comments only, zero executable code changes):Updated
on_block()docstring — documents the two-phase structure:Removed TODO: "extract signature verification to a pre-checks function" (was at line 352) — signature verification stays inside
on_block(), which is the only safe design. Extracting it creates a "forgotten precheck" risk across all 3 call sites.Removed TODO: "fail the block if an attestation is invalid" (was at line 385) — replaced with a comment explaining that block body attestations fail validation for legitimate reasons (unseen forks, source exceeding target after justification advances).
Removed TODO: "validate attestations before processing" (was at line 434) — replaced with a comment explaining that proposer attestations can reference the block being processed or have stale checkpoint data.
Added phase boundary marker (
// === Store mutations ===) at the exact point where store mutations begin, making the validate-then-mutate structure grep-able.Relationship to #113 and #78
This PR supersedes #113's approach. Rather than extracting verification to a separate precheck (which creates safety risks), it documents that the current structure already achieves the goal: all validation happens before any store mutations, so
on_block()either rejects early (no side effects) or succeeds fully. Issue #78's concern about "accepting blocks with invalid attestations" is addressed by documenting that this is intentional protocol behavior, not a bug.Test plan
make fmtpassesmake lintpasseslet _ =(test_reorg_on_newly_justified_slot,test_all_validators_attest_in_single_aggregation,test_multiple_specs_same_target_merge_into_one)main(pre-existing fixture deserialization issue, unrelated)