-
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
EIP-1283: Net gas metering for SSTORE without dirty maps #1283
Merged
Merged
Changes from 6 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
6e0338f
Net gas metering for SSTORE without dirty maps
sorpaas f3ee50c
typo: opcode
sorpaas 5f05bc1
Merge branch 'master' of https://github.com/ethereum/EIPs into sp-sst…
sorpaas 8d21d6b
typo: changed
sorpaas 40c9c4e
Self-assign the PR number 1283
sorpaas 6a9400e
Add a dummy discussion url
sorpaas 7074767
Fix R_sclear loopholes
sorpaas 0fca9b3
Properly handle refund for 0 value issue
sorpaas f859a90
fix: refund should only be added again if new value is 0
sorpaas 6195cd6
clarify if statement
sorpaas 9b5ece7
Clearly state what () means
sorpaas 2d972d1
typo fix: unnecessary wording "additional"
sorpaas 8f9bb86
fix: should have parent clause if original value is not zero
sorpaas 23ebc94
Remove 15k gas from refund counter instead of deduct it as gas cost
sorpaas 30daaa0
Be more clear on EIP-658 enabled only-commit-storage-changes-at-end-o…
sorpaas 598d42e
Move some discussion comments to motivations section
sorpaas b8f9659
typo: commons -> common
sorpaas ba8a613
Be more specific when gas reduction won't happen compared with EIP-1087
sorpaas f0e1590
typo: duplicate description
sorpaas 39505aa
Add explanation section
sorpaas 49b5f22
becomes -> become
sorpaas 0710ff6
typo: covers -> cover
sorpaas ddfe7ca
Add state transition diagrams
sorpaas df15cbd
Fix table formatting
sorpaas ee38de0
typo: 0 -> `current`
sorpaas 8dd32c9
typo: missing -
sorpaas e5f00a1
Change state transition table to use `(current, original)` vs `new`
sorpaas 7a18e1b
fix: vertical <-> horizontal
sorpaas d863e66
Be more specific on usages benefited by this EIP
sorpaas 2daf07f
Merge branch 'master' into sp-sstore-no-dirty-map
Arachnid 3125d0e
Typo fix
sorpaas a9171ac
Merge branch 'sp-sstore-no-dirty-map' of github.com:sorpaas/eips into…
sorpaas File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
--- | ||
eip: 1283 | ||
title: Net gas metering for SSTORE without dirty maps | ||
author: Wei Tang (@sorpaas) | ||
discussions-to: https://github.com/sorpaas/EIPs/issues/1 | ||
status: Draft | ||
type: Standards Track | ||
category: Core | ||
created: 2018-08-01 | ||
--- | ||
|
||
## Abstract | ||
|
||
This EIP proposes net gas metering changes for SSTORE opcode, as an | ||
alternative for EIP-1087. It tries to be friendlier to implementations | ||
that uses different opetimiazation strategies for storage change | ||
caches. | ||
|
||
## Motivation | ||
|
||
EIP-1087 proposes a way to adjust gas metering for SSTORE opcode, | ||
enabling new usages on this opcodes where it is previously too | ||
expensive. However, EIP-1087 requires keeping a dirty map for storage | ||
changes, and implictly makes the assumption that a transaction's | ||
storage changes are committed to the storage trie at the end of a | ||
transaction. This works well for some implementations, but not for | ||
others. Some implementations do the optimization to only commit | ||
storage changes at the end of a block. For them, it is possible to | ||
know a storage's original value and current value, but it is not | ||
possible to iterate over all storage changes. For EIP-1087, they will | ||
need to keep a separate dirty map to keep track of gas costs. This | ||
adds additional memory consumptions. | ||
|
||
This EIP proposes an alternative way for gas metering on SSTORE, using | ||
information that is more universially available to most | ||
implementations: | ||
|
||
* *Storage slot's original value*. This is the value of the storage if | ||
a call/create reversion happens on the current VM execution | ||
context. It is universially available because all clients need to | ||
keep track of call/create reversion. | ||
* *Storage slot's current value*. | ||
* Refund counter. | ||
|
||
## Specification | ||
|
||
Term *original value* is as defined in Motivation. *Current value* | ||
refers to the storage slot value before SSTORE happens. *New value* | ||
refers to the storage slot value after SSTORE happens. | ||
|
||
Replace SSTORE opcode gas cost calculation (including refunds) with | ||
the following logic: | ||
|
||
* If *current value* equals *new value* (this is a no-op), 200 gas is | ||
deducted. | ||
* If *current value* does not equal *new value* | ||
* If *original value* equals *current value* (this storage slot has | ||
not been changed by the current execution context) | ||
* If *original value* is 0, 20000 gas is deducted. | ||
* Otherwise, 5000 gas is deducted. If *new value* is 0, add 15000 | ||
gas to refund counter. | ||
* If *original value* does not equal *current value* (this storage | ||
slot is dirty), 200 gas is deducted. | ||
* If *original value* equals *new value* | ||
* If *original value* is 0, add 19800 gas to refund counter. | ||
* Otherwise, add 4800 gas to refund counter. | ||
|
||
Refund counter works as before -- it is limited to half of the gas | ||
consumed. | ||
|
||
## Rationale | ||
|
||
This EIP mostly archives what EIP-1087 tries to do, but without the | ||
complexity of introducing the concept of "dirty maps". One limitation | ||
is that the dirtiness tracking only applies to current execution | ||
context -- if a sub-frame executes on the same address as the | ||
parent-frame, it won't benefit from the parent dirtiness gas refund. | ||
|
||
Examine examples provided in EIP-1087's Motivation: | ||
|
||
* If a contract with empty storage sets slot 0 to 1, then back to 0, | ||
it will be charged `20000 + 200 - 19800 = 400` gas. | ||
* A contract with empty storage that increments slot 0 5 times will be | ||
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. | ||
* 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. | ||
|
||
## Backwards Compatibility | ||
|
||
This EIP requires a hard fork to implement. No gas cost increase is | ||
anticipated, and many contract will see gas reduction. | ||
|
||
## Test Cases | ||
|
||
To be added. | ||
|
||
## Implementation | ||
|
||
To be added. | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Following this process, starting with original = 1 and current = 1:
Thus for every 5k gas deducted from the gas meter, we can add 19800 gas to the refund counter.
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.
Fixed! Added an additional clause when storage slot is dirty. If original value is not 0, if current value is 0 (also means that new value is not 0, because of the parent clause "If current value does not equal new value"), deduct 15000 gas.
new = 0, original = 1, current = 1
; deducts 5k gas and adds 15k gas to refund counter.new = 1, original = 1, current = 0
; deducts200 + 15k
gas, adds 4800 gas to the refund counter.original = 1, current = 1
; goto 1; for every round200 + 20k
gas is deducted, and19800
gas in the refund counter.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.
This seems reasonable. A couple of critiques:
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.
Thanks! I think (1) is a really good point. If there're cases where it can cost a lot most gases compared with the current scheme, then we may break backward compatibility for existing contracts. So in 23ebc94 I changed the clause from deducting 15k gas to removing 15k gas from refund counter. In this way, we will never consume more gases compared with current scheme. Indeed, this adds a new semantics for gas refunds (we never removed gas from refund counter before), so I'm definitely open to better ideas on this. The current rationale/assumption for this is:
Talking about other cases where it may cost more gases compared with EIP-1087 -- it happens with sub-call frames to the same contract where we cannot track the dirtiness. But I still think it may be worth the trade off because:
Still working on (2). Let me try to see whether there are clearer ways to describe the spec.
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.
Added an explanation section to make the logic more clearer!