refactor(blockchain): group on_tick conditionals by interval - #450
Conversation
🤖 Codex Code ReviewNo findings. The change in crates/blockchain/src/lib.rs looks non-semantic: the interval-4 Residual gap: I could not complete a Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
f8d6ec2 to
9e43879
Compare
🤖 Claude Code ReviewHere is the review output: PR Review:
|
Greptile SummaryThis PR reorders the per-interval blocks inside
Confidence Score: 4/5Safe to merge — the reorder is purely cosmetic because every block is guarded by its own interval predicate, and the one ordering constraint that matters (interval-4 snapshot before store::on_tick) is correctly preserved and now explicitly documented. The only actionable finding is that unconditional metrics calls (update_safe_target_slot, update_head_slot, advance_keys_to) land under the // ==== interval 3 ==== banner, which could mislead a future developer into treating them as interval-3-specific. This is a readability concern with no current behavioral impact. crates/blockchain/src/lib.rs — the tail of on_tick after the interval-2 block mixes unconditional per-tick calls under the interval-3 section label.
|
c0d6ff0 to
f690ec7
Compare
on_tick ran its per-interval blocks out of order (4-snapshot, tick, 2, 0, 1). Regroup them into ascending interval order behind `==== interval N ====` markers so the slot timeline reads top to bottom and matches the duty schedule. Pure reorder, behavior unchanged. The interval-4 new_payloads snapshot is the one block that stays ahead of store::on_tick: the interval-4 tick promotes new_payloads out, so it cannot move into a post-tick group. A comment now pins that constraint.
…ick flag Compute scheduled_proposer just before store::on_tick and pass the raw is_proposer (= scheduled_proposer.is_some()) to it; gate the actual proposal on duties_allowed() at the call site instead. While syncing and scheduled to propose, on_tick now accepts attestations early at interval 0 (it did not before); the proposal itself is still skipped.
f77faf2 to
d003f85
Compare
main (#447/#449/#450) merged cleanly textually, but the simple BFT finality condition removed slot_is_justifiable_after, which main's block_builder and store still called. Reconciled those call sites to the new model (every slot justifiable; finalize only on consecutive source+1 == target): - store::get_attestation_target_with_checkpoints: drop the justifiability walk-back (now a no-op); finalized arg unused, kept as _finalized. - block_builder: drop the target_not_justifiable rejection; the finalizes predicate now checks source.slot + 1 == target.slot.
#450 (the on_tick interval regrouping) landed in main via squash, so both sides added the same interval markers/blocks relative to the pre-#450 merge-base. Git kept both with no textual conflict, duplicating the interval 2/3/4 sections (start_aggregation_session would have run twice). Removed the duplicate set, keeping a single interval 0-4 sequence with the prebuild trigger in interval 4.

Split out of #445 (proposer pre-build). Stacked on #449 (
gate_proposerremoval) — review/merge that first; this PR's base retargets tomainonce #449 lands.on_tickran its per-interval blocks out of order (interval-4 snapshot, then tick, then 2, 0, 1). This regroups them into ascending interval order behind==== interval N ====markers so the slot timeline reads top-to-bottom and lines up with the duty schedule.Pure reorder, behavior unchanged.
One block intentionally does not move
The interval-4
new_payloadssnapshot stays ahead ofstore::on_tick. At interval 4 the tick runsaccept_new_attestations → promote_new_aggregated_payloads(), which drainsnew_payloads; snapshotting after the tick would capture an already-drained set and silently break the post-block coverage report's "timely" cohort. A comment now pins that ordering constraint.