-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
Update EIP-4762: reworked gas schedule from interop #8550
Changes from all commits
a8cfb56
06b7248
acec5e6
2e609fd
7af9770
271a9e4
508f0ab
ea647e7
96e3281
29da746
65aafe5
9e5644f
e785fdf
427e408
285a2e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
eip: 4762 | ||
title: Statelessness gas cost changes | ||
description: Changes the gas schedule to reflect the costs of creating a witness by requiring clients update their database layout to match. | ||
author: Guillaume Ballet (@gballet), Vitalik Buterin (@vbuterin), Dankrad Feist (@dankrad) | ||
author: Guillaume Ballet (@gballet), Vitalik Buterin (@vbuterin), Dankrad Feist (@dankrad), Ignacio Hagopian (@jsign), Tanishq Jasoria (@tanishqjasoria), Gajinder Singh (@g11tech) | ||
discussions-to: https://ethereum-magicians.org/t/eip-4762-statelessness-gas-cost-changes/8714 | ||
status: Draft | ||
type: Standards Track | ||
|
@@ -39,47 +39,42 @@ We define access events as follows. When an access event takes place, the access | |
|
||
#### Access events for account headers | ||
|
||
When a non-precompile address is the target of a `CALL`, `CALLCODE`, `DELEGATECALL`, `SELFDESTRUCT`, `EXTCODESIZE`, or `EXTCODECOPY` opcode, or is the target address of a contract creation whose initcode starts execution, process these access events: | ||
When: | ||
|
||
``` | ||
(address, 0, VERSION_LEAF_KEY) | ||
(address, 0, CODE_SIZE_LEAF_KEY) | ||
``` | ||
1. a non-precompile address is the target of a `*CALL`, `SELFDESTRUCT`, `EXTCODESIZE`, or `EXTCODECOPY` opcode, | ||
2. a non-precompile address is the target address of a contract creation whose initcode starts execution, | ||
3. any address is the target of the `BALANCE` opcode | ||
4. a _deployed_ contract calls `CODECOPY` | ||
gballet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
If a call is value-bearing (ie. it transfers nonzero wei), whether or not the callee is a precompile, process these two access events: | ||
process this access events: | ||
gballet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
``` | ||
(caller_address, 0, BALANCE_LEAF_KEY) | ||
(callee_address, 0, BALANCE_LEAF_KEY) | ||
(address, 0, BASIC_DATA_LEAF_KEY) | ||
``` | ||
|
||
When a contract is created, process these access events: | ||
|
||
``` | ||
(contract_address, 0, VERSION_LEAF_KEY) | ||
(contract_address, 0, NONCE_LEAF_KEY) | ||
(contract_address, 0, BALANCE_LEAF_KEY) | ||
gballet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
(contract_address, 0, CODE_KECCAK_LEAF_KEY) | ||
(contract_address, 0, CODE_SIZE_LEAF_KEY) | ||
``` | ||
Note: a non-value-bearing `SELFDESTRUCT` or `*CALL`, targetting a precompile, will not cause the `BASIC_DATA_LEAF_KEY` to be added to the witness. | ||
|
||
If the `BALANCE` opcode is called targeting some address, process this access event: | ||
If a `*CALL` or `SELFDESTRUCT` is value-bearing (ie. it transfers nonzero wei), whether or not the callee is a precompile, process this additional access event: | ||
|
||
``` | ||
(address, 0, BALANCE_LEAF_KEY) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we also touch the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: add version |
||
(origin, 0, BASIC_DATA_LEAF_KEY) | ||
``` | ||
|
||
If the `SELFDESTRUCT` opcode is called by some caller_address targeting some target_address (regardless of whether it’s value-bearing or not), process access events of the form: | ||
Note: when checking for the existence of the callee, the existence check is done by validating that there is an extension-and-suffix tree at the corresponding stem, and does not rely on `CODEHASH_LEAF_KEY`. | ||
|
||
When calling `EXTCODEHASH` on a non-precompile target, process the access event: | ||
|
||
``` | ||
(caller_address, 0, BALANCE_LEAF_KEY) | ||
(target_address, 0, BALANCE_LEAF_KEY) | ||
(address, 0, CODEHASH_LEAF_KEY) | ||
``` | ||
|
||
If the `EXTCODEHASH` opcode is called targeting some address, process an access event of the form: | ||
Note that precompiles are excluded, as their hashes are known to the client. | ||
|
||
When a contract is created, process these access events: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this is also duplicated - https://github.com/ethereum/EIPs/pull/8550/files#diff-cd2aaa222faeb6081a41605386a509b3c4839285cd15f1b0ebe009318707914eL143 |
||
|
||
``` | ||
(address, 0, CODEHASH_LEAF_KEY) | ||
(contract_address, 0, BASIC_DATA_LEAF_KEY) | ||
(contract_address, 0, CODEHASH_LEAF_KEY) | ||
``` | ||
|
||
#### Access events for storage | ||
|
@@ -120,34 +115,29 @@ We define **write events** as follows. Note that when a write takes place, an ac | |
|
||
#### Write events for account headers | ||
|
||
When a nonzero-balance-sending `CALL` or `SELFDESTRUCT` with a given sender and recipient takes place, process these write events: | ||
When a nonzero-balance-sending `*CALL` or `SELFDESTRUCT` with a given sender and recipient takes place, process these write events: | ||
|
||
``` | ||
(sender, 0, BALANCE_LEAF_KEY) | ||
(recipient, 0, BALANCE_LEAF_KEY) | ||
(origin, 0, BASIC_DATA_LEAF_KEY) | ||
(target, 0, BASIC_DATA_LEAF_KEY) | ||
``` | ||
|
||
When a contract creation is initialized, process these write events: | ||
if no account exists at `callee_address`, also process: | ||
|
||
``` | ||
(contract_address, 0, VERSION_LEAF_KEY) | ||
(contract_address, 0, NONCE_LEAF_KEY) | ||
(target, 0, CODEHASH_LEAF_KEY) | ||
``` | ||
|
||
Only if the value sent with the creation is nonzero, also process: | ||
When a contract creation is initialized, process these write events: | ||
|
||
``` | ||
(contract_address, 0, BALANCE_LEAF_KEY) | ||
(contract_address, 0, BASIC_DATA_LEAF_KEY) | ||
``` | ||
|
||
When a contract is created, process these write events: | ||
|
||
``` | ||
(contract_address, 0, VERSION_LEAF_KEY) | ||
(contract_address, 0, NONCE_LEAF_KEY) | ||
(contract_address, 0, BALANCE_LEAF_KEY) | ||
(contract_address, 0, CODE_KECCAK_LEAF_KEY) | ||
(contract_address, 0, CODE_SIZE_LEAF_KEY) | ||
(contract_address, 0, CODEHASH_LEAF_KEY) | ||
``` | ||
|
||
#### Write events for storage | ||
|
@@ -174,36 +164,31 @@ When a contract is created, process the write events: | |
|
||
For `i` in `0 ... (len(code)+30)//31`. | ||
|
||
Note: since no access list existed for code up until this EIP, note that no warm costs are charged for code accesses. | ||
|
||
### Transactions | ||
|
||
#### Access events | ||
|
||
For a transaction, make these access events: | ||
|
||
``` | ||
(tx.origin, 0, VERSION_LEAF_KEY) | ||
(tx.origin, 0, BALANCE_LEAF_KEY) | ||
(tx.origin, 0, NONCE_LEAF_KEY) | ||
(tx.origin, 0, CODE_SIZE_LEAF_KEY) | ||
(tx.origin, 0, CODE_KECCAK_LEAF_KEY) | ||
(tx.target, 0, VERSION_LEAF_KEY) | ||
(tx.target, 0, BALANCE_LEAF_KEY) | ||
(tx.target, 0, NONCE_LEAF_KEY) | ||
(tx.target, 0, CODE_SIZE_LEAF_KEY) | ||
(tx.target, 0, CODE_KECCAK_LEAF_KEY) | ||
(tx.origin, 0, BASIC_DATA_LEAF_KEY) | ||
(tx.origin, 0, CODEHASH_LEAF_KEY) | ||
Comment on lines
+176
to
+177
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Edit: comment quoting code is not correct, I meant L173 If we have a tx (non-value-bearing) targeting a precompile or system contract, we don't need to touch BASIC_DATA. (i.e: stateless client knows the code-size) We can still argue that this rule should be avoided to avoid a border case. But considering we didn't do any similar simplification for precompiles/system contracts in other places in the EIP (i.e. we avoid adding in the witness for them as much as possible), then maybe not doing it here is actually adding a border case (we have to remember this is an exception), not removing it. No strong opinions, just surfacing this. |
||
(tx.target, 0, BASIC_DATA_LEAF_KEY) | ||
gballet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
(tx.target, 0, CODEHASH_LEAF_KEY) | ||
``` | ||
|
||
#### Write events | ||
|
||
``` | ||
(tx.origin, 0, NONCE_LEAF_KEY) | ||
(tx.origin, 0, BASIC_DATA_LEAF_KEY) | ||
``` | ||
|
||
if `value` is non-zero: | ||
If `value` is non-zero: | ||
|
||
``` | ||
(tx.origin, 0, BALANCE_LEAF_KEY) | ||
(tx.target, 0, BALANCE_LEAF_KEY) | ||
(tx.target, 0, BASIC_DATA_LEAF_KEY) | ||
``` | ||
|
||
### Witness gas costs | ||
|
@@ -216,15 +201,15 @@ Remove the following gas costs: | |
|
||
Reduce gas cost: | ||
|
||
* `CREATE` to 1000 | ||
* `CREATE`/`CREATE2` to 1000 | ||
|
||
|Constant |Value| | ||
|-|-| | ||
|`WITNESS_BRANCH_COST` |1900| | ||
|`WITNESS_BRANCH_COST`|1900| | ||
|`WITNESS_CHUNK_COST` |200| | ||
|`SUBTREE_EDIT_COST` |3000| | ||
|`CHUNK_EDIT_COST` |500| | ||
|`CHUNK_FILL_COST` |6200| | ||
|`CHUNK_EDIT_COST` |500| | ||
|`CHUNK_FILL_COST` |6200| | ||
|
||
When executing a transaction, maintain four sets: | ||
|
||
|
@@ -251,6 +236,13 @@ When a **write** event of `(address, sub_key, leaf_key)` occurs, perform the fol | |
|
||
Note that tree keys can no longer be emptied: only the values `0...2**256-1` can be written to a tree key, and 0 is distinct from `None`. Once a tree key is changed from `None` to not-`None`, it can never go back to `None`. | ||
|
||
Note that values should only be added to the witness if there is sufficient gas to cover their associated event costs. | ||
gballet marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
`CREATE*` and `*CALL` reserve 1/64th of the gas before the nested execution. In order to match the behavior of this charge with the pre-fork behavior of access lists: | ||
|
||
* this minimum 1/64th gas reservation is checked **AFTER** charging the witness costs when performing a `CALL`, `CODECALL`, `DELEGATECALL` or`STATICCALL` | ||
* this 1/64th of the gas is subtracted **BEFORE** charging the witness costs when performing a `CREATE` or `CREATE2` | ||
|
||
### Replacement for access lists | ||
|
||
We replace [EIP-2930](./eip-2930.md) access lists with an SSZ structure of the form: | ||
|
@@ -268,6 +260,22 @@ class AccessSubtree(Container): | |
elements: BitVector[256] | ||
``` | ||
|
||
### Block-level operations | ||
|
||
None of: | ||
|
||
* Precompile accounts, system contract accounts and slots of a system contract that are accessed during a system call, | ||
* The coinbase account | ||
* Withdrawal accounts | ||
|
||
are warm at the start of a transaction. | ||
|
||
Note: When (and only when) calling a system contract _via a system call_, the code chunks and account should not appear in the witness. | ||
|
||
### Account abstraction | ||
|
||
TODO : still waiting on a final decision between 7702 and 3074 | ||
|
||
## Rationale | ||
|
||
### Gas reform | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this is covered below?
https://github.com/ethereum/EIPs/pull/8550/files#diff-cd2aaa222faeb6081a41605386a509b3c4839285cd15f1b0ebe009318707914eR126