Estimate worst-case EVM gas costs from runtime measurements.
Project description
evm-gasfit
Estimate worst-case EVM gas costs from runtime measurements.
evm-gasfit is a standalone, analysis-only Python package. Given a YAML test
config, a CSV of per-client runtime measurements, and a JSON of opcode counts,
it fits NNLS regressions over the runtimes, applies an optional glue-opcode
adjustment, and produces a gas-cost proposal as CSV and Markdown artifacts.
Install
For development (editable + test tools):
pip install -e ".[dev]"
The optional specs extra pulls per-fork GasCosts tables directly from
ethereum/execution-specs.
Without it, the package falls back to a bundled per-fork table:
pip install -e ".[specs]"
Python 3.10 or newer is required.
Quickstart
A minimal tests.yaml:
version: 1
anchor_rate: 1.0e8
clients:
- geth
- besu
gas_costs:
fork: osaka
models:
presets:
- arithmetic_add
clients is required: only rows whose client_name matches an entry here are
kept from the runtimes CSV, and a configured client that produced no fits at
all surfaces in the proposal report's Incomplete client coverage section.
Any gas-param name that the model proposes but the fork's GasCosts doesn't
already define must be declared up front under new_params. The value is
either null ("no prior default") or an integer that renders as the
current_gas baseline in the proposal diff:
new_params:
COLD_ACCOUNT_NOCODE_ACCESS: null # no prior default to diff against
STORAGE_WRITE: 2800 # render 2800 in the diff column
Names without a declaration are a hard config error — this catches typos in
model_params RHS values at load time.
Run the full pipeline from the command line:
evm-gasfit run \
--config tests.yaml \
--runtimes runtime.csv \
--opcounts opcounts.json \
--out ./out
Exit codes: 0 on success, 1 for config/input errors, 2 for modeling
failures.
Or drive it from Python:
from evm_gasfit import GasFit
fit = GasFit.from_config("tests.yaml")
fit.load_runtimes("runtime.csv")
fit.load_opcounts("opcounts.json")
fit.estimate_models()
fit.build_proposal()
fit.write_reports("./out")
Adapters
Prepare EEST blockchain_tests fixtures before joining them to benchmark
runtimes:
evm-gasfit prepare-eest \
--eest-fixtures /path/to/fixtures_geth/blockchain_tests \
--out ./prepared/eest
This writes opcounts.json, fixtures.csv, and excluded.csv.
prepare-eest reads _info.metadata.opcode_count and
_info.metadata.target_opcode, derives block_limit_million from
benchmark-gas-value_60M fixture names, and records stable EEST provenance
(original_test_name, source_path, block_index).
Precompile targets such as SHA2-256 get a synthetic target count from
STATICCALL when EEST traces only the call opcode.
Public API
The top-level package re-exports a small surface:
from evm_gasfit import GasFit, GasCosts, load_config
Everything else is internal. See the rendered API reference at
docs/api.md (auto-deployed to GitHub Pages from mkdocs.yml).
Outputs
write_reports(out_dir) emits:
results.csv— one row per fit ((spec, model_by-combo, client)).new_gas_all_params.csv— every per-client candidate fit, with the per-client worst-case pick flaggedis_winner.new_gas.csv— worst-case across clients (one row per gas param).runtime_estimation_autogenerated_report.md— per-spec regression summary.new_gas_proposal.md— final proposal, opening with aContentsTOC. Carries a diff table for fitted rows (against patched fork values +new_paramsinteger baselines), aClient comparisonsection showing each parameter's worst vs. second-worst client and aworst / second-worstratio (large ratios flag the worst client as an outlier) plus a per-client overview of proposed values — rendered as alog2(proposed / current)heatmap when plots are on (red = more expensive than current, green = cheaper, blank rows fornew_paramsdeclared without a baseline) or as a markdown table when plots are off, aWorst-case provenancesection with one collapsible block per gas param showing every per-client candidate (one row per(test_name, target_opcode, model_coef_name, model_by)combo, one column per client, cells = proposed gas); the cell the per-client selector picked as that client's worst-case is highlighted (outlined on the heatmap, bolded in the markdown-table fallback), and a warnings section containingMissing parameters(proposed names that produced no value),Incomplete client coverage(proposed names fit for some clients but missing on others),Missing glue adjustments, andOther. A trailingPoor-fit selectionssection flags winning fits whose p-value or R² crossed themodeling.poor_fit_*_thresholdknobs (Winners with poor fit) plus any losing candidates that failed the same thresholds (Other weak candidates).
When glue adjustment is enabled, glue_results.csv,
glue_opcodes_by_test.csv, and glue_opcodes_autogenerated_report.md are
written too. Each priced glue opcode's per-client contribution is applied
only when its fit passes both glue_contribution_p_value_threshold (default
0.05) and glue_contribution_rsquared_threshold (default 0.7); skipped
contributions surface under Missing glue adjustments in the proposal so
the affected gas params and clients are auditable. When output.plots: true,
regression and diagnostic figures land under figs/.
Tests
pytest
The end-to-end suite synthesizes its own inputs and exercises the public API and CLI; there are no fixtures to download.
License
See LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file evm_gasfit-0.0.3.tar.gz.
File metadata
- Download URL: evm_gasfit-0.0.3.tar.gz
- Upload date:
- Size: 124.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d2f0a48c8a76dfc8217dfb973ea372d8b46d0ad1837951b2478a1588df946976
|
|
| MD5 |
fd70595e01b063eb793d2d5b1a835785
|
|
| BLAKE2b-256 |
e40b79981d4cc6073610b02d8a4d8b7896dc72deb8dc3cd10610988537aa791f
|
Provenance
The following attestation bundles were made for evm_gasfit-0.0.3.tar.gz:
Publisher:
release.yml on misilva73/evm-gasfit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
evm_gasfit-0.0.3.tar.gz -
Subject digest:
d2f0a48c8a76dfc8217dfb973ea372d8b46d0ad1837951b2478a1588df946976 - Sigstore transparency entry: 1693329801
- Sigstore integration time:
-
Permalink:
misilva73/evm-gasfit@54be41978383fcab13b3cd54a834087d00fd4288 -
Branch / Tag:
refs/tags/v0.0.3 - Owner: https://github.com/misilva73
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@54be41978383fcab13b3cd54a834087d00fd4288 -
Trigger Event:
release
-
Statement type:
File details
Details for the file evm_gasfit-0.0.3-py3-none-any.whl.
File metadata
- Download URL: evm_gasfit-0.0.3-py3-none-any.whl
- Upload date:
- Size: 89.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fcd59890c76cc59c12f5ca7f2ab51c20a1d4252b4492d579a8b1f6380337623a
|
|
| MD5 |
79df690a6110fd8f6989b4ca03f5d3a3
|
|
| BLAKE2b-256 |
13123acb4623900c84fba3ff2e556dd110f92bb3edf877fdf848177a0291e9ac
|
Provenance
The following attestation bundles were made for evm_gasfit-0.0.3-py3-none-any.whl:
Publisher:
release.yml on misilva73/evm-gasfit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
evm_gasfit-0.0.3-py3-none-any.whl -
Subject digest:
fcd59890c76cc59c12f5ca7f2ab51c20a1d4252b4492d579a8b1f6380337623a - Sigstore transparency entry: 1693329942
- Sigstore integration time:
-
Permalink:
misilva73/evm-gasfit@54be41978383fcab13b3cd54a834087d00fd4288 -
Branch / Tag:
refs/tags/v0.0.3 - Owner: https://github.com/misilva73
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@54be41978383fcab13b3cd54a834087d00fd4288 -
Trigger Event:
release
-
Statement type: