State trie clearing (invariant-preserving alternative)
相关视频
正文
Hard fork
Parameters
FORK_BLKNUM
: 2,675,000CHAIN_ID
: 1 (Mainnet)
Specification
a. Account creation transactions and the CREATE
operation SHALL, prior to the execution of the initialisation code, increment the nonce over and above its normal starting value by one (for normal networks, this will be simply 1, however test-nets with non-zero default starting nonces will be different).
b. Whereas CALL
and SUICIDE
would charge 25,000 gas when the destination is non-existent, now the charge SHALL only be levied if the operation transfers more than zero value and the destination account is dead.
c. No account may change state from non-existent to existent-but-empty. If an operation would do this, the account SHALL instead remain non-existent.
d. At the end of the transaction, any account touched by the execution of that transaction which is now empty SHALL instead become non-existent (i.e. deleted).
Where:
An account is considered to be touched when it is involved in any potentially state-changing operation. This includes, but is not limited to, being the recipient of a transfer of zero value.
An account is considered empty when it has no code and zero nonce and zero balance.
An account is considered dead when either it is non-existent or it is empty.
At the end of the transaction is immediately following the execution of the suicide list, prior to the determination of the state trie root for receipt population.
An account changes state when:
- it is the target or refund of a
SUICIDE
operation for zero or more value; - it is the source or destination of a
CALL
operation or message-call transaction transferring zero or more value; - it is the source or creation of a
CREATE
operation or contract-creation transaction endowing zero or more value; - as the block author ("miner") it is the recipient of block-rewards or transaction-fees of zero or more value.
Notes
In the present Ethereum protocol, it should be noted that very few state changes can ultimately result in accounts that are empty following the execution of the transaction. In fact there are only four contexts that current implementations need track:
- an empty account has zero value transferred to it through
CALL
; - an empty account has zero value transferred to it through
SUICIDE
; - an empty account has zero value transferred to it through a message-call transaction;
- an empty account has zero value transferred to it through a zero-gas-price fees transfer.
Rationale
Same as #158 except that several edge cases are avoided since we do not break invariants:
that an account can go from having code and storage to not having code or storage mid-way through the execution of a transaction;[corrected]- that a newly created account cannot be deleted prior to being deployed.
CREATE
avoids zero in the nonce to avoid any suggestion of the oddity of CREATE
d accounts being reaped half-way through their creation.
Addendum (2017-08-15)
On 2016-11-24, a consensus bug occurred due to two implementations having different behavior in the case of state reverts.[3] The specification was amended to clarify that empty account deletions are reverted when the state is reverted.
References
- EIP-158 issue and discussion: https://github.com/ethereum/EIPs/issues/158
- EIP-161 issue and discussion: https://github.com/ethereum/EIPs/issues/161
- https://blog.ethereum.org/2016/11/25/security-alert-11242016-consensus-bug-geth-v1-4-19-v1-5-2/
Details: Geth was failing to revert empty account deletions when the transaction causing the deletions of empty accounts ended with an out-of-gas exception. An additional issue was found in Parity, where the Parity client incorrectly failed to revert empty account deletions in a more limited set of contexts involving out-of-gas calls to precompiled contracts; the new Geth behavior matches Parity’s, and empty accounts will cease to be a source of concern in general in about one week once the state clearing process finishes.