Skip to content

sequencer: raise backfillMaxDepth to cover the reth unpersisted window - #45

Merged
panos-xyz merged 2 commits into
mainfrom
fix/backfill-max-depth
Sep 16, 2026
Merged

panos-xyz merged 2 commits into
mainfrom
fix/backfill-max-depth

Conversation

@panos-xyz

@panos-xyz panos-xyz commented Sep 16, 2026

Copy link
Copy Markdown

Summary

backfillMaxDepth (added in #43) bounds how far the execution layer's head may have regressed when a parent-not-found triggers a replay. That distance is upstream reth configuration rather than a fixed quantity — the ceiling is persistence_backpressure_threshold + memory_block_buffer_target:

reth persistence_threshold memory_block_buffer_target backpressure_threshold max gap
v2.4.0 2 0 16 16
v2.5.2 7 5 16 21

At 16 the walk refuses any gap above 16, so on reth v2.5.2 defaults a crash that loses 17–21 blocks makes recovery a no-op. Nothing is applied and the only signal is a generic Backfill failed line — indistinguishable from a node that simply stopped catching up.

The constant's comment was also written against the v2.4.0 numbers ("reth buffers only a couple of unpersisted blocks by default"), which no longer hold.

Changes

  • backfillMaxDepth 16 → 32. Covers the v2.5.2 ceiling with margin, and stays well under backfillCacheCapacity (64).

  • Document the coupling the limit depends on, so the next EL persistence tuning does not silently disable recovery:

    EL persistence_backpressure_threshold + memory_block_buffer_target <= backfillMaxDepth <= backfillCacheCapacity
    
  • Log the refusal explicitly (Backfill refused: gap exceeds backfillMaxDepth, carrying head / oldestMissing / newestMissing / gap). Both callers only report the error generically, and this case is a configuration mismatch rather than a transient failure they could retry away. Note libs/log.Logger has no Warn, so this is at Error level.

  • TestStateV2_Backfill_DepthBoundary pins the boundary: a 21-block gap (the v2.5.2 ceiling) and exactly backfillMaxDepth succeed, backfillMaxDepth + 1 is refused. This path previously had no test coverage.

Verification

  • go test ./sequencer/... -race -count=1 — pass

  • go vet ./sequencer/..., go build ./... — clean

  • The new test is a genuine regression test: against the old value it fails with

    depth 21: backfill refused, want success: gap exceeds backfillMaxDepth: head 100 up to block 121, limit 16
    

Not addressed here

A deployment that tunes the EL above 32 (for example --engine.persistence-backpressure-threshold 512) still disables recovery, and raising backfillMaxDepth alone cannot fix it because the walk is capped by backfillCacheCapacity (64) as well. Deriving the limit from the EL at runtime would be the robust fix, but those values are not readable over the Engine API today. This PR only makes the default configuration correct and the failure visible.

Follow-up to #43.

…window

backfillMaxDepth bounds how far the EL head may have regressed when a
parent-not-found triggers a replay. That distance comes from upstream reth
configuration rather than being a fixed quantity:
persistence_backpressure_threshold + memory_block_buffer_target is 16 on
reth v2.4.0 (16 + 0) and 21 on reth v2.5.2 (16 + 5) by default.

At 16 the walk refuses any wider gap, so on reth v2.5.2 defaults a crash
that loses 17-21 blocks makes recovery a no-op, which is indistinguishable
from a node that simply stopped catching up. Raise the limit to 32: it
covers the v2.5.2 ceiling with margin and stays under backfillCacheCapacity.

Also document the coupling the limit depends on, so the next EL tuning
change does not silently disable recovery, and log the refusal explicitly.
Both callers only report the error generically, and this one is a
configuration mismatch rather than a transient failure they could retry.
Note tendermint log.Logger has no Warn, so it is logged at Error level.

TestStateV2_Backfill_DepthBoundary pins the boundary. It fails against 16,
where a 21-block gap (the reth v2.5.2 ceiling) is refused.
@panos-xyz
panos-xyz requested a review from a team as a code owner September 16, 2026 05:20
@panos-xyz
panos-xyz requested review from twcctop and removed request for a team September 16, 2026 05:20

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.

Tip: disable this comment in your organization's Code Review settings.

Include the memory block buffer target in the documented invariant, report the actual missing range, verify the refusal fields, and add the pending changelog entry.
@panos-xyz panos-xyz changed the title fix(sequencer): raise backfillMaxDepth to cover the reth unpersisted window sequencer: raise backfillMaxDepth to cover the reth unpersisted window Sep 16, 2026
@panos-xyz
panos-xyz merged commit 560fb46 into main Sep 16, 2026
10 of 23 checks passed
crazywriter1 pushed a commit to crazywriter1/morph that referenced this pull request Sep 17, 2026
Point every Tendermint module replacement at morph-l2/tendermint#45's merged commit and refresh the affected checksums.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants