feat(exec): opt into grevm deterministic skip of tx-level-invalid txns#388
Open
Richard1048576 wants to merge 1 commit into
Open
feat(exec): opt into grevm deterministic skip of tx-level-invalid txns#388Richard1048576 wants to merge 1 commit into
Richard1048576 wants to merge 1 commit into
Conversation
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
force-pushed
the
feat/exec-opt-in-skip-invalid-txn
branch
from
July 12, 2026 07:48
4e9184a to
a74a388
Compare
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>
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>
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.
What
Opts the parallel executor into grevm's deterministic skip of tx-level-invalid transactions:
One call in
crates/ethereum/evm/src/parallel_execute.rs, plus agrevmrev bump in theworkspace
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/CREATE2run by an EIP-7702-delegated authority bumps thataccount's nonce a second time, so a same-block follow-up tx becomes
NonceTooLowonly atexecution (gravity-audit#838). Today any such tx makes
parallel_executereturnErr, which thenode 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
resultsaligned 1:1) and keeps producing blocks. This is the durableclose-out of the halt class (gravity-audit#823) — the pre-execution
tx_filtercompleteness stopsbeing 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-fatalconditions (state-root divergence, storage/IO); only tx-level
EVMError::Transactionisdowngraded 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):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 forkRelated
Update — ready for review; two things gate the actual merge
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): aNonceTooLowis committer-detectedand
parallel_executereturnedErrbefore the skip → the caller still panicked. Fixed(routes commit-detected tx-level errors to
fallback_sequential). Verified with a 102-tx block.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 intoGalxe/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_txnflipped network-widetogether.
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".