-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Gas Cost for Cached Reads #5154
Comments
This is a particularly pertinent issue given #5006 since each decorator must read and write potentially the same value from the context, whereas with a single AnteHandler function there could be a single read, multiple updates, and then a final write which will consume much less gas. I think we should accept this proposal since it would greatly reduce gas cost of #5006, and generally improve how closely out gas costs align with the actual computation/IO cost. It also has a relatively simple (albeit breaking) implementation: func (gs *Store) Get(key []byte) (value []byte) {
value, cached = gs.parent.Get(key)
if !cached {
gs.gasMeter.ConsumeGas(gs.gasConfig.ReadCostFlat, types.GasReadCostFlatDesc)
// TODO overflow-safe math?
gs.gasMeter.ConsumeGas(gs.gasConfig.ReadCostPerByte*types.Gas(len(value)), types.GasReadPerByteDesc)
}
return value
} Pros:
Cons:
|
Good point on (2) but this is no different really from the current implementation. Since these are not on-chain params, they're more-or-less hard-coded per app. Would like to get other's opinions on if we should charge gas for cached reads. (1) is pretty simple. |
I think gas should absolutely be charged for cached reads. I think it makes sense to maintain a canonical "expected cache", which assumes some amount of caching. e.g. Reading the same variable twice in a row should be much cheaper given any reasonable cache policy. This is reminiscent to how you write optimized code expecting cachelines, and how ETH charges gas based on "commodity laptop". This likely doesn't matter much for gaia, but becomes very important when creating a smart contracting language. |
Ok, questions I have are (1) what do we charge for cached-reads (% of non-cached cost) and (2) how to do this cleanly (e.g. |
I feel charging differently for cached-hits vs not would make gas-estimation pretty difficult because you won't know whats in the cache when the tx actually runs. |
This feels untrue for param store entries which usually can be assumed to be cached under high load. Though you make a good point that this is pointless without improved gas estimation, since unlike Ethereum we have to fill blocks based on the estimate. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Ethereum is handling this at the level of a single tx, by raising the gas of each location queried in state for the first time: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2929.md Maybe this is the approach that ought to be taken to achieve this here? (Espec. since we now have multiple VMs nearing completion) Cache arguments across txs get more complex once one considers optimizations for parallelizing their execution. |
Summary
Through the
GasMeter
charges gas costs per read regardless if that read hits the cache or not of the subseqentKVStore
.Problem Definition
It would be ideal and more economical to either not charge at all for cache hits or have parameterized costs for cache hits (i.e. charge much less).
Proposal
To not charge at all would be to simply update the
KVStore
interface to haveGet
return([]byte, ok)
where the boolean signifies if there is a cache hit or not. This is just an idea as we can instead only alter theCacheKVStore
interface.If we want to charge based on parameterization, this will be slightly more difficult but perhaps one solution could be to have
Stores
return their own respective gas params viaGetGasCosts() GasParams
./cc @AdityaSripal
For Admin Use
The text was updated successfully, but these errors were encountered: