Skip to content

deps(l2): upgrade SP1 from v5.0.8 (Turbo) to v6.0.1 (Hypercube)#6188

Closed
avilagaston9 wants to merge 53 commits into
mainfrom
bench/sp1-hypercube
Closed

deps(l2): upgrade SP1 from v5.0.8 (Turbo) to v6.0.1 (Hypercube)#6188
avilagaston9 wants to merge 53 commits into
mainfrom
bench/sp1-hypercube

Conversation

@avilagaston9
Copy link
Copy Markdown
Contributor

@avilagaston9 avilagaston9 commented Feb 11, 2026

Motivation

SP1 Hypercube is Succinct's new proof system built on multilinear polynomials, claiming up to 5x improvement for compute-heavy workloads and ~2x for precompile-heavy workloads like Ethereum proving. This PR upgrades ethrex from SP1 Turbo (v5.0.8) to SP1 Hypercube (v6.0.1) so we can benchmark the new prover against our existing Turbo baseline.

Description

Bump all SP1 dependencies to =6.0.1 and update all accelerated cryptography patches to v6 stable tags. Bump Rust toolchain from 1.90.0 to 1.91.0 (required by SP1 v6.0.1 transitive dependencies).

Rewrite the SP1 prover backend (crates/l2/prover/src/backend/sp1.rs) to use the v6 blocking API (sp1_sdk::blocking::EnvProver), which unifies CPU/CUDA/Mock behind the SP1_PROVER env var. Migrate to the new Elf type, builder pattern for prove (prove().mode().run()), and pk.verifying_key() for VK access.

Additional changes:

  • Remove the ecdsa patch (breaks p256's VerifyPrimitive in v6 — k256 brings its own via git)
  • Remove sp1-zkvm/embedded feature (removed in v6)
  • Update on-chain verifier contract to v6 (v6.0.0/SP1VerifierGroth16.sol from sp1-contracts main)
  • Temporarily disable aligned-sdk SP1 submission (sp1-sdk v5/v6 type mismatch)
  • Add docs/prover/sp1-hypercube-upgrade.md with full upgrade notes and next steps
  • Add missing .gitignore for crates/guest-program/ — when refactor(l1,l2): extract guest program to dedicated ethrex-guest crate #5995 extracted the guest program from crates/l2/, the out/ and target/ directories lost coverage from crates/l2/.gitignore which had a blanket out/ entry

How to Test

# Install SP1 v6 toolchain
sp1up --version 6.0.1

# Build guest program
cargo build --release -p ethrex-guest-program --features sp1,l2

# Check host compilation
cargo check -p ethrex --features sp1

Checklist

  • Updated STORE_SCHEMA_VERSION (crates/storage/lib.rs) if the PR includes breaking changes to the Store requiring a re-sync.

avilagaston9 added 30 commits February 9, 2026 11:02
Switch the prover loop from prove() to prove_timed() so each batch logs
a structured line with batch number and elapsed proving time (seconds and
milliseconds). Add scripts/sp1_bench_metrics.sh that tails the prover log,
collects results into a CSV, and prints a summary table on exit.
… of prover

The guest program was moved from crates/l2/prover/src/ethrex_guest_program/
to crates/guest-program/, but the fallback VK paths in the deployer were not
updated. This caused deploy-l1-sp1 to fail with "No such file or directory"
when running outside Docker. CI was unaffected because it passes explicit
VK paths via ETHREX_SP1_VERIFICATION_KEY_PATH in docker-compose.yaml.
…nce conflicts,

and add --endless flag for continuous load generation. The load_test function now
fetches the pending nonce (instead of latest) so re-runs pick up where the previous
round left off. wait_until_all_included now tracks per-account target nonces instead
of a flat tx_amount, which was incorrect for any run where the starting nonce was
not zero.
…ndpoint.

The script now fetches batch_gas_used, batch_tx_count, and batch_size from
the L2 metrics endpoint (localhost:3702/metrics) for each proved batch, joining
them with proving time into a single CSV and summary table.
…ing.

It now parses all proving_time lines from the file, fetches batch metadata
from Prometheus, prints the table, and exits immediately.
…last]

contains last - first + 1 blocks, not last - first. A single-block batch
was reported as size 0.
…ment.

When enabled (default), the prover wraps each prove() call with timing and logs
structured fields (proving_time_s, proving_time_ms). When disabled with --no-timed,
the prover calls prove() directly without timing overhead. Also fixes a clippy
as_conversions warning in the elapsed.as_millis() cast.
…ess mode.

The clap args now accept LOAD_TEST_RPC_URL, LOAD_TEST_TX_AMOUNT, and
LOAD_TEST_ENDLESS environment variables as alternatives to --node, --tx-amount,
and --endless flags respectively. CLI flags take precedence over env vars.
The guide (docs/l2/prover-benchmarking.md) explains how to use the localnet,
prover timing, load test, and benchmark script together to measure proving
performance. The agent workflow (docs/workflows/prover_benchmarking.md) provides
step-by-step instructions for running a remote benchmark session, following the
same format as the existing execution witness benchmarking workflow.
or in a loop depending on --endless, instead of a loop-with-break pattern.
…lient,

