Split on_block() and on_gossip_attestation() into verified and unverified variants#157
Split on_block() and on_gossip_attestation() into verified and unverified variants#157MegaRedHand merged 8 commits intomainfrom
Conversation
…ified variants, removing the skip-signature-verification compile-time feature flag entirely. on_block() and on_gossip_attestation() now always verify signatures (safe default). on_block_without_verification() and on_gossip_attestation_without_verification() provide explicit opt-outs for tests where signatures are absent. Shared block processing logic is extracted into a private on_block_core() that takes parent_state by value to avoid cloning.
🤖 Kimi Code ReviewReview SummaryThis PR removes the Key Issues Found
Minor Issues
Positive Changes
Recommendations
Automated review by Kimi (Moonshot AI) · custom prompt |
🤖 Codex Code ReviewFindings:
What looks good:
Validation note:
Automated review by OpenAI Codex · custom prompt |
🤖 Claude Code ReviewNow I have a clear picture of all the changes. Let me write up my review. Review: PR #157 — Split
|
Greptile SummaryThis PR successfully eliminates the Key improvements:
Code organization:
Changes include:
Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| crates/blockchain/src/store.rs | Successfully splits on_block() and on_gossip_attestation() into verified/unverified variants with shared logic, eliminating feature flags. Minor timing change in signature storage warrants verification. |
| crates/blockchain/tests/forkchoice_spectests.rs | Correctly updated to use on_block_without_verification() and fixed pre-existing clippy warnings for collapsible if statements using modern Rust syntax. |
| crates/blockchain/Cargo.toml | Cleanly removes skip-signature-verification feature flag and associated test requirements. No issues found. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Block Received] --> B{Production or Test?}
B -->|Production| C[on_block]
B -->|Fork Choice Tests| D[on_block_without_verification]
C --> E[Check for Duplicate]
D --> F[Check for Duplicate]
E --> G[Get Parent State]
F --> H[Get Parent State]
G --> I[verify_signatures]
I --> J[Store Proposer Signature]
J --> K[on_block_core]
H --> K
K --> L[State Transition]
L --> M[Store Block & State]
M --> N[Process Attestations]
N --> O[Update Fork Choice Head]
O --> P[Process Proposer Attestation]
P --> Q[Complete]
style C fill:#90EE90
style D fill:#FFB6C1
style I fill:#87CEEB
style J fill:#FFD700
style K fill:#DDA0DD
Last reviewed commit: aff6594
Co-authored-by: Tomás Grüner <47506558+MegaRedHand@users.noreply.github.com>
…on duplication into shared core functions with a runtime verify flag, restore parent-state comment, remove redundant forkchoice test target from Makefile, and add BUILD_PROFILE example to RELEASE.md.
…on duplication into shared core functions with a runtime verify flag, restore parent-state comment, keep proposer signature storage in original position, remove redundant forkchoice test target from Makefile, and add BUILD_PROFILE example to RELEASE.md.
the "new" stage instead of "known", addressing review feedback.
Motivation
PR #113 proposed extracting signature verification out of
on_block()into a separateprecheck_block_signatures()function called by the network layer before processing. Four automated reviewers flagged a critical security flaw: 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.PR #154 responded by taking the conservative approach: keep
on_block()unchanged and document its validate-then-mutate structure. It argued against extraction.This PR is the compromise: instead of removing verification from
on_block(), we keepon_block()as the safe default (always verifies) and addon_block_without_verification()as an explicit opt-out. This follows Zeam's architecture whereForkChoice.onBlock()is signature-agnostic and verification happens at the chain layer, but inverted — verification is the default and opting out requires calling a function whose name makes the risk obvious.This eliminates the
skip-signature-verificationcompile-time feature flag entirely.Description
store.rs— Spliton_block()Three functions replace the old
on_block():on_block()lib.rs),signature_spectestson_block_without_verification()forkchoice_spectestson_block_core()on_block_core()takesparent_stateby value (avoids the previous.clone()— minor perf win). The 4-line dedup + parent-state preamble is duplicated in both public functions to avoid double deserialization (verification needs the state, core needs the state).store.rs— Spliton_gossip_attestation()Same pattern:
on_gossip_attestation()on_gossip_attestation_without_verification()Both share the validation +
on_attestation()+ logging logic. Some duplication is acceptable to keep each function self-contained.Cargo.toml— Remove feature flag[features]section withskip-signature-verificationrequired-features = ["skip-signature-verification"]from forkchoice test entryforkchoice_spectests.rsstore::on_block()→store::on_block_without_verification()collapsible_ifclippy warnings (now surfaced because the test no longer requires a feature flag to compile, soclippy --all-targetssees it)Makefile--features skip-signature-verificationfromtesttargetCLAUDE.mdandRELEASE.mdskip-signature-verificationreferences from test commands, gotchas, and Docker build examplesRelationship to #113 and #78
This PR supersedes #113's approach. Rather than extracting verification to a separate precheck (which creates the "forgotten precheck" security risk flagged by reviewers), it splits the function into safe and unsafe variants. The safe variant (
on_block()) always verifies — callers can't accidentally skip verification. The unsafe variant (on_block_without_verification()) makes the risk explicit in its name. Issue #78's concern about signature verification is fully addressed: production paths always verify, and the compile-time feature flag is eliminated.How to test
Confirm no feature flag remnants:
grep -r "skip-signature-verification" crates/Note:
signature_spectestshave pre-existing failures (fixture deserialization issue withProposerSignature). These failures are identical onmainand are unrelated to this change.