--- eip: 7981 title: Increase Access List Cost description: Price access lists for data to reduce maximum block size author: Toni Wahrstätter (@nerolation) discussions-to: https://ethereum-magicians.org/t/eip-7981-increase-access-list-cost/24680 status: Draft type: Standards Track category: Core created: 2024-12-27 requires: 2930, 7623, 7976 --- ## Abstract This EIP charges access lists for their data footprint, preventing the circumvention of the [EIP-7623](./eip-7623.md) floor pricing. This effectively reduces the worst-case block size by ~21% with minimal impact on users. ## Motivation Access lists are only priced for storage but not for their data. Furthermore, access lists can circumvent the [EIP-7623](./eip-7623.md) floor pricing by contributing to EVM gas while still leaving a non-negligible data footprint. This enables achieving the maximal possible block size by combining access lists with calldata at a certain ratio. ## Specification | Parameter | Value | Source | | -------------------------------------- | ----- | ------ | | `ACCESS_LIST_ADDRESS_COST` | `2400` | [EIP-2930](./eip-2930.md) | | `ACCESS_LIST_STORAGE_KEY_COST` | `1900` | [EIP-2930](./eip-2930.md) | | `TOTAL_COST_FLOOR_PER_TOKEN` | `16` | [EIP-7976](./eip-7976.md) | Let `access_list_bytes` be the total byte count of addresses (20 bytes each) and storage keys (32 bytes each) in the access list. Let `access_list_data_cost = 64 * access_list_bytes` (i.e. `1280` gas per address and `2048` gas per storage key). The `64` gas-per-byte rate matches the [EIP-7976](./eip-7976.md) calldata floor. The access list data cost is added as a flat surcharge to the gas used calculation, leaving the [EIP-2930](./eip-2930.md) `access_list_cost` and the [EIP-7976](./eip-7976.md) floor calculation unchanged: ```python tx.gasUsed = ( 21000 + access_list_data_cost + max( STANDARD_TOKEN_COST * tokens_in_calldata + execution_gas_used + isContractCreation * (32000 + INITCODE_WORD_COST * words(calldata)) + access_list_cost, TOTAL_COST_FLOOR_PER_TOKEN * floor_tokens_in_calldata ) ) ``` Any transaction with a gas limit below `tx.gasUsed` evaluated with `execution_gas_used = 0` is considered invalid. ## Rationale Access list data is always charged at floor rate (added to `access_list_cost`), and access list tokens are included in the floor calculation. This ensures: - Access list data always pays floor rate regardless of execution level - Access lists cannot be used to bypass the calldata floor pricing - Consistent pricing across all transaction data sources ## Backwards Compatibility This is a backwards incompatible gas repricing that requires a scheduled network upgrade. Requires updates to gas estimation in wallets and nodes. Normal usage patterns remain largely unaffected. ## Reference Implementation ```python def calculate_access_list_data_cost(access_list): """EIP-7981: flat 64 gas per byte of access list data.""" # Each access entry: 20-byte address + 32 bytes per storage key total_bytes = sum(20 + 32 * len(access.slots) for access in access_list) return total_bytes * 64 def calculate_intrinsic_cost(tx): """ Calculate intrinsic gas cost and floor gas cost. Both include the EIP-7981 access list data surcharge, so that tx.gasUsed = max(intrinsic_gas + execution_gas_used, floor_gas). """ # Calldata tokens (EIP-7976) zero_bytes = count_zero_bytes(tx.data) nonzero_bytes = len(tx.data) - zero_bytes tokens_in_calldata = zero_bytes + nonzero_bytes * 4 floor_tokens_in_calldata = len(tx.data) * 4 # Access list cost (EIP-2930, unchanged) and EIP-7981 data surcharge access_list_cost = 0 access_list_data_cost = 0 if has_access_list(tx): for access in tx.access_list: access_list_cost += ( ACCESS_LIST_ADDRESS_COST + len(access.slots) * ACCESS_LIST_STORAGE_KEY_COST ) access_list_data_cost = calculate_access_list_data_cost(tx.access_list) # EIP-7976 floor (calldata only) plus EIP-7981 surcharge floor_gas = ( TX_BASE_COST + floor_tokens_in_calldata * TOTAL_COST_FLOOR_PER_TOKEN + access_list_data_cost ) # Intrinsic gas plus EIP-7981 surcharge calldata_cost = tokens_in_calldata * STANDARD_TOKEN_COST create_cost = TX_CREATE_COST + init_code_cost(tx.data) if is_create(tx) else 0 intrinsic_gas = ( TX_BASE_COST + calldata_cost + create_cost + access_list_cost + access_list_data_cost ) return intrinsic_gas, floor_gas ``` ## Security Considerations This EIP closes a loophole that allows circumventing [EIP-7623](./eip-7623.md) floor pricing. Without this fix, attackers can achieve larger blocks than intended by combining access lists with calldata. All transaction data sources now contribute to the floor calculation consistently. ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md).