Skip to content

Conversation

@0u-Y
Copy link

@0u-Y 0u-Y commented Jan 20, 2026

Motivation

Fixes #3408

When blocks are missed, transactions could poll forever if their confirmation block was in the missed range.

Example from the issue on Arbitrum:

DEBUG alloy_provider::heart: handling block block_height=413480103
DEBUG alloy_provider::heart: watching tx=0xa957...
DEBUG alloy_provider::heart: handling block block_height=413480111
DEBUG alloy_provider::heart: reorg/unpause detected

Transaction was confirmed in block 413480106, but blocks 104-110 were not observed -> watch_pending_transaction polls forever.
The existing code only handled unconfirmed transactions during large gaps, but transactions in waiting_confs were not moved back to unconfirmed, causing them to wait forever even though their confirmation block was missed.

Solution

Modified move_reorg_to_unconfirmed to move gap-affected transactions from waiting_confs back to unconfirmed before timeout. Transactions are timed out when gap >= 10 blocks to balance between handling legitimate reorgs and preventing infinite polling.
Added 3 tests covering large gaps (>= 10), small gaps (< 10), and transactions confirmed within missed blocks.

PR Checklist

  • Added Tests
  • Added Documentation
  • Breaking changes

Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

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

I think this makes sense for blocktimes like on arb

would like to see some docs because this isnt super obvious what this check does

Comment on lines 555 to 558
let gap_size = new_height.saturating_sub(last_height + 1);
const MAX_RECOVERABLE_GAP: u64 = 10;

if gap_size >= MAX_RECOVERABLE_GAP {
Copy link
Member

Choose a reason for hiding this comment

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

not immediately clear what this does

can we add some docs for this

Copy link
Author

Choose a reason for hiding this comment

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

Added documentation explaining why the threshold is set to 10 blocks. Thanks for the feedback!

@github-project-automation github-project-automation bot moved this to In Progress in Alloy Jan 20, 2026
@0u-Y 0u-Y requested a review from mattsse January 21, 2026 04:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

[Bug] watch_pending_transaction will never pause heartbeat if transaction is missed due to reorg when calling get_receipt

2 participants