Skip to content

feat(exec): opt into grevm deterministic skip of tx-level-invalid txns#388

Open
Richard1048576 wants to merge 1 commit into
Galxe:mainfrom
Richard1048576:feat/exec-opt-in-skip-invalid-txn
Open

feat(exec): opt into grevm deterministic skip of tx-level-invalid txns#388
Richard1048576 wants to merge 1 commit into
Galxe:mainfrom
Richard1048576:feat/exec-opt-in-skip-invalid-txn

Conversation

@Richard1048576

@Richard1048576 Richard1048576 commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

Draft — merge after Galxe/grevm#110. This is the
greth-side consumer of that grevm feature; the grevm rev here is pinned to #110's branch head
and must be re-pointed to the merged grevm commit before this lands.

What

Opts the parallel executor into grevm's deterministic skip of tx-level-invalid transactions:

let executor = Scheduler::new(cfg_env, block_env, txs, state, false, precompiles)
    .with_skip_invalid_txn(true);

One call in crates/ethereum/evm/src/parallel_execute.rs, plus a grevm rev bump in the
workspace Cargo.toml.

Why

Gravity is order-then-execute: consensus commits an ordered block whose per-tx validity
cannot be fully pre-screened, because some invalidity is execution-induced and unmodelable
without executing — e.g. a CREATE/CREATE2 run by an EIP-7702-delegated authority bumps that
account's nonce a second time, so a same-block follow-up tx becomes NonceTooLow only at
execution (gravity-audit#838). Today any such tx makes parallel_execute return Err, which the
node turns into panic!whole-network halt.

With grevm#110 and this opt-in, the executor deterministically skips the offending tx
(re-checked against the committed pre-state in grevm's sequential fallback; no state change, a
phantom 0-gas result keeps results aligned 1:1) and keeps producing blocks. This is the durable
close-out of the halt class (gravity-audit#823) — the pre-execution tx_filter completeness stops
being a halt-safety requirement and becomes only a liveness/efficiency optimization.

The stopgap #387 narrows #838's reachability at
the filter; this PR removes the halt at its root in the executor.

Deployment — this is an STF change

A bad tx goes from halt to skip, so the state-transition function changes. Deploy as a
coordinated ungated upgrade (like the filter fixes) or behind a hardfork gate. Mixed versions
cause a liveness stall, not a state fork — only the skip result exists, so a non-upgraded node
stalls rather than forking. The executor's panic! stays as the backstop for genuinely-fatal
conditions (state-root divergence, storage/IO); only tx-level EVMError::Transaction is
downgraded to skip.

Verification

Validated on a 4-validator Prague devnet with the EIP-7702 authority-nonce halt pair (built into
gravity_node, driven via RPC):

mode result
opt-in ON skipping tx-level-invalid tx ... txid=1 err=NonceTooLow{tx:1,state:2}; chain keeps producing; all 4 validators produce a byte-identical block (same hash) and keep advancing → deterministic, no fork
opt-in OFF (grevm default) node aborts on the same block — original halt behaviour preserved (non-breaking)

Related

Update — ready for review; two things gate the actual merge

  1. Consumed grevm now has the parallel-path fix. A review found grevm#110's skip was bypassed
    on the parallel path (block_size >= MIN_PARALLEL_TXS): a NonceTooLow is committer-detected
    and parallel_execute returned Err before the skip → the caller still panicked. Fixed
    (routes commit-detected tx-level errors to fallback_sequential). Verified with a 102-tx block.

  2. revm-version alignment (blocks merge). grevm main is on revm 40, but gravity-reth is on
    revm 29, so grevm#110's PR head (revm 40) is not consumable here. This PR therefore pins the
    revm-29 backport of the same feature+fix (Richard1048576/grevm feat/skip-invalid-txn-optin-revm29
    @ d0d0911e). Before merge, the team should decide: (a) upstream the revm-29 backport into
    Galxe/grevm and re-point here, or (b) upgrade gravity-reth to revm 40 and consume grevm#110
    directly. Also: this is an STF change (bad tx: halt → skip) → deploy as a coordinated
    ungated upgrade or behind a hardfork gate, with with_skip_invalid_txn flipped network-wide
    together.

Note: this opt-in is now the durable close-out for the RPC-reachable #838 halt (the earlier
"byzantine-only" assessment was corrected — an already-delegated account makes it reachable by an
honest proposer), so it moved from "not urgent" to "should prioritize".

Wire ParallelExecutor to grevm's with_skip_invalid_txn(true): a tx-level-
invalid tx (EVMError::Transaction, e.g. NonceTooLow from an EIP-7702
delegate-then-CREATE nonce double-bump) is deterministically skipped in
grevm's sequential fallback instead of panicking the whole block — closing
the execution-induced halt class the pre-execution filter cannot model
(gravity-audit#838, durable close-out of #823).

STF change (bad tx: halt -> skip); deploy behind a coordinated upgrade.
Bumps grevm rev to the grevm#110 branch head for the method; re-point to
the merged grevm commit before merge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Richard1048576 Richard1048576 force-pushed the feat/exec-opt-in-skip-invalid-txn branch from 4e9184a to a74a388 Compare July 12, 2026 07:48
@Richard1048576 Richard1048576 marked this pull request as ready for review July 12, 2026 07:48
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.

1 participant