This EIP charges access lists for their data footprint, preventing the circumvention of the EIP-7623 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 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.
Any transaction with a gas limit below 21000 + TOTAL_COST_FLOOR_PER_TOKEN * total_floor_data_tokens or below its intrinsic gas cost 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
defcalculate_access_list_floor_tokens(access_list:Tuple[Access,...])->Uint:"""Count floor data tokens in access list addresses and storage keys."""total_bytes=Uint(0)foraccessinaccess_list:total_bytes+=ulen(access.account)forslotinaccess.slots:total_bytes+=ulen(slot)returntotal_bytes*Uint(4)defcalculate_intrinsic_cost(tx:Transaction)->Tuple[Uint,Uint]:"""
Calculate intrinsic gas cost and floor gas cost.
Returns (intrinsic_gas, floor_gas).
"""# Calldata tokens (EIP-7976)
calldata_zero_bytes=Uint(0)forbyteintx.data:ifbyte==0:calldata_zero_bytes+=Uint(1)calldata_nonzero_bytes=ulen(tx.data)-calldata_zero_bytestokens_in_calldata=(calldata_zero_bytes+calldata_nonzero_bytes*Uint(4))floor_tokens_in_calldata=((calldata_zero_bytes+calldata_nonzero_bytes)*Uint(4))# Access list floor tokens and cost
floor_tokens_in_access_list=Uint(0)access_list_cost=Uint(0)ifhas_access_list(tx):floor_tokens_in_access_list=calculate_access_list_floor_tokens(tx.access_list)foraccessintx.access_list:access_list_cost+=TX_ACCESS_LIST_ADDRESS_COSTaccess_list_cost+=ulen(access.slots)*TX_ACCESS_LIST_STORAGE_KEY_COST# EIP-7981: Always charge data cost
access_list_cost+=floor_tokens_in_access_list*TOTAL_COST_FLOOR_PER_TOKEN# EIP-7981: Floor includes all floor data tokens
total_floor_data_tokens=floor_tokens_in_calldata+floor_tokens_in_access_listfloor_gas=TX_BASE_COST+total_floor_data_tokens*TOTAL_COST_FLOOR_PER_TOKEN# Intrinsic gas
calldata_cost=tokens_in_calldata*STANDARD_TOKEN_COSTcreate_cost=TX_CREATE_COST+init_code_cost(tx.data)ifis_create(tx)elseUint(0)intrinsic_gas=TX_BASE_COST+calldata_cost+create_cost+access_list_costreturnintrinsic_gas,floor_gas
Security Considerations
This EIP closes a loophole that allows circumventing EIP-7623 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.