ZK Rollup Architecture

This section develops a model of the architecture of a ZK rollup by abstracting away most of the internal complexity, and focusing mainly on the interactions between the sequencer and other components. Thus, this model should be sufficient to guide the integration of a wide variety of Zk rollups with the Espresso Sequencer.

Background

In this model, a ZK rollup is a distributed state machine in which one or more agents that compute state transitions (the executors or provers) use zero-knowledge proofs to convince additional, non-computing agents (such as the end users) of the validity of state updates. The state transitions are determined by applying the deterministic function which defines the rollup to a sequence of transactions, or state transition requests, starting from a known initial state. This sequence is usually represented as a sequence of blocks, where each block consists of an ordered list of many transactions.

The architecture model will aim to isolate the sequencer, the component of the system which determines this sequence. Modelling the sequencer's interactions with the rest of the system can shed light on how to replace that sequencer with the decentralized Espresso Sequencer.

Components

We model the rollup as a collection of three components:

  • The sequencer is responsible for batching transactions from various users into ordered blocks, and then committing to an order of those blocks. The order can be arbitrary or subject to rollup-specific . The important thing is that the order is public and immutable: all rollup users at all times should agree on the relative ordering of blocks.

  • The executor and prover is an abstract component which may in reality consist of several components. Its primary job is to execute the rollup's state transition function, usually some in which transactions represent programs to execute. By executing this function, the executor computes and stores a VM state which is a deterministic result of the ordering of blocks produced by the sequencer.

    By virtue of maintaining and storing the state, this component is equipped to perform some additional functions, including

    • Running a web server which allows users to interact with the VM state (such as an Ethereum JSON-RPC server, if the rollup VM is Ethereum-compatible).

    • Running a ZK prover which produces zero-knowledge proofs of the correctness of the state stored by the executor. This component proves to other, untrusting participants that the executor has correctly computed the state transition function on the sequence of blocks produced by the sequencer.

  • The rollup contract validates ZK proofs produced by the prover and stores recent, certified state roots in the storage of a lower-layer blockchain (like Ethereum). This allows clients who neither trust the executor nor want to do the work of validating ZK proofs to authenticate the state of the VM, by trusting a majority of the L1 validators to have correctly verified the ZK proof. The state roots stored in the contract are usually succinct digests of the VM state, like Merkle roots, so that clients can fetch large pieces of the state from an untrusted, off-chain source and then validate them against the state root.

    This is an optional component. Some L2s (so-called sovereign rollups) do not verify their state with any other blockchain, and instead rely on each peer either computing the correct state themselves or validating a ZK proof directly, rather than trusting the L1 validators to check the proof.

This model is designed to make it easy to understand what changes when the sequencer is replaced by the Espresso Sequencer. However, in a real rollup one or more of these components may be combined. For example, the sequencer and executor may be part of the same service.

Transaction Flow

The figure below shows the interactions between these components as a transaction flows through the system. The dashed arrows indicate places where more than one design is possible, and different ZK rollups may make different choices.

  1. The user submits a transaction. This will often be submitted to a rollup-specific service of the user's choice (such as a JSON-RPC server) before being forwarded to the sequencer. However, many rollups also allow the user to submit directly to the sequencer. In some rollups, the sequencer may even be combined with the rollup service, so that it can execute transactions before sequencing them and filter out invalid transactions.

  2. The sequencer eventually includes the transaction in a block.

  3. The block is sent to the rollup contract, where it is stored. This serves two purposes:

    • The contract can act as a source of truth for the order of blocks, so that if the sequencer later tries to equivocate, and report a different order to different participants, all parties can take the order saved in the contract as authoritative.

    • The layer 1 blockchain hosting the contract provides data availability for the rollup. Even if the sequencer goes down, users and executors/provers can read the data for each sequenced block from storage in the layer 1 blockchain, which is presumed to be highly available. This means that the sequencer cannot stop any participant from reconstructing the state of the layer 2 blockchain.

  4. The executor is notified of the new block. They may get it from the rollup contract, or directly from the sequencer. In the latter case, they will authenticate the block provided by the sequencer against the ordering (or a succinct commitment to the ordering) stored in the contract.

  5. The executor executes the block and updates its local copy of the VM state.

  6. The prover produces a zero-knowledge proof that the new state is the result of correctly applying the state transition function to the sequenced block.

  7. The prover sends the proof and the new state root to the rollup contract, which verifies the proof and stores the state root.

  8. The user observes the result of their transaction by querying the server provided by the executor. If the user does not trust the executor, they can check the response against the state root stored in the contract, or they can request a zero-knowledge proof of the state root and verify it themselves.

Last updated