Skip to content

feat(sp1): upgrade to SP1 v6.0.0 (Hypercube)#798

Open
fakedev9999 wants to merge 39 commits intomainfrom
fakedev9999/prover-mainnet-ready
Open

feat(sp1): upgrade to SP1 v6.0.0 (Hypercube)#798
fakedev9999 wants to merge 39 commits intomainfrom
fakedev9999/prover-mainnet-ready

Conversation

@fakedev9999
Copy link
Member

@fakedev9999 fakedev9999 commented Feb 5, 2026

Summary

Upgrades SP1 from v5.2.4 to v6.0.0 (Hypercube) across the entire op-succinct stack.

Dependency changes

  • SP1 crates: =5.2.46.0.0 (sp1-sdk, sp1-lib, sp1-zkvm, sp1-build, sp1-prover, sp1-core-executor) + new crates sp1-hypercube, sp1-primitives
  • sp1-sdk features: added blocking (for CpuProver execution outside async context), profiling features
  • sp1-patches: all patch tags updated from sp1-4.0.0/sp1-5.0.0sp1-6.0.0 (sha2, sha3, substrate-bn, p256, k256, tiny-keccak)
  • kzg-rs: 0.2.60.2.8 (from crates.io, uses sp1_bls12_381 v0.8.0-sp1-6.0.0)
  • hokulea: Layr-Labs/hokulea tag v1.1.4fakedev9999/hokulea branch fakedev9999/bump-sp1-v6 (SP1 v6 compatible fork with rebuilt ELF + updated vkey)
  • reth patches: removed unused reth-optimism-* and reth-chain-state patches from Cargo.lock
  • rust-toolchain: nightly-2025-08-02nightly-2025-09-15 (SP1 v6 requires duration_constructors_lite unstable feature)

SP1 v6 API migration

  • ProverClient::builder().build().build().await (async)
  • prover.setup(elf_bytes)prover.setup(Elf::Static(elf_bytes)).await (returns ProvingKey, vkey accessed via pk.verifying_key() instead of tuple destructuring)
  • prover.prove(pk, &stdin)prover.prove(pk, &stdin).await
  • SP1Stdin::new()SP1Stdin::default(), stdin now owned (not borrowed)
  • load_aggregation_proof_data changed from sync to async
  • Removed embedded feature from zkVM program crates (no longer needed in v6)
  • Removed range-elf-bump ELF variant (v6 no longer needs separate bump allocator build)
  • SP1 local execution uses sp1_sdk::blocking::CpuProver with tokio::task::spawn_blocking to avoid nested tokio runtime panics (CpuProver creates its own internal tokio runtime)

CI & Docker

  • All Dockerfiles: pin sp1up -v v6.0.0, add protobuf-compiler (new SP1 v6 build dependency)
  • CI workflows: unpinned sp1up version (v6 is now the default release), added protobuf-compiler install step
  • CI setup actions: add protobuf-compiler install step
  • justfile: --tag v5.2.4--tag v6.0.0, removed --features embedded flags

ELF binaries

  • Rebuilt all ELF binaries with SP1 v6 toolchain (range, celestia-range, eigenda-range, aggregation)

Upstream PRs

Test plan

  • cargo check --workspace passes
  • CI passes
  • Range proof generation works with SP1 v6 network prover
  • Aggregation proof generation works

BREAKING CHANGE: SP1 SDK v6.0.0-beta.1 introduces significant API changes

## SDK Changes
- Upgraded sp1-sdk from v5.2.4 to v6.0.0-beta.1

## API Migration

### Async Prover Building
- `ProverClient::builder()...build()` now returns a `Future` requiring `.await`
- All prover client instantiation updated across codebase

### ELF Handling
- Raw `&[u8]` ELF bytes must now be wrapped in `Elf::Static()`
- Updated all `setup()` and `execute()` calls

### Setup Method Changes
- `setup()` now returns `Result<SP1ProvingKey>` instead of tuple `(ProvingKey, VerifyingKey)`
- Use `pk.verifying_key().clone()` to get the verifying key

