owned this note
owned this note
Published
Linked with GitHub
# Based Rollups with Stronger Finality & Revenue Share (WIP)
In this note we describe a version of Ethereum shared sequencing for "based rollups" that retains the benefits of vanilla based sequencing (liveness, censorship resistance, L1 security and composability etc) while offering rollups stronger finality and a share of sequencing revenue. These are two separate ideas, one that leverages a separate BFT finality gadget (in which L1 validators can optionally participate), and one that uses a proposer selection mechanism similar to execution tickets.
**TLDR**
- This version of based sequencing offers two flavors of preconfirmations: proposer preconfs, and attester preconfs. The proposer preconf comes first (subsecond latency) backed by collateral of an individual proposer for a shared sequencer slot, while the attester preconf comes second (~1-2 second latency) is backed by the collateral (and/or honest supermajority assumption) of all attesters participating in the preconfirmation layer.
- Ethereum L1 proposers inherit the right to act as the shared proposer for L2 blocks as well. Participation in the preconfirmation layer as either an attester or proposer requires re-staking ETH (e.g., through Eigenlayer, though other implementations could be used and integrated).
- We propose a way for *rollups* to elevate the status of attester preconfirmations without disrupting any other property of based sequencing. With this change, transactions that carry an attester preconfirmation are **final conditioned on some published Ethereum block**, meaning they are guaranteed to be executed unless either said Ethereum block is reorged or a threshold of the attesters are malcious (in which case their staked collateral is slashed). Crucially, these transactions may occur on the rollup long after the Ethereum block has already been published. This is not possible with vanilla based sequencing: new rollup transactions included by an L1 proposer in some block $B_t$ that builds on block $B_{t-1}$ are not conditionally final based on $B_{t-1}$ because they will be abandoned in a reorg that drops $B_{t}$! A preconfirmation from the L1 proposer doesn't change this fact (i.e., a preconfirmation for the transactions included in $B_t$ cannot be given risk free, unless the L1 proposer has already seen enough Ethereum attestations to be certain its proposal $B_t$ won't be reorged).
- The L1 proposer for block $B_t$ may interleave L1 and L2 (rollup) transactions, enabling synchronous composability between L1 contracts and L2 contracts. However, it may prefer to *first* (using the attester preconfirmation mechanism) sequence rollup transactions that are conditionally final on block $B_{t-1}$. These transactions may either execute on the rollup prior to any of the transactions included in $B_t$, or are simply guaranteed to execute on the rollup even in the event that $B_t$ is reorged. Users may pay tips to enjoy this stronger/faster finality of being conditioned on $B_{t-1}$, particularly transactions on the L2 that do not depend on any L1 activity in block $B_t$.
- Another significant distinction is that while L1 proposers inherit the right to propose for rollups and give preconfirmations, in the event that an L1 proposer does not exercise this right for their slot another party can acquire it instead. This is particularly beneficial in the (likely) case that initially only a small fraction of L1 proposers participate in rollup sequencing and preconfirmations, and thus L1<>L2 synchronous interactions are less frequent.
- Outside of blocks that have synchronous interaction between L1 and L2, which may not be every block for most rollups, transactions can be recorded and made available through the attester side protocol (DA + BFT) and settled to the rollup contract periodically (instead of every Ethereum block). Assuming the side protocol has higher throughput and is cheaper than Ethereum L1, this helps with data compression for rollups. This is particularly advantageous for validiums.
- This Ethereum shared sequencer version is also unique in that it internalizes the revenue generated by the preconfirmation layer and it will redistribute this revenue to the based rollups that join it proportional to their marginal contribution.
- - -
What is an *Ethereum shared sequencer* for *based rollups?*
*Quoted from Justin Drake, it is a shared sequencer that achieves the following properties:*
1. **Credible neutrality**: Firstly, we need a credibly neutral sequencer that every rollup and their competitor feel comfortable opting into. The ideal shared sequencer should be maximally neutral—technically, economically, socially, and memetically.
2. **Security**: Secondly, we need the shared sequencer to be secure enough to handle the economic load of all Ethereum rollups, simultaneously. This means that we need a decentralized sequencer with extremely high economic security—51%-attack takeovers are simply not acceptable. A permanent sequencer takeover may necessitate mass exits through rollup escape hatches. Even short and temporary takeovers can lead to catastrophic harvesting of toxic MEV through market manipulation—think censorship-based oracle and DEX manipulations.
3. **Preconfirmations**: Thirdly, we need the shared sequencer to offer low-latency preconfirmations to provide the UX that users have come to expect with centralized sequencing and chains like Solana. A preconfirmation is a cryptoeconomic promise made by the shared sequencer to a user that gets the sequencer slashed if the preconfirmation promise is not honored.
4. **L1-compatible**: The shared sequencer should ideally encompass mainnet EVM execution on L1. That is, rollups should enjoy universal synchronous composability with L1 smart contracts, not just among themselves. Indeed, the vast majority of assets (think Safe, Uniswap, Aave, ENS) still sit at L1 and it would be hugely valuable to embrace existing L1 network effects.
## Proposed construction (WIP)
There are two key components that are introduced on top of the Ethereum L1. Importantly, they will not be used in any way to compromise on the four properties listed above.
- **BFT finality gadget:** This is can run as an AVS protocol on Eigenlayer. Ideally this is a State Machine Replication (SMR) protocol that achieves safety and liveness under partial synchrony, so long as not more than 1/3 of the participating stake is corrupt. Any safety violation will result in 1/3 of the stake being slashed (and also requires coordination of a set of nodes controlling 1/3 of the stake). It optimistically reaches finality on block proposals within a few seconds. We call participants *attesters*. The state tracks a chain of blocks for each unique domain identifier (aka namespace). It is also synchronized with a proposer selection mechanism (below) so that in any given state it can only append blocks to a namespace signed by the proposer(s) assigned to that namespace. The slots of this protocol are synchronized with (but may be more frequent than) the Ethereum L1. We will refer to these slots henceforth as "BFT-FG slots".
- **Combinatorial proposer selection:** This will run a *combinatorial lottery* to assign proposers to namespaces for each BFT-FG slot. A BFT-FG slot is for a duration of time and may accept multiple sequential block proposals during a single slot. A proposer may be assigned to more than one namespace at a name, which we call a *bundle*. Participants in the selection mechanism may purchase lottery tickets both for individual namespaces and namespace bundles. A combinatorial lottery is the lottery equivalent of a combinatorial auction, where participants would bid on bundles, or equivalently, it can be viewed as a pay-as-you-bid combinatorial auction with proportional allocation. Finally, the L1 proposer for an Ethereum slot will be given the option to purchase the BFT-FG proposer rights for any namespace bundle from the proposer to whom it was assigned (i.e., at the winning bid/ticket price). In essence, the L1 proposer holds an “ROFR” (right of first refusal) for the sale of any namespace bundle proposing rights within its slot.
The following is a description of how these components are utilized to achieve an Ethereum shared sequencer for rollups.
First let us distinguish two types of rollup contract calls:
(a L1–>L2 txs: function call depends on and may write to state of Ethereum L1. These include bridge deposits. This will not immediately write to the L2 state but will update a queue that is eventually consumed by an L2->L2 txn.
(b) L2—>L2/L1: updates the rollup state st, has no immediate side effect on L1 state, but may depend on queue of L1->L2 txs, and may update a queue of L1 txs (e.g., withdrawals) that is eventually consumed by an L1 txn.
1. *Tracking the state of Ethereum L1 in BFT-FG.* While the BFT-FG state does not execute rollup transactions, there is a minimal state and execution engine within the protocol. The BFT-FG state will track the state of Ethereum as follows. Each BFT state points to the tip of an Ethereum L1 fork, which we can call the <*L1_ref>.* Every BFT-FG block proposal has the opportunity to update the <L1_ref> to point to a new Ethereum block if either (a) the block is at the tip of a chain that extends the old <L1_ref>, or (b) the block is at the tip of a fork that is “heavier”, i.e. preferred according to the fork choice rule of Ethereum. Note that the BFT-FG state is not guaranteed to track the true latest state of Ethereum at any given time, nor is this equivalent to having all the BFT-FG validators to vote on their opinion of the Ethereum state. However, any honest BFT-FG proposer that knows the latest state will be able to successfully update BFT-FG to reflect this. This is the key property that we want. In essence, BFT-FG acts as a trusted client for the Ethereum L1.
2. *Implicit DAG in the BFT-FG.* The chain of BFT-FG blocks induces a DAG structure over L2 states indexed by L1 forks. Every round of BFT-FG may update <L1_ref> pointing to a fork of Ethereum L1 and also adds L2 blocks on the respective rollup namespaces. The <L1_ref> of any L2 block is the <L1_ref> of the *previous* BFT-FG block. All successive L2 blocks that share the same <L1_ref> will be interpreted by rollups as being executed after the <L1_ref> block and before the next L1 block that follows <L1_ref>. Each L2 block is an L2->L2 contract call to the rollup contract, and thus can be retroactively inserted before the next L1 block without having any immediate impact on L1 state. L2 blocks may still queue operations (e.g. withdrawals) that will eventually have effect on L1 when the contract is updated in an L1 block. L2 blocks may also consume queued txs from the L1 (e.g., deposits). The L1 block also cannot change the state of the rollup contract without going through BFT-FG, but can queue L1->L2 transactions (like bridge deposits). Queued transactions from L2 blocks will be settled in the L1 block that finally updates the L2 state of the rollup contract. Thus, every BFT-FG block is interpreted by the rollups derivation pipelines as being executed on a particular fork of Ethereum, and is by default only final conditioned on the fork finalizing on Ethereum. However, an individual transaction included in a BFT-FG block may elect to be conditionally final based on an earlier Ethereum block that precedes <L1_ref>. Concretely, if a transaction sets its reference point to some Ethereum block **id**, then rollups will execute this transaction on any fork of Ethereum that includes **id.** There is a strong reason to do so if the transaction does not depend on any L1→L2 transactions appearing between blocks id and <L1_ref> because it will have stronger finality (block id is less likely to reorg). We provide more details on the contract next.
3. *Proposer for L1 pointer.* Every BFT-FG slot has an assigned proposer to update the tracked Ethereum state <L1_ref>, just as any other namespace. The L1 proposer always has the ability to acquire the proposer rights for this as well. Note that while an <L1_ref> update may be proposed simultaneously with rollup blocks in the same BFT-FG slot, as detailed in item 2 above the rollup blocks will be applied first (i.e., occurring before the new L1 block not after).
4. *Rollup smart contract on the L1*. The rollup smart contract on the L1 tracks the state of the rollup, but may lag behind. A rollup smart contact is updated by calling it inside an L1 block. Today, rollup contracts are typically only called once per Ethereum block or even less frequently. However, if L1 block building is coordinated with L2 block building, then it is possible that a rollup contract may be called multiple times within a single L1 block, interacting synchronously with other contracts on the L1. Today, most rollup smart contracts have a designated sequencer, a party that must sign off on any update to the contract (with the exception of bridge transactions). **We propose that rollups replace this with the following logic.**
-- The rollup contract stores a state of the BFT-FG (it is a light client for the BFT-FG). The BFT-FG forms a continuous chain (it never forks).
-- Rollup contract stores rollup state **st,** a **queue** of L1 contract calls, and pointers to the last BFT-FG block **h** used to update this state. When it receives bridge transactions from contract call inside L1 block, they are added to the **queue** but this doesn’t immediately change **st**, which can only be changed by providing proof of the correct execution of L2 blocks finalized by BFT-FG from the last time the contract was updated on the present branch. In more detail, if the contract is called to update the rollup state in an L1 block with identifier **id,** with current state **st** and pointer to **h** where it was updated last, the new state **st’** with pointers to **h’** should be the result of executing all finalized BFT-FG blocks between **h** to **h’** along the unique fork that **id** extends. (In the case of OR the rollup contract receives **st’** which can be challenged through fraud proofs, and in a ZKR it directly receives a proof of correct derivation). Importantly, it is the order in which L2 blocks and L1 references appear in the BFT-FG that determines the relative ordering of L1/L2 transactions. The L1 block in which the L2 state update is ultimately recorded has no impact on relative ordering, and the recorded state in the L1 contract may lag behind the true state of the L2.
-- In the description so far, the BFT-FG only interleaves entire L1 blocks with entire L2 blocks. We add one more feature to enable synchronous interaction between L1 and L2, when the L1 proposer is simultaneously the BFT-FG proposer, which is for BFT-FG to record *partial L1 states*. Essentially, this allows for building a branch off some <L1_ref> block that interleaves L1 and L2 transactions before a full L1 block is complete, and which will be abandoned if the L1 block containing these transactions is never proposed on the L1. These transactions have much weaker finality until the L1 block containing them is proposed. The L1 proposer can easily reorg this temporary branch recorded in BFT-FG by never proposing. The main purpose of this feature is to enable synchronous composability between L1 and L2 without breaking anything else. We can’t simply allow every L1 block to include L2 transactions without BFT-FG’s involvement as that would break the ability of BFT-FG to provide finality on L2 blocks between L1 blocks as described above. Instead, when the L1 proposer building off of <L1_ref> is also the BFT-FG proposer, it can first get BFT-FG to accept <L1_ref> as the current Ethereum chain head, and then gets BFT-FG to record each successive L1>L2 and L2->L2/L1 transaction in order. The rollup derivation pipeline will execute these transactions in the order they appear. After BFT-FG finalizes each L2->L2/L1 txn the L1 proposer can record the state change in the L1 contract. This enables passing messages from L1 to L2 and from L2 back to L1 in the same block.
Other notes:
- To synchronize the BFT-FG with Eth block times, we’ll just use the same mechanism Eth uses to synchronize slot times to 12s
- L1 proposer gets the ROFR to update the L1 ref for free
- The combinatorial auction takes place before the L1 proposer is known, such that everyone is incentivized to participate in the auction
- Once the L1 proposer is known they’ll need to get the BFT-FG to agree that they’ve taken the ROFR. This can be done through creating a namespace to track the L1 ROFR. The proposer of this namespace is the L1 proposer executing their ROFR for 32 blocks in the future (where 32 blocks is how far in advance the L1 proposer is known).
- The BFT-FG must support multiple simultaneous proposers in the same slot (e.g. one proposer per namespace), similar to DAG-BFT protocols.