Skip to content

Commit 1ea4042

Browse files
committed
add new gas-map tool and documentation to help with repricing
1 parent fd310c5 commit 1ea4042

5 files changed

Lines changed: 581 additions & 0 deletions

File tree

docs/gas_repricing/reference.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# GasCosts Reference
2+
3+
This page lists the `GasCosts` fields and the opcodes they affect. Use this as
4+
a reference when creating or editing a `gas_repricing.json` config file to help
5+
you know which field to override.
6+
7+
For an up-to-date, fork-specific mapping, run:
8+
9+
```bash
10+
uv run gas-map --fork <ForkName>
11+
```
12+
13+
## Base Operation Costs
14+
15+
| GasCosts Field | Typical Value | Affected Opcodes |
16+
|---|---|---|
17+
| `GAS_VERY_LOW` | 3 | ADD, SUB, CALLDATALOAD, LT, GT, SLT, SGT, EQ, ISZERO, AND, OR, XOR, NOT, BYTE, SHL, SHR, SAR, SIGNEXTEND, PUSH1-PUSH32, DUP1-DUP16, SWAP1-SWAP16, MLOAD, MSTORE, MSTORE8 |
18+
| `GAS_LOW` | 5 | MUL, DIV, SDIV, MOD, SMOD, CLZ |
19+
| `GAS_MID` | 8 | ADDMOD, MULMOD, JUMP |
20+
| `GAS_HIGH` | 10 | JUMPI |
21+
| `GAS_BASE` | 2 | ADDRESS, ORIGIN, CALLER, CALLVALUE, CALLDATASIZE, CODESIZE, GASPRICE, COINBASE, TIMESTAMP, NUMBER, PREVRANDAO, GASLIMIT, POP, PC, MSIZE, GAS, RETURNDATASIZE, CHAINID, SELFBALANCE, BASEFEE, BLOBBASEFEE |
22+
| `GAS_JUMPDEST` | 1 | JUMPDEST |
23+
| `GAS_BLOCK_HASH` | 20 | BLOCKHASH |
24+
25+
## Storage Costs
26+
27+
| GasCosts Field | Typical Value | Notes |
28+
|---|---|---|
29+
| `GAS_WARM_SLOAD` | 100 | SLOAD when slot is warm |
30+
| `GAS_COLD_SLOAD` | 2100 | SLOAD when slot is cold |
31+
| `GAS_STORAGE_SET` | 20000 | SSTORE: setting a slot from zero to non-zero |
32+
| `GAS_STORAGE_UPDATE` | 2900 | SSTORE: updating existing non-zero slot |
33+
| `GAS_STORAGE_RESET` | 2900 | SSTORE: resetting to original value |
34+
35+
## Account Access Costs
36+
37+
| GasCosts Field | Typical Value | Notes |
38+
|---|---|---|
39+
| `GAS_WARM_ACCOUNT_ACCESS` | 100 | BALANCE, EXTCODESIZE, etc. when warm |
40+
| `GAS_COLD_ACCOUNT_ACCESS` | 2600 | BALANCE, EXTCODESIZE, etc. when cold |
41+
| `GAS_TX_ACCESS_LIST_ADDRESS` | 2400 | Per address in access list |
42+
| `GAS_TX_ACCESS_LIST_STORAGE_KEY` | 1900 | Per storage key in access list |
43+
44+
## Exponentiation
45+
46+
| GasCosts Field | Typical Value | Notes |
47+
|---|---|---|
48+
| `GAS_EXPONENTIATION` | 10 | EXP base cost |
49+
| `GAS_EXPONENTIATION_PER_BYTE` | 50 | EXP per byte of exponent |
50+
51+
## Memory and Copy
52+
53+
| GasCosts Field | Typical Value | Notes |
54+
|---|---|---|
55+
| `GAS_MEMORY` | 3 | Memory expansion cost coefficient |
56+
| `GAS_COPY` | 3 | Per-word copy cost (CALLDATACOPY, CODECOPY, etc.) |
57+
| `GAS_KECCAK256` | 30 | SHA3 base cost |
58+
| `GAS_KECCAK256_PER_WORD` | 6 | SHA3 per 32-byte word |
59+
60+
## Logging
61+
62+
| GasCosts Field | Typical Value | Notes |
63+
|---|---|---|
64+
| `GAS_LOG` | 375 | LOG base cost |
65+
| `GAS_LOG_DATA_PER_BYTE` | 8 | LOG per byte of data |
66+
| `GAS_LOG_TOPIC` | 375 | LOG per topic |
67+
68+
## Transaction Costs
69+
70+
| GasCosts Field | Typical Value | Notes |
71+
|---|---|---|
72+
| `GAS_TX_BASE` | 21000 | Base transaction cost |
73+
| `GAS_TX_CREATE` | 32000 | Additional cost for contract creation tx |
74+
| `GAS_TX_DATA_PER_ZERO` | 4 | Per zero byte in tx data |
75+
| `GAS_TX_DATA_PER_NON_ZERO` | 16 | Per non-zero byte in tx data |
76+
| `GAS_TX_DATA_TOKEN_STANDARD` | 4 | Token cost per data element |
77+
| `GAS_TX_DATA_TOKEN_FLOOR` | 0 | Minimum token cost |
78+
79+
## Call and Create
80+
81+
| GasCosts Field | Typical Value | Notes |
82+
|---|---|---|
83+
| `GAS_CALL_VALUE` | 9000 | Additional cost when transferring value |
84+
| `GAS_CALL_STIPEND` | 2300 | Gas stipend for calls with value |
85+
| `GAS_NEW_ACCOUNT` | 25000 | Creating a new account via call |
86+
| `GAS_CREATE` | 32000 | CREATE opcode base cost |
87+
| `GAS_CODE_DEPOSIT_PER_BYTE` | 200 | Per byte of deployed code |
88+
| `GAS_CODE_INIT_PER_WORD` | 2 | Per word of init code (EIP-3860) |
89+
| `GAS_SELF_DESTRUCT` | 5000 | SELFDESTRUCT base cost |
90+
91+
## Auth (EIP-3074)
92+
93+
| GasCosts Field | Typical Value | Notes |
94+
|---|---|---|
95+
| `GAS_AUTH_PER_EMPTY_ACCOUNT` | 25000 | AUTH cost for empty account |
96+
97+
## Precompile Costs
98+
99+
| GasCosts Field | Typical Value | Precompile |
100+
|---|---|---|
101+
| `GAS_PRECOMPILE_ECRECOVER` | 3000 | ecRecover (0x01) |
102+
| `GAS_PRECOMPILE_SHA256_BASE` | 60 | SHA-256 base (0x02) |
103+
| `GAS_PRECOMPILE_SHA256_PER_WORD` | 12 | SHA-256 per word (0x02) |
104+
| `GAS_PRECOMPILE_RIPEMD160_BASE` | 600 | RIPEMD-160 base (0x03) |
105+
| `GAS_PRECOMPILE_RIPEMD160_PER_WORD` | 120 | RIPEMD-160 per word (0x03) |
106+
| `GAS_PRECOMPILE_IDENTITY_BASE` | 15 | Identity base (0x04) |
107+
| `GAS_PRECOMPILE_IDENTITY_PER_WORD` | 3 | Identity per word (0x04) |
108+
| `GAS_PRECOMPILE_ECADD` | 150 | BN256 add (0x06) |
109+
| `GAS_PRECOMPILE_ECMUL` | 6000 | BN256 mul (0x07) |
110+
| `GAS_PRECOMPILE_ECPAIRING_BASE` | 45000 | BN256 pairing base (0x08) |
111+
| `GAS_PRECOMPILE_ECPAIRING_PER_POINT` | 34000 | BN256 pairing per point (0x08) |
112+
| `GAS_PRECOMPILE_BLAKE2F_BASE` | 0 | BLAKE2 base (0x09) |
113+
| `GAS_PRECOMPILE_BLAKE2F_PER_ROUND` | 1 | BLAKE2 per round (0x09) |
114+
| `GAS_PRECOMPILE_POINT_EVALUATION` | 50000 | Point evaluation (0x0a) |
115+
| `GAS_PRECOMPILE_BLS_G1ADD` | 500 | BLS G1 add (0x0b) |
116+
| `GAS_PRECOMPILE_BLS_G1MUL` | 12000 | BLS G1 mul (0x0c) |
117+
| `GAS_PRECOMPILE_BLS_G1MAP` | 5500 | BLS G1 map (0x12) |
118+
| `GAS_PRECOMPILE_BLS_G2ADD` | 800 | BLS G2 add (0x0d) |
119+
| `GAS_PRECOMPILE_BLS_G2MUL` | 45000 | BLS G2 mul (0x0e) |
120+
| `GAS_PRECOMPILE_BLS_G2MAP` | 110000 | BLS G2 map (0x13) |
121+
| `GAS_PRECOMPILE_BLS_PAIRING_BASE` | 115000 | BLS pairing base (0x11) |
122+
| `GAS_PRECOMPILE_BLS_PAIRING_PER_PAIR` | 23000 | BLS pairing per pair (0x11) |
123+
| `GAS_PRECOMPILE_P256VERIFY` | 6900 | P256 verify (0x100) |
124+
125+
## Refund Constants
126+
127+
| GasCosts Field | Typical Value | Notes |
128+
|---|---|---|
129+
| `REFUND_STORAGE_CLEAR` | 4800 | Refund for clearing a storage slot |
130+
| `REFUND_AUTH_PER_EXISTING_ACCOUNT` | 25000 | AUTH refund for existing account |
131+
132+
## Dynamic Opcodes
133+
134+
Some opcodes have dynamic gas costs that depend on multiple `GasCosts` fields
135+
and runtime context:
136+
137+
| Opcode | Relevant GasCosts Fields | Notes |
138+
|---|---|---|
139+
| EXP | `GAS_EXPONENTIATION`, `GAS_EXPONENTIATION_PER_BYTE` | Cost depends on exponent size |
140+
| SLOAD | `GAS_WARM_SLOAD`, `GAS_COLD_SLOAD` | Warm vs cold access |
141+
| SSTORE | `GAS_STORAGE_SET`, `GAS_STORAGE_UPDATE`, `GAS_STORAGE_RESET`, `GAS_WARM_SLOAD`, `GAS_COLD_SLOAD` | Complex rules based on original/current/new values |
142+
| SHA3 | `GAS_KECCAK256`, `GAS_KECCAK256_PER_WORD` | Base + per-word cost |
143+
| LOG0-LOG4 | `GAS_LOG`, `GAS_LOG_DATA_PER_BYTE`, `GAS_LOG_TOPIC` | Base + data + topics |
144+
| CALL/CALLCODE | `GAS_WARM_ACCOUNT_ACCESS`, `GAS_COLD_ACCOUNT_ACCESS`, `GAS_CALL_VALUE`, `GAS_NEW_ACCOUNT` | Complex rules based on account state |
145+
| CREATE/CREATE2 | `GAS_CREATE`, `GAS_CODE_INIT_PER_WORD` | Base + init code cost |
146+
| BALANCE/EXTCODESIZE | `GAS_WARM_ACCOUNT_ACCESS`, `GAS_COLD_ACCOUNT_ACCESS` | Warm vs cold access |
147+
| SELFDESTRUCT | `GAS_SELF_DESTRUCT`, `GAS_COLD_ACCOUNT_ACCESS`, `GAS_NEW_ACCOUNT` | Depends on target account state |
148+
149+
## Generating Up-to-Date Mappings
150+
151+
The tables above reflect typical values. Exact values vary by fork.
152+
153+
For the authoritative mapping for a specific fork:
154+
155+
```bash
156+
# Full mapping
157+
uv run gas-map --fork Osaka
158+
159+
# Single opcode detail
160+
uv run gas-map --opcode SLOAD --fork Osaka
161+
```
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Gas Repricing Guide
2+
3+
## What is Gas Repricing?
4+
5+
Gas repricing allows you to override the default gas cost constants for any fork
6+
without modifying source code. This is useful for:
7+
8+
- Experimenting with alternative gas schedules
9+
- Testing the impact of proposed EIP gas changes
10+
- Running "what-if" analyses on existing test suites
11+
12+
## JSON Config Format
13+
14+
Create a JSON file mapping fork names to `GasCosts` field overrides:
15+
16+
```json
17+
{
18+
"Osaka": {
19+
"GAS_VERY_LOW": 4,
20+
"GAS_COLD_SLOAD": 2200
21+
},
22+
"Prague": {
23+
"GAS_WARM_SLOAD": 150
24+
}
25+
}
26+
```
27+
28+
Each key is a fork name (e.g., `Osaka`, `Prague`, `Cancun`). Each value is an
29+
object mapping `GasCosts` field names to their new integer values. Only the
30+
fields you want to change need to be specified; all others retain their
31+
defaults.
32+
33+
## Activation
34+
35+
Set the `EELS_GAS_REPRICING_CONFIG` environment variable to the path of your
36+
JSON config file:
37+
38+
```bash
39+
export EELS_GAS_REPRICING_CONFIG=./my_gas_repricing.json
40+
uv run fill tests/osaka/
41+
```
42+
43+
The repricing config is loaded once (cached) and applied transparently whenever
44+
`gas_costs()` is called on a fork.
45+
46+
## Finding the Right Field Names
47+
48+
The `GasCosts` dataclass has ~90 fields. To find which field controls a
49+
particular opcode's gas cost, use the `gas-map` CLI tool:
50+
51+
```bash
52+
# Show full mapping for a fork
53+
uv run gas-map --fork Osaka
54+
55+
# Look up a specific opcode
56+
uv run gas-map --opcode SLOAD
57+
```
58+
59+
See [GasCosts Reference](reference.md) for a static reference table.
60+
61+
## Example Workflow
62+
63+
1. Identify the opcodes you want to reprice:
64+
65+
```bash
66+
uv run gas-map --opcode SLOAD
67+
```
68+
69+
Output shows `GAS_WARM_SLOAD` and `GAS_COLD_SLOAD` are the relevant fields.
70+
71+
2. Create a repricing config:
72+
73+
```json
74+
{
75+
"Osaka": {
76+
"GAS_WARM_SLOAD": 150,
77+
"GAS_COLD_SLOAD": 2500
78+
}
79+
}
80+
```
81+
82+
3. Run tests with the new gas schedule:
83+
84+
```bash
85+
EELS_GAS_REPRICING_CONFIG=./reprice.json uv run fill tests/osaka/
86+
```
87+
88+
4. Compare results against the baseline to see which tests break or change
89+
behavior under the new gas schedule.