tx_builder, and accounts instead of owned values, removing unnecessary clones
at the call sites in run_round.
This removes the need for --no-timed; users pass --timed when they want
proving time measurement, and omit it otherwise.
both the default and gpu-enabled cargo run commands.
--timed can be passed via make (e.g. make init-prover-sp1 PROVER_ARGS=--timed).
Update docs to use the Makefile commands with GPU=true and PROVER_ARGS examples.
PROVER_ARGS, so timing is enabled with TIMED=true (e.g. make init-prover-sp1
GPU=true TIMED=true).
…alias.

Clap already reads the env var, so no Makefile plumbing is needed. Reverts
the TIMED/PROVER_ARGS additions to the Makefile targets.
…ummary

instead of CSV. Add load-test Makefile target with env var configuration.
Update docs to use Makefile commands throughout, add mempool limit warning,
note that L2 must be running when collecting results, and reference
PROVER_CLIENT_TIMED env var instead of --timed flag.
root Makefile target instead. Update docs to run make load-test from
the repo root.
script. The report now includes a Server Specs section with hardware
info detected from /proc/cpuinfo, /proc/meminfo, sysctl, and nvidia-smi.
by default) in the prover benchmarking workflow.
batch assignments by whether the prover's type is needed. Previously
the coordinator assigned a batch whenever ANY required proof was missing,
causing provers to waste time re-proving batches they had already proved
(e.g. an SP1 prover proving a batch that only needed an exec proof).

The ProverBackend trait now has a prover_type() method, implemented for
each backend (todo!() for ZisK and OpenVM which lack ProverType variants).
The prover client stores its type at startup and sends it with every
BatchRequest. The coordinator checks needed_proof_types.contains() before
assigning.

Also fixes the deploy-l1-sp1 Makefile target which used the removed
--sp1.deploy-verifier flag — replaced with --sp1 and removed dummy
verifier addresses for other backends. Updated benchmarking docs to
reference deploy-l1-sp1 for SP1 benchmarks.
already exposes it via the prover_type() trait method.
…oad_test formatting.

Commit 517e535 added prover_type to BatchRequest but didn't update the TDX
quote-gen sender (outside the workspace), breaking the tdx lint/build CI jobs.
The load_test formatting was also off since it's outside the main workspace.
…arted

immediately after the L2 is up, not just before the prover. The prover proves
batches faster than the sequencer fills them with transactions, so any delay
in starting the load test results in empty batches being proved.
empty batches. The block producer and committer build and commit
empty blocks/batches faster than the load test can start sending
transactions (especially for erc20/fibonacci/io-heavy which have
a contract deployment setup phase). By pre-compiling the binary
in step 1b and running it directly in step 3, the load test starts
immediately when the L2 is up.
…t recompilation.

Previously each step (deploy, L2 start, prover start) triggered its own `cargo run`
which recompiled the binary. Now step 1b builds everything once with all needed features,
and all subsequent steps use `target/release/ethrex` directly. Also made the docs
backend-agnostic (not SP1-specific) with placeholder flags and tables for SP1/RISC0/Exec,
and made the branch/commit prompt mandatory (no default).
…name

sp1_bench_metrics.sh to bench_metrics.sh since the script is backend-agnostic,
fix the load test targets table in the workflow doc to show -t flag values
instead of Makefile targets, and add a note clarifying that the hardcoded
keys in the deploy command are default test keys from fixtures/.
fix the load test progress percentage to be relative to the current round
(not the absolute nonce), make run_round return Result so endless mode
survives individual round failures, remove a duplicate debug log in the
proof coordinator, add bash 4+ note to bench_metrics.sh, and clarify that
LOAD_TEST_RPC_URL must point to the L2 port for benchmarking.
backend that is not in the deployment's required proof types, instead of
silently sending an empty batch response. The prover now logs an error
and surfaces the rejection clearly, rather than endlessly polling for
batches it will never be assigned.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Feb 11, 2026

Lines of code report

Total lines added: 50
Total lines removed: 39
Total lines changed: 89

Detailed view
+-----------------------------------------------+-------+------+
| File                                          | Lines | Diff |
+-----------------------------------------------+-------+------+
| ethrex/crates/guest-program/build.rs          | 199   | +6   |
+-----------------------------------------------+-------+------+
| ethrex/crates/l2/prover/src/backend/error.rs  | 43    | +5   |
+-----------------------------------------------+-------+------+
| ethrex/crates/l2/prover/src/backend/sp1.rs    | 202   | +20  |
+-----------------------------------------------+-------+------+
| ethrex/crates/l2/prover/src/prover.rs         | 246   | +19  |
+-----------------------------------------------+-------+------+
| ethrex/crates/l2/sequencer/l1_proof_sender.rs | 553   | -39  |
+-----------------------------------------------+-------+------+

…dirs).

