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
Richard1048576 added a commit to Richard1048576/gravity-reth that referenced this pull request Jul 12, 2026
Neutralise the EIP-7702 nonce-bump executor-halt class at the pre-execution transaction
filter, gated by a compile-time const EIP7702_LOCKDOWN (currently `true` — this build ships
it active) until the durable executor-skip fix (gravity-reth Galxe#388 + grevm Galxe#110) is deployed.

Three deterministic drops against certified block-start state, applied when the lockdown is on:
  L1  reject every type-4 (SetCode) tx      - no new delegations (covers audit#822)
  L2  drop any tx FROM a delegated account   - its execution-time CREATE cannot leave a
                                               same-block stale tx (audit#838)
  L3  drop any tx TO a delegated account      - no inbound CALL triggers the delegated CREATE

The filter's in-block simulation models the 7702 authorization-apply nonce bump (audit#822)
but not the execution-time CREATE bump (audit#838): a delegated account's current-nonce tx
reached the executor as NonceTooLow and panicked it at lib.rs:1137. Dropped txs are excluded
via the existing invalid_tx_idxs path, so the drop itself cannot halt the chain.

EIP7702_LOCKDOWN is a compile-time const (not a CLI/env flag) because it is consensus-critical:
a per-node value would fork the chain, so fleet-consistency is made structural by baking it
into the binary — the coordinated upgrade IS the binary version. Set it back to false and
rebuild to revert once the skip fix is deployed and 7702 can be re-enabled.

Trade-off: freezes delegated accounts' tx origination and disables new 7702 usage while active.

Tests: filter_invalid_txs takes an eip7702_lockdown param so the unit tests cover both states
(L1/L2/L3 + the audit#838 attack shape + non-delegated-traffic-unaffected). The full-pipeline
regression test test_finding_a_lockdown_survives_grevm drives OrderedBlock -> filter_invalid_txs
-> executor: with the lockdown the attack block survives; without it the executor panics at
lib.rs:1137 with NonceTooLow{tx:0,state:1}. The P-13/P-14 7702-delegation positive controls are
#[ignore]'d while the lockdown ships (7702 delegation is disabled by it).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Richard1048576 added a commit to Richard1048576/gravity-reth that referenced this pull request Jul 12, 2026
Neutralise the EIP-7702 nonce-bump executor-halt class at the pre-execution transaction
filter, gated by a compile-time const EIP7702_LOCKDOWN (currently `true` — this build ships
it active) until the durable executor-skip fix (gravity-reth Galxe#388 + grevm Galxe#110) is deployed.

Three deterministic drops against certified block-start state, applied when the lockdown is on:
  L1  reject every type-4 (SetCode) tx      - no new delegations (covers audit#822)
  L2  drop any tx FROM a delegated account   - its execution-time CREATE cannot leave a
                                               same-block stale tx (audit#838)
  L3  drop any tx TO a delegated account      - no inbound CALL triggers the delegated CREATE

The filter's in-block simulation models the 7702 authorization-apply nonce bump (audit#822)
but not the execution-time CREATE bump (audit#838): a delegated account's current-nonce tx
reached the executor as NonceTooLow and panicked it at lib.rs:1137. Dropped txs are excluded
via the existing invalid_tx_idxs path, so the drop itself cannot halt the chain.

EIP7702_LOCKDOWN is a compile-time const (not a CLI/env flag) because it is consensus-critical:
a per-node value would fork the chain, so fleet-consistency is made structural by baking it
into the binary — the coordinated upgrade IS the binary version. Set it back to false and
rebuild to revert once the skip fix is deployed and 7702 can be re-enabled.

Trade-off: freezes delegated accounts' tx origination and disables new 7702 usage while active.

Tests: filter_invalid_txs takes an eip7702_lockdown param so the unit tests cover both states
(L1/L2/L3 + the audit#838 attack shape + non-delegated-traffic-unaffected). The full-pipeline
regression test test_finding_a_lockdown_survives_grevm drives OrderedBlock -> filter_invalid_txs
-> executor: with the lockdown the attack block survives; without it the executor panics at
lib.rs:1137 with NonceTooLow{tx:0,state:1}. The P-13/P-14 7702-delegation positive controls are
#[ignore]'d while the lockdown ships (7702 delegation is disabled by it).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
nekomoto911 pushed a commit that referenced this pull request Jul 12, 2026
…alt (#389)

Neutralise the EIP-7702 nonce-bump executor-halt class at the pre-execution transaction
filter, gated by a compile-time const EIP7702_LOCKDOWN (currently `true` — this build ships
it active) until the durable executor-skip fix (gravity-reth #388 + grevm #110) is deployed.

Three deterministic drops against certified block-start state, applied when the lockdown is on:
  L1  reject every type-4 (SetCode) tx      - no new delegations (covers audit#822)
  L2  drop any tx FROM a delegated account   - its execution-time CREATE cannot leave a
                                               same-block stale tx (audit#838)
  L3  drop any tx TO a delegated account      - no inbound CALL triggers the delegated CREATE

The filter's in-block simulation models the 7702 authorization-apply nonce bump (audit#822)
but not the execution-time CREATE bump (audit#838): a delegated account's current-nonce tx
reached the executor as NonceTooLow and panicked it at lib.rs:1137. Dropped txs are excluded
via the existing invalid_tx_idxs path, so the drop itself cannot halt the chain.

EIP7702_LOCKDOWN is a compile-time const (not a CLI/env flag) because it is consensus-critical:
a per-node value would fork the chain, so fleet-consistency is made structural by baking it
into the binary — the coordinated upgrade IS the binary version. Set it back to false and
rebuild to revert once the skip fix is deployed and 7702 can be re-enabled.

Trade-off: freezes delegated accounts' tx origination and disables new 7702 usage while active.

Tests: filter_invalid_txs takes an eip7702_lockdown param so the unit tests cover both states
(L1/L2/L3 + the audit#838 attack shape + non-delegated-traffic-unaffected). The full-pipeline
regression test test_finding_a_lockdown_survives_grevm drives OrderedBlock -> filter_invalid_txs
-> executor: with the lockdown the attack block survives; without it the executor panics at
lib.rs:1137 with NonceTooLow{tx:0,state:1}. The P-13/P-14 7702-delegation positive controls are
#[ignore]'d while the lockdown ships (7702 delegation is disabled by it).

Co-authored-by: Richard1048576 <178553006+Richard1048576@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Richard1048576
Richard1048576 requested a review from AshinGau July 13, 2026 02:13
Lchangliang pushed a commit that referenced this pull request Jul 24, 2026
Neutralise the EIP-7702 nonce-bump executor-halt class at the pre-execution transaction
filter, gated by a compile-time const EIP7702_LOCKDOWN (currently `true` — this build ships
it active) until the durable executor-skip fix (gravity-reth #388 + grevm #110) is deployed.

Three deterministic drops against certified block-start state, applied when the lockdown is on:
  L1  reject every type-4 (SetCode) tx      - no new delegations (covers audit#822)
  L2  drop any tx FROM a delegated account   - its execution-time CREATE cannot leave a
                                               same-block stale tx (audit#838)
  L3  drop any tx TO a delegated account      - no inbound CALL triggers the delegated CREATE

The filter's in-block simulation models the 7702 authorization-apply nonce bump (audit#822)
but not the execution-time CREATE bump (audit#838): a delegated account's current-nonce tx
reached the executor as NonceTooLow and panicked it at lib.rs:1137. Dropped txs are excluded
via the existing invalid_tx_idxs path, so the drop itself cannot halt the chain.

EIP7702_LOCKDOWN is a compile-time const (not a CLI/env flag) because it is consensus-critical:
a per-node value would fork the chain, so fleet-consistency is made structural by baking it
into the binary — the coordinated upgrade IS the binary version. Set it back to false and
rebuild to revert once the skip fix is deployed and 7702 can be re-enabled.

Trade-off: freezes delegated accounts' tx origination and disables new 7702 usage while active.

Tests: filter_invalid_txs takes an eip7702_lockdown param so the unit tests cover both states
(L1/L2/L3 + the audit#838 attack shape + non-delegated-traffic-unaffected). The full-pipeline
regression test test_finding_a_lockdown_survives_grevm drives OrderedBlock -> filter_invalid_txs
-> executor: with the lockdown the attack block survives; without it the executor panics at
lib.rs:1137 with NonceTooLow{tx:0,state:1}. The P-13/P-14 7702-delegation positive controls are
#[ignore]'d while the lockdown ships (7702 delegation is disabled by it).

Co-Authored-By: Claude Opus 4.8 (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

None yet

Development

Successfully merging this pull request may close these issues.

1 participant