Skip to content
Draft
Show file tree
Hide file tree
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,6 @@ logs/
env.yaml

site/

# Gas Repricing
gas_repricing.json
161 changes: 161 additions & 0 deletions docs/gas_repricing/reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# GasCosts Reference

This page lists the `GasCosts` fields and the opcodes they affect. Use this as
a reference when creating or editing a `gas_repricing.json` config file to help
you know which field to override.

For an up-to-date, fork-specific mapping, run:

```bash
uv run gas-map --fork <ForkName>
```

## Base Operation Costs

| GasCosts Field | Typical Value | Affected Opcodes |
|---|---|---|
| `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 |
| `GAS_LOW` | 5 | MUL, DIV, SDIV, MOD, SMOD, CLZ |
| `GAS_MID` | 8 | ADDMOD, MULMOD, JUMP |
| `GAS_HIGH` | 10 | JUMPI |
| `GAS_BASE` | 2 | ADDRESS, ORIGIN, CALLER, CALLVALUE, CALLDATASIZE, CODESIZE, GASPRICE, COINBASE, TIMESTAMP, NUMBER, PREVRANDAO, GASLIMIT, POP, PC, MSIZE, GAS, RETURNDATASIZE, CHAINID, SELFBALANCE, BASEFEE, BLOBBASEFEE |
| `GAS_JUMPDEST` | 1 | JUMPDEST |
| `GAS_BLOCK_HASH` | 20 | BLOCKHASH |

## Storage Costs

| GasCosts Field | Typical Value | Notes |
|---|---|---|
| `GAS_WARM_SLOAD` | 100 | SLOAD when slot is warm |
| `GAS_COLD_SLOAD` | 2100 | SLOAD when slot is cold |
| `GAS_STORAGE_SET` | 20000 | SSTORE: setting a slot from zero to non-zero |
| `GAS_STORAGE_UPDATE` | 2900 | SSTORE: updating existing non-zero slot |
| `GAS_STORAGE_RESET` | 2900 | SSTORE: resetting to original value |

## Account Access Costs

| GasCosts Field | Typical Value | Notes |
|---|---|---|
| `GAS_WARM_ACCOUNT_ACCESS` | 100 | BALANCE, EXTCODESIZE, etc. when warm |
| `GAS_COLD_ACCOUNT_ACCESS` | 2600 | BALANCE, EXTCODESIZE, etc. when cold |
| `GAS_TX_ACCESS_LIST_ADDRESS` | 2400 | Per address in access list |
| `GAS_TX_ACCESS_LIST_STORAGE_KEY` | 1900 | Per storage key in access list |

## Exponentiation

| GasCosts Field | Typical Value | Notes |
|---|---|---|
| `GAS_EXPONENTIATION` | 10 | EXP base cost |
| `GAS_EXPONENTIATION_PER_BYTE` | 50 | EXP per byte of exponent |

## Memory and Copy

| GasCosts Field | Typical Value | Notes |
|---|---|---|
| `GAS_MEMORY` | 3 | Memory expansion cost coefficient |
| `GAS_COPY` | 3 | Per-word copy cost (CALLDATACOPY, CODECOPY, etc.) |
| `GAS_KECCAK256` | 30 | SHA3 base cost |
| `GAS_KECCAK256_PER_WORD` | 6 | SHA3 per 32-byte word |

## Logging

| GasCosts Field | Typical Value | Notes |
|---|---|---|
| `GAS_LOG` | 375 | LOG base cost |
| `GAS_LOG_DATA_PER_BYTE` | 8 | LOG per byte of data |
| `GAS_LOG_TOPIC` | 375 | LOG per topic |

## Transaction Costs

| GasCosts Field | Typical Value | Notes |
|---|---|---|
| `GAS_TX_BASE` | 21000 | Base transaction cost |
| `GAS_TX_CREATE` | 32000 | Additional cost for contract creation tx |
| `GAS_TX_DATA_PER_ZERO` | 4 | Per zero byte in tx data |
| `GAS_TX_DATA_PER_NON_ZERO` | 16 | Per non-zero byte in tx data |
| `GAS_TX_DATA_TOKEN_STANDARD` | 4 | Token cost per data element |
| `GAS_TX_DATA_TOKEN_FLOOR` | 0 | Minimum token cost |

## Call and Create

| GasCosts Field | Typical Value | Notes |
|---|---|---|
| `GAS_CALL_VALUE` | 9000 | Additional cost when transferring value |
| `GAS_CALL_STIPEND` | 2300 | Gas stipend for calls with value |
| `GAS_NEW_ACCOUNT` | 25000 | Creating a new account via call |
| `GAS_CREATE` | 32000 | CREATE opcode base cost |
| `GAS_CODE_DEPOSIT_PER_BYTE` | 200 | Per byte of deployed code |
| `GAS_CODE_INIT_PER_WORD` | 2 | Per word of init code (EIP-3860) |
| `GAS_SELF_DESTRUCT` | 5000 | SELFDESTRUCT base cost |

## Auth (EIP-3074)

| GasCosts Field | Typical Value | Notes |
|---|---|---|
| `GAS_AUTH_PER_EMPTY_ACCOUNT` | 25000 | AUTH cost for empty account |

## Precompile Costs

| GasCosts Field | Typical Value | Precompile |
|---|---|---|
| `GAS_PRECOMPILE_ECRECOVER` | 3000 | ecRecover (0x01) |
| `GAS_PRECOMPILE_SHA256_BASE` | 60 | SHA-256 base (0x02) |
| `GAS_PRECOMPILE_SHA256_PER_WORD` | 12 | SHA-256 per word (0x02) |
| `GAS_PRECOMPILE_RIPEMD160_BASE` | 600 | RIPEMD-160 base (0x03) |
| `GAS_PRECOMPILE_RIPEMD160_PER_WORD` | 120 | RIPEMD-160 per word (0x03) |
| `GAS_PRECOMPILE_IDENTITY_BASE` | 15 | Identity base (0x04) |
| `GAS_PRECOMPILE_IDENTITY_PER_WORD` | 3 | Identity per word (0x04) |
| `GAS_PRECOMPILE_ECADD` | 150 | BN256 add (0x06) |
| `GAS_PRECOMPILE_ECMUL` | 6000 | BN256 mul (0x07) |
| `GAS_PRECOMPILE_ECPAIRING_BASE` | 45000 | BN256 pairing base (0x08) |
| `GAS_PRECOMPILE_ECPAIRING_PER_POINT` | 34000 | BN256 pairing per point (0x08) |
| `GAS_PRECOMPILE_BLAKE2F_BASE` | 0 | BLAKE2 base (0x09) |
| `GAS_PRECOMPILE_BLAKE2F_PER_ROUND` | 1 | BLAKE2 per round (0x09) |
| `GAS_PRECOMPILE_POINT_EVALUATION` | 50000 | Point evaluation (0x0a) |
| `GAS_PRECOMPILE_BLS_G1ADD` | 500 | BLS G1 add (0x0b) |
| `GAS_PRECOMPILE_BLS_G1MUL` | 12000 | BLS G1 mul (0x0c) |
| `GAS_PRECOMPILE_BLS_G1MAP` | 5500 | BLS G1 map (0x12) |
| `GAS_PRECOMPILE_BLS_G2ADD` | 800 | BLS G2 add (0x0d) |
| `GAS_PRECOMPILE_BLS_G2MUL` | 45000 | BLS G2 mul (0x0e) |
| `GAS_PRECOMPILE_BLS_G2MAP` | 110000 | BLS G2 map (0x13) |
| `GAS_PRECOMPILE_BLS_PAIRING_BASE` | 115000 | BLS pairing base (0x11) |
| `GAS_PRECOMPILE_BLS_PAIRING_PER_PAIR` | 23000 | BLS pairing per pair (0x11) |
| `GAS_PRECOMPILE_P256VERIFY` | 6900 | P256 verify (0x100) |

## Refund Constants

| GasCosts Field | Typical Value | Notes |
|---|---|---|
| `REFUND_STORAGE_CLEAR` | 4800 | Refund for clearing a storage slot |
| `REFUND_AUTH_PER_EXISTING_ACCOUNT` | 25000 | AUTH refund for existing account |

## Dynamic Opcodes

Some opcodes have dynamic gas costs that depend on multiple `GasCosts` fields
and runtime context:

| Opcode | Relevant GasCosts Fields | Notes |
|---|---|---|
| EXP | `GAS_EXPONENTIATION`, `GAS_EXPONENTIATION_PER_BYTE` | Cost depends on exponent size |
| SLOAD | `GAS_WARM_SLOAD`, `GAS_COLD_SLOAD` | Warm vs cold access |
| SSTORE | `GAS_STORAGE_SET`, `GAS_STORAGE_UPDATE`, `GAS_STORAGE_RESET`, `GAS_WARM_SLOAD`, `GAS_COLD_SLOAD` | Complex rules based on original/current/new values |
| SHA3 | `GAS_KECCAK256`, `GAS_KECCAK256_PER_WORD` | Base + per-word cost |
| LOG0-LOG4 | `GAS_LOG`, `GAS_LOG_DATA_PER_BYTE`, `GAS_LOG_TOPIC` | Base + data + topics |
| CALL/CALLCODE | `GAS_WARM_ACCOUNT_ACCESS`, `GAS_COLD_ACCOUNT_ACCESS`, `GAS_CALL_VALUE`, `GAS_NEW_ACCOUNT` | Complex rules based on account state |
| CREATE/CREATE2 | `GAS_CREATE`, `GAS_CODE_INIT_PER_WORD` | Base + init code cost |
| BALANCE/EXTCODESIZE | `GAS_WARM_ACCOUNT_ACCESS`, `GAS_COLD_ACCOUNT_ACCESS` | Warm vs cold access |
| SELFDESTRUCT | `GAS_SELF_DESTRUCT`, `GAS_COLD_ACCOUNT_ACCESS`, `GAS_NEW_ACCOUNT` | Depends on target account state |

## Generating Up-to-Date Mappings

The tables above reflect typical values. Exact values vary by fork.

For the authoritative mapping for a specific fork:

```bash
# Full mapping
uv run gas-map --fork Osaka

