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 #1

Open
sorpaas opened this Issue Aug 1, 2018 · 9 comments

Comments

Projects
None yet
4 participants
@sorpaas
Copy link
Owner

sorpaas commented Aug 1, 2018

eip: 1283
title: Net gas metering for SSTORE without dirty maps
author: Wei Tang (@sorpaas)
status: Draft
type: Standards Track
category: Core
created: 2018-08-01

Abstract: This EIP proposes net gas metering changes for SSTORE opcode. Rendered

Note on Undefined Behavior

In this specification, we assert that contract creations are always on empty account with empty storage. This is true for Ethereum and all Ethereum-based networks. As a result, contract creations on empty account with non-empty storage is considered undefined behavior.

@veox

This comment has been minimized.

Copy link

veox commented Aug 9, 2018

A small style note: gas in this case is an uncountable noun, if used in a "vehicle fuel" metaphor.

I.e.,

s/gases/gas/g

@sorpaas

This comment has been minimized.

Copy link
Owner Author

sorpaas commented Aug 10, 2018

Thanks. Fixed!

@fulldecent

This comment has been minimized.

Copy link

fulldecent commented Oct 16, 2018

Here is my complete review on the current proposal draft.

Complicated

The state diagram and explanation are too complicated. This table may or may not help:

A is any non-zero value and B is any-zero value that is not equal to A.

Original value Current value New value Outcome
ANY ANY = current value Deduct 200 gas
0 0 A Deduct 20,000 gas
0 A 0 Deduct 200 gas, add 19,800 to refund
0 A B Deduct 200 gas
A 0 A or B Deduct 200 gas, remove 15,000 from refund
A A 0 Deduct 5,000 gas, add 15,000 to refund
A A B Deduct 5,000 gas
A B 0 Deduct 200 gas, add 15,000 to refund
A B A Deduct 200 gas, add 4,800 to refund

Review alternatives considered

There are several obvious alternatives to consider:

  • Increase cost of SLOAD because now it must check the local cache AND the storage state.
  • Choose a different value than 200.
  • Charge 200 for all SSTORE and then charge and refund more gas at the end of a transaction based on whether the writes are necessary.

Please explain the level of review that was performed to evaluate the fitness of the proposed solution versus these options and other considered options.

Review economics

The value 200 is a new constant. Please explain this choice.

The price to store a word and then erase it from storage is a fixed 400 gas including refunds. At some point this will be cheaper than the memory expansion function, which is variable priced based on the amount of memory used. This means optimizers will do well to instantiate dummy storage variables as overflow memory registers. Before we encourage this perverse behavior, I would like to see this proposal provide an analysis of the break even point where this optimization saves gas.

@sorpaas

This comment has been minimized.

Copy link
Owner Author

sorpaas commented Oct 16, 2018

Hi @fulldecent, thanks for the review!

Regarding the state diagram, I would encourage you to look deeper into the state diagram provided by Nick Johnson in the explanation section. By separating what the original value of the storage is, we can make everything look much clearer.

Regarding "review alternatives considered":

Increase cost of SLOAD because now it must check the local cache AND the storage state.

Check local cache and the storage state is the current behavior. The reason is that checking storage state is much more expensive compared with checking cache. That's why we have cache in the first place!

Choose a different value than 200.

The reason we have 200 is because it aligns with SLOAD gas cost. That fits current assumption of how much gas a storage cache read/write would take.

Charge 200 for all SSTORE and then charge and refund more gas at the end of a transaction based on whether the writes are necessary.

That's EIP-1087, if you want to take a look. You can also see EIP-1283's motivation section for more explanation of why it doesn't work for some clients.

Regarding "review economics":

At some point this will be cheaper than the memory expansion function, which is variable priced based on the amount of memory used.

This "economics" is present right now on mainnet, and either EIP-1283 or EIP-1087 does not affect it. An initial SSTORE operation which creates a new cache slot on execution would cost just as much as it currently does. So I think this discussion would fit more on topics of "storage rent", but not probably not here.

@fulldecent

This comment has been minimized.

Copy link

fulldecent commented Oct 16, 2018

Isn't the local cache is currently an implementation detail? This proposal creates a read/write storage layer. So I believe this is additive.


Regarding 1087, any notes leading to the decisions in this EIP should be discussed here so that this document can stand on its own.


