fix: keep tx in pool when pre-simulation hits a non-transaction error#540
Open
mooncitydev wants to merge 1 commit into
Open
fix: keep tx in pool when pre-simulation hits a non-transaction error#540mooncitydev wants to merge 1 commit into
mooncitydev wants to merge 1 commit into
Conversation
the top-of-block pre-simulator evicts a tx whenever evm.transact returns an error that isn't a nonce gap. but transact also errors when the state read itself fails, e.g. the pinned tip state was reorged out or pruned before the background sim task ran. that comes back as EVMError::Database, which isn't a nonce error, so a valid revert-protected tx gets silently dropped from the pool (and in the override path the sender already got a Pending response back, so from their side it just vanishes). only InvalidTransaction errors say anything about the tx, so evict on those and fail open on everything else, matching how nonce gaps are already handled. pulled the decision into a small helper and added unit tests for the db/custom, nonce and fund cases.
julio4
reviewed
Jun 16, 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.
hey, its moondev. was reading through the pre-simulation path and i think this one is a real bug rather than a nitpick.
what happens
in
crates/op-rbuilder/src/pool/presim.rs,run_simulationruns a revert-protected tx through the evm against the pinned tip state and decides whether to keep it in the pool:Ok(..)=> keep only if it didn't revertErr(..)=> keep only if it's aNonceTooLow/NonceTooHigh(the pool can still order those), otherwise drop itthe problem is that last "otherwise drop it" branch.
evm.transactdoesn't only fail because the tx is invalid, it also fails when the state read itself fails. the tip state is pinned to a specific block (state_by_block_hash(tip.hash_slow())), and by the time the background sim task actually runs that block can be reorged out or pruned. that surfaces asEVMError::Database(..), which isn't a nonce error, so the current code treats it like a revert and evicts the tx.so a transient state hiccup silently drops a valid, revert-protected tx. and in the override path (
pool/overrides.rs) the sender already gotAddedTransactionOutcome { state: Pending }back, so from their side the tx just disappears with no error. the only trace is adebug!("evicting reverting tx")line, which is misleading because it never reverted.alloy's
EvmErrortrait actually spells this out in its docs: "if caller occurs a error different fromEvmError::InvalidTransaction, it should most likely be treated as fatal error flagging some EVM misconfiguration." ie a non-InvalidTransactionerror is not a verdict on the tx.the fix
only evict on a genuine
InvalidTransaction(keeping the existing nonce-gap pass-through), and fail open on everything else with a warning so the failure is visible. behavior for real reverts and real validity errors (insufficient funds etc.) is unchanged. pulled the decision into a smallkeep_tx_on_simulation_errorhelper and added unit tests for the db/custom (kept), nonce (kept) and fund (evicted) cases.notes
i know the contributing guide likes an issue first, happy to open one if you'd prefer. also happy to adjust naming or add a metric for the fail-open case. cheers