Skip to content

fix(node): one stale-nonce transaction could halt the chain - #16

Merged
MehranMazhar merged 1 commit into
mainfrom
fix/stale-nonce-halts-chain
Sep 14, 2026
Merged

MehranMazhar merged 1 commit into
mainfrom
fix/stale-nonce-halts-chain

Conversation

@MehranMazhar

Copy link
Copy Markdown
Member

Stage stopped at block 84 on 2026-09-14 and stayed there. The cause was a single mint whose nonce the chain had already consumed, sitting in the transaction pool:

Verification failed: Incorrect nonce for transaction from
'0x662c5f11ed534ae93f29ed5e02a928081056f5f9'. Expected: 2, got: 1.

author_new_block puts the whole pool into its candidate block, so that one transaction failed validation and took every block with it. And a pooled transaction is deleted only by the import of a block carrying it — so it could never leave, and the chain could never produce again.

Restarting the nodes did not help and could not: the poison is in the database, not in process state. That is why two redeploys changed nothing.

Only the provably-permanent case is evicted

An account's nonce never decreases, so nonce <= last can never satisfy nonce == last + 1 again. A nonce above the next one is a gap that the transaction filling it may still close — those are left alone, or a busy pool would lose good work. A nonce that cannot be read is not evidence of anything and is also left alone.

Two tests: a consumed nonce is evicted, a gap is kept.

Related

The stall was invisible until #15 — the authoring error is logged at debug!, correctly for a per-tick failure, so three nodes sat at the same height for hours saying nothing. That change is what produced the message above.

This fixes the deadlock. It does not explain how the treasury came to submit a transaction with an already-consumed nonce, which is worth its own look.

🤖 Generated with Claude Code

Stage stopped at block 84 on 2026-09-14 and stayed there. The cause was a single mint whose nonce
the chain had already consumed, sitting in the transaction pool:

  Verification failed: Incorrect nonce for transaction from
  '0x662c5f11ed534ae93f29ed5e02a928081056f5f9'. Expected: 2, got: 1.

author_new_block puts the whole pool into its candidate block, so that one transaction failed
validation and took every block with it. And a pooled transaction is deleted only by the import of
a block carrying it -- so it could never leave, and the chain could never produce again. Restarting
the nodes did not help and could not: the poison is in the database.

Only the provably-permanent case is evicted. An account's nonce never decreases, so nonce <= last
can never satisfy nonce == last + 1 again. A nonce ABOVE the next one is a gap that the transaction
filling it may still close, and those are left alone; a nonce that cannot be read is not evidence
of anything and is also left alone.

Two tests: a consumed nonce is evicted, a gap is kept.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@MehranMazhar
MehranMazhar merged commit 76f7172 into main Sep 14, 2026
6 checks passed
@MehranMazhar
MehranMazhar deleted the fix/stale-nonce-halts-chain branch September 14, 2026 13:43
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