Skip to content

Commit dc45656

Browse files
committed
Refactored Gas chapter.
1 parent a1759b6 commit dc45656

File tree

1 file changed

+64
-43
lines changed
  • pages/guide/cosmwasm-core/architecture

1 file changed

+64
-43
lines changed
Lines changed: 64 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,108 @@
11
[#1599]: https://github.com/CosmWasm/cosmwasm/pull/1599
22
[JSON numbers]: https://www.json.org/
33
[default-gas-multiplier]: https://github.com/CosmWasm/wasmd/blob/04cb6e5408cc54c27247b0b327dfa99769d5103c/x/wasm/types/gas_register.go#L34
4-
[near-gas]: https://docs.near.org/concepts/protocol/gas
4+
[inspired by NEAR]: https://docs.near.org/concepts/protocol/gas
55
[#1120]: https://github.com/CosmWasm/cosmwasm/pull/1120
66

77
# Gas
88

99
Gas is a way to measure computational expense of a smart contract execution, including CPU time and
10-
storage cost. Its unit is 1, i.e. you can think of it as countable points. Gas consumption is
11-
deterministic, so executing the same thing costs the same amount of gas across all hardware and
10+
storage cost. Gas unit is 1, i.e. you can think of it as countable points. Gas consumption is
11+
deterministic, so executing the same code costs the same amount of gas across all hardware and
1212
operating systems.
1313

14-
## CosmWasm gas vs. Cosmos SDK gas
14+
## CosmWasm gas versus Cosmos SDK gas
1515

16-
CosmWasm charges gas for Wasm operations, calls to host functions and calls to the Cosmos SDK.
17-
_**CosmWasm gas**_ is different from _**Cosmos SDK gas**_ as the numbers here are much larger.
16+
CosmWasm charges gas for:
17+
- Wasm operations,
18+
- calls to host functions,
19+
- calls to the Cosmos SDK.
20+
21+
_**CosmWasm gas**_ is different from _**Cosmos SDK gas**_ as the numbers in CosmWasm are much larger.
1822
Since we charge gas for arbitrary user defined operations, we need to charge each Wasm operation
1923
individually and cannot group larger tasks together. As a result, the gas values become much larger
2024
than in Cosmos SDK even for very fast executions. There is a [multiplier][default-gas-multiplier]
21-
to translate between _**CosmWasm gas**_ and _**Cosmos SDK**_ gas.
22-
It was measured and set to 100 a while ago and can be adjusted when necessary.
25+
to translate between _**Cosmos SDK gas**_ and _**CosmWasm gas**_.
26+
It was measured and set to `140 000` a while ago and can be adjusted when necessary.
2327

2428
## CosmWasm gas pricing
2529

26-
For CosmWasm gas, the target gas consumption is 1 Teragas ($10^{12}$ gas) per second. This idea is
27-
[inspired by NEAR][near-gas] and we encourage you to read their excellent docs on that topic.
30+
For CosmWasm gas, the target gas consumption is **1 Teragas per second** (Tera = $10^{12}$).
31+
This idea is [inspired by NEAR]; see their excellent documentation for more details. Summarizing:
32+
33+
$$ 1\ Teragas = (shortly)\ 1\ Tgas = 10^{12}\ gas $$
2834

2935
In order to meet this target, we execute Argon2 in a test contract ([#1120]). This is a CPU and
3036
memory intense job that does not call out into the host. At a constant gas cost per operation of 1
31-
(pre CosmWasm 1.0), this consumed 96837752 gas and took 15ms on our CI system. The ideal cost per
32-
operation for this system is `10^12 / (96837752 / (15 / 1000))`: 154. This is rounded to 150 for
33-
simplicity.
37+
(before CosmWasm 1.0), this consumed **96837752** gas and took 15 ms on our CI system.
38+
The ideal cost per Wasm operation for this system is:
39+
40+
$$ {10^{12} : {96837752 \over {15 \times 10^{-3}}}} = 154 $$
41+
42+
This is rounded to $\lfloor 154 \rfloor = \mathbf{150}$ for simplicity.
43+
44+
**CosmWasm 2.1 update**
3445

35-
CosmWasm 2.1 update: All gas values were re-evaluated and adjusted to meet the 1 Teragas/second
36-
target mentioned above. A rerun of the Argon2 test contract consumed 5270718300 gas with the
37-
previous cost of 150, so the operation count was `5270718300 / 150 = 35138122`. This took 6ms on our
38-
benchmark server, so the new cost per operation is `10^12 / (35138122 / (6 / 1000))`: 171. This is
39-
rounded to 170 for simplicity.
46+
All gas values were re-evaluated and adjusted to meet the **1 Teragas per second** target mentioned above.
47+
A rerun of the Argon2 test contract consumed **5270718300** gas with the
48+
previous cost of 150, so the operation count was:
49+
50+
$$ {5270718300 \over 150} = 35138122 $$
51+
52+
This took 6 ms on our benchmark server, so the new cost per operation is:
53+
54+
$$ {10^{12} : {35138122 \over {6 \times 10^{-3}}}} = 171 $$
4055

41-
Benchmarking system:
56+
This is rounded to $\lfloor 171 \rfloor = \mathbf{170}$ for simplicity.
57+
58+
**Benchmarking system**
4259

4360
- CPU: Intel(R) Core(TM) i7-6700 CPU @ 3.40GHz (4 cores, 8 threads)
4461
- RAM: 32GB DDR4 2133 MHz
4562

46-
Each machine is different, we know that. But the above target helps us in multiple ways:
63+
Each machine is different, this is obvious. But the above model helps us in multiple ways:
4764

48-
1. Develop an intuition what it means to burn X gas or how much gas can be used if a block should be
49-
executable in e.g. 1 second.
50-
2. Have a target for adjustments, e.g. when the Wasm runtime becomes faster or slower.
51-
3. Allow pricing of calls that are not executed in Wasm, such as crypto APIs.
52-
4. Find significant over- or underpricing.
65+
- develop an intuition what it means to burn N units of gas or how much gas can be used if a block
66+
should be executable in 1 second,
67+
- have a target for adjustments when the Wasm runtime becomes faster or slower,
68+
- allow pricing of calls that are not executed in Wasm, such as crypto APIs or Cosmos APIs,
69+
- find significant over- or underpricing.
5370

5471
## Gas overflow potential
5572

56-
CosmWasm gas aims for Teragas/second, i.e. the 64-bit unsigned integer range exceeds
57-
after 18 million seconds (≈5000 hours)<sup>1)</sup>. Assuming a maximal supported block execution
58-
time of 30 seconds, the gas price has to be over-priced by a factor of 614891 (614891 Teragas/second)
59-
in order to exceed the 64-bit unsigned integer range<sup>2)</sup>. Since serious over- or underpricing
60-
is considered a bug, using 64-bit unsigned integer for gas measurements is **considered safe**.
73+
CosmWasm gas aims for **1 Teragas per second**, which means that the 64-bit unsigned integer range exceeds
74+
after 18 million seconds:
75+
76+
$$ \frac{2^{64} - 1}{10^{12}} \approx 18446744\ seconds \approx 5124\ hours \approx 213\ days $$
77+
78+
Assuming a maximal supported block execution time of 30 seconds, the gas price has to be overpriced
79+
by a factor of **614891** in order to exceed the 64-bit unsigned integer range:
6180

62-
Cosmos SDK gas uses values that are smaller by a factor of 150, so those don't overflow as well.
81+
$$ \frac{2^{64} - 1}{30 \times 10^{12}} \approx 614891\ {Teragas \over s} $$
82+
83+
84+
Since serious over- or underpricing is considered a bug, using 64-bit unsigned integer
85+
for gas measurements is **considered safe**.
86+
87+
Cosmos SDK gas uses values that are smaller by a factor of 170, so those don't overflow as well.
6388
Since no Cosmos SDK gas values are processed inside of this repository, this is not our main
6489
concern. However, it's good to know that we can safely pass them in 64-bit fields, as long as the
6590
full range is supported. This is the case for the C API as well as [JSON numbers] as long as both
6691
sides support integers in their JSON implementation. Go and Rust do that while many other
67-
implementations don't support integers, and convert them to IEEE-754 doubles, which has a safe
92+
implementations don't support integers, and convert them to IEEE754 doubles, which has a safe
6893
integer range up to about 53 bit (e.g. JavaScript and jq).
6994

70-
<sup>1)</sup> $\frac{2^{64} - 1}{10^{12}} \approx 18446744s$, ${18446744 \over 3600} \approx 5124 h$
71-
72-
<sup>2)</sup> $\frac{2^{64} - 1}{30 \times 10^{12}} \approx 614891$
73-
74-
## Changes from version 1.x to 2.0 of CosmWasm
95+
## Gas changes in CosmWasm
7596

