EIP-158 Cleanup of empty account state (State clearing)
Final · EVM & execution · EIP status Final · created 2016-10-16
A change that removes 'empty accounts' (accounts whose balance, nonce, and code are all empty) from Ethereum state and prevents new ones from being created going forward. This substantially reduces the state size that every node must store.
Why it is needed
Ethereum's early protocol had a flaw that let 'empty accounts' be added to state at very low cost. An empty account has zero balance, zero transaction count (nonce), and empty code and storage, making it useless, but once created every node still had to keep storing it forever. This caused state size to balloon, increasing the disk burden on full nodes and lengthening the fast sync time for new nodes catching up with the network. This proposal reduces state size by removing these empty accounts from state and preventing new ones from being created. It also means that once all empty accounts are gone, there is no longer a need to distinguish between 'an account being empty' and 'an account not existing,' simplifying the protocol in the long run.
What changes
Today
- Useless empty accounts still remain in state and every node must store them
- 'An account being empty' and 'an account not existing' are treated as distinct from each other
- Even a call that sends 0 ether can incur the 25000 gas account creation cost
After EIP-158
- If a situation would result in an account being stored as empty, it is deleted instead of being stored
- When an empty account is 'touched,' it is deleted on the spot, and the EVM treats emptiness as equivalent to nonexistence
- A 0 ether call and a 0 ether SUICIDE never incur the 25000 gas cost under any circumstances
Who is affected
- Node operators: Reduced state size lowers the disk burden on full nodes and shortens fast sync time.
- Client teams: Account existence checks, touch handling, and gas calculation logic must be implemented to match the new rules. The simplified emptiness check in Specification (1b) can be used.
- Contract and app developers: Since an account's emptiness and nonexistence become identical from the EVM execution's standpoint, any assumptions that relied on the difference between the two no longer hold.
In depth
Definition of an empty account and the two deletion rules
Applies to every block where block.number >= FORK_BLKNUM (TBA in the original text). First, if a state change occurs on an account and the result would be stored as an 'empty account' with nonce = 0, balance = 0, no code, and empty storage, the account is deleted instead of being stored. Second, if an address is 'touched' and that address has an empty account, it is deleted. A touch is defined as 'any situation in which an account would have been created had no account existed at that address.'
Six cases that cause a touch
The touch cases listed in the original text are: a CALL sending 0 ether, a CREATE (where the finally stored code is empty and the account has no ether left at the time of storage), a SUICIDE sending 0 ether, the recipient of a transaction, a contract created by a contract-creation transaction, and the miner receiving transaction fees. For the miner case, the original text separately notes that since gasprice can be 0 and block, uncle, and nephew rewards are only received after all transactions have been processed, the account may not yet exist.
Equivalence of emptiness and nonexistence, abolition of the 25000 gas cost
Whenever the EVM checks account existence, it treats emptiness as equivalent to nonexistence. Once this change is active, there is no longer any meaningful difference between emptiness and nonexistence from the EVM execution's standpoint. In addition, a zero-value call and a zero-value SUICIDE never consume the 25000 gas account creation cost under any circumstances.
Specification (1b): storage excluded from the emptiness check
The emptiness check used to decide whether the 25000 gas applies is defined as is_empty(acct): return get_balance(acct) == 0 and get_code(acct) == "" and get_nonce(acct) == 0, and it does not look at whether storage is empty. This avoids the extra complexity needed to make the cache correctly enumerable, which simplifies client implementations. The original text explains that the case where balance, code, and nonce are empty but storage remains, causing the extra 25000 gas to be charged, is a pathological case with no practical value.
Specification (1c): the alternative of deleting 1000 per block
An alternative that does not implement item 2 above (deletion on touch). It prevents new empty accounts from being created, but does not automatically destroy existing empty accounts unless their state is actually changed. Instead, starting from block N, until no null accounts remain, each block selects and deletes the 1000 leftmost null accounts in sha3(address) order. Sorting by hash order is necessary to make it easy to find accounts while traversing the tree.
Effects and temporary side effects
This change removes the large number of empty accounts that entered state at very low cost due to the early protocol flaw, substantially reducing state size and together reducing the disk burden on full clients and fast sync time. Once all empty objects are cleaned up, the distinction between emptiness and nonexistence disappears, simplifying the protocol in the long run as well. However, existing guarantees are temporarily broken. Repeatedly sending 0 ether calls to an existing empty account can cause a state change for 700 gas per account (350 gas with the SUICIDE refund) instead of the usual minimum of 5000 gas. More state writes per block increases block processing time and temporarily raises the uncle rate, but this problem disappears once all empty accounts have been cleaned up.