Abstract
EIP-2929 tracks accessed addresses and storage keys in the transaction-scoped sets accessed_addresses and accessed_storage_keys, and rolls both sets back to their pre-call state when a call frame reverts or exceptionally halts. This EIP removes that rollback: once an address or storage key is added to an access set, it remains warm for the rest of the transaction, regardless of any subsequent revert.
Motivation
Warm and cold pricing exists to reflect the client's real cost of loading state. That cost is paid when the data is first read from the database; a revert undoes state changes, but it does not unload the data — it stays in the client's caches, and a second access within the same transaction is cheap in reality. Rolling the access sets back on revert therefore charges cold prices for accesses that are warm in practice.
Removing the rollback aligns the gas schedule with actual execution cost and simplifies implementations: access sets become append-only for the duration of the transaction and no longer need to participate in the state journal or checkpoint/revert machinery.
Specification
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
As of the fork block:
- When a call frame ends in any outcome other than successful completion,
accessed_addressesandaccessed_storage_keysMUST NOT be rolled back. All entries added during the frame's execution, including those added by its subcalls, MUST remain in the sets.
Rationale
Access sets are a metering mechanism, not observable state, so reverting them protects nothing: reverting a frame cannot make the client forget the bytes it already read. Making the sets append-only prices the second access at what it actually costs and removes the only piece of the journal that models a cache rather than state.
An alternative would be keeping the rollback but discounting repeated cold accesses; that adds a third pricing tier for no benefit over simply keeping entries warm.
Backwards Compatibility
This EIP requires a hard fork. After the fork, some accesses that were previously charged cold are charged warm, so transactions become cheaper or stay the same — no transaction becomes more expensive. Contracts relying on exact gas costs of accesses after a revert may observe different gas consumption.
Test Cases
- Frame A calls frame B; B does a cold
SLOADof slotsand reverts. A then loadss: chargedWARM_STORAGE_READ_COST(previouslyCOLD_SLOAD_COST). - Frame A calls frame B; B does a cold
BALANCEof addressaand exceptionally halts (out of gas). A then accessesa: chargedWARM_STORAGE_READ_COST(previouslyCOLD_ACCOUNT_ACCESS_COST). - State changes made in a reverted frame remain reverted; only the access-set entries persist.
Security Considerations
Persisting warmth across reverts lets a transaction warm addresses and storage keys inside a frame that is then reverted, and access them cheaply afterwards. This is not a new capability: an EIP-2930 transaction access list already changes the warm/cold status of arbitrary addresses and storage keys in exactly the same way, before execution even begins. In both cases the cold cost of every warmed entry is paid once within the transaction, so total charged work still covers the client's actual loading cost.
Copyright
Copyright and related rights waived via CC0.
