mirror of
https://github.com/status-im/EIPs.git
synced 2025-01-27 23:26:03 +00:00
Automatically merged updates to draft EIP(s) 1283
Hi, I'm a bot! This change was automatically merged because: - It only modifies existing Draft or Last Call EIP(s) - The PR was approved or written by at least one author of each modified EIP - The build is passing
This commit is contained in:
parent
6ecbcaa6e9
commit
2933084869
101
EIPS/eip-1283.md
101
EIPS/eip-1283.md
@ -40,19 +40,15 @@ implementations:
|
||||
* *Storage slot's current value*.
|
||||
* Refund counter.
|
||||
|
||||
We provided two possible specification versions here. Version II is
|
||||
recommended for Constantinople.
|
||||
For the specification provided here:
|
||||
|
||||
* For both of the two versions, we don't suffer from the optimization
|
||||
limitation of EIP-1087, and it never costs more gas compared with
|
||||
current scheme.
|
||||
* For Version I, it covers most common usages, and we have two edge
|
||||
cases it do not cover, one of which may potentially be useful.
|
||||
* For Version II, it covers nearly all usages for a transient
|
||||
storage. Clients that are easy to implement EIP-1087 will also be
|
||||
easy to implement Version II. Some other clients might require a
|
||||
little bit extra refactoring on this. Nonetheless, no extra memory
|
||||
or processing cost is needed on runtime.
|
||||
* We don't suffer from the optimization limitation of EIP-1087, and it
|
||||
never costs more gas compared with current scheme.
|
||||
* It covers all usages for a transient storage. Clients that are easy
|
||||
to implement EIP-1087 will also be easy to implement this
|
||||
specification. Some other clients might require a little bit extra
|
||||
refactoring on this. Nonetheless, no extra memory or processing cost
|
||||
is needed on runtime.
|
||||
|
||||
Usages that benefits from this EIP's gas reduction scheme includes:
|
||||
|
||||
@ -66,13 +62,12 @@ Usages that benefits from this EIP's gas reduction scheme includes:
|
||||
frame, where this information does not need to be persistent outside
|
||||
of a transaction. This is covered by Version II but not Version I.
|
||||
|
||||
## Specification (Version I)
|
||||
## Specification
|
||||
|
||||
Definitions of terms are as below:
|
||||
|
||||
* *Storage slot's original value*: This is the value of the storage if
|
||||
a call/create reversion happens on the *current VM execution
|
||||
context*.
|
||||
a reversion happens on the *current transaction*.
|
||||
* *Storage slot's current value*: This is the value of the storage
|
||||
before SSTORE operation happens.
|
||||
* *Storage slot's new value*: This is the value of the storage after
|
||||
@ -106,15 +101,6 @@ the following logic:
|
||||
Refund counter works as before -- it is limited to half of the gas
|
||||
consumed.
|
||||
|
||||
## Specification (Version II)
|
||||
|
||||
This is the recommended version for Constantinople. Everything else
|
||||
is the same as Version I, except we change the definition of *original
|
||||
value* to:
|
||||
|
||||
* *Storage slot's original value*: This is the value of the storage if
|
||||
a reversion happens on the *current transaction*.
|
||||
|
||||
## Explanation
|
||||
|
||||
The new gas cost scheme for SSTORE is divided to three different
|
||||
@ -123,14 +109,11 @@ types:
|
||||
* **No-op**: the virtual machine does not need to do anything. This is
|
||||
the case if *current value* equals *new value*.
|
||||
* **Fresh**: this storage slot has not been changed, or has been reset
|
||||
to its original value either on current frame, or on a sub-call
|
||||
frame for the same contract. This is the case if *current value*
|
||||
does not equal *new value*, and *original value* equals *current
|
||||
value*.
|
||||
* **Dirty**: this storage slot has already been changed, either on
|
||||
current frame or on a sub-call frame for the same contract. This is
|
||||
the case if *current value* does not equal *new value*, and
|
||||
*original value* does not equal *current value*.
|
||||
to its original value. This is the case if *current value* does not
|
||||
equal *new value*, and *original value* equals *current value*.
|
||||
* **Dirty**: this storage slot has already been changed. This is the
|
||||
case if *current value* does not equal *new value*, and *original
|
||||
value* does not equal *current value*.
|
||||
|
||||
We can see that the above three types cover all possible variations of
|
||||
*original value*, *current value*, and *new value*.
|
||||
@ -140,24 +123,10 @@ We can see that the above three types cover all possible variations of
|
||||
|
||||
All initial (not-**No-op**) SSTORE on a particular storage slot starts
|
||||
with **Fresh**. After that, it will become **Dirty** if the value has
|
||||
been changed (either on current call frame or a sub-call frame for the
|
||||
same contract). When going from **Fresh** to **Dirty**, we charge the
|
||||
gas cost the same as current scheme.
|
||||
|
||||
For Version I, when entering a sub-call frame, a previously-marked
|
||||
**Dirty** storage slot will again become **Fresh**, but only for this
|
||||
sub-call frame. Note that we don't charge any more gas compared with
|
||||
current scheme in this case.
|
||||
|
||||
In current call frame, a **Dirty** storage slot can be reset back to
|
||||
**Fresh** via a SSTORE opcode either on current call frame or a
|
||||
sub-call frame. For current call frame, this dirtiness is tracked, so
|
||||
we can issue refunds. For Version I's sub-call frame, it is not
|
||||
possible to track this dirtiness reset, so the refunds (for *current
|
||||
call frame*'s initial SSTORE from **Fresh** to **Dirty**) are not
|
||||
issued. For Version II's sub-call frame, This refund is tracked and
|
||||
properly issued. In the case where refunds are not issued, the gas
|
||||
cost is the same as the current scheme.
|
||||
been changed. When going from **Fresh** to **Dirty**, we charge the
|
||||
gas cost the same as current scheme. A **Dirty** storage slot can be
|
||||
reset back to **Fresh** via a SSTORE opcode. This will trigger a
|
||||
refund.
|
||||
|
||||
When a storage slot remains at **Dirty**, we charge 200 gas. In this
|
||||
case, we would also need to keep track of `R_SCLEAR` refunds -- if we
|
||||
@ -166,15 +135,13 @@ already issued the refund but it no longer applies (*current value* is
|
||||
issue the refund but it applies now (*new value* is 0), then adds this
|
||||
refund to the refund counter. It is not possible where a refund is not
|
||||
issued but we remove the refund in the above case, because all storage
|
||||
slot starts with **Fresh** state, either on current call frame or a
|
||||
sub-call frame.
|
||||
slot starts with **Fresh** state.
|
||||
|
||||
### State Transition
|
||||
|
||||
Below is a graph ([by
|
||||
@Arachnid](https://github.com/ethereum/EIPs/pull/1283#issuecomment-410229053))
|
||||
showing possible state transition of gas costs. Note that for Version
|
||||
I, this applies to current call frame only, and we ignore **No-op**
|
||||
showing possible state transition of gas costs. We ignore **No-op**
|
||||
state because that is trivial:
|
||||
|
||||
![State Transition](../assets/eip-1283/state.png)
|
||||
@ -202,16 +169,13 @@ When *original value* is not 0:
|
||||
|
||||
This EIP mostly archives what a transient storage tries to do
|
||||
(EIP-1087 and EIP-1153), but without the complexity of introducing the
|
||||
concept of "dirty maps", or an extra storage struct. One limitation is
|
||||
that for some edge cases dirtiness will not be tracked:
|
||||
concept of "dirty maps", or an extra storage struct.
|
||||
|
||||
* For Version I, the first SSTORE for a storage slot on a sub-call
|
||||
frame for the same contract won't benefit from gas reduction. For
|
||||
Version II, this type of gas reduction is properly tracked and
|
||||
applied.
|
||||
* If a storage slot is changed, and it's reset to its original value,
|
||||
the next SSTORE will effectively move gas to refund counter. This
|
||||
case still benefits from this EIP's gas reduction.
|
||||
* For *absolute gas used* (that is, actual *gas used* minus *refund*),
|
||||
this EIP is equivalent to EIP-1087 for all cases.
|
||||
* For one particular case, where a storage slot is changed, reset to
|
||||
its original value, and then changed again, EIP-1283 would move more
|
||||
gases to refund counter compared with EIP-1087.
|
||||
|
||||
Examine examples provided in EIP-1087's Motivation:
|
||||
|
||||
@ -221,13 +185,7 @@ Examine examples provided in EIP-1087's Motivation:
|
||||
charged `20000 + 5 * 200 = 21000` gas.
|
||||
* A balance transfer from account A to account B followed by a
|
||||
transfer from B to C, with all accounts having nonzero starting and
|
||||
ending balances
|
||||
* If the token contract has multi-send function, it will cost
|
||||
`5000 * 3 + 200 - 4800 = 10400` gas.
|
||||
* For Version I, if this transfer from A to B to C is invoked by a
|
||||
third-party contract, and the token contract has no multi-send
|
||||
function, then it won't benefit from this EIP's gas reduction. For
|
||||
Version II, this gas reduction is properly tracked and applied.
|
||||
ending balances, it will cost `5000 * 3 + 200 - 4800 = 10400` gas.
|
||||
|
||||
## Backwards Compatibility
|
||||
|
||||
@ -240,8 +198,7 @@ To be added.
|
||||
|
||||
## Implementation
|
||||
|
||||
* Parity Ethereum: [Version I
|
||||
PR](https://github.com/paritytech/parity-ethereum/pull/9319).
|
||||
To be added.
|
||||
|
||||
## Copyright
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user