7697
In all versions before 2.0, the gas values were bigger by a factor of **1000**.
7798
There is no need to have them this big and in order to reduce the risk of
7899
overflow, the gas values were lowered in this issue [#1599].
79100

80101
Below is a breakdown of what this change entails:
81102

82-
| | CosmWasm 1.x | CosmWasm 2.x |
83-
|-----------------------------------------------------|:---------------------:|:-------------------------:|
84-
| **Cost target** | 1 Teragas/millisecond | 1 Teragas/second |
85-
| **Exceeds 64-bit unsigned<br/>integer range after** | 5 hours | 5124 hours<br/>≈ 213 days |
86-
| **Cost per Wasm operation** | 150.000 | 150 |
87-
| **Multiplier** | 140.000.000 | 140.000 |
103+
| | CosmWasm 1.x | CosmWasm 2.0 | CosmWasm 2.1 |
104+
|-----------------------------------------------------|:------------:|:------------:|:------------:|
105+
| **Cost target** | 1 Tgas/ms | 1 Tgas/s | 1 Tgas/s |
106+
| **Exceeds 64-bit unsigned<br/>integer range after** | 5 hours | 5124 hours | 5124 hours |
107+
| **Cost per Wasm operation** | 150.000 | 150 | 170 |
108+
| **Multiplier** | 140.000.000 | 140.000 | 140.000 |

0 commit comments

Comments
 (0)