Arbitrum Nitro integration
Last updated
Last updated
For the Gibraltar release Espresso has built a proof-of-concept integration to run the Arbitrum Nitro optimistic rollup stack on top of Espresso.
Transactions are forwarded from the Nitro RPC node to Espresso and processed as they are sequenced and made available on the Espresso Query Service (EQS).
The Nitro nodes fetch the commitments to HotShot blocks from the HotShot contract and validate that the transactions in the Nitro block match the ones included in Espresso.
The most important design decision for rollup integrations with Espresso is how to derive the stream of rollup blocks from the stream of HotShot blocks. We have written a more general post on this topic: The Derivation Pipeline. Espresso currently uses a namespaced Merkle tree (NMT), where each namespace corresponds to one rollup.
For this integration we chose to do a 1-to-1 mapping of HotShot blocks to Nitro blocks. This means that the rollup will produce exactly one rollup block for each HotShot block.
To justify how the Nitro block is built from HotShot, the block producer creates an instance of the following type and posts it to the L1.
The Header
contains the root of the NMT. With the proof and the rollup ID (this is akin to chain ID within the EVM ecosystem, except specific to rollups in the shared sequencer), validators can verify that the ordered list of transactions in a rollup block corresponds exactly to the one sequenced by Espresso.
Arbitrum uses L1 Messages as a container for communication through the L1 (see for example here). For this integration, a new message type was defined for a batch of transactions sequenced through Espresso. The message also includes the Espresso block justification.
Transactions contained in this type of L1 Message are handled a bit differently than in the original Nitro node. In the original Nitro node, the sequencer is expected to filter out invalid transactions and will be punished by having its entire block discarded by validators if it fails to do so. When using a shared or decentralized sequencer unaware of the state of the rollups, it’s not possible to prevent invalid transactions from being sequenced. Instead, invalid transactions, either malformed or otherwise invalid (e.g., bad signature, double spend, nonce error) are included in L2 blocks but cannot cause state changes. The invalid transactions are kept such that:
validators can verify that these transactions are invalid
validators can recompute the HotShot commitment and equate it to the one in the HotShot contract for which the HotShot consensus has been verified on L1. This serves to ensure that the block producer included the correct transactions in the L2 block.
We envision that, through the Espresso sequencing marketplace, builders would aim to produce blocks with only valid transactions, in order to maximize value, which would make invalid transactions rare, but not impossible. Furthermore, Espresso prevents free DA of invalid transactions, and can further implement mechanisms to avoid rollup nodes bearing the cost of invalid transaction spam.
Arbitrum Nitro uses WASM for validation and a modified WASM called WAVM for proving. For more background please refer to the official docs. In order to make validation work with our changes there were two main requirements:
All the transactions need to be available in the WASM VM.
The HotShot commitment needs to be available in the WASM VM.
The first requirement is taken care of by the new type of L1 Message described above. For the second requirement, we modified the interaction of the WASM VM with the host to allow the host to provide the HotShot commitment as an input.
We have not yet implemented fault proofs for this integration. It would require supporting our changes in WAVM VM and the One Step Proof on L1.
For this release, the Arbitrum Nitro rollup uses the Ethereum L1 for data availability (DA). Since Espresso has its own DA called Tiramisu, we could use it for the integration or as a AnyTrust DA provider in future work.
Our integration supports preconfirmations. Clients can get an updated view of the state by interacting with the rollup RPC as soon as new rollup blocks have been built. They don't need to wait for rollup blocks to be posted on L1 by the batch poster.
Clients can also query a validation node, which derives its state from validated L1 batches. Because validation nodes need to perform more work, this path is slower, but may be appropriate for clients with weaker trust assumptions.