Context: based rollups.
Since L2’s are permissionless, they too need a mechanism to cap their throughput. As per the custom, let’s refer to the computational load on L2 nodes in gas units. This load applies to any L2 operator – entities parsing the state, eg L2 explorers, wallets, etc. – but more importantly to provers. The latter’s load is 2-3 order of magnitude heavier than entities merely executing the state.
What entities should regulate L2 throughput? One could imagine a setup where an L2 instance caps its own throughput by encoding a gas limit rule in its program, but this could lead to an undesirable outcome where users’ transactions are included in L1 blocks but ignored by the corresponding L2. If we want to avoid such horrible UX, then L1 sequencers are the only relevant entities to take on the responsibility of regulating L2 throughput.
Let’s start by defining the requirements for a regulation mechanism:
- L2 throughput must be capped.
- L1 shouldn’t typically include transactions that exceed the throughput cap.
- L2 quality of service (QoS) should be preserved: Users with higher urgency should be able to prioritize their txns. (This crucial property is often overlooked, ignoring this requirement can lead to practical DoS for urgent transactions, similarly to the havoc on KAS, June '24, due to the lack of RBF to deal with txn congestion.)
- The mechanism shouldn’t rely on users’ honesty or miners’ goodwill.
- The mechanism shouldn’t require L1 actors executing L2 logic.
- L2 provers should be compensated for sustainability.
One simple approach we propose (@FreshAir08 +the usual suspects) is:
i. Transaction issuers declare the maximum gas their transactions consume.
ii. Miners ensure no more than X gas units are confirmed per block per L2 instance (enforced in L1 consensus).
iii. Transactions that exceed their declared maximum gas are reverted but still pay their fees, similar to Ethereum L1 rules. Note: Wallets can typically provide reasonable gas estimates. Even for complex transactions, users can often give tight bounds, so they won’t usually suffer from gross misestimates.
iv. Transactions that don’t exhaust their declared gas still pay the full gas fee to L2 from the perspective of L1. Whether this is refunded to the user within L2 logic is outside this discussion. [A riddle for the reader: If users are refunded the gas change, can they overestimate gas just to be lazy? Why not?]
It is easy to verify that this design satisfies all aforementioned requirements.
Observe an important implication of this design: When L2 demand is high, revenue and fees go to L1 sequencers, not to L2 provers. I argue this is not a problem, and the preservation of L1’s security budget outweighs L2 layer biz model concerns. An alternative proposal will be be described at the end of the post.
Another observation is that introducing gas units and limits per block (point ii above) adds complexity for sequencers (miners) optimizing their blocks. It effectively creates a multi-knapsack problem for sequencers, which is NP-hard. However, this computation isn’t done on-chain or in consensus, and simple heuristics can achieve a sufficient approximation of the optimal solution. Importantly, this challenge isn’t unique to gas units; similar considerations apply to storage-mass (KIP9) units. See KIP13 by @coderofstuff.
Importantly, each L2 instance can define its own interpretation and scale for gas—there’s no implication in L1 consensus about what gas specifically means. If one instance computes gas differently — whether in a simple or complex manner — that’s fine. L2 instances can also dynamically adjust gas scales based on load (@proof note this). However, this dynamic adjustment should be carefully designed to avoid situations where users’ transactions are included by miners but ignored by L2 programs, causing fee loss and poor UX.
Finally, since we proposed that all transaction fees — regardless of rising demand — flow to sequencers, one might ask how L2 provers are paid and what guarantees their compensation and sustainability. One alternative advocated by @someone235 is that a fraction of L1 fees associated with a certain L2 instance flow to its P2SH address and be distributed to provers via its PROG. Hopefully others can evaluate this direction or provide alternative L2 sustainability schemes