EVM#5410
Open
mpapierski wants to merge 15 commits into
Open
Conversation
Add shared EVM-native types, global-state keys and stored values, chainspec configuration, and a new casper-executor-evm crate backed by revm. The executor runs against a caller-provided TrackingCopy so callers can decide whether to commit effects or discard a forked view execution. This introduces typed EVM account, bytecode, and storage records so contract state can be queried and pruned by address prefix. EVM balances are backed by deterministic Casper main purses, with balance reads and writes reconciled through existing purse balance storage. Signed Ethereum RLP decoding and sender recovery are added to casper-types for legacy, EIP-2930, and EIP-1559 transactions. Blob transactions and EIP-7702 set-code transactions return explicit unsupported errors in this first pass. The node and storage layers learn the new transaction/hash/initiator shapes without routing EVM transactions through existing Casper transaction execution yet. Chainspecs now include disabled-by-default EVM configuration with CSP namespace chain IDs. Solidity fixtures, Makefile targets, and integration tests cover deployment, calls, ERC20/ERC721 behavior, storage deletion, selfdestruct semantics, and native EVM purse-balance reconciliation.
Require signed EVM transactions to carry the configured chain ID so legacy pre-EIP-155 transactions cannot bypass the Casper EVM replay domain. Reject non-empty Ethereum access lists until the executor maps them into revm transaction environments. Add explicit validation modes for unsigned call requests so simulation calls remain available while commit-capable calls can opt into revm balance, nonce, chain-id, base-fee, and gas-limit checks. Add a block hash provider abstraction for the EVM BLOCKHASH opcode, including an LMDB-backed provider for future node wiring and tests for the 256-block lookup window. Complete selfdestruct cleanup by pruning the deterministic main purse balance alongside the EVM account and storage.# Please enter the commit message for your changes. Lines starting
Bump the pinned stable Rust toolchain from 1.85.1 to 1.91.0 so the workspace can use dependencies that require the newer compiler. Keep the existing Makefile lint gate on -D warnings while allowing lint categories that were introduced or tightened by newer clippy versions and would otherwise force unrelated API churn. Apply small mechanical updates and targeted dead-code annotations needed for the 1.91.0 lint run.
Allow native transfer targets to be encoded as 20-byte EVM addresses when EVM support is enabled. Resolve those targets to existing EVM account purses or create deterministic EVM account records on first funding, while preserving the native transfer record schema. Stop seeding EVM accounts at genesis and require explicit funding through native transfers. Reject EVM address transfer targets when EVM is disabled, add the binary-port error code, and cover the genesis and transfer behavior with tests. Document the explicit EVM funding flow and add CL typing/schema support for EVM addresses.
EVM addresses and Casper account hashes come from different preimages, so using the same signing key currently gives users two separate identities. This change adds a small identity record under `EvmAddr::Account` so an EVM address can point either at an existing Casper account or at an EVM-native purse. The old EVM account blob is split into separate records for identity, nonce, code hash, bytecode, and storage. Runtime and transaction validation now resolve the EVM sender before balance and nonce checks, while the executor only reads and writes the new layout. When an EVM transaction is signed by a key that already has a Casper account, the runtime links the EVM sender address to that account. When no Casper account exists yet, it creates one using the deterministic EVM purse as the main purse. EVM-native accounts and contract-created accounts stay purse-backed and are not forced into Casper account identities. Native transfers to EVM addresses now follow the same identity model: linked accounts credit the Casper main purse, EVM-native identities credit their purse, and missing targets create the deterministic purse-backed identity first. This also removes the unreleased `EvmValue::Account` and `EvmValue::ByteCode` storage forms, storing bytecode as `StoredValue::ByteCode` instead.
Introduce type 0x04 EVM transaction decoding, serialization, signing, verification, config checks, and executor translation. Store signed authorization-list items as transaction data while keeping Casper approvals limited to the outer Ethereum signature. Pass EIP-7702 authorization lists through to revm so Prague execution handles authority recovery, delegation writes, invalid-entry skipping, nonce updates, and delegation clearing. Keep existing Casper policies for blob transactions, non-empty access lists, and non-zero priority fees. Normalize missing dynamic priority fees to zero in the executor to match validation. Update sidecar dependency patches, receipt projection, raw transaction tests, and JSON schema snapshots for type 0x04 transactions. Document EIP-7702 support and devnet verification steps, and add coverage for type-4 decoding, round trips, config compliance, executor semantics, and sidecar raw transaction handling.
Remove the binary-port EVM call simulation command and route sidecar read-only EVM calls through TrySpeculativeExec. Add an unsigned EVM call marker transaction that carries chain ID and gas price so normal EVM config compliance still applies before execution. Return EVM speculative execution data through a dedicated binary-port result type, and keep unsigned call marker transactions rejected by transaction acceptance so they cannot be submitted as normal network transactions.
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
This PR adds a proof-of-concept EVM execution path to
casper-node. It proves that Casper can accept, validate, execute, account for, and persist Ethereum-shaped transactions while keeping the execution and storage model rooted in Casper: global state, transaction flow, account/purse accounting, fee/refund policy.The companion
casper-sidecarchanges in casper-network/casper-sidecar#468 provide the Ethereum JSON-RPC surface for this PoC. Sidecar currently implementseth_chainId,eth_blockNumber,eth_getBlockByNumber,eth_getTransactionCount,eth_sendRawTransaction,eth_getTransactionReceipt,eth_getLogs,eth_newFilter,eth_getFilterChanges,eth_getFilterLogs,eth_uninstallFilter,eth_call, and websocket log subscriptions. It uses node binary-port APIs to submit signed EVM transactions, run speculative EVM calls, read blocks and transaction execution info, and project Casper EVM receipts/logs into Ethereum-compatible JSON-RPC responses.What Changed
On the node side, this branch introduces:
Transaction::EvmandTransactionHash::Evm.U256JSON quantities.casper-executor-evmcrate backed byrevm.ExecutionResult::Evm, carrying EVM receipt data plus Casper accounting fields.eth_call.What Works
The current PoC supports signed Ethereum RLP ingestion through sidecar, conversion into
Transaction::Evm, node-side validation, execution throughrevm, persistence of EVM state, and Ethereum-compatible receipt projection.Tested flows include contract deployment, contract calls, native EVM value transfer, event logs in receipts, simple ERC20/ERC721-style behavior, speculative
eth_call, native Casper funding of EVM addresses, and EIP-7702 delegated-code execution using Foundry.The PoC supports the Ethereum transaction envelopes needed for the current tooling flow:
max_priority_fee_per_gas == 0.Prague/Pectra Compatibility
The executor is configured with a Prague-capable EVM spec, and this branch implements the main PoC execution path needed for EIP-7702. In that sense, the exercised EVM path is Prague-compatible.
It is not yet a complete Prague/Electra network implementation. The canonical Prague/Electra meta EIP is EIP-7600. Remaining Prague/Pectra work includes:
requests_hash.Blob transactions are still rejected. Full blob support requires EIP-4844 sidecars, KZG data, blob gas accounting, and the Prague blob parameter updates from EIP-7691. Client configuration should also eventually account for EIP-7840.
Current Limitations
EVM is disabled by default in chainspecs and must be explicitly enabled.
The sidecar RPC surface is enough for the PoC Foundry flow, transaction submission, receipts, calls, logs, filters, and log subscriptions. Some Ethereum RPC methods are still future work, including
eth_estimateGas,eth_getBalance,eth_getCode, andeth_getTransactionByHash.eth_getBlockByNumbercurrently returns transaction hashes only; full transaction objects are explicitly rejected for now. Block and receipt projection still needs to mature around complete Ethereum roots, bloom handling, gas-used accounting, and historical query performance.Access lists are decoded but non-empty lists are rejected. Priority fees are also rejected because Casper does not currently prioritize transactions using Ethereum fee-market tips.
Future Work
Next steps are to move this from PoC towards a spec-complete feature:
Not every Ethereum feature maps cleanly onto Casper’s existing execution, storage, accounting, and consensus model. For those cases, the plan is to make a best-effort compatibility layer, keep the Casper-side semantics explicit, and document where behavior intentionally differs from Ethereum mainnet.
Validation
This branch adds unit and integration coverage for EVM transaction decoding, approval handling, executor behavior, account/state storage, receipts, native transfers to EVM addresses, nonce validation, binary-port speculative EVM calls, Casper fee/refund handling, and EIP-7702 delegation behavior.
The manual Foundry validation flow is documented in
EVM.md.