I am not concerned with creating new cache slots. I am concerned with a contract that initializes with 60016fff55 60016ffe55 ... and then uses (and resets) these storage locations as an alternative to using memory. Presently this approach would cost 5000 per word stored. But this proposal reduces that to 200 per access plus 200 to reset. So I'd like to understand the breakeven.


New issue. Was there a consideration to make STATICCALL compatible with storage where a word is set and then reset before the transaction finishes? This might be valuable to people doing formal verification where they use *CALL more than the average bear.

ping @jacqueswww

@sorpaas

This comment has been minimized.

Copy link
Owner Author

sorpaas commented Oct 16, 2018

Isn't the local cache is currently an implementation detail?

Many things in EVM can be argued to be implementation detail. That's true. The goal for having gas cost is to make it matches the most common implementation structure's actual cost.

This proposal creates a read/write storage layer. So I believe this is additive.

We have some explanations in the Motivation section that we don't introduce any unnecessary new concepts compared with what all current client implementations have. The only thing added is to make refund counter able to be reduced. All other structures discussed are needed to be kept by clients anyway due to reasons like transaction reverts, etc.

Regarding 1087, any notes leading to the decisions in this EIP should be discussed here so that this document can stand on its own.

Yeah sure. Right now most of the explanations of this are in EIP-1283's motivation section, if you want to take a look. I would also appreciate help fetching relevant link to this discussion issue.

Presently this approach would cost 5000 per word stored. But this proposal reduces that to 200 per access plus 200 to reset.

Memory cost is only calculated when the memory is expanded, meaning only the first time when MSTORE is called on an upper address. For SSTORE, we charge the same gas as present the first time when an address is allocated, and this is the only time when we need to allocate cache for the storage item. If someone wants to maximize the memory allocated, he or she would want to touch upper address only once -- because subsequent touches of those address would have no memory expansion cost, but individual cost would be more for SSTORE compared with MSTORE. For this case, using either MSTORE or SSTORE would make no difference before or after this EIP, because (whenever storage cache item allocation is needed) we charge the same gas when SSTORE first touches an address.

Was there a consideration to make STATICCALL compatible with storage where a word is set and then reset before the transaction finishes?

That would change the semantic of STATICCALL and I would think it's too much for this EIP. I don't have opinion whether that would be a useful feature, but if it indeed does, we probably would want to use another EIP to track that.

@fulldecent

This comment has been minimized.

Copy link

fulldecent commented Oct 18, 2018

I don't disagree with your points, but I believe that at least some of this analysis belongs in the EIP proper.

Regarding memory cost. The current cost of memory at large quantities is quadratic.

screen shot 2018-10-17 at 10 21 00 pm

But the proposed SSTORE cost is linear and much lower than before.

Abusing SSTORE (with pre-paid dirty blocks) allows SSTORE to work effectively like memory. SSTORE usage is linear. Therefore this EIP reduces some large memory store costs from quadratic to linear.

I do not know if this leads to any practical problems. However this topic should be studied to its logical conclusion and presented inside the EIP.

@sorpaas

This comment has been minimized.

Copy link
Owner Author

sorpaas commented Oct 18, 2018

With this EIP, whenever we're allocating memory for storage cache, the cost is always the same as current. Yes, indeed later we can add more gas to refund counter compared with current, but that doesn't present attack vector -- you cannot use gas from refund counter in the current transaction.

I think if we want to provide any analysis, it's basically this: Given a block gas limit, it is not possible to allocate more memory using SSTORE comparing EIP-1283 and current scheme. It is, however, possible to have (potentially a lot of) transaction fee reduction comparing EIP-1283 and current scheme.

sorpaas pushed a commit that referenced this issue Jan 15, 2019

Address and ERC20-compliant transfer rules (#2)
* Proposed EIP for address and ERC20 transfer rules

* Update eip-X.md

Updating creation date

* Update eip-X.md (#1)

* Update eip-X.md

* Update eip-X.md

* Update eip-X.md

Rule -> IRule consistently
fix missing links
improve abstract

* Update eip-X.md

typos
small improvements
adds implementation section
@alex-forshtat-tbk

This comment has been minimized.

Copy link

alex-forshtat-tbk commented Jan 16, 2019

I've created a pull request to modify the proposal with regard to reentrancy issue, but I think this is a correct place for a discussion.

Here is a link:
ethereum#1706

In short, I propose to revert any attempt to perform SSTORE if gasleft <= 2300, which makes an assumption that 'gas stipend' is not enough to modify storage more explicit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment