Skip to content

test(requester): add BatchTxPool wedge → recovery e2e test - #988

Merged
vishalchangrani merged 1 commit into
mpeter/solidify-tx-mempoolfrom
vishal/pr986-wedge-recovery-e2e-test
Aug 19, 2026
Merged

test(requester): add BatchTxPool wedge → recovery e2e test#988
vishalchangrani merged 1 commit into
mpeter/solidify-tx-mempoolfrom
vishal/pr986-wedge-recovery-e2e-test

Conversation

@vishalchangrani

Copy link
Copy Markdown
Contributor

Stacked on top of #986.

Why

#986 changes BatchTxPool to solidify it as a legitimate mempool, and its staleEntry eviction is what closes the wedge described in #983 (comment): a Cadence wrapper reverts, on-chain state stays at N, but the pool's lastSubmittedNonce marker is at N — every retry hits ErrInFlightNonce until the queue is evicted.

The PR ships Test_BatchTxPool_InFlightNonceRejection, which proves the wedge state is entered. What was missing was a test proving the wedge exits within TxBatchInterval * stalenessFactor (~10s at mainnet timings).

What the test does

  1. Freezes on-chain state by disabling auto-mine (this is load-bearing — see below).
  2. Sends tx1 at nonce 0 → fast-path submits, pool sets lastSubmittedNonce = 0.
  3. Sends tx2 at nonce 0 with a different payload → asserts ErrInFlightNonce. Wedge confirmed.
  4. Sleeps TxBatchInterval * stalenessFactor + 2s cushion (12s total).
  5. Sends tx3 at nonce 0 with another different payload → asserts submission succeeds. Wedge cleared.

Why the auto-mine has to be off

Without freezing state, validateTransactionWithState (services/requester/requester.go:224) intercepts every retry with ErrNonceTooLow as soon as tx1 mines and state indexes to 1 — that happens in ~1–3s regardless of pool implementation, so the pool's own eviction timing is never exposed. This is also the reason the wedge cannot be reproduced or measured on testnet: state validation always preempts before the pool's staleEntry window elapses.

Test plan

  • go test ./ -run Test_BatchTxPool_WedgeRecovery -v passes in ~16s (10s staleness + 2s cushion + fixture cost)
  • Existing Test_BatchTxPool_InFlightNonceRejection still passes — this test doesn't share state with it

🤖 Generated with Claude Code

Reproduces the wedge state from #983 (Cadence wrapper reverts before
advancing state, leaving the pool's in-flight marker ahead of the
on-chain frontier) and asserts BatchTxPool clears it within
TxBatchInterval*stalenessFactor. Auto-mine is disabled so the pool's
staleEntry timing is exposed - otherwise validateTransactionWithState
preempts once state catches up, masking the pool's recovery.

This is the counterpart to Test_BatchTxPool_InFlightNonceRejection,
which only verifies the wedge state is entered, not that it recovers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f3cafa82-737a-4940-b3e8-e3fc0e1c9837

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@m-Peter m-Peter left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM!

@vishalchangrani
vishalchangrani merged commit cb4995e into mpeter/solidify-tx-mempool Aug 19, 2026
2 checks passed
@vishalchangrani
vishalchangrani deleted the vishal/pr986-wedge-recovery-e2e-test branch August 19, 2026 19:02
@github-project-automation github-project-automation Bot moved this from 👀 In Review to ✅ Done in 🌊 Flow 4D Aug 19, 2026
vishalchangrani added a commit that referenced this pull request Aug 20, 2026
#986)

* Rework BatchTxPool functionality to a legitimate Ethereum tx mempool

* Address review comments

* Log transaction submissions from BatchTxPool

* Close the window between batch detachment and the lastSubmittedAt update

* Deprecate --eoa-activity-cache-ttl CLI flag as it is no longer applicable

* Reject transactions with in-flight nonces

* Solidify BatchTxPool rework: fix log tag, race, sizing, and add unit tests

- flush success log tagged as flushReasonPrefix (metric already correct)
- flush success/failure paths merge lastSubmittedNonce/At with max() so a
  concurrent Add() fast-path is never regressed by a stale ack or rollback
- eoaEnqueueTxs preserves an existing same-nonce entry: last-write-wins
  keeps a client's fresher payload over a re-queued failed batch
- rename maxEOAPoolSize -> maxNonceLookahead (that's what it enforces and
  add a real per-EOA size cap at admission time via maxEOAQueueSize +
  ErrTxPoolFull
- staleEntry no longer marks a freshly-created queue (zero lastSubmittedAt)
  as stale
- selectSequentialNonces walks the nonce-keyed map directly (O(k)) instead
  of sorting the full queue every tick
- add batch_tx_pool_test.go: txQueue primitives + rollback preserve-fresh

* Revert logic change on staleEntry()

* Move state index nonce read after the duplication, in-flight checks

* Update comments on the new logic of BatchTxPool

* Remove unused from field from batchSubmission type

* Re-use eoaQueueEntry() in eoaEnqueueTxs()

* Move the cap check to just before the enqueue, so fast-path-eligible txs bypass it

* Prune transactions that exceed the queue TTL

* Cap retries per tx and drop with a WARN + TransactionsDropped after N attempts

* Add unit tests for ErrTxPoolFull and the flush failure/success merge branches

* Reset txQueue retries on submission success

* Update stalenessFactor so that it's about 10 seconds with the current tx-batch-interval

* Fix comment on eoaEnqueueTxs boolean value

Co-authored-by: Leo Zhang <zhangchiqing@gmail.com>

* Move rollback of nonce range reservation to eoaEnqueueTxs()

* Add comments on the fields of batchSubmission type

* Distinguish the 2 cases for fast-path submission for logging

* Guard elapsed spacing in processPooledTransactions() and add an E2E test

* test(requester): add BatchTxPool wedge -> recovery e2e test (#988)

Reproduces the wedge state from #983 (Cadence wrapper reverts before
advancing state, leaving the pool's in-flight marker ahead of the
on-chain frontier) and asserts BatchTxPool clears it within
TxBatchInterval*stalenessFactor. Auto-mine is disabled so the pool's
staleEntry timing is exposed - otherwise validateTransactionWithState
preempts once state catches up, masking the pool's recovery.

This is the counterpart to Test_BatchTxPool_InFlightNonceRejection,
which only verifies the wedge state is entered, not that it recovers.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: vishal <1117327+vishalchangrani@users.noreply.github.com>
Co-authored-by: Leo Zhang <zhangchiqing@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

2 participants