docs/navigation.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
* [Adding a Blockchain Test](writing_tests/tutorials/blockchain.md)
3333
* [Opcode Metadata](writing_tests/opcode_metadata.md)
3434
* [Porting Legacy Tests](writing_tests/porting_legacy_tests.md)
35+
* Gas Repricing
36+
* [Repricing Guide](gas_repricing/repricing_guide.md)
37+
* [GasCosts Reference](gas_repricing/reference.md)
3538
* [Filling Tests](filling_tests/index.md)
3639
* [Getting Started](filling_tests/getting_started.md)
3740
* [Filling Tests at a Prompt](filling_tests/filling_tests_command_line.md)

packages/testing/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ order_fixtures = "execution_testing.cli.order_fixtures:order_fixtures"
9494
evm_bytes = "execution_testing.cli.evm_bytes:evm_bytes"
9595
hasher = "execution_testing.cli.hasher:main"
9696
eest = "execution_testing.cli.eest.cli:eest"
97+
gas-map = "execution_testing.cli.eest.commands.gas_map:gas_map"
9798
fillerconvert = "execution_testing.cli.fillerconvert.fillerconvert:main"
9899
groupstats = "execution_testing.cli.show_pre_alloc_group_stats:main"
99100
extract_config = "execution_testing.cli.extract_config:extract_config"

0 commit comments

Comments
 (0)