feat: top-of-block pre-simulation to filter reverting tx spam#62
Closed
dmarzzz wants to merge 1 commit into
Closed
feat: top-of-block pre-simulation to filter reverting tx spam#62dmarzzz wants to merge 1 commit into
dmarzzz wants to merge 1 commit into
Conversation
Adds a new `PreSimulateOrders` pipeline step that simulates pending pool transactions at the top of each new block before the flashblock building loop starts. Transactions that revert during pre-simulation are removed from the pool, preventing them from consuming block building time on the critical path. Inspired by rbuilder's `OrderSimulationPool`. Uses a random coinbase during simulation (configurable) to prevent adversaries from detecting the simulation environment by checking the COINBASE opcode. Step is placed after `OptimismPrologue` and `FlashtestationsPrologue` so it sees post-sequencer state. Only loose transactions are pre-simulated; bundles continue to be handled by the existing `RemoveRevertedTransactions` step during building. EVM-level errors (wrong nonce, insufficient balance) are treated as "keep" since they may become valid after earlier transactions execute. New CLI flags (both default true): --builder.presim --builder.presim-random-coinbase Verification: cargo check -- clean for new code cargo clippy -- clean for new code cargo fmt -- clean for new code Tests in src/tests/presim.rs validate that presim alone filters reverting txs when revert protection is disabled, that presim + revert protection both keep reverting txs out, and that valid txs are kept. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Member
Author
|
Wrong repo — redoing this in op-rbuilder where the work is actually needed. |
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.
Summary
PreSimulateOrderspipeline step that simulates pending pool transactions at the top of each block before the flashblock building loop, removing reverting txs from the pool so they never consume building time on the critical path.COINBASEopcode — same anti-gaming technique as rbuilder'sOrderSimulationPool.OptimismPrologue/FlashtestationsPrologueso it sees post-sequencer state. Bundles are deferred to the existingRemoveRevertedTransactionsstep. EVM-level errors (wrong nonce, etc.) are kept since they may become valid later.Why
Builder time is being burned simulating adversarial reverting txs during flashblock production.
RemoveRevertedTransactionscurrently filters them but only after the expensive simulation has already run on the critical path. This moves the filtering to the top of the block (once per payload job), so the flashblock loop sees a pre-cleaned pool.This is the L2 analogue of rbuilder's two-phase approach on L1: pre-sim → filter → build, with random coinbase so
tx.origin == known_builderstyle detection doesn't work.Configuration
Two new CLI flags (both default
true):--builder.presim(envPRESIM_ENABLED)--builder.presim-random-coinbase(envPRESIM_RANDOM_COINBASE)Metrics
New metrics emitted by the step:
txs_simulated_total,txs_dropped_total,gas_saved_total(counters)txs_simulated_per_job,txs_dropped_per_job,gas_saved_per_job(histograms)presim_duration(histogram, seconds)Test plan
cargo check— clean for new code (pre-existing flashtestations typos unrelated)cargo clippy— clean for new codecargo +nightly fmt --check— clean for new codecargo test --workspace --all-features— run full suitegrep "presim: dropping reverting transaction"in logs) and metrics are emitted--builder.presim-random-coinbase=falseand confirm a tx that branches onCOINBASEto revert can detect simulation (negative test for the anti-gaming property)Tests added (
src/tests/presim.rs)presim_filters_reverting_tx_without_revert_protection— the key test: presim ON, revert protection OFF. Proves presim alone is sufficient.presim_and_revert_protection_both_active— belt and suspenders.presim_keeps_valid_transactions— no false positives.Open questions / follow-ups
--builder.presim-time-budget=200ms) to bound the worst case if the pool is huge or sims are unusually expensive? Easy to add.remove_any_withremoves from both order pool and system pool. If a loose tx is also part of a bundle, the bundle gets dropped too. Unlikely in practice but worth flagging.🤖 Generated with Claude Code