Skip to content
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

Improve readability of Gas docs and add section on overflow potential #1222

Merged
merged 3 commits into from
Feb 21, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion docs/GAS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ including CPU time and storage cost. It's unit is 1, i.e. you can think of it as
countable points. Gas consumption is deterministic, so executing the same thing
costs the same amount of gas across all hardware and operating systems.

## CosmWasm gas vs. Cosmos SDK gas

CosmWasm charges gas for Wasm operations, calls to host functions and calls to
the Cosmos SDK. CosmWasm gas is different from Cosmos SDK gas as the numbers
the Cosmos SDK. _CosmWasm gas_ is different from _Cosmos SDK gas_ as the numbers
here are much larger. Since we charge gas for arbitrary user defined operations,
we need to charge each Wasm operation individually and cannot group larger tasks
together. As a result, the gas values become much larger than in Cosmos SDK even
for very fast executions. There is a [multiplier][defaultgasmultiplier] to
translate between CosmWasm gas and Cosmos SDK. It was measured and set to 100 a
while ago and can be adjusted when necessary.

## CosmWasm gas pricing

For CosmWasm gas, the target gas consumption is 1 Teragas (10^12 gas) per
millisecond. This idea is [inspired by NEAR][neargas] and we encourage you to
read their excellent docs on that topic.
Expand All @@ -38,3 +42,26 @@ multiple ways:
https://github.com/CosmWasm/wasmd/blob/v0.19.0/x/wasm/keeper/gas_register.go#L18
[neargas]: https://docs.near.org/docs/concepts/gas
[#1120]: https://github.com/CosmWasm/cosmwasm/pull/1120

## Gas overflow potential

CosmWasm gas aims for 1 Teragas/millisecond, i.e. the uint64 range exceeds after
18 million seconds (5 hours)<sup>1</sup>. Assuming a max supported block
execution time of 30 seconds, the gas price has to be over-priced by a factor of
614 (614 Teragas/millisecond) in order to exceed the uint64 range<sup>2</sup>.
Since serious over or underpricing is considered a bug, using uint64 for gas
measurements is considered safe.

Cosmos SDK gas uses values that are smaller by a factor of 150_000, so those
don't overflow as well. Since no Cosmos SDK gas values are processed inside of
this repository, this is not our main concern. However, it's good to know that
we can safely pass them in uint64 fields, as long as the full range is
supported. This is the case for the C API as well as
[JSON numbers](https://www.json.org/) as long as both sides support integers in
their JSON implementation. Go and Rust do that while many other implementations
don't support integers, and convert them to IEEE-754 doubles, which has a safe
integer range up to about 53 bit (e.g. JavaScript and jq).

<sup>1</sup> Python3: `(2**64-1)/1000 / 10**12`

<sup>2</sup> Python3: `((2**64-1)/1000/30) / 10**122`