Evm nonce error fix - #5442
Open
mpapierski wants to merge 18 commits into
Open
Evm nonce error fix#5442mpapierski wants to merge 18 commits into
mpapierski wants to merge 18 commits into
Conversation
Exercise two transactions accepted against the same pre-state nonce and included in one block. The second transaction must become a zero-cost precondition failure without stopping the reactor or changing state.
Compare each EVM nonce with the evolving block state before creating payment effects. Record a zero-cost transaction failure when an earlier transaction in the same block has already advanced that nonce.
Cover intrinsic gas, Prague calldata floors, oversized initcode, nonce overflow, and senders with deployed code. Each case must produce a zero-cost transaction failure without stopping the reactor or changing state.
Run revm transaction validation against the evolving block state before creating payment effects. Convert every current validation rejection into a per-transaction error so malformed execution requests cannot stop the reactor.
Require block-included EVM transactions to retain the EVM execution result shape when a precondition rejects them. Sidecar relies on that variant to project receipts for every EVM transaction in a block.
Build an EVM receipt for every rejected block-included EVM request and carry the precondition error alongside it. This keeps receipt projection consistent while retaining a useful error message for clients.
Send a validly signed transaction whose value cannot be represented by a Casper purse. The transaction must fail without stopping the reactor, charging fees, advancing the nonce, or changing total supply.
Run EVM request validation before required-balance calculation. A value that contains fractional motes can then become a transaction-scoped precondition failure instead of a fatal payment conversion error.
Exercise a signed transaction that offers an effective priority fee on a network that does not support transaction prioritization. It must be rejected without reactor failure or state changes.
Repeat transaction-acceptor chainspec checks in the execution precondition path. Proposed transactions can bypass the acceptor, so policy violations must still become per-transaction failures.
Transfer one wei from a newly created contract and self-destruct it in the same transaction. Require execution to succeed, report one mote of dust, preserve supply for later consumption, and avoid reactor failure.
Combine balances removed by self-destruct with remaining wei before converting the execution outcome to motes. Avoid pruning state keys that were created and destroyed within the same transaction.
Show that signature validation alone accepts a peer-fetched transaction whose value cannot be represented in motes. Block validation must still reject that transaction before accepting the proposal.
Show that peer fetch validation accepts a correctly signed transaction with an unsupported effective priority fee. Require proposal validation to apply the missing chainspec policy check.
Apply EVM chainspec compliance while creating transaction footprints. This covers both the transaction buffer and proposed-block validation, so peer-fetched policy violations never reach block execution.
Tell future changes to reject malformed network-reachable input or record per-item failures. Reserve fatal reactor announcements for internal invariants and unrecoverable local state.
mpapierski
requested review from
EdHastingsCasperAssociation,
darthsiroftardis and
zajko
September 17, 2026 14:50
Provide a testnet-derived chainspec with EVM and addressable entities enabled. Add a mainnet-derived node config with speculative execution and temporary higher request limits for sidecar. Update the devnet documentation to consume the checked-in EVM resources directly.
zajko
approved these changes
Sep 18, 2026
| Transaction(String), | ||
| /// revm rejected the transaction during pre-execution validation. | ||
| #[error("EVM transaction validation failed: {0}")] | ||
| InvalidTransaction(#[source] EvmTransactionError), |
Contributor
There was a problem hiding this comment.
nit: could you attach this at the end?
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.
On an EVM-enabled network, two transactions with the same nonce could be accepted against the same pre-state and included in one block.
The first transaction advanced the sender’s nonce. When the second transaction was executed, revm rejected it because its nonce was now stale:
We treated that validation error as a transaction-conversion failure. It then became a fatal control announcement and stopped the reactor.
A transaction that becomes invalid during block execution should fail on its own. It should not stop the node.
What this PR changes
EVM preconditions are now checked against the current block state before payment processing and execution. A rejected transaction produces a failed
ExecutionResult::Evmwith zero cost, no state changes, and a useful error message.This also closes paths where a transaction received while validating a proposed block could bypass checks normally performed by the transaction acceptor. EVM chainspec compliance is now checked when creating the transaction footprint, before the transaction enters a block or the transaction buffer.
The same handling is applied to the currently known revm transaction-validation errors, including:
We also reject unsupported EVM values containing fractional motes and transactions with a positive effective priority fee before they can reach a fatal execution path.
Regression coverage
The regression tests cover:
SELFDESTRUCTFor rejected transactions, the tests confirm that:
ExecutionResult::EvmSELFDESTRUCT dust accounting
A separate regression exposed an accounting problem when a contract transferred a sub-mote amount and was then destroyed. This amount is aggregated in the transaction outcome and will be burned.