The rollup node is the component responsible for deriving the L2 chain from L1 blocks (and their associated receipts).
The part of the rollup node that derives the L2 chain is called the rollup driver. This document is currently only concerned with the specification of the rollup driver.
Table of Contents
The task of the driver in the rollup node is to manage the derivation process:
- Keep track of L1 head block
- Keep track of the L2 chain sync progress
- Iterate over the derivation steps as new inputs become available
This process happens in three steps:
- Select inputs from the L1 chain, on top of the last L2 block: a list of blocks, with transactions and associated data and receipts.
- Read L1 information, deposits, and sequencing batches in order to generate payload attributes (essentially a block without output properties).
- Pass the payload attributes to the execution engine, so that the L2 block (including output block properties) may be computed.
While this process is conceptually a pure function from the L1 chain to the L2 chain, it is in practice incremental. The L2 chain is extended whenever new L1 blocks are added to the L1 chain. Similarly, the L2 chain re-organizes whenever the L1 chain re-organizes.
For a complete specification of the L2 block derivation, refer to the L2 block derivation document.
The Rollup node has its own RPC method, optimism_outputAtBlock
which returns a 32
byte hash corresponding to the L2 output root.
These define the types used by rollup node API methods. The types defined here are extended from the engine API specs.
hash
:DATA
, 32 Bytesnumber
:QUANTITY
, 64 Bits
hash
:DATA
, 32 Bytesnumber
:QUANTITY
, 64 BitsparentHash
:DATA
, 32 Bytestimestamp
:QUANTITY
, 64 Bits
hash
:DATA
, 32 Bytesnumber
:QUANTITY
, 64 BitsparentHash
:DATA
, 32 Bytestimestamp
:QUANTITY
, 64 Bitsl1origin
:BlockID
sequenceNumber
:QUANTITY
, 64 Bits - distance to first block of epoch
Represents a snapshot of the rollup driver.
current_l1
:Object
- instance ofL1BlockRef
.current_l1_finalized
:Object
- instance ofL1BlockRef
.head_l1
:Object
- instance ofL1BlockRef
.safe_l1
:Object
- instance ofL1BlockRef
.finalized_l1
:Object
- instance ofL1BlockRef
.unsafe_l2
:Object
- instance ofL2BlockRef
.safe_l2
:Object
- instance ofL2BlockRef
.finalized_l2
:Object
- instance ofL2BlockRef
.pending_safe_l2
:Object
- instance ofL2BlockRef
.queued_unsafe_l2
:Object
- instance ofL2BlockRef
.
The input and return types here are as defined by the engine API specs.
- method:
optimism_outputAtBlock
- params:
blockNumber
:QUANTITY
, 64 bits - L2 integer block number.
- returns:
version
:DATA
, 32 Bytes - the output root version number, beginning with 0.outputRoot
:DATA
, 32 Bytes - the output root.blockRef
:Object
- instance ofL2BlockRef
.withdrawalStorageRoot
: 32 bytes - storage root of theL2toL1MessagePasser
contract.stateRoot
:DATA
: 32 bytes - the state root.syncStatus
:Object
- instance ofSyncStatus
.
The rollup-node should monitor the recommended and required protocol version by monitoring the Protocol Version contract on L1, as specified in the Superchain Version Signaling specifications.
This can be implemented through polling in the Driver loop.
After polling the Protocol Version, the rollup node SHOULD communicate it with the execution-engine through an
engine_signalSuperchainV1
call.
The rollup node SHOULD warn the user when the recommended version is newer than the current version supported by the rollup node.
The rollup node SHOULD take safety precautions if it does not meet the required protocol version. This may include halting the engine, with consent of the rollup node operator.