When the guest program was extracted from crates/l2/ to crates/guest-program/
in PR #5995, the out/ and target/ directories lost coverage from
crates/l2/.gitignore which had a blanket out/ entry. Without this, built
ELF binaries and verification keys show up as untracked files.
@avilagaston9 avilagaston9 changed the base branch from main to bench/prover-tooling February 12, 2026 13:10
avilagaston9 added 4 commits February 12, 2026 10:27
…rmatting

in sp1.rs and l1_proof_sender.rs, and regenerate Cargo.lock. SP1 Hypercube
(v6) introduced a dependency on protobuf-compiler via sp1-prover-types, which
was missing from the GitHub Actions runners.
requiring Rust >1.90.0), update tooling/Cargo.lock to match the base branch,
and automate the substrate-bn sp1-lib version workaround in the Makefile's
check-cargo-lock target so CI can validate the SP1 guest lockfile without
manual cargo cache patching.
(CpuProver / CudaProver) to match the approach used on main. The gpu
feature flag selects the CUDA prover at compile time instead of relying
on the SP1_PROVER environment variable at runtime.
.verifying_key() resolves on the CpuProver's proving key type.
"Cannot start a runtime from within a runtime" panic. The CudaProver
builder internally calls block_on, which conflicts with the prover's
tokio runtime. CpuProver is unaffected. The fix runs once via OnceLock.
avilagaston9 added 2 commits February 12, 2026 15:29
tokio runtime nesting panics. The SP1 v6 blocking SDK uses block_on()
internally for proving, execution, and verification — not just
initialization. Since the prover runs inside a tokio runtime, all
these calls must run on threads without an active runtime.
…kwell) attempt.

The pre-built sp1-gpu-server v6.0.0-rc.1 binary crashes with an AllocError on compute
capability 12.0 GPUs. Report covers three issues encountered (CUDA 12 library mismatch,
CUDA_VISIBLE_DEVICES propagation, and the fatal AllocError), workarounds applied, and
recommendations to use Ampere/Hopper GPUs until SP1 adds Blackwell support.
Base automatically changed from bench/prover-tooling to main February 20, 2026 13:48
avilagaston9 pushed a commit that referenced this pull request Feb 24, 2026
…nces.

The standalone native rollups integration guide is removed since the
implementation details now live in the open PRs (#6186, #6248). The L2
roadmap is updated to reflect current progress: distributed proving is
done (#6158), SP1 Hypercube upgrade is in progress (#6188), native
rollups EXECUTE precompile and L2 PoC are in progress (#6186, #6248),
and custom contract errors are in progress (#6206).
@avilagaston9 avilagaston9 mentioned this pull request Feb 24, 2026
1 task
… patch

tags, Docker tags, CI workflows, and the on-chain verifier contract path. Remove
the three RC-specific workarounds that are no longer needed: the sp1-lib patch
entry (stable semver now resolves correctly), the Makefile cargo-cache patching
for substrate-bn's sp1-lib constraint, and the temporary sp1-contracts PR branch
(v6.0.0 contracts are merged to main). Regenerate all three lockfiles.
@avilagaston9 avilagaston9 changed the title Upgrade SP1 from v5.0.8 (Turbo) to v6.0.0-rc.1 (Hypercube) deps(l2): upgrade SP1 from v5.0.8 (Turbo) to v6.0.0 (Hypercube) Feb 25, 2026
avilagaston9 added 3 commits February 25, 2026 12:23
# Conflicts:
#	crates/l2/prover/src/prover.rs
#	crates/l2/sequencer/proof_coordinator.rs
SP1 v6.0.1 transitive dependencies require Rust 1.91. Also fix duplicate
ProverTypeNotNeeded enum variant and match arm introduced by the merge
with main (both branches added the same variant independently).
@avilagaston9 avilagaston9 changed the title deps(l2): upgrade SP1 from v5.0.8 (Turbo) to v6.0.0 (Hypercube) deps(l2): upgrade SP1 from v5.0.8 (Turbo) to v6.0.1 (Hypercube) Feb 25, 2026
@github-actions github-actions Bot added the L2 Rollup client label Feb 25, 2026
avilagaston9 added 4 commits February 25, 2026 15:23
propagation to satisfy the ethrex-prover crate's strict clippy lints
(expect_used, unwrap_used, panic are all denied). Add BackendError::Initialization
variant for setup failures. Use process::exit(1) for the one-time prover
startup path where recovery is not possible. Pin vergen to 9.0.6 to avoid
a trait mismatch with vergen-git2 1.0.7 caused by vergen-lib version split.
…revious

hash corresponded to Rust 1.90.0 and caused all Nix-based CI jobs (Test, TDX,
Reorg Tests) to fail with a fixed-output derivation hash mismatch.
…ss lines

to satisfy the formatter (sp1.rs:55).
…event

the resolver from upgrading to 9.1.0 which uses vergen-lib 9.1.0, breaking
compatibility with vergen-git2 1.0.7 (which requires vergen-lib 0.1.6).
Without this pin, CI merge refs that re-resolve dependencies hit a trait
mismatch: vergen::Rustc does not implement vergen_lib::entries::Add.
@avilagaston9
Copy link
Copy Markdown
Contributor Author

avilagaston9 commented May 12, 2026

Closed for inactivity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

L2 Rollup client

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant