# EIP-7918 in Fusaka: 3 reasons and 1 trick Tonight, Fusaka goes live and Ethereum updates its blob pricing mechanism with a blob reserve price (a price floor) via [EIP-7918](https://eips.ethereum.org/EIPS/eip-7918). Here are three reasons why EIP-7918 ties the reserve price to the execution price, and the trick that made it all come together on the final submission day. ## Three reasons for tying the reserve price to the execution price ### Reason 1: to retain control over demand Ethereum adapts the gas price with demand. If more blobs are used than the target, the price rises; if fewer, the price falls. Due to this automatic pricing, users do not need to guess how much to pay for inclusion. However, the pricing system only works when the price actually influences demand. If the blob base fee is 1 wei, users hardly notice the fee even if it increases 1,000-fold. Since the blob base fee can at most increase by 12.5% every slot, it may take several hours until it is sufficiently high to produce a target consumption of blobs. During that time, users may want to buy more blobspace than what is available, but it can be hard to know how much to pay (via tips) for it. Where is that inflection point where users begin to care about the blob base fee? Presumably, since users also need to pay for the blob-carrying transaction with execution gas, they only start caring once the cost of the blob gas is some relevant fraction of the execution cost. Therefore, by tying the reserve price to the execution base fee, we can ensure that users always care, at least a little, about the blob base fee. This idea is also explained in a [children's book](https://notes.ethereum.org/@anderselowsson/AIG). ### Reason 2: to use the price of calldata as a reference point In economics, things should often be evaluated on a *relative* basis. If we want to say that the reserve price for blobdata is "too low" or "too high", we need some form of reference point. A good reference point is calldata, which is priced in execution gas. It is preferable not to set the reserve price for blobdata higher than the price for calldata. A fixed reserve price, as was considered in EIP-7762, could have led the reserve price to become either "too low" or "too high" using the calldata reference point. To see the problem, here is what happens with some concrete numbers. At the current base fee of 0.03 gwei, the price per byte of calldata is 16 * 0.03 = 0.48 gwei. That's below the reserve price of 1 gwei per blobdata byte (~2**30 wei) that was suggested in the spring by leading researchers (albeit the EIP-7623 calldata cost floor is 40 * 0.03 = 1.2 gwei, thus slightly higher). The constant actually proposed in EIP-7762 would still be safe, currently pricing calldata 14 times higher than blobdata. But the execution base fee could always fall further, pushing the calldata price below the fixed blob price floor. ![](https://notes.ethereum.org/_uploads/B1YBu_pZbx.jpg) The point I'm trying to make here is that if we want to ensure that blobs have a reserve price that is reasonable relative to the price of calldata or the price of executing the blob-carrying transaction, then the robust approach is to tie the two prices together. In EIP-7918, the reserve price for one byte of blobdata is always 1/256 of the price for one byte of calldata, because it ties the reserve price to the execution price. If calldata is cheaper, some L2s might pivot to calldata, and its equilibrium price could still end up higher than or equal to the blob reserve price. But this pivot would impede the scaling achieved via blobs. If L2s use calldata, they crowd out other users. ### Reason 3: to align the price with the compute costs imposed by blobs Blobs also impose a computational cost on nodes. Nodes must cryptographically verify KZG proofs to ensure that associated commitments correspond to provided blobs. This process is computationally expensive. It seems desirable to ensure that blob consumers pay at least some fraction of the market rate for the compute they impose. The execution base fee reflects how in-demand nodes’ compute services are at the time that blob consumers request them, and is therefore suitable as a reference point for the reserve price. This provides an additional rationale for the design, and was suggested by Ben Adams during the discussion phase for the EIP. ## The trick that made it all come together On the final submission day, it was clear that the design should have a reserve price tied to the execution fee. However, I could not directly enforce it! The issue is that the blob base fee is encoded in `excess_blob_gas` and calculated from it using an exponential function. I wanted to first compute the reserve blob base fee from the execution base fee, and then compute the reserve `excess_blob_gas` from the reserve blob base fee. While the execution layer can easily convert `excess_blob_gas` into a blob base fee, it lacks the "inverse" function to convert a blob base fee into `excess_blob_gas`. Implementing that inverse function would have substantially increased the complexity of the EIP. It was time to think things through and come up with an alternative solution. While the execution layer could not calculate exactly what the `excess_blob_gas` reserve price should be, it could always ask: is the current `excess_blob_gas` too low? You do not need the inverse for that—you only need to determine the blob base fee from the `excess_blob_gas` and compare it with the execution base fee. And this is actually all it takes. If the blob base fee is too low in that comparison, you just let `excess_blob_gas` rise! This is why the EIP has that `if` condition. It was necessary to compare the exponentiation of `excess_blob_gas` with the execution base fee and adjust the response accordingly, because it was not possible to set a specific reserve `excess_blob_gas` from the execution base fee. For reference, here is the final EIP-7918 reserve price logic: ```python if execution_base_fee > 16 * compute_blob_base_fee(excess_blob_gas): # excess_blob_gas rises with every blob consumed else: # excess_blob_gas is updated as normal ```