Skip to content

fix(sync/pending): stop chasing the tip when building pre-confirmed data#3499

Open
t00ts wants to merge 5 commits into
mainfrom
t00ts/anchored-preconfirmed
Open

fix(sync/pending): stop chasing the tip when building pre-confirmed data#3499
t00ts wants to merge 5 commits into
mainfrom
t00ts/anchored-preconfirmed

Conversation

@t00ts

@t00ts t00ts commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Problem:

Clients querying the pre_confirmed tag were getting intermittent 503s.

The producer asked the gateway for its latest pre-confirmed block and required it to line up with the pending (pre-latest) block fetched alongside it.

While this makes sense in theory, in practice it's hard to get right because they come from different endpoints sampled a few moments apart. This is due to how the fgw API is designed, and there are no plans to change it.

TDLR: By the time we read the pre-latest at N, the pre-confirmed had already raced ahead to N+2. Right now if they don't chain we discard the update. This can result in long periods of nothing to serve. Which is wrong.

Solution:

Stop chasing a moving target. Instead of asking for latest, we anchor the pre-confirmed query on our own (known) committed head. So the block we fetch (by number) is the exact pre-confirmed block that chains onto it by construction. The race should no longer happen. Ever.

Then, one step further as suggested by SW: The pre-latest is really just a pre-confirmed block one height down that's already past consensus (waiting for block hash), which is exactly what the pending block was giving us. So instead of a separate pending poll, we fetch the pre-latest by number from the same get_preconfirmed endpoint. Both levels then come from the same place.

Also, a couple notable changes:

  • A transient gateway failure keeps serving the last good view instead of going blank.
  • Removed a panic! from the read path. We just return an empty block instead.

This is a major rewrite. I have tested it live on sepolia-integration and the pre_confirmed serves well with zero drops.

See also #3495

Base automatically changed from t00ts/pending-optimization to main June 30, 2026 14:08
@t00ts t00ts force-pushed the t00ts/anchored-preconfirmed branch from 023394d to 3dda16c Compare June 30, 2026 14:15
@t00ts t00ts marked this pull request as ready for review June 30, 2026 14:16
@t00ts t00ts requested a review from a team as a code owner June 30, 2026 14:16
@t00ts

t00ts commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

Note: This does not fix the latency issue. Especially in mainnet we'll need variable depth (3-5 blocks) for the pre-confirmed flow. But that's another big (and orthogonal) change to this one, which focuses on fixing the bug and cleaning up the polling flow.

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.

1 participant