# Single opcode detail
uv run gas-map --opcode SLOAD --fork Osaka
```
89 changes: 89 additions & 0 deletions docs/gas_repricing/repricing_guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Gas Repricing Guide

## What is Gas Repricing?

Gas repricing allows you to override the default gas cost constants for any fork
without modifying source code. This is useful for:

- Experimenting with alternative gas schedules
- Testing the impact of proposed EIP gas changes
- Running "what-if" analyses on existing test suites

## JSON Config Format

Create a JSON file mapping fork names to `GasCosts` field overrides:

```json
{
"Osaka": {
"GAS_VERY_LOW": 4,
"GAS_COLD_SLOAD": 2200
},
"Prague": {
"GAS_WARM_SLOAD": 150
}
}
```

Each key is a fork name (e.g., `Osaka`, `Prague`, `Cancun`). Each value is an
object mapping `GasCosts` field names to their new integer values. Only the
fields you want to change need to be specified; all others retain their
defaults.

## Activation

Set the `EELS_GAS_REPRICING_CONFIG` environment variable to the path of your
JSON config file:

```bash
export EELS_GAS_REPRICING_CONFIG=./my_gas_repricing.json
uv run fill tests/osaka/
```

The repricing config is loaded once (cached) and applied transparently whenever
`gas_costs()` is called on a fork.

## Finding the Right Field Names

The `GasCosts` dataclass has ~90 fields. To find which field controls a
particular opcode's gas cost, use the `gas-map` CLI tool:

```bash
# Show full mapping for a fork
uv run gas-map --fork Osaka