### Trait Requirements
- Added `ProvingKey` trait import for `.verifying_key()` method
- Added `ProveRequest` trait import for `.compressed()`, `.mode()`, `.strategy()`
- Added `Prover` trait import for `.execute()` method

### Prove Method Changes
- `prove()` now takes `SP1Stdin` by value, not by reference

### Async vs Blocking Execution
- Async prover: use `.await` directly (IntoFuture pattern, no `.run()`)
- Blocking prover: use `sp1_sdk::blocking::CpuProver` with `.run()` for sync contexts (e.g., rayon parallel iterators)

### Verification Changes
- `verify()` now takes 3 arguments (third is `Option<StatusCode>`)

### Network Prover Changes
- `request_async()` renamed to `request()`
- `.run().await` pattern changed to direct `.await`

### Report API Changes
- `report.gas` field changed to `report.gas()` method

## Cleanup
- Removed 10 unused reth patches from Cargo.toml to eliminate build warnings
SP1 v6.0.0-beta.1 introduced a dependency on Protocol Buffers in the
sp1-prover-types crate. This requires protoc to be installed during
the build process.

Changes:
- Added protobuf-compiler to all Dockerfiles (validity, fault-proof)
- Added protobuf-compiler to GitHub Actions workflows:
  - .github/actions/setup/action.yml (shared action)
  - .github/actions/setup-e2e-sysgo/action.yml (e2e tests)
  - .github/workflows/cargo-tests.yml
  - .github/workflows/elf.yml
  - .github/workflows/integration-tests.yml
  - .github/workflows/lint.yml
- Restore embedded = ["sp1-zkvm/embedded"] feature in range program
  Cargo.toml files that was accidentally removed during SP1 v6 upgrade
- Fix "Cannot start a runtime from within a runtime" error in
  cost_estimator.rs by wrapping parallel execution in spawn_blocking
In SP1 v6, the embedded allocator is now the default (previously bump).
- Replace `embedded = ["sp1-zkvm/embedded"]` with `bump = ["sp1-zkvm/bump"]`
- Update justfile ELF build commands to use v6.0.0-beta.1 tag
- Remove --features embedded (now default) from embedded ELF builds
- Add --features bump for the bump allocator ELF build
Switch SP1 dependencies from git sources to crates.io to match hokulea's
dependency resolution. This eliminates the duplicate `koalabear*` symbols
that occurred when both git and crates.io versions of sp1-recursion-gnark-ffi
were linked together.

Changes:
- Update sp1-sdk, sp1-lib, sp1-zkvm, sp1-build, sp1-prover, sp1-core-executor
  to use crates.io version "6.0.0-beta.1" instead of git tag
- Remove sp1-lib and sp1-zkvm patches from [patch.crates-io] section
- Refresh Cargo.lock to consolidate SP1 packages to single source
Pin sp1up to specific version matching SP1 v6 crate dependency.
Without version pinning, CI could install incompatible toolchain versions.
@fakedev9999 fakedev9999 force-pushed the fakedev9999/prover-mainnet-ready branch from d3269d4 to 27ae0ba Compare February 5, 2026 11:40
@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

Performance Comparison (ELF: eigenda-range-elf-embedded)

Range 1782104~1782109

Metric Base Branch Current PR Diff (%)
Total Instructions 746551545 606325818 -18.78%
Oracle Verify Cycles 76799603 70409507 -8.32%
Derivation Cycles 495592611 441715263 -10.87%
Block Execution Cycles 6831862 6456173 -5.50%
Blob Verification Cycles 728 633 -13.05%
Total SP1 Gas 1217338830 922425532 -24.23%
Cycles per Block 149310309 121265163 -18.78%
Cycles per Transaction 149310309 121265163 -18.78%
BN Pair Cycles 0 0 0.00%
BN Add Cycles 0 0 0.00%
BN Mul Cycles 0 0 0.00%
KZG Eval Cycles 0 0 0.00%
EC Recover Cycles 0 0 0.00%
P256 Verify Cycles 0 0 0.00%

