EIP-161 State trie empty account clearing (State trie clearing (invariant-preserving alternative))

Final · EVM & execution · EIP status Final · created 2016-10-24

Changes the account creation and gas charging rules so that 'empty accounts' with no code, nonce, or balance are deleted from state at the end of a transaction, and so that new empty accounts can no longer be created.

Why it is needed

Ethereum keeps all account information in a data structure called the state trie, which every node stores. However, an 'empty account' with no code and with both nonce and balance at 0 could remain in state. Such an account serves no function while still taking up storage space. The security advisory cited in the source text notes that once the state cleanup is complete, empty accounts will no longer be a general concern, which shows that empty accounts were a real operational burden. EIP-158 was proposed earlier for the same purpose, but it had edge cases that broke existing invariants, such as a newly created account being deletable before it was even deployed. EIP-161 is an alternative that achieves the same cleanup while preserving those invariants. It deletes empty accounts at the end of a transaction and introduces four rules to prevent new empty accounts from being created in the first place. This EIP was included in the Spurious Dragon hard fork (block 2,675,000) and applied to mainnet.

What changes

Today

After EIP-161

Who is affected

In depth

Rule a: Start the nonce at 1 upon CREATE

Account creation transactions and the CREATE operation set the new account's nonce to 1 more than the default starting value before executing the initialization code. On the main network this simply becomes 1, while on test networks with a nonstandard default starting nonce the value differs. The rationale explains that the reason for not leaving the nonce at 0 is to avoid the odd situation where an account being created via CREATE is classified as empty and becomes subject to deletion during its own creation.

Rule b: Narrow the condition for charging 25,000 gas

Previously, 25,000 gas was charged whenever the target of CALL or SUICIDE was a nonexistent account. Now it is charged only when the operation transfers a value greater than 0 and the target account is dead. Dead means an account that is either nonexistent or empty. Therefore this cost is not incurred for a zero-value transfer.

Rule c: Prohibit transitioning from nonexistent to empty

No operation can move an account from a nonexistent state to an 'existing but empty' state. If an operation would otherwise produce that result, the account remains nonexistent instead. While rule d is responsible for removing existing empty accounts, this rule is responsible for preventing new empty accounts from arising in the first place.

Rule d: Delete touched empty accounts at the end of a transaction

An account touched by transaction execution is moved to a nonexistent state, i.e. deleted, if it is empty at the end of the transaction. Touched refers to involvement in an operation that could potentially change state, including being the recipient of a zero-value transfer. Empty means an account with no code, nonce 0, and balance 0. Cases where an account is considered to have 'changed state' include being the target or refund recipient of a SUICIDE for a value of 0 or more, being the source or destination of a CALL or message-call transaction, being the source or creation target of a CREATE or contract-creation transaction, and receiving block rewards or fees as the block's producer. The 'end of the transaction' is right after the suicide list is executed and before the state trie root to be placed in the receipt is determined.

Four contexts implementations must track

According to the Notes in the source text, under the current protocol there are not many paths by which an empty account can remain after transaction execution, so implementations need to track only four situations: an empty account receiving a zero value via CALL, via SUICIDE, via a message-call transaction, or via a fee transfer when the gas price is 0.

Difference from EIP-158: preserving invariants

The Rationale explains that this proposal is equivalent to EIP-158 but avoids several edge cases because it does not break invariants. Specifically, the invariant that a newly created account cannot be deleted before it is deployed is preserved. Starting the nonce at a nonzero value on CREATE is also a safeguard to eliminate the possibility of an account being mistakenly treated as subject to deletion while it is still being created.

The 2016-11-24 consensus bug and the specification patch

On November 24, 2016, a consensus bug occurred because two implementations behaved differently during a state rollback. Geth failed to roll back an empty-account deletion when the transaction that caused it ended in an out-of-gas exception, and Parity made the same mistake in a more limited context involving out-of-gas calls to precompiled contracts. Geth was subsequently fixed to match Parity's behavior, and on August 15, 2017 the specification was updated to state explicitly that empty-account deletions are rolled back along with state rollbacks. This EIP was included in the Spurious Dragon hard fork (block 2,675,000, mainnet CHAIN_ID 1) and its status is Final.

Original EIP · ← EIPs