Skip to content
Open
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
871 changes: 871 additions & 0 deletions .github/workflows/zilkworm-benchmark.yml

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
members = [
"bin/reth-benchmark",
"bin/reth-verify",
"bin/zilkworm-benchmark",
"crates/mpt",
"crates/revm-crypto",
"crates/stateless-executor",
Expand Down
45 changes: 45 additions & 0 deletions bin/zilkworm-benchmark/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[package]
name = "openvm-zilkworm-benchmark"
edition.workspace = true
repository.workspace = true
homepage.workspace = true
exclude.workspace = true
version.workspace = true

[lib]
path = "src/lib.rs"

[lints]
workspace = true

[dependencies]
tracing-subscriber.workspace = true
tracing.workspace = true
dotenv = "0.15.0"
clap = { version = "4.5.7", features = ["derive", "env"] }
hex = "0.4.3"
eyre.workspace = true
zstd.workspace = true

# Note: the openvm-sdk commit does not need to be exactly the same as the `openvm` commit used in the guest program: as long as
# the openvm-sdk commit doesn't change any guest libraries, they are compatible
openvm-stark-sdk = { git = "https://github.com/openvm-org/stark-backend.git", branch = "develop-v2.1.0", default-features = false }
openvm-cuda-backend = { git = "https://github.com/openvm-org/stark-backend.git", branch = "develop-v2.1.0", default-features = false, optional = true }
openvm-transpiler = { git = "https://github.com/openvm-org/openvm.git", branch = "develop-v2.1.0", default-features = false }
openvm-circuit = { git = "https://github.com/openvm-org/openvm.git", branch = "develop-v2.1.0", default-features = false }
openvm-verify-stark-host = { git = "https://github.com/openvm-org/openvm.git", branch = "develop-v2.1.0", default-features = false }
openvm-sdk = { git = "https://github.com/openvm-org/openvm.git", branch = "develop-v2.1.0", default-features = false }
openvm-sdk-config = { git = "https://github.com/openvm-org/openvm.git", branch = "develop-v2.1.0", default-features = false }

[features]
default = ["parallel", "jemalloc", "metrics"]
parallel = ["openvm-sdk/parallel"]
metrics = ["openvm-sdk/metrics", "openvm-circuit/metrics", "openvm-stark-sdk/metrics"]
tco = ["openvm-sdk/tco"]
rvr = ["openvm-sdk/rvr"]
perf-metrics = ["openvm-sdk/perf-metrics"]
mimalloc = ["openvm-sdk/mimalloc"]
jemalloc = ["openvm-sdk/jemalloc"]
cuda = ["dep:openvm-cuda-backend", "openvm-sdk/cuda"]
unprotected = ["openvm-sdk/unprotected"]
nvtx = ["openvm-stark-sdk/nvtx"]
67 changes: 67 additions & 0 deletions bin/zilkworm-benchmark/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# OpenVM Zilkworm Benchmark

Benchmark host for [Zilkworm](https://github.com/eth-act/zilkworm-stateless)
(mirrored at [axiom-crypto/zilkworm-stateless](https://github.com/axiom-crypto/zilkworm-stateless)), a bare-metal C++
stateless Ethereum block validator compiled to an RV64IM ELF. The guest runs
on OpenVM's RV64 target (`rv64i + rv64m + io + keccak + sha2` extensions) and
goes through the same execute / prove pipeline as the Reth benchmark.

## Guest

Build the guest ELF from the `feat/openvm-rv64` branch of
`axiom-crypto/zilkworm-stateless` (requires cmake >= 3.28 and the xPack
`riscv-none-elf-gcc` toolchain, see that repo's README):

```bash
git clone https://github.com/axiom-crypto/zilkworm-stateless.git
cd zilkworm-stateless
git checkout feat/openvm-rv64
make guest_openvm # produces build/openvm/z6m_guest.elf
```

## Input

The guest consumes one eth-act SSZ `StatelessInput` byte vector (the
`*_input.bin` format produced by the zilkworm `conformance` vector
generator) and reveals the SSZ `StatelessValidationResult`
(`root[32] || success[1] || offset[4] || chain_config`) as public values.

Generate the synthetic mock vector (note: the mock block intentionally
*fails* validation — assert `mock_expected_failure.bin`):

```bash
cd zilkworm-stateless/conformance
cargo run --release -- mock --out-dir vectors --name mock
```

EEST stateless fixtures can be converted with the same tool's `eest`
subcommand; real-block vectors with `real` (see `conformance/README.md`).

## Run

```bash
cargo run --bin openvm-zilkworm-benchmark --release -- \
--mode execute \
--guest-elf path/to/z6m_guest.elf \
--input-path path/to/mock_input.bin \
--expected-output path/to/mock_expected_failure.bin
```

Modes: `execute`, `execute-metered`, `prove-app`, `prove-stark`, `keygen`,
`generate-vm-vkey`. Proving parameters (`--app-log-blowup`, `--app-l-skip`,
`--leaf-log-blowup`, `--internal-log-blowup`, `--segment-max-memory`,
`--num-children-leaf`, `--num-children-internal`) match the Reth benchmark
host.

Feature flags also mirror the Reth host: `rvr` (recompile the guest to
native C for execution; needs `clang-22` and `lld`), `tco`, `cuda`,
`jemalloc`/`mimalloc`, `metrics`, `perf-metrics`, `unprotected`, `nvtx`.

## CI

The `Zilkworm Benchmark` workflow
(`.github/workflows/zilkworm-benchmark.yml`) runs parallel to the Reth
Benchmark: it builds the guest ELF from `axiom-crypto/zilkworm-stateless` with the
pinned xPack toolchain, prepares the input (`mock` or an `s3://` / `https://`
URL to a `StatelessInput` .bin), and uploads metrics / markdown to S3 and
gh-pages using the same tooling.
50 changes: 50 additions & 0 deletions bin/zilkworm-benchmark/openvm.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# VM extension config for the Zilkworm RV64IM guest.
#
# The order of supported_moduli / fp2 moduli / ecc curves is ABI: it defines
# the funct7 indices of the modular / Fp2 / short-Weierstrass custom
# instructions the guest emits. Keep in sync with zilkworm-stateless's
# zkvm/openvm/src/include/openvm_ecc.hpp (MOD_*/FP2_*/CURVE_* constants).

[app_vm_config.rv64i]
[app_vm_config.rv64m]
[app_vm_config.io]

[app_vm_config.keccak]
[app_vm_config.sha2]

[app_vm_config.modular]
supported_moduli = [
# 0: secp256k1 coordinate field
"115792089237316195423570985008687907853269984665640564039457584007908834671663",
# 1: secp256k1 scalar field
"115792089237316195423570985008687907852837564279074904382605163141518161494337",
# 2: bn254 (alt bn128) coordinate field
"21888242871839275222246405745257275088696311157297823662689037894645226208583",
# 3: bn254 scalar field
"21888242871839275222246405745257275088548364400416034343698204186575808495617",
]

[app_vm_config.fp2]
supported_moduli = [
# 0: bn254 Fp2
[
"Bn254Fp2",
"21888242871839275222246405745257275088696311157297823662689037894645226208583",
],
]

# 0: secp256k1
[[app_vm_config.ecc.supported_curves]]
struct_name = "Secp256k1Point"
modulus = "115792089237316195423570985008687907853269984665640564039457584007908834671663"
scalar = "115792089237316195423570985008687907852837564279074904382605163141518161494337"
a = "0"
b = "7"

# 1: bn254 G1
[[app_vm_config.ecc.supported_curves]]
struct_name = "Bn254G1Affine"
modulus = "21888242871839275222246405745257275088696311157297823662689037894645226208583"
scalar = "21888242871839275222246405745257275088548364400416034343698204186575808495617"
a = "0"
b = "3"
Loading
Loading