- Update all SP1 crate versions to 6.0.0-rc.1
- Update hokulea branch refs to fakedev9999/bump-sp1-v6-rc1
- Update sp1-patches tags and kzg-rs branch to rc.1
- Pin sp1up to v6.0.0-rc.1 in all CI workflows (5 files)
- Pin sp1up to v6.0.0-rc.1 in all Dockerfiles (7 files)
- Update justfile docker build tags to v6.0.0-rc.1
- Add package = "substrate-bn-succinct-rs" for renamed bn patch

Note: Cargo.lock update pending - SP1 rc.1 crates not yet
published to crates.io.
SP1 6.0.0-rc.1 crates are not yet published to crates.io.
Switch all 6 SP1 workspace deps to git tag source to avoid
duplicate symbol linker errors from mixed sources.
Embedded is now the default allocator in SP1 v6 (Hypercube) and the bump
allocator was never consumed anywhere in the codebase. Remove the bump
feature flag, ELF binary, and build command to reduce maintenance burden.
Patched crypto crates (k256, p256, etc.) depend on sp1-lib ^6.0.0-rc.1
from crates.io, but rc.1 isn't published there yet. Adding sp1-lib to
[patch.crates-io] redirects the lookup to the SP1 git repo.
- Move CpuProver::new() inside spawn_blocking in cost_estimator to
  avoid creating a nested tokio runtime (SP1 v6 CpuProver creates its
  own runtime internally)
- Switch cycle-count-diff execute_multi from async ProverClient to
  blocking CpuProver wrapped in spawn_blocking for the same reason
- Add protobuf-compiler installation to sqlx-check workflow (sp1-prover-types
  requires protoc for prost codegen)
- Add sp1-hypercube and sp1-primitives deps for eigenda witness generator
  proof deserialization refactor
…tokio runtime

