Author: Ethereum researcher Justin Drake, ethresearch; Translator: Tao Zhu, Golden Finance
Credit for this article goes to the broader Ethereum R&D community. Key contributions originated in 2017, and the design has had significant incremental unlocking over the years. Recent zkVM engineering breakthroughs have triggered a thorough design space exploration. This article is just a best effort to try to piece together a coherent design for a big idea that may finally be here.
Abstract
We propose an elegant and powerful EXECUTE precompilation that exposes the native L1 EVM execution engine to the application layer. Native Execution Rollup ("native rollup" for short) is a rollup that uses EXECUTE to verify EVM state transitions for batched user transactions. Native rollups can be thought of as "programmable execution shards", wrapping precompilations in derived functions to handle system logic outside the EVM, such as ordering, bridging, mandatory inclusion, and governance.
Because EXECUTE precompiles are executed directly by validators, they enjoy (zk)EL client diversity and provide EVM equivalence that is bug-free by construction and forward-compatible with EVM upgrades via L1 hard forks. For EVM-equivalent rollups that wish to fully inherit the security of Ethereum, a form of EVM introspection like EXECUTE precompiles is necessary. We call rollups that fully inherit the security of Ethereum “trustless rollups”.
EXECUTE precompiles greatly simplify the development of EVM-equivalent rollups because no complex infrastructure (e.g., cheat-proof games, SNARK circuits, security committees) is required for EVM simulation and maintenance. With EXECUTE, minimal native and built-on rollups can be deployed with just a few lines of Solidity code using simple derivative functions, eliminating the need for special handling of ordering, mandatory inclusion, or governance.
Most importantly, native rollups can enjoy real-time settlement without having to worry about real-time proofs, greatly simplifying synchronous composability.
This article is divided into two parts, first introducing the proposed precompiles and finally discussing native rollups.
Part 1 — EXECUTE Precompile
Structure
EXECUTE precompile accepts inputs pre_state_root, post_state_root, trace, and gas_used. It returns true if and only if:
trace is a well-formed execution trace (e.g. a list of L2 transactions and corresponding state access proofs)
the stateless execution of trace starts at pre_state_root and ends at post_state_root
the stateless execution of trace consumes exactly gas_used gas
There is an EIP-1559-style mechanism for metering and pricing the cumulative gas consumed by all EXECUTE calls in an L1 block. Specifically, there is a cumulative gas limit, EXECUTE_CUMULATIVE_GAS_LIMIT, and a cumulative gas target, EXECUTE_CUMULATIVE_GAS_TARGET. (When the L1 EVM is statelessly executable by validators, the cumulative limit and target can be merged with the L1 EIP-1559 mechanism.)
Calling a precompile costs a fixed amount of L1 gas, EXECUTE_GAS_COST, plus gas_used * gas_price, where gas_price (denominated in ETH/gas) is set by an EIP-1559-style mechanism. The full upfront fee is extracted even if the precompile returns false.
The trace must point to available Ethereum data from calldata, blob, state, or memory.
Re-execution
If EXECUTE_CUMULATIVE_GAS_LIMIT is small enough, a validator can simply re-execute the trace to enforce the correctness of the EXECUTE call. An initial deployment of re-execution-based precompilations can serve as a stepping stone, similar to the simple re-download of blobs to full danksharding for original danksharding. Note that simple re-execution imposes no state growth or bandwidth overhead on validators, and any execution overhead can be parallelized across CPU cores.
Validators must hold an explicit copy of the trace for re-execution, preventing the use of pointers to blob data that was sampled (rather than downloaded) via DAS. Note that optimistic native rollups may still publish rollup data as blobs, falling back to call data only in fraud proof games. Also note that optimistic native rollups can have gas limits far in excess of EXECUTE_CUMULATIVE_GAS_LIMIT, as the EXECUTE precompilation only needs to be called once on a small EVM segment to solve the fraud proof challenge.
As a historical note, a similar “EVM inside EVM” precompilation called EXECTX was proposed by Vitalik in 2017.
Execution via SNARKs
To unlock a larger EXECUTE_CUMULATIVE_GAS_LIMIT, it is natural to have validators selectively verify SNARK proofs. From now on, we assume one-slot delayed execution, where invalid blocks (or invalid transactions) are treated as no-ops. (For more on delayed execution, see this ethresearch post, this EIP, and this design by Francesco.) One-slot delayed executions yield a few seconds (a whole slot) for proofs. They also avoid incentivizing MEV-driven proof races, which would introduce a centralization vector.
Note that even though EXECUTE is enforced by SNARKs, no explicit proof system or circuit is baked into consensus. (Note that the EXECUTE precompile does not take any explicit proofs as input.) Instead, each stake operator is free to choose their favorite zkEL validator client, similar to how EL clients are subjectively chosen today. The next section, “Off-Chain Proofs”, explains the benefits of this design decision.
From now on, we assume that execution proposers are mature in the context of prover-proposer separation (APS) with alternating execution and consensus slots. To incentivize rational execution proposers to generate proofs in a timely manner (within 1 slot), we require provers to only attest to the execution of block n+1 if the proof for block n is available. (We propose to bundle block n+1 with the EXECUTE proof for block n at the p2p layer.) Execution proposers who skip attestations may miss their slots, resulting in missed fees and MEV. We further impose a fixed penalty on missed execution slots, setting it high enough (e.g. 1 ETH) to always exceed the cost of attestation.
Note that in the context of APS, the generation of consensus blocks is not blocked by missed execution slots. However, timely attestation generation is important for light clients so that they can easily read the state on the chain side without stateless re-execution. To ensure that proofs are generated in time for light clients, even in the special case that the next execution proposer misses its slot, we rely on the altruistic minority prover assumption. A single altruistic prover is sufficient to generate a proof within 1 slot. To avoid unnecessary redundant proofs, a majority of altruistic provers can wait on standby and only start if no proofs arrive within 1 slot, acting as a failsafe for a maximum of 2 slots of latency.
Note that EXECUTE_CUMULATIVE_GAS_LIMIT needs to be set low enough to make the altruistic minority prover assumption credible (and so that execution of proposals is not unrealistically complicated). A conservative strategy could be to set EXECUTE_CUMULATIVE_GAS_LIMIT so that single-slot proofs are accessible to laptops (e.g. high-end MacBook Pros). A more pragmatic and aggressive policy might be to target a small subset of GPUs, and perhaps eventually SNARK ASIC provers once they are sufficiently commoditized.
Off-Chain Proofs
To reiterate, we recommend not putting the zkEL EXECUTE proof on-chain, but sharing it off-chain. Not storing the proof is a good idea, first proposed by Vitalik, and it has several advantages:
Diversity: Validators are free to choose proof validators (both the proof system and the circuits) from development teams they trust, similar to how validators choose EL clients they trust. This provides robustness through diversity. zkEL validator clients (and the underlying zkVM for some clients) are complex cryptographic software. A bug in any one client should not bring down Ethereum.
Neutrality: Having a market for zkEL validator clients allows the consensus layer to not pick technical winners. For example, the zkVM market is highly competitive, and the selection of the winning vendor (such as Risc0, Succinct, or many others) may not be seen as neutral.
Simplicity:The consensus layer does not need to include a specific SNARK validator, greatly simplifying the specification of the consensus layer. Only the format of the state access proof needs to be included, not the specific proof validator implementation details.
Flexibility:If a bug or optimization is discovered, affected validators can update their clients without a hard fork.
Having off-chain proofs does come with some manageable complications:
Proof Load and p2p Fragmentation:Since there is no single canonical proof, multiple proofs need to be generated (at least one per zkEL client). Each zkEL client customization (such as swapping out one RISC-V zkVM for another) requires a different proof. Likewise, each zkEL version upgrade will require a different attestation. This will result in an increased attestation load. It will also further fragment the p2p network if there are separate gossip channels for each attestation type.
Minority zkEL:It is difficult to incentivize a minority of zkEL to generate attestations. Rational execution proposers may only generate enough attestations to reach a supermajority of attestors without missing their slot. To address this, stake operators can be socially incentivized to run multiple zkEL clients in parallel, similar to how Vouch operators do today. Running a k-of-n setup has the added benefit of increased security, in particular preventing soundness vulnerabilities that allow an attacker to craft attestations for arbitrary EXECUTE calls (a situation that is uncommon with traditional EL clients).
Off-chain proofs also reduce the efficiency of real-time settlement L2s:
No replacement DA:Since the trace inputs to EXECUTE need to be provided to the L1 validator, a real-time settled L2 (i.e. an L2 that updates its canonical state root immediately) must consume L1 DA, i.e. rollups. Note that optimistic L2s that delay settlement via fraud proof games do not have this restriction, i.e. can be valid values.
State access overhead:Since the trace must be stateless executable, it must include state trie leaves that are read or written, which introduces a small amount of DA overhead over typical L2 blocks. Note that optimistic L2s do not have this restriction, as the state trie leaves are only needed during a fraud proof challenge, which the challenger can recompute.
Stateless diffing:Since given the trace, the proofs should be permissionless, no aggregate state diffing is possible. However, stateless access proofs or EVM transaction signatures can be compressed if the corresponding specialized proofs are incorporated into consensus.
RISC-V native execution
Given the de facto convergence towards RISC-V zkVM today, there may be an opportunity to expose RISC-V state transitions natively to the EVM (similar to WASM in the context of Arbitrum Stylus) and keep it SNARK-friendly.
Part 2 — Native Rollup
Naming
We’ll start by discussing the naming of native Rollup to address a few points of confusion:
Alternative Names: Native Rollups were previously known as enshrined rollups. (The term “canonical rollups” was also briefly used in Polynya 12.) The term “enshrined” was later dropped in favor of “native” to indicate that existing EVM-equivalent rollups can choose to upgrade to native. The name “native” was independently proposed by Dan Robinson and a Lido contributor who wishes to remain anonymous in November 2022.
Rollup-based:Rollup-based and native rollups are orthogonal concepts: “based” is about L1 ordering, while “native” is about L1 execution. Rollups that are both based and native have been whimsically called “supersonic rollups”.
Execution shards:Execution shards (i.e., enshrined copies of the L1 EVM chain) are a different but related concept to native rollups that predate native rollups by a few years. (Execution shards were previously “Phase 2” of the Ethereum 2.0 roadmap.) Unlike native rollups, execution shards are not programmable, i.e., there are no options for custom governance, custom ordering, custom gas tokens, etc. Execution shards are also typically instantiated in a fixed number (e.g., 64 or 1,024 shards). Unfortunately, Martin Köppelmann used the term “native L2” in his 2024 Devcon talk on execution sharding7.
Benefits
Native Rollups have several benefits, which we detail below:
Simplicity:Much of the complexity of the native rollup VM can be encapsulated via precompilation. Today, EVM-equivalent optimism and zk-rollup have thousands of lines of code for their fraud proof games or SNARK validators, which can be compressed into a single line of code. Native rollups also do not require auxiliary infrastructure such as proof networks, watchtowers, and security committees.
Security:Building a bug-free EVM fraud proof game or SNARK validator is an extremely difficult engineering task that may require deep formal verification. Today, every optimism and zk EVM rollup is likely to have serious vulnerabilities in its EVM state transition function. To protect against vulnerabilities, centralized ordering is often used as a crutch to control adversarial block production. Native EXECUTE precompiles allow permissionless ordering to be deployed securely. Trustless rollups that fully inherit L1 security also fully inherit L1 asset fungibility.
EVM equivalence:Today, the only way for rollups to stay in sync with L1 EVM rules is for governance (typically a security committee and/or a governance token) to mirror L1 EVM upgrades. (EVM updates still happen regularly via hard forks, roughly once a year.) Governance is not only an attack vector, it is strictly speaking a departure from the L1 EVM and prevents any rollup from achieving true long-term EVM equivalence. Native rollups, on the other hand, can be upgraded in sync with L1 without governance.
SNARK gas costs:It is expensive to verify SNARKs on-chain. As a result, many zk-rollups settle very rarely to minimize costs. Since SNARKs are not verified on-chain, EXECUTE precompiles can be used to reduce verification costs. EXECUTE_GAS_COST can be set relatively low if SNARK recursion is used to batch EXECUTE proofs for multiple calls in a block.
Synchronous Composability:Today, synchronous composability with L1 requires same-slot real-time proofs. For zk rollups, achieving ultra-low latency proofs (e.g., 100ms or so) is a particularly challenging engineering task. Using a single-slot delayed state root, the proof latency for native execution of precompiled code can be relaxed to one full slot.