Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

State clearing #158

Closed
vbuterin opened this issue Oct 16, 2016 · 11 comments
Closed

State clearing #158

vbuterin opened this issue Oct 16, 2016 · 11 comments

Comments

@vbuterin
Copy link
Contributor

vbuterin commented Oct 16, 2016

Specification

For all blocks where block.number >= FORK_BLKNUM (TBA):

  1. In all cases where a state change is made to an account, and this state change results in the account state being saved with nonce = 0, balance = 0, code empty, storage empty (hereinafter "empty account"), the account is instead deleted.
  2. If a address is "touched" and that address contains an empty account, then it is deleted. A "touch" is defined as any situation where if the account at the given address were nonexistent it would be created.
  3. Whenever the EVM checks if an account exists, emptiness is treated as equivalent to nonexistence. Particularly, note that this implies that, once this change is enabled, there is no longer a meaningful difference between emptiness and nonexistence from the point of view of EVM execution.
  4. Zero-value calls and zero-value suicides no longer consume the 25000 account creation gas cost in any circumstance

The cases where a "touch" takes place can be enumerated as follows:

  • Zero-value-bearing CALLs
  • CREATEs (if the code that is ultimately saved is empty and there is no ether remaining in the account when it is saved)
  • Zero-value-bearing SUICIDEs
  • Transaction recipients
  • Contracts created in contract creation transactions
  • Miners receiving transaction fees (note the case where the gasprice is zero, and the account does not yet exist because it only receives the block/uncle/nephew rewards after processing every transaction)

Specification (1b)

When the EVM checks for emptiness (for the purpose of possibly applying the 25000 gas cost), emptiness is defined by is_empty(acct): return get_balance(acct) == 0 and get_code(acct) == "" and get_nonce(acct) == 0; emptiness of storage does not matter. This simplifies client implementation because there is no need to add extra complexity to make caches enumerable in the correct way and does not significantly affect the intended result, as the cases where balance/code/nonce are empty but storage is nonempty where this change would lead to an extra 25000 gas being paid are pathological and have no real use value.

Specification (1c)

Do not implement point 2 above (ie. no new empty accounts can be created, but existing ones are not automatically destroyed unless their state is actually changed). Instead, during each block starting from (and including) N and ending when there are no null accounts left, select the 1000 null accounts that are left-most in order of sha3(address), and delete them (ordering by hash is necessary so as to allow the accounts to be easily found by iterating the tree).

Rationale

This removes a large number of empty accounts that have been put in the state at very low cost due to flaws in earlier versions of the Ethereum protocol, thereby greatly reducing state size and hence both reducing the hard disk load of a full client and reducing the time for a fast sync. Additionally, it simplifies the protocol in the long term, as once all "empty" objects are cleared out there is no longer any meaningful distinction between an account being empty and being nonexistent, and indeed one can simply view nonexistence as a compact representation of emptiness.

Note that this proposal does introduce a temporary breaking of existing guarantees, in that by repeatedly zero-value-calling already existing empty accounts one can create a state change at a cost of 700 gas per account instead of the usual 5000 per gas minimum (with SUICIDE refunds this goes down further to 350 gas per account). Allowing such a large number of state writes per block will lead to heightened block processing times and increase uncle rates in the short term while the existing empty accounts are being cleared, and eventually once all empty accounts are cleared this issue will no longer exist.

@Smithgift
Copy link

To be clear, in this proposal, there is no irregular state change to clear it all en masse?

@vbuterin
Copy link
Contributor Author

Correct.

@veox
Copy link
Contributor

veox commented Oct 17, 2016

In all cases where, if an account was nonexistent right before the operation an empty account would have been created, if right before the operation the account is in fact empty then the account is deleted.

This is hard to read. Did you mean:

In all cases where an operation would create a new empty account out of a previously nonexistent one, the account shall remain nonexistent.

EDIT: nope, see next comment.


How is "zero-value suicide" defined? Is it: execution of a SUICIDE instruction that results in a zero-value balance transfer?

@vbuterin
Copy link
Contributor Author

In all cases where an operation would create a new empty account out of a previously nonexistent one, the account shall remain nonexistent.

No, it should be read exactly as written; becoming nonexistent, not remaining. That is, in all situations where an operation would formerly turn a nonexistent account into an empty account, the operation would keep the account nonexistent, and in fact if there's an empty account in that position it would turn it into a nonexistent one. The condition for instantiation becomes a condition for deletion.

How is "zero-value suicide" defined? Is it: execution of a SUICIDE instruction that results in a zero-value balance transfer?

Yes.

@crossed1000
Copy link

Has this taken place? My geth client still goes over 18mil states when syncing from scratch. I'm on 1.4.18

@evertonfraga
Copy link
Member

@crossed1000 this EIP was not yet delivered. Only EIP #150 on yesterday's HF.

@BlameByte
Copy link

If a call with a value were to hit one of these empty but not deleted accounts would that permanently preserve an empty account?

Note that this proposal does introduce a temporary breaking of existing guarantees, in that by repeatedly zero-value-calling already existing empty accounts one can create a state change at a cost of 700 gas per account instead of the usual 5000 per gas minimum (with SUICIDE refunds this goes down further to 350 gas per account).

Since it would require an action to remove these empty accounts it would require calling them with zero value and due to the low cost as you mentioned I assume the block gas limit would have to decrease to prevent huge block processing delays?

In all cases where a state change is made to an account, and this state change results in the account state being saved with nonce = 0, balance = 0, code empty, storage empty (hereinafter "empty account"), the account is instead deleted.

Zero-value calls and zero-value suicides no longer consume the 25000 account creation gas cost in any circumstance

Does that mean if you were to zero value call twice on the same empty account it would delete it and then try to create it again realize it is empty and delete it again? So repetitively calling this account would require a lot of processing at the cost of a single call?

@vbuterin
Copy link
Contributor Author

Since it would require an action to remove these empty accounts it would require calling them with zero value and due to the low cost as you mentioned I assume the block gas limit would have to decrease to prevent huge block processing delays?

Yes, it would require such an action - zero-value calling them. But this is only a 14x difference from the cost of processing normal execution so it shouldn't break the chain while it's happening, though uncle rates would substantially go up in the meantime.

@BlameByte
Copy link

Yes, it would require such an action - zero-value calling them. But this is only a 14x difference from the cost of processing normal execution so it shouldn't break the chain while it's happening, though uncle rates would substantially go up in the meantime.

What about if there is an EVM exception such as running out of gas these state changes will be reverted back to the empty account which would require the state to be changed and reverted on each call and would allow the same empty accounts to be zero value called repetitively?

Unless the empty accounts are deleted even in the case of an EVM exception, if that is the case would that not break the guarantee that EVM exceptions revert the state back as if the transaction was never made?

@axic
Copy link
Member

axic commented Aug 22, 2017

@vbuterin @cdetrio is this considered obsolete / closed since #161 was chosen?

@cdetrio
Copy link
Member

cdetrio commented Nov 26, 2017

Please see EIP 161 for the finalized state clearing spec.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants