Skip to content

Fix bridging backfill gap in RPC log streamer#1903

Open
xmtp-coder-agent wants to merge 3 commits intoxmtp:mainfrom
xmtp-coder-agent:fix/issue-1889
Open

Fix bridging backfill gap in RPC log streamer#1903
xmtp-coder-agent wants to merge 3 commits intoxmtp:mainfrom
xmtp-coder-agent:fix/issue-1889

Conversation

@xmtp-coder-agent
Copy link
Copy Markdown
Collaborator

@xmtp-coder-agent xmtp-coder-agent commented Mar 30, 2026

Summary

Resolves #1889

  • Modified buildSubscription and buildSubscriptionWithBackoff to return the WS head block number used as the subscription's FromBlock
  • Added a bridging backfill loop in watchContract that runs after the initial backfill completes, fetching any logs between the HTTP head and the WS subscription start block
  • Added test verifying the bridging backfill fetches logs in the gap

Test plan

  • Existing TestRpcLogStreamer passes
  • New TestBridgingBackfill validates gap coverage: HTTP head=10, WS head=15, verifies logs at block 12 are fetched via bridging
  • dev/lint-fix passes with 0 issues

🤖 Generated with Claude Code

Note

Fix bridging backfill gap between HTTP head and WS head in RPC log streamer

  • When transitioning from HTTP backfill to a WS subscription in watchContract, a bridging backfill loop now fetches logs for any blocks between the HTTP head and the WS subscription start block before processing subscription events.
  • buildSubscription and buildSubscriptionWithBackoff now return the WS head block number used to initialize the subscription, so watchContract knows where to stop the bridging loop.
  • GetNextPage now sets NextBlockNumber to toBlock+1 (previously nil) when returning ErrEndOfBackfill, which the bridging loop relies on to advance correctly.
  • A new TestBridgingBackfill test simulates an HTTP head at block 10 and WS head at block 15, asserting logs at block 12 are emitted during bridging.

Macroscope summarized 0470a5e.

The RPC log streamer was missing logs between the HTTP RPC head (where
backfill ends) and the WS head (where the subscription starts). This
happened because buildSubscription set FromBlock to the WS head but
never communicated that value back to watchContract, so there was no
bridging fetch between the two endpoints.

Return the subscription start block from buildSubscription and
buildSubscriptionWithBackoff, then perform a bridging backfill loop
after the initial backfill completes to cover any gap before entering
the subscription loop.

Resolves xmtp#1889

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@xmtp-coder-agent xmtp-coder-agent requested a review from a team as a code owner March 30, 2026 15:36
xmtp-coder-agent and others added 2 commits March 30, 2026 17:34
…kfill

- GetNextPage now returns NextBlockNumber on ErrEndOfBackfill so the
  caller advances past already-fetched blocks instead of re-fetching
  from the original start block
- Remove redundant if-check before bridging loop
- Simplify test: replace goto + redundant verification with simple loop

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GetNextPage returns nil NextBlockHash on ErrEndOfBackfill since the
next block header can't be fetched beyond the chain head. Preserve
the existing backfillFromBlockHash when NextBlockHash is nil to
prevent NewUpdateProgressLog from panicking on a zero-length slice
to [32]byte conversion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@neekolas
Copy link
Copy Markdown
Contributor

neekolas commented Apr 1, 2026

I don't know enough about the indexer to be able to properly review this. The original issue came from the security audit, even though it's a correctness issue. @fbac do you mind taking a look at #1889 and seeing if it makes sense.

The high level premise is that RPC providers might load balance your requests to different instances, and the web socket and HTTP request could be in different states.

The solution looks a little ugly and over-complicated, but it does seem like a real (even if edge) potential issue. Would be very bad if our indexer could skip over messages.

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.

Subscription FromBlock set to WS head without bridging backfill in RPC log streamer causes missed head-of-chain logs

2 participants