EIP-7706: Separate gas type for calldata
Create a separate basefee and gaslimit for calldata
Abstract
Add a new type of gas for transaction calldata. Add a new transaction type that provides max_basefee
and priority_fee
as a vector, providing values for execution gas, blob gas and calldata gas. Modify the basefee adjustment to use the same mechanism for the three types of gas.
Motivation
A major argument against raising the Ethereum gas limit, making calldata cheaper, or increasing the EIP-4844 blob count before technologies like PeerDAS become available, is that the theoretical maximum size of an Ethereum block is already too large, and we cannot afford to increase it further. However, there is an inefficiency here: the current average size of a block (not including blobs) is ~100 kB, and the theoretical max is 30,000,000 / 16 = 1,875,000
bytes (one could make larger blocks using zero bytes, but in practice zero-byte-heavy blocks would be compressed to less than 1.87 million bytes due to snappy compression). Ideally, we would have a way to bound the maximum, without making calldata more scarce on average.
This EIP does exactly this, by adopting the same technique that was applied for blob data in EIP-4844: we introduce a separate fee market for calldata, with a separate basefee and a separate per-block gas limit. The theoretical max calldata size of a block would be greatly reduced, while basic economic analysis suggests that on average, calldata would become considerably cheaper.
The EIP also introduces a new transaction type which includes the three types of max-basefees and priority fees as a vector, allowing the same code paths to handle all three types of gas. We also make the basefee adjustment, which currently uses separate mechanisms for execution gas (introduced in EIP-1559) and blobs (introduced in EIP-4844), use the same approach for all three types of gas. This simplifies the basefee adjustment rules, and ensures that the stronger mathematical properties of the newer EIP-4844 basefee adjustment algorithm cover all three types of gas.
Specification
The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
Parameters
FORK_BLKNUM
=TBD
NEW_TX_TYPE
=TBD
CALLDATA_GAS_PER_TOKEN
=4
TOKENS_PER_NONZERO_BYTE
=4
CALLDATA_GAS_LIMIT_RATIO
=4
LIMIT_TARGET_RATIOS = [2, 2, 4]
MIN_BASE_FEE_PER_GAS = 1
# Rename of EIP-4844 MIN_BASE_FEE_PER_BLOB_GASBASE_FEE_UPDATE_FRACTION = 8
# Roughly matches EIP-4844 parameters
New transaction type
As of FORK_BLOCK_NUMBER
, a new EIP-2718 transaction is introduced with TransactionType
= TX_TYPE(NEW_TX_TYPE)
.
The EIP-2718 TransactionPayload
for this transaction is
We require max_fees_per_gas
and priority_fees_per_gas
to be length-3 vectors, each of which contain integers from 0
to 2**64-1
.
The intrinsic cost of the new transaction is inherited from EIP-4844, except that the calldata gas cost (16 per nonzero byte, 4 per zero byte) is removed.
Block processing and transaction fees
We add the functions get_max_fees
and get_priority_fees
, to compute these length-3 vectors for previous transaction types:
We also add some helpers:
At the start of block processing:
- We initialize a vector
gas_used_so_far
to[0, 0, 0]
At the start of processing a transaction:
- Compute
fees_per_gas = get_fees_per_gas(tx, get_block_basefees(block))
andtx_gaslimits = get_gaslimits(tx)
- Check that
all_less_or_equal(vector_add(gas_used_so_far, tx_gaslimits), block.gas_limits)
- Deduct
sum(vector_mul(fees_per_gas, tx_gaslimits))
wei from thetx.origin
account
Note that get_block_basefees(block)
is not yet defined, we will define it in the section below. The block.gas_limits
field is also defined in the section below.
At the end of processing a transaction:
- Compute
tx_gas_consumed
as a three item vector, where the first item is the amount of gas actually consumed by the transaction execution, and the second and third match the values inget_gaslimits(tx)
- Refund
sum(vector_mul(fees_per_gas, vector_sub(tx_gaslimits, tx_gas_consumed)))
to thetx.origin
account (in practice, only the first term will be nonzero for now) - Set
gas_used_so_far = vector_add(gas_used_so_far, tx_gas_consumed)
At the end of processing a block:
- Require
block.gas_used = gas_used_so_far
The block.gas_used
field will be defined in the section below.
Block structure:
We update BlockHeader
field, to remove the blob_gas_used
, gas_used
, base_fee_per_gas
, gas_limit
and excess_blob_gas
fields, and we add new fields, all of the [int, int, int]
type: gas_limits
, gas_used
, excess_gas
. The resulting RLP encoding becomes:
We define:
We calculate the required excess_gas
values as follows:
We calculate the required gas_limits
as follows:
gas_limits[0]
must follow the existing adjustment formulagas_limits[1]
must equalMAX_BLOB_GAS_PER_BLOCK
gas_limits[2]
must equalgas_limits[0] // CALLDATA_GAS_LIMIT_RATIO
Now, we define get_block_basefees
:
Rationale
Conversion of all gas-related mechanics into vectors
This allows the same logic that is used for handling gas to handle all three types of gas. As a result, it's arguably a net simplification of protocol gas handling logic, despite the fact that the total number of gas types increases from 2 to 3
Target ratios
The target ratios for execution gas and blobs are set to 2; the target ratio for calldata is set to 4. This greatly decreases the number of scenarios in which calldata actually hits the limit, which mitigates economic impact of the EIP, because analysis of EIP-1559-style fee markets is much simpler in "under-the-limit" conditions than in "at-the-limit" conditions. Additionally, it reduces the risk that applications requiring large calldata will outright stop working.
The current parameters set the target calldata per block to 187,500 bytes, about 2x the current average. Using basic supply-and-demand reasoning, this implies that calldata is likely to become significantly cheaper as a result of this EIP.
Backwards Compatibility
Previous transaction types set the calldata basefee and priority fee to equal each other. The calldata gas costs were intentionally set to be identical to today, and the gas target similar to present-day usage, so that setting the two fees to be equal each other is a reasonable approximation to optimal behavior. In practice, the new transaction type would be superior, so we expect users to switch to it over time. However, the loss suffered by old-style transaction users would not be that high, because priority fees are generally small compared to basefees, and the amount that a user pays is proportional to the basefee.
Security Considerations
Optimal block building behavior becomes more complex as a result of this EIP, particularly under the boundary conditions when blocks are full of one or both types of gas. We argue that the effects of this are not too large, because in practice over 90% of blocks are under-full, and naive "greedy algorithms" can get a close-enough-to-optimal outcome. The centralization risks of proprietary block-building algorithms are thus likely to be much smaller than other existing risks with eg. MEV extraction.
Copyright
Copyright and related rights waived via CC0.