Rollups are currently a heated topic in the Ethereum community, and for a good reason. It is clear that the current Ethereum architecture is not ready for mass adoption, with gas fees fluctuating wildly, sometimes reaching such prohibitive heights that the network gets gentrified and entire DApps become effectively unusable. The infamous scalability problem has been proven very hard to solve without compromising on security and decentralization. Rollups, however, are gaining more and more traction and support, becoming almost universally considered to be one of the key scalability solutions for Ethereum’s woes. Vitalik himself suggested a rollup-centric roadmap for Ethereum that is worth the read.
At Cartesi, we are building a rollups solution. Check out the previous articles written, by my awesome colleagues, about it: The Rollups Rollout Announcement introduced the different pieces of our solution and offered a brief explanation of each of them. Readers looking for more details can delve into Erick de Moura’s “Cartesi Rollup — Scalable smart contracts built with mainstream software stacks” where they’ll find the reasoning behind many of our design decisions and in-depth explanations of the rollups behavior.
This article is part of the Rollup Rollout series, meant to get users and developers up to speed on what we’ve been building in the Rollups team. Two great articles have been released in this series: State Fold and Transaction Manager. Both of them introduce open-source Rust tools that aid interactions with the blockchain. In this article, we’ll summarize some topics we’ve written about before and expand on them. Then, we’ll focus on the on-chain smart contracts that make the Cartesi Rollups possible.
There are multiple ways to conceptualize scalability on blockchains, though it is commonly divided into two main components: data scalability and execution scalability. Rollups deal mainly with the latter — improving the former as a fortuitous consequence. As he often does, Vitalik Buterin wrote an informative post in which he highlights the relation between data and execution that I recommend.
To put it simply, rollups achieve scalability by moving the bulk of the computation outside the blockchain, using the ledger as a data source but not as an execution environment. As such, the rollups solution contains both off-chain and on-chain components.
Users interact with a rollup through Ethereum transactions. They send it messages (inputs) that define a computation to be processed and advance the state of the rollups machine. Interested parties run an off-chain component that watches the blockchain for inputs — understanding and executing the state updates. Once in a while, the state of the machine is checkpointed on-chain.
Checkpointing a state on-chain has to be done responsibly, which is guaranteed by the on-chain part. Here it is important to differentiate between two possible ways to gate-keep state updates: validity proofs and fraud proofs.
In validity proof schemes, every state update comes accompanied by a cryptographic proof, created off-chain, attesting its validity. The update is only accepted if the proof successfully passes verification on-chain. Zero-Knowledge Proofs are frequently used for this, which is why these types of rollups are usually referred to as ZK Rollups. Validity proofs bring the big benefit of instant finality — as soon as a state update appears on-chain, they can be fully trusted and acted upon. The choice, however, also brings less than ideal properties: generating ZK proofs for general-purpose computations is, when possible, immensely expensive and each on-chain state update must pay the extra gas fee from including and verifying a validity proof.
Fraud-proof schemes work by a different paradigm. State updates come unaccompanied by proofs, they’re proposed and, if not challenged, confirmed on-chain. Challenging a state update proposal is done by the use of fraud proofs, which can be divided into two categories: non-interactive fraud proofs and interactive fraud proofs.
Non-interactive refers to the fact that the challengers can prove that a state update is invalid in one single step. With interactive fraud proofs, the claimer and challenger have to, mediated by the blockchain, partake in something similar to a verification game. The assumption that state updates will most likely be honest often gives solutions like this the name of Optimistic Rollups. Naturally, this optimism comes paired up with financial incentives for honest behavior and guarantees that, unless the proposed false state is undisputed for a significant amount of time, it will never get accepted.
At Cartesi, we chose to create Optimistic Rollups with interactive fraud proofs. The interactive model was chosen because it imposes a higher ceiling to the size of computations that can be executed. With Cartesi Rollups we’re tackling an additional scalability aspect that was not mentioned at the beginning of this article: social scalability.
The idea that developers will be able to build their DApps using mainstream software stacks, libraries, and tools they’re used to is very dear to us. We want to bridge the gap between day-to-day and blockchain developers. We want developers to build impossible DApps, the ones only that need complex and powerful software stacks.
Tackling social scalability required an awesome VM, and we built one. The Cartesi Machine runs on a deterministic RISC-V architecture, capable of running a general fully self-contained Linux operating system. When giving developers the ability to run Linux on a fast VM, we also need to give them access to a dispute resolution method capable of adjudicating massive computations — such as the verification game.
As mentioned in the previous sections, rollups move the execution environment to layer-2 but still use layer-1 for its data availability guarantees. This doesn’t mean, however, that bringing execution to layer-2 doesn’t have positive impacts on the amount of data on-chain and the cost of transactions.
There are multiple strategies to translate the improved execution environment into more efficient ways to deal with data. Since much of the data doesn’t have to be known by the smart contracts, it can be stored inside Ethereum in a cheaper way (e.g., calldata instead of storage). It is also possible to transform data into computation by using techniques such as compression methods and signature aggregation. That is what aggregators do, they receive inputs off-chain and batch them together into a single bundle before sending them to the blockchain. The idea behind it is that, by aggregating user’s signatures, they can dilute the cost per user in that bundle of transactions — creating cheaper transactions.
There are a lot of different design decisions to be made when creating an aggregation scheme. Those choices impact a variety of different features such as order guarantees, censorship resistance, and AEV (aggregator-extractable value). The details on our design and analysis of those concepts will come in a later article.
The shift from global to local consensus means that data availability has to be guaranteed for a smaller set of interested participants. Hungry DApps can, therefore, choose different sources for storing data, as long as their users are comfortable with the tradeoffs.
The rollups smart contracts, designed to mediate the relationship between the off-chain rollups with other smart contracts and externally owned accounts (EOAs), were built for modularity. Each module has clear responsibilities and communicates with others through well-defined interfaces. This gives us lots of flexibility when it comes to customizing, configuring, and upgrading each part. DApps that need a different model for their on-chain input sanitation can easily swap theirs for the current implementation, for example.
There are two different agents that interact with the smart contract infrastructure: users and validators. Both run off-chain nodes but interact with the on-chain rollups in different ways. Validators are tasked with checkpointing the state of the off-chain machine on-chain, which includes fighting possible dishonest validators to ensure the prevalence of the honest claim. Users, on the other hand, send inputs to the machine, either directly or through aggregators, and execute the outputs they’re interested in.
In order to avoid over interacting with the blockchain, validators don’t checkpoint every new state update on the off-chain machine. They do it at the end of an epoch, which are batched inputs that follow the same cycle.
We can imagine epochs in three different states:
- Accumulating, when the epoch is open and waiting for inputs.
- Sealed, when the inputs for that epoch are well defined and the validators are preparing to or sending their claims. Sealed epochs can also be under dispute.
- Finalized epochs, when consensus was reached and the outputs can be safely executed.
The on-chain machine, depending on the phase it is at, can contain one or two epochs. These are the possible phases:
- Input Accumulation: there is a single accumulating epoch, active and waiting for the inputs it is going to batch.
- Awaiting Consensus: there are two epochs. A sealed one, for which validators are preparing to or sending their claims, and an accumulating one, which is active and receiving inputs.
- Awaiting Dispute: also has two epochs. A sealed one and an accumulating one. The sealed epoch is under dispute. Two conflicting claims were received and the validators are enrolling in a verification game to decide which claim stands. Since the sealed epoch’s inputs are well defined, honest validators will always reach the same claim. A dispute necessarily means that a claim is provably false.
The trigger for phase changes is explained in the previously mentioned Cartesi Rollups article.
Now that epochs, phases, and interactions are known, let’s go over each of the on-chain modules and explain their purpose: