Skip to content

Let a client retry a cursor this instance cannot resolve - #212

Merged
sduchesneau merged 5 commits into
developfrom
fix/retryable-unresolvable-cursor
Aug 17, 2026
Merged

Let a client retry a cursor this instance cannot resolve#212
sduchesneau merged 5 commits into
developfrom
fix/retryable-unresolvable-cursor

Conversation

@sduchesneau

@sduchesneau sduchesneau commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

What

firehose/server/blocks.go maps *stream.ErrUnavailable to codes.Unavailable, ahead of the existing *stream.ErrInvalidArgcodes.InvalidArgument branch.

bstream#63 returns that type for one case: the cursor names a block above the live head that did not arrive within CursorHeadWaitTimeout (5s). Nothing about it says the cursor is wrong — this instance may simply be lagging while another one already serves that block, which is what a client reconnecting to a fleet member a few blocks behind looks like. InvalidArgument would have that client throw away a good cursor; in the SQL sink it is one of four fatal codes (sink/sinker.go), so the process exits.

A cursor no source can resolve keeps its InvalidArgument mapping (firehose cannot handle that, even if substreams can)

Without this change the error falls to the default branch and reaches clients as Internal with the message replaced by "unexpected stream termination" — retryable in practice, unreadable in a log.

Measured

Against devel/standard (dummy chain), forging a cursor 500 blocks above head:

  • before bstream#63: silent until the merged bundle covering that block number lands
  • with bstream#63 alone: 5s wait, then Internal
  • with this change: 5s wait, then code = Unavailable, which the substreams sink logs as a retryable error

Mapping the failure to InvalidArgument had clients discard a cursor another
instance may well resolve, and the SQL sink exit on it.
@sduchesneau

sduchesneau commented Aug 17, 2026

Copy link
Copy Markdown
Contributor Author

🔍 Vulnerabilities of ghcr.io/streamingfast/firehose-core:395efc8-amd64

📦 Image Reference ghcr.io/streamingfast/firehose-core:395efc8-amd64
digestsha256:89282328b2239250b6faf3e120a2667c36312059d8442325a9d8ddb88904aeab
vulnerabilitiescritical: 0 high: 0 medium: 0 low: 0
platformlinux/amd64
size164 MB
packages509
📦 Base Image oisupport/staging-amd64:24.04
also known as
  • a215e986b44aae6f10795ded1e39ce93d9c236d8163d21a522ffd0ab3659f546
  • noble
  • noble-20260730.1
digestsha256:019e8eb29a85e74d64925745884f2ec79aa27e3feab36353d24656f4d6b89467
vulnerabilitiescritical: 0 high: 0 medium: 5 low: 4

@sduchesneau
sduchesneau marked this pull request as ready for review August 17, 2026 19:27

@maoueh maoueh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do we want to add a e2e test for it?

@sduchesneau

Copy link
Copy Markdown
Contributor Author

Do we want to add a e2e test for it?

no, that part is not important enough, the bstream unit tests are good enough for me.
The substreams part is more important and works well.

@sduchesneau
sduchesneau merged commit 4458bf2 into develop Aug 17, 2026
8 checks passed
@sduchesneau
sduchesneau deleted the fix/retryable-unresolvable-cursor branch August 17, 2026 20:01
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.

3 participants