fix(blockchain): record tick-interval sample on proposer interval-0 skip#513
fix(blockchain): record tick-interval sample on proposer interval-0 skip#513MegaRedHand wants to merge 2 commits into
Conversation
On a proposer slot the block is built during interval 4 of the previous slot, which advances the store clock to the next slot's interval 0. The real interval-0 tick is then skipped by on_tick's idempotency guard. Because lean_tick_interval_duration_seconds measures wall-clock time between consecutive *recorded* ticks, and a skipped tick neither records a sample nor advances last_tick_instant, the following interval-1 tick measured across two intervals and reported a false ~1.6s spike, even though ticks were firing on their 0.8s cadence. Record the tick-interval sample from the proposal path, after the publish-alignment sleep (i.e. at ~the interval-0 boundary), standing in for the skipped interval-0 tick so samples stay at ~one interval.
🤖 Codex Code Review
I didn’t see consensus, fork-choice, attestation, SSZ, or security-impacting changes in this diff beyond that metrics-path bug. Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
🤖 Kimi Code ReviewThe fix addresses a legitimate metrics drift issue caused by the interaction between block proposal timing and the idempotency guard in Concerns:
Minor:
Consensus note: Accurate timing metrics are critical for detecting network partitioning and clock skew. This fix prevents false positives in the Verdict: Correct fix, but verify the concurrency model for Automated review by Kimi (Moonshot AI) · kimi-k2.5 · custom prompt |
Greptile SummaryThis PR adjusts tick metric accounting in the proposer path.
Confidence Score: 5/5This looks safe to merge.
|
| Filename | Overview |
|---|---|
| crates/blockchain/src/lib.rs | Adds proposer-path tick interval metric recording after publish alignment to account for the skipped interval-0 tick. |
Reviews (1): Last reviewed commit: "fix(blockchain): record tick-interval sa..." | Re-trigger Greptile
… don't inflate it (#514) Alternative to #513 (same bug, different approach). ## Problem `lean_tick_interval_duration_seconds` reported a spurious ~1.6s tail on every proposer slot. It measures wall-clock time between consecutive *recorded* ticks, recorded inside `on_tick` **after** the idempotency guard. A guard-skipped tick records no sample and doesn't advance `last_tick_instant`. On a proposer slot the block is built during interval 4 of the previous slot, which advances the store clock to the next slot's **interval 0**, so the real interval-0 tick is skipped — and the following **interval-1** tick then measured across two intervals (~1.6s) even though ticks were firing on their 800ms cadence. ## Approach Move the sample to `handle_tick`, the scheduler-level handler that runs for **every** tick (including guard-skipped ones). One sample per tick regardless of whether `on_tick` drops the duty, so a skipped interval no longer inflates the next sample. Versus #513 (which records from the proposer path after the publish-alignment sleep): this needs **no proposer special-casing** and covers any skip uniformly. It matches how Zeam records the same metric (at the clock layer, decoupled from duty execution). **Tradeoff:** wall-clock-drift duplicate ticks (which the guard also swallows) are now sampled too, adding occasional sub-interval samples. Harmless for a metric meant to surface *late* ticks; noted in the comment. ## Verification Confirmed on a single-node local devnet (0 gossip imports isolate the proposer path). Behavior is equivalent to #513: the skipped interval-0 tick is now sampled (sample count rises to ~5/slot), no pinned ~1.6s artifact remains, and the large samples track the real (variable) block-build duration rather than a fixed two-interval value. Total recorded time is unchanged (`_sum` matches #513's run). Co-authored-by: Pablo Deymonnaz <pdeymon@fi.uba.ar>
|
Superseded by #514 |
Problem
lean_tick_interval_duration_secondswas reporting a spurious ~1.6s tail on every proposer slot, which read as the tick loop stalling. It is a metric-accounting artifact, not real tick lag.On a proposer slot, the block is built during interval 4 of the previous slot; building advances the store clock to the next slot's interval 0, so the real interval-0 tick is skipped by
on_tick's idempotency guard. The metric measures wall-clock time between consecutive recorded ticks, and a skipped tick neither records a sample nor advanceslast_tick_instant, so the following interval-1 tick measured across two intervals (~1.6s) even though ticks were firing on their 0.8s cadence.Fix
Record the tick-interval sample from the proposal path, after the publish-alignment sleep (i.e. at ~the interval-0 boundary), standing in for the skipped interval-0 tick. Per-slot samples then stay at ~one interval.
Scope: only the proposer path is touched, since that is the only source of the interval-0 skip. A genuinely delayed tick (e.g. a slow
on_blockimport) is unaffected and still shows as real lag.Verification
Confirmed on a single-node local devnet (0 gossip imports isolate the proposer path): before the fix, tick samples >1.2s were 1:1 with block builds and pinned at ~1.6s; all skipped ticks were at interval 0 (BlockPublication). With the fix the skipped interval-0 slot is accounted for.