# Look up a specific opcode
uv run gas-map --opcode SLOAD
```

See [GasCosts Reference](reference.md) for a static reference table.

## Example Workflow

1. Identify the opcodes you want to reprice:

```bash
uv run gas-map --opcode SLOAD
```

Output shows `GAS_WARM_SLOAD` and `GAS_COLD_SLOAD` are the relevant fields.

2. Create a repricing config:

```json
{
"Osaka": {
"GAS_WARM_SLOAD": 150,
"GAS_COLD_SLOAD": 2500
}
}
```

3. Run tests with the new gas schedule:

```bash
EELS_GAS_REPRICING_CONFIG=./reprice.json uv run fill tests/osaka/
```

4. Compare results against the baseline to see which tests break or change
behavior under the new gas schedule.
3 changes: 3 additions & 0 deletions docs/navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
* [Adding a Blockchain Test](writing_tests/tutorials/blockchain.md)
* [Opcode Metadata](writing_tests/opcode_metadata.md)
* [Porting Legacy Tests](writing_tests/porting_legacy_tests.md)
* Gas Repricing
* [Repricing Guide](gas_repricing/repricing_guide.md)
* [GasCosts Reference](gas_repricing/reference.md)
* [Filling Tests](filling_tests/index.md)
* [Getting Started](filling_tests/getting_started.md)
* [Filling Tests at a Prompt](filling_tests/filling_tests_command_line.md)
Expand Down
1 change: 1 addition & 0 deletions packages/testing/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ order_fixtures = "execution_testing.cli.order_fixtures:order_fixtures"
evm_bytes = "execution_testing.cli.evm_bytes:evm_bytes"
hasher = "execution_testing.cli.hasher:main"
eest = "execution_testing.cli.eest.cli:eest"
gas-map = "execution_testing.cli.eest.commands.gas_map:gas_map"
fillerconvert = "execution_testing.cli.fillerconvert.fillerconvert:main"
groupstats = "execution_testing.cli.show_pre_alloc_group_stats:main"
extract_config = "execution_testing.cli.extract_config:extract_config"
Expand Down
2 changes: 2 additions & 0 deletions packages/testing/src/execution_testing/cli/eest/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import click

from .commands import clean, info
from .commands.gas_map import gas_map
from .make.cli import make


Expand Down Expand Up @@ -33,3 +34,4 @@ def eest() -> None:
eest.add_command(make)
eest.add_command(clean)
eest.add_command(info)
eest.add_command(gas_map, name="gas-map")
Loading
Loading