feat(loadtest): nonce-too-low fast-forward and --reverse-nonce-order - #997
Open
praetoriansentry wants to merge 3 commits into
Open
feat(loadtest): nonce-too-low fast-forward and --reverse-nonce-order#997praetoriansentry wants to merge 3 commits into
praetoriansentry wants to merge 3 commits into
Conversation
When a send fails with a geth-style "nonce too low: next nonce X, tx nonce Y" error, parse the next nonce from the message and fast-forward the account's local nonce to it instead of grinding through stale nonces one failed transaction at a time. The nonce is never rewound, so stale error messages can't undo progress made by concurrent in-flight transactions, and reusable nonces below the new value are dropped. If the message doesn't match this exact format, behavior is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… txpool dynamics Each sending account computes its planned nonce range from the test parameters (concurrency * requests / number of accounts) and sends transactions in descending nonce order, from the top of the range down to its current nonce. All txs except the last per account land in the queued pool, and the final tx at the base nonce promotes the whole chain to pending at once. Constraints enforced at startup: - total requests must divide evenly across sending accounts - requires --fire-and-forget (waiting for receipts of queued txs would deadlock) - incompatible with --wait-for-receipt, --eth-call-only, --duplicate-nonce-rate, and --adaptive-rate-limit (its pending-tx probe assumes ascending nonces) The nonce-too-low fast-forward is skipped in reverse mode since jumping the counter forward would corrupt the descending sequence. Failed nonces are re-sent as-is via the existing reusable-nonce queue without moving the descending counter. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
obynonwane
approved these changes
Aug 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Two nonce-management features for
polycli loadtest:1. Fast-forward account nonce on nonce-too-low errors
When a send fails with a geth-style
nonce too low: next nonce X, tx nonce Yerror, the account's local nonce is fast-forwarded to thenext noncevalue parsed from the message, instead of grinding through stale nonces one failed transaction at a time. Only this exact message format is parsed; anything else keeps the existing increment behavior (noRefreshNoncefallback). The nonce is never rewound, so stale error messages from concurrent in-flight transactions can't undo progress, and reusable nonces below the new value are dropped since the network already considers them consumed.2.
--reverse-nonce-orderflagEach sending account computes its planned nonce range from the test parameters (
concurrency × requests / number of accounts) and sends transactions in descending nonce order, from the top of the range down to its current nonce. All txs except the last per account land in the queued pool, and the final tx at the base nonce promotes the whole chain to pending at once — useful for stressing queued vs pending txpool dynamics.Constraints enforced at startup, before any funding or sending:
--fire-and-forget(waiting for receipts of queued txs would deadlock)--wait-for-receipt,--eth-call-only,--duplicate-nonce-rate, and--adaptive-rate-limit(its pending-tx probe assumes ascending nonces)The nonce-too-low fast-forward is skipped in reverse mode since jumping the counter forward would corrupt the descending sequence. Failed nonces are re-sent as-is via the existing reusable-nonce queue without moving the descending counter.
--time-limitis allowed but logs a warning, since stopping early strands queued transactions.No breaking changes; both features are additive and default-off.
Jira / Linear Tickets
Testing
go test -race ./loadtest/...— new unit tests cover the nonce-too-low regex parsing,FastForwardNonce(fast-forward, no-rewind, reusable-nonce pruning),PrepareReverseNonces(offsets, overflow, not-ready), reverse round-robinNext()sequencing and exhaustion, reusable-nonce retry in reverse mode, the per-account divisibility math, and all flag-combination validationsmake build,go vet,shadowpass; docs regenerated viadocutil--reverse-nonce-orderwithout--fire-and-forgetand with--adaptive-rate-limitare rejected at startup with clear errors🤖 Generated with Claude Code