SP1 v6's blocking ProverClient creates its own internal tokio runtime.
When get_sp1_stdin is called from an async context (e.g. #[tokio::test]),
this causes "Cannot start a runtime from within a runtime" panics,
failing both da-integration-tests and cycle-count-diff-eigenda CI.
sp1-lib 6.0.0-rc.1 is now available on crates.io, so the git redirect
patch is no longer needed.
Cargo.toml Outdated
p256 = { git = "https://github.com/sp1-patches/elliptic-curves", tag = "patch-p256-13.2-sp1-6.0.0-rc.1" }
k256 = { git = "https://github.com/sp1-patches/elliptic-curves", tag = "patch-k256-13.4-sp1-6.0.0-rc.1" }
tiny-keccak = { git = "https://github.com/sp1-patches/tiny-keccak", tag = "patch-2.0.2-sp1-6.0.0-rc.1" }
kzg-rs = { git = "https://github.com/succinctlabs/kzg-rs", branch = "fakedev9999/patch-6.0.0-rc.1" }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove patch once merged and bump kzg-rs crate directly.

fakedev9999 added a commit that referenced this pull request Feb 6, 2026
Backport of PR #798 from main into release/v3.x.

## SP1 v6.0.0-rc.1 API Changes
- Async prover building: `ProverClient::builder().build()` → `.build().await`
- ELF wrapping: raw `&[u8]` → `Elf::Static(bytes)`
- Setup return type: `(PK, VK)` → `Result<SP1ProvingKey>`, use `pk.verifying_key().clone()`
- Prove by value: `prove(&pk, &stdin)` → `prove(&pk, stdin)` (stdin moved)
- Async execution: `.run()` → `.await`
- Verification: `verify(proof, &vk)` → `verify(proof, &vk, None)` (3rd arg)
- Network prover: `request_async()` → `request()`, `.run().await` → `.await`
- Report API: `report.gas` → `report.gas()`
- New trait imports: `Elf`, `Prover`, `ProveRequest`, `ProvingKey`
- Blocking prover: `sp1_sdk::blocking::CpuProver` for sync contexts (rayon)

## Other Changes
- Updated hokulea deps to SP1 v6-compatible branch
- Updated sp1-patches to rc.1 tags
- Added kzg-rs patch for rc.1 compatibility
- Added protobuf-compiler to all Dockerfiles and CI workflows
- Pinned sp1up to v6.0.0-rc.1 in CI and Dockerfiles
- Removed unused bump allocator ELF and feature
- Removed unused reth patches
- Added sp1-hypercube and sp1-primitives deps for eigenda witness generator
@fakedev9999 fakedev9999 changed the title feat(sp1): upgrade to SP1 v6.0.0-beta.1 (Hypercube) feat(sp1): upgrade to SP1 v6.0.0-rc.1 (Hypercube) Feb 6, 2026
Bump SP1 dependency chain from v6.0.0-rc.1 to v6.0.0 final release:
- SP1 crate versions 6.0.0-rc.1 → 6.0.0
- sp1-patches tags updated to 6.0.0
- kzg-rs branch updated to fakedev9999/patch-6.0.0
- hokulea branch updated to fakedev9999/bump-sp1-v6
- sp1up installer version in CI workflows and Dockerfiles
- cargo-prove --tag in justfile build commands
- rust-toolchain bumped to nightly-2025-09-15 for SP1 v6.0.0 compat
@fakedev9999 fakedev9999 force-pushed the fakedev9999/prover-mainnet-ready branch from de1c0e6 to 3981d37 Compare February 15, 2026 14:14
@fakedev9999 fakedev9999 changed the title feat(sp1): upgrade to SP1 v6.0.0-rc.1 (Hypercube) feat(sp1): upgrade to SP1 v6.0.0 (Hypercube) Feb 15, 2026
The fakedev9999/patch-6.0.0 branch was merged to master via kzg-rs#29,
so the branch specifier is no longer needed.
Remove git override for kzg-rs now that 0.2.8 (with sp1_bls12_381
v0.8.0-sp1-6.0.0 from crates.io) has been published.
Pick up kzg-rs 0.2.8 from crates.io transitively via hokulea, rsp,
and sp1-contract-call updates.
…time

The blocking::CpuProver creates its own internal tokio runtime, which
can panic when called from within an existing tokio context. Reuse the
async ProverClient already created in main() for proof verification.
Picks up CI fixes (MSRV 1.91, ELF rebuilt for v6.0.0 final,
clippy 1.91 lints, stale RC/beta tag cleanup).
- Change `prover` parameter type from `&ProverClient` to `&impl Prover`
  since `ProverClient::from_env()` now returns `EnvProver`
- Remove `.await` from `prover.verify()` which is synchronous in SP1 v6
The sp1-patches/bn repo at tag patch-0.6.0-sp1-6.0.0 renamed the
package to substrate-bn-succinct-rs, which breaks Cargo's patch
mechanism (replacement must have the same package name as the original).

Use new tag patch-0.6.0-sp1-6.0.0-substrate-bn which has the correct
package name "substrate-bn", allowing [patch.crates-io] to properly
replace the transitive crates.io dependency used by revm-precompile.

This fixes the ~18x BN254 pairing cycle blowup (21.4M vs 1.18M
cycles/pairing) caused by guest programs running pure-software field
arithmetic instead of SP1 precompile syscalls.
hokulea bump-sp1-v6 added a boot_info parameter to extract l1_head
and l1_chain_id for EigenDAWitnessWithTrustedData construction.
Resolve ELF conflicts by keeping the rebuilt ELFs with the
substrate-bn patch fix applied.
…n-patch

fix: use correct substrate-bn package name in [patch.crates-io]
Merge main's v4.0.2 release and fault-proof backward compat fix
(l2BlockNumber) into the SP1 v6 upgrade branch.

Conflict resolution: all SP1 version pins resolved in favor of
branch's unpinned sp1up (v6 default). range-elf-bump deleted as
SP1 v6 uses embedded allocator by default. ELFs kept as branch's
SP1 v6 compiled versions (need rebuild to include fault-proof fix).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments