fix(taiko-client-rs): report execution head in /status when unsafe counter lags it#21777
Open
davidtaikocha wants to merge 1 commit into
Open
fix(taiko-client-rs): report execution head in /status when unsafe counter lags it#21777davidtaikocha wants to merge 1 commit into
davidtaikocha wants to merge 1 commit into
Conversation
…unter lags it The highest-unsafe counter only moves on preconfirmation imports, local builds, and the startup re-seed; canonical L1 derivation advances the execution head without touching it. The /status reconciliation only clamped the counter-above-head direction, so during no-gossip catch-up (post-checkpoint backfill, first operator coming online after an outage) the reported value permanently lags the head. Catalyst's sync gate requires exact equality with the EE head, so a lagging report blocks preconfirmation and puts Catalyst in a self-restart loop that only a driver restart clears. Report the execution head in both drift directions instead, keeping the report-only/self-healing design and matching the Go driver, which advances its counter on every canonical proposal.
Contributor
🐋 DeepSeek Code Review🔵 Suggestions
🟢 What Looks Good
Automatically triggered on PR update • model: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
The whitelist driver's
highest_unsafecounter only moves on three events: a localPOST /preconfBlocksbuild (set), a P2P envelope import (raise), and the startup re-seed from the EE head. Canonical L1 derivation advances the execution head without touching the counter, and the/statusreconciliation only handled the counter-above-head direction (the L1-reorg case).So whenever the head advances via derivation with no gossip flowing — post-checkpoint-sync backfill, or the first operator coming online after a sequencing outage —
/status.highestUnsafeL2PayloadBlockIdpermanently lags the EE head.Catalyst's sync gate (
is_block_height_synced_between_taiko_geth_and_the_driver) requires the reported value to exactly equal the EElatesthead (or be 0). A lagging value means: Catalyst never starts preconfirming, its cancel counter trips after ~96 heartbeats (~3.2 min), and it self-restarts in a loop — which never resolves, because restarting Catalyst doesn't re-seed the driver's counter, and with no preconfirmations flowing nothing ever raises it. Only a driver restart clears the wedge.The Go driver doesn't have this problem: it advances its counter to the canonical tip on every derived proposal (
recordLatestSeenProposal).The fix
reconcile_highest_unsafenow reports the execution head whenever it is readable, in both drift directions. This is always an honest answer — every canonical block was inserted by this driver too. The reorg (above-head) direction keeps itswarn; the catch-up (below-head) direction logs atdebugsince it's a normal transient state polled every ~2s.The report-only design is unchanged: the stored counter is never written back (the head is read without the state lock and may be stale; the next poll self-heals), and import/build semantics (
raise/set) are untouched —/statusis the only reader of the counter.Notes
reconcile_keeps_counter_when_below_reth_headtest pinned the wedge behavior as intended; it now asserts the head is reported.cargo test -p whitelist-preconfirmation-driver --lib(105 passed), crate-scoped clippy with CI flags, andjust fmt-checkare green.