# Asynchronous blobs ## Abstract We propose *asynchronous blobs* as a means of disentangling the act of propagating blob data from the act of having the blob transaction interacting with the EL state. Asynchronous blobs can be understood as a way of providing pre-propagation that is guaranteed rather than optimistic as is the case for blobpool based pre-propagation. Thus, asynchronous blobs allow for a more evenly spread out bandwidth consumption, increasing the achievable data throughput as well as providing a mechanism for aleviating the free option problem. ## Introduction We say that a blob tx is *synchronous* if it is able to interact with the EL state in the same slot in which blob availability is determined. In contrast, we say that a blob tx is *asynchronous* if it is able to interact with the EL state in a slot subseeding the one in which blob availability is determined. Today, blobs are *synchronous* from the protocol's perspective, but there is no necessity for this to be the case in their actual usage. While some rollups use blob txs to do minor bookkeeping, there is nothing that requires this to happen synchronously (and in fact some rollups do otherwise, e.g. OP stack rollups send blob txs without any calldata). ![](https://notes.ethereum.org/_uploads/S1GKOibm-g.png) *A synchronous blob in Ethereum. When a blob tx is included in a block, three things happen: the blob data is propagated alongside the block, availability of the blob data is determined, and the blob tx affects the EL state during the block's execution. The execution has the guarantee that the blob data is available, because the block would not become canonical otherwise.* The main use case for synchronous blobs for rollups is synchronous composability with the L1, which in addition requires real time proving and based sequencing. Moreover, synchronous blobs become significant for the L1 as well, once we project ourselves in the future we're rapidly moving towards, where zkEVM + DAS are used to scale the L1 itself. Still, the portion of blob throughput consumed by the L1 is likely to be a fraction of the total (even scaling the L1 by a factor of 100x would only require ~50 blobs). The same might hold for the portion of the remaining throughput that requires synchronous composability with the L1, because based sequencing might not be attractive to all rollups, and because synchronous composability will always come at a cost. A component of this is the cost for Ethereum to provide synchronous versus asynchronous blobs, which is reflected in the throughput that the Ethereum DA layer can offer, and thus also in the equilibrium prices for blob data. While today all blobs are synchronous, we argue that *the asynchronous blob throughput that Ethereum can provide is (all else being equal) strictly higher than synchronous blob throughput*. This comes down to two factors: 1. With asynchronous blobs, propagation of blob data is outside of the critical path, and can be fully spread out over time, see Fig.3. Avoiding high fluctuations in bandwidth usage means that we can achieve an overal increased throughput as we can make maximal usage of the available bandwidth, rather than being limited by the propagation possible in the critical path and having bandwidth go unused the rest of the time. 2. With synchronous blobs, there are limitations to how much we can increase the time available for propagation, and thus the bandwidth utilization. On the one hand, the next proposer and builder need to be able to determine availability before acting. Thus the propagation period is fundamentally upper bounded by the slot width (minus the time required for the availability signal to reach the proposer/builder). On the other hand there is an even stricter limitation due to the [free option problem](https://collective.flashbots.net/t/the-free-option-problem-in-epbs/5115). The free option problem dictates that the propagation window should be kept *as small as possible* limiting the time for propagation and thus the throughput significantly. ![](https://notes.ethereum.org/_uploads/Byqj5WYE-g.png) We argue that we should recognize that a) not all blob throughput requires nor will require synchronous composability and that b) we can safely provide significantly more asynchronous than synchronous blob throughput, without running into hard tradeoffs like those posed by the free option problem. We should therefore consider introducing asynchronous blobs to the protocol. ## Concrete design Asynchronous blobs as discussed above can be built through a type of blobpool ticketing system. In its simplest form, the blobpool ticket mechanism was developed in order to ensure DoS resistant pre-propagation of blobs in the blobpool. In order to submit and propagate a blob in the blobpool a submitter is required to hold a valid ticket which they acquire by placing a corresponding transaction in a slot within a time window $\Delta$. Asynchronous blobs can be realized by an analogous mechanism. To submit an asynchronous blob a user places a corresponding transaction. Once this transaction lands on chain, for some time window $\Delta$, the blob submitter has the right to propagate the blob content using the gossipsub mechanism meaning it acts akin to the proposer vis a vis data propagation. Similarly, nodes record all asynchronous blob transactions and participate in the data propagation mechanism if and only if an asynchronous blob transaction was placed by the blob submitter. Thus, asynchronous blobs can effectively be understood as enshrining into the protocol the blobpool's pre propagation logic. ## Steps towards async blobs ------------ Here in case needed: ![](https://notes.ethereum.org/_uploads/ryo5qcGmbx.png) ![](https://notes.ethereum.org/_uploads/r1Diq5zmWe.png) ---------- TO ERASE EVENTUALLY ## Stage 0 (current) Blobs can be propagated in advance, through the EL mempool, and this pre-propagation can be used to reduce the propagation in the critical path, or even make it entirely redundant, through the `getBlobs` mechanism. This stage lacks: 1. Global allocation of pre-propagation throughput, i.e., of mempool space in this case (there are only local mempool rules) 2. Consensus over which blobs have been pre-propagated and whether they are available ## Stage 1 This stage introduces 1., allocation of pre-propagation throughput. Examples of stage 1 mechanisms are various forms of [mempool tickets](https://www.notion.so/efdn/Variants-of-Mempool-Tickets-26cd98955541804180b5c4419a0a9673). The improvement in this stage is that we can resolve congestion ahead of the time, as part of the allocation mechanism, rather than by (for example) applying local rate limits that fragment the mempool and limit its utility. This way, we get clear guarantees about the throughput which the pre-propagation mechanism can support, and thus about the maximum blob throughput as well. In comparison, a stage 0 mechanism cannot entirely rely on the pre-propagation mechanism to support its blob throughput. This stage still lacks 2., consensus over which blobs have been pre-propagated and whether they are available. ## Stage 2 This stage introduces 2. as well. An example of this could be a stage 1 mechanism with the addition of availability committees that vote on the availability of pre-propagated blobs. Another option is adding a tx type that just carries kzg commitments without blob data, with tx inclusion doing two things: 1. Allowing data propagation (i.e. allocating pre-propagation throughput) 2. Letting availability of the associated data be established onchain later (i.e. establishing consensus over availability) - slot N: - tx included, kzg commitments recorded in the beacon state, for the last two *payloads*. - Once the beacon block is out, the blob data can be propagated, just like for regular blobs - Also like for regular blobs, these count against max blobs, pay the basefee, and increase excess blob gas: since the primary ropagation is done in this slot, they consume the same resources. - The blob gas per async blob can be set lower than the blob gas per regular blob, because they can take longer to propagate - slot N+1: - the proposer can record availability of these kzg commitments, from slots N or N-1, without necessarily including blob txs that use them. These kzg commitments are now going to be subject to sampling (availability determination), so *on this chain* they are to be considered as available in the future (say for 32 slots or something, e.g., `available_kzg_commitments: Vector[List[KZGCommitment, MAX_BLOBS_PER_BLOCK], 32]`) - They do *not* count against max blobs or excess blob gas, and do *not* re-pay the blob basefee. - the PTC votes on the availability of the remaining (not yet used) kzg commitments among the recorded ones (in the vector) - slot N+2: - if the PTC determines that the blob data for a certain commitment is available, the beacon block *has to* record this, adding them to the ones which are considered available from now on While a kzg commitment is in`available_kzg_commitments`, any blob tx can use without paying the blob basefee for it, and without needing another availability determination. Moreover, without counting against max blobs or the excess blob gas (the blob basefee). In other words, `available_kzg_commitments` are commitments for which the availability work has already been done, and which can now be used freely on the execution layer.