Skip to content

[SharovBot] fix(txpool): evict zombie queued txns exceeding MaxNonceGap (cherry-pick #19449 → release/3.3)#19591

Merged
yperbasis merged 2 commits intorelease/3.3from
cherry-pick/txpool-nonce-gap-3.3
Mar 5, 2026
Merged

[SharovBot] fix(txpool): evict zombie queued txns exceeding MaxNonceGap (cherry-pick #19449 → release/3.3)#19591
yperbasis merged 2 commits intorelease/3.3from
cherry-pick/txpool-nonce-gap-3.3

Conversation

@Giulio2002
Copy link
Collaborator

[SharovBot]

Cherry-pick of #19449 onto release/3.3.

What

Evicts zombie queued transactions from senders whose nonce has advanced past MaxNonceGap (default: 64). These txns pile up in the queued sub-pool indefinitely without this fix, causing txpool_queued to grow unbounded (observed: 4.4K → 80-120 after fix on Gnosis/Sepolia validators).

Original PR

See #19449 for full description, rationale, and test coverage.

Changes

  • txpoolcfg/txpoolcfg.go: Added NonceTooDistant discard reason (37), MaxNonceGap config field (default 64)
  • txnprovider/txpool/pool.go: MaxNonceGap eviction logic in onSenderStateChange
  • txnprovider/txpool/pool_test.go: TestZombieQueuedEviction test (3 sub-cases)

Testing

All tests pass. Validated in production on Gnosis/Sepolia validator nodes.

…ap (#19449)

**[SharovBot]**

## Split from #19393 per @yperbasis review

This PR contains **Bug #2 only** (zombie queued transaction eviction),
extracted from #19393 which was asked to be split into separate PRs.

## Problem

Queued transactions with an impossibly large nonce gap (e.g. on-chain
nonce=281, queued nonce=16,814 — gap of 16,533) sit in the pool forever.
They can never become pending without filling thousands of nonce
positions first, causing unbounded queued pool bloat (4,000+ txns
observed on Gnosis Chain, Erigon 3.3.8).

The existing blob-txn nonce-gap eviction only covered `BlobTxnType`.
Regular transactions had no gap limit.

## Fix

- Add `MaxNonceGap uint64` to `txpoolcfg.Config` (default: 64)
- Add `NonceTooDistant` (DiscardReason 37) for observability
- In `onSenderStateChange`, evict txns whose nonce exceeds `noGapsNonce`
by more than `MaxNonceGap`
- `noGapsNonce` accounts for consecutive txns already pooled, so
consecutive txns are never zombie-evicted
- Fix `toDelReasons` parallel slice to track correct discard reason per
evicted tx (was always logging `NonceTooLow`)

## Tests

- `TestZombieQueuedEviction` — 3 sub-tests:
1. Zombie tx (gap=65 > MaxNonceGap=64) is evicted with `NonceTooDistant`
  2. Tx at exactly MaxNonceGap boundary (gap=64) is kept
  3. Consecutive txns beyond MaxNonceGap are never zombie-evicted

## Testing

```
go build ./txnprovider/txpool/... ✅
go test ./txnprovider/txpool/... -run TestZombieQueuedEviction -count=1 ✅
```

## Related

- Bug #1 (stale pending / AuRa nonce) will be addressed separately per
@yperbasis feedback
- Backport to release/3.3 will follow once this is merged
- Original combined PR: #19393
Copy link
Member

@yperbasis yperbasis left a comment

Choose a reason for hiding this comment

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

CI is red

…h{} for release/3.3 compat

EmptyCodeHash is not exported in the release/3.3 accounts package; use the
zero-value common.Hash{} instead. Functionally identical for nonce-eviction tests.
@yperbasis yperbasis merged commit ae344d1 into release/3.3 Mar 5, 2026
11 checks passed
@yperbasis yperbasis deleted the cherry-pick/txpool-nonce-gap-3.3 branch March 5, 2026 08:30
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.

2 participants