Skip to content

feat(prover): upgrade SP1 from v5.2.4 to v6.2.0#952

Open
chengwenxi wants to merge 8 commits into
mainfrom
feat/upgrade-sp1-to-v6
Open

feat(prover): upgrade SP1 from v5.2.4 to v6.2.0#952
chengwenxi wants to merge 8 commits into
mainfrom
feat/upgrade-sp1-to-v6

Conversation

@chengwenxi
Copy link
Copy Markdown
Collaborator

@chengwenxi chengwenxi commented May 14, 2026

Summary

  • Upgrade SP1 zkVM dependencies (sp1-sdk, sp1-zkvm, sp1-verifier) from v5.2.4 to v6.2.0
  • Migrate all prover call sites to SP1 v6's fully-async API
  • Update precompile patch tags (k256, p256, bls12_381) to v6.2.0 variants
  • Remove deprecated patches (sha2, sha3, substrate-bn) that are no longer needed in v6

Dependency changes

Package Before After
sp1-sdk / sp1-zkvm / sp1-verifier v5.2.4 v6.2.0
k256 patch patch-k256-13.4-sp1-5.0.0 patch-k256-13.4-sp1-6.2.0
p256 patch patch-p256-13.2-sp1-5.0.0 patch-p256-13.2-sp1-6.2.0
bls12_381 patch branch=main tag=patch-0.8.0-sp1-6.2.0
cfg-if 1.0.0 1.0.4
sha2 / sha3 / bn patches present removed (not needed in v6)

API migration

SP1 v6 moves to a fully-async model. Key changes:

// v5 (sync)
let client = ProverClient::builder().cpu().build();
let (pk, vk) = client.setup(elf);
let (vals, report) = client.execute(elf, &stdin).run()?;
let proof = client.prove(&pk, &stdin).plonk().run()?;
client.verify(&proof, &vk)?;

// v6 (async)
let client = ProverClient::builder().cpu().build().await;
let pk = client.setup(Elf::Static(elf)).await?;
let vk = pk.verifying_key();
let (vals, report) = client.execute(Elf::Static(elf), stdin).await?;
let proof = client.prove(&pk, stdin).plonk().await?;
client.verify(&proof, vk, None)?;
  • BatchProver::default() replaced with BatchProver::new().await
  • Prover::new() in the server queue made async
  • #[tokio::main] added to test host binaries; tokio with macros feature added to their Cargo.toml

Notes

  • protoc (protobuf compiler) is now a build-time requirement for SP1 v6. Install via brew install protobuf on macOS.
  • Cargo.lock updated to resolve transitive dependency conflicts (libc ≥ 0.2.180, rustc_version ≥ 0.4.1).

Test plan

  • cargo check --workspace --features local passes cleanly
  • Run morph-prove binary with --devnet flag to verify execution path
  • Run morph-prove binary with --prove flag to verify proof generation

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Upgraded SP1 SDK to v6.2.0, bumped dependencies, and enabled Tokio features across crates; migrated prover binaries and server to async/await.
  • Tests
    • Converted host and unit tests to async Tokio runtimes and updated test harnesses to async proving/verification.
  • Contracts
    • Updated on-chain verifier contracts and local verifier constants to accept the new proof layout and expanded public-input shape.
  • Documentation
    • README updated for SP1 v6 setup and Docker build instructions.

Review Change Stack

Upgrades the SP1 zkVM dependency across the prover workspace from v5.2.4
to v6.2.0, adapting all call sites to the new fully-async API.

Dependency changes:
- Bump sp1-sdk, sp1-zkvm, sp1-verifier: v5.2.4 → v6.2.0
- Remove sha2/sha3 precompile patches (no longer needed in v6)
- Update k256/p256 elliptic-curves patches to sp1-6.2.0 tags
- Remove substrate-bn patch (package renamed; v6 handles internally)
- Bump cfg-if: 1.0.0 → 1.0.4 (required by SP1 v6 transitive deps)
- Update bls12_381 patch tag to patch-0.8.0-sp1-6.2.0
- Add tokio macros feature to test host crates (needed for async main)

API migration (SP1 v6 is fully async):
- ProverClient::builder().cpu().build() → .build().await
- ProverClient::from_env() → .from_env().await
- prover.setup(&elf) → prover.setup(Elf::Static(elf)).await
  (returns Result<SP1ProvingKey> instead of (pk, vk) tuple;
   vk accessed via pk.verifying_key())
- execute(elf, &stdin).run() → execute(Elf::Static(elf), stdin).await
- prove(&pk, &stdin).plonk().run() → prove(&pk, stdin).plonk().await
- client.verify(&proof, &vk) → client.verify(&proof, vk, None)
- BatchProver::default() replaced with async BatchProver::new().await
- Prover::new() in server queue made async accordingly

Note: protoc (protobuf compiler) is now required to build SP1 v6
(install via `brew install protobuf` on macOS).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@chengwenxi chengwenxi requested a review from a team as a code owner May 14, 2026 06:09
@chengwenxi chengwenxi requested review from secmgt and removed request for a team May 14, 2026 06:09
Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR upgrades on-chain and local PLONK verifier constants and changes SP1 verifier proof parsing: proofs now include exitCode, vkRoot, and nonce, public-inputs expand to five elements, vk root is validated, and Verify is invoked on a shifted proof slice; related verifier constants are updated accordingly.

Changes

Verifier constants and SP1 verify flow

Layer / File(s) Summary
PLONK verifier constant blocks
prover/contracts/src/PlonkVerifier.sol, prover/bin/shadow-prove/contracts/src/libs/PlonkVerifier.sol, contracts/contracts/libraries/verifier/PlonkVerifier.sol
Replaced hardcoded PLONK verifying-key parameter blocks: VK_NB_PUBLIC_INPUTS, VK_DOMAIN_SIZE, VK_INV_DOMAIN_SIZE, VK_OMEGA, commitment coordinates (VK_QL_COM..VK_QK_COM), SRS VK_S1/S2/S3 constants, VK_QCP_0, and VK_INDEX_COMMIT_API_0.
SP1Verifier: proof parsing, inputs, and vk root checks
contracts/contracts/libraries/verifier/SP1VerifierPlonk.sol, prover/contracts/src/SP1VerifierPlonk.sol, prover/bin/shadow-prove/contracts/src/libs/SP1VerifierPlonk.sol
Adds errors InvalidExitCode/InvalidVkRoot, updates VERSION() and VERIFIER_HASH(), implements VK_ROOT(), parses exitCode, vkRoot, nonce from proofBytes, requires exitCode == 0 and vkRoot == VK_ROOT(), expands inputs from 2→5, and forwards proofBytes[100:] to this.Verify.

Sequence Diagram

sequenceDiagram
  participant Caller
  participant SP1Verifier
  participant PlonkVerifier
  Caller->>SP1Verifier: verifyProof(programVKey, publicValues, proofBytes)
  SP1Verifier->>SP1Verifier: parse exitCode, vkRoot, nonce, publicValuesDigest
  SP1Verifier->>SP1Verifier: require(exitCode == 0) / require(vkRoot == VK_ROOT())
  SP1Verifier->>PlonkVerifier: this.Verify(proofBytes[100:], inputs[5])
  PlonkVerifier-->>SP1Verifier: verification result
  SP1Verifier-->>Caller: valid/invalid or revert with InvalidExitCode/InvalidVkRoot/InvalidProof
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • morph-l2/morph#819: Updates the same programVkey fields in deployment configs.
  • morph-l2/morph#895: Also changes programVkey values across deploy-config files.
  • morph-l2/morph#821: Overlaps on server queue/proof processing changes related to prover initialization and proving loop.

Suggested reviewers

  • Web3Jumb0
  • anylots

Poem

🐰 Hopping through bytes and a verifier's song,

I parse exit codes and check vk roots strong,
Five inputs now dance where once there were two,
Proofs slice forward, contracts sing anew,
Tiny paws applaud — the on-chain hops along.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the main objective: upgrading SP1 from v5.2.4 to v6.2.0, which is the primary change across the codebase.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/upgrade-sp1-to-v6

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@prover/bin/host/src/lib.rs`:
- Around line 41-42: BatchProver::new currently panics via expect during prover
initialization; change its signature from pub async fn new() -> Self to pub
async fn new() -> Result<Self, E> (choose an appropriate error type or Box<dyn
Error>) and remove all expect calls around creating prover_client and the
subsequent initialization (the blocks that create/await prover_client and the
later 56-61 expect usages); instead propagate errors using ? (or map_err to your
chosen error) so callers can handle/retry, and update any call sites to handle
the Result. Ensure you reference and modify the prover_client construction and
any other expect-wrapped operations inside BatchProver::new to return errors
rather than panic.

In `@prover/bin/server/src/server.rs`:
- Line 90: The current startup unconditionally unwraps
Prover::new(Arc::clone(&PROVE_QUEUE)).await which will panic on failure; change
this to handle the Result from Prover::new instead of unwrap: call
Prover::new(...).await, match or if let Err(e) for the error case, log the error
with the app logger (e.g., tracing::error or processLogger) including the error
details and then follow a controlled failure path (exit with a non-zero code or
trigger a retry/backoff loop) and on Ok(p) assign to the mutable prover
variable; reference symbols: Prover::new, PROVE_QUEUE, and the prover binding so
you can locate and replace the unwrap.

In `@prover/tests/algebra/host/src/main.rs`:
- Around line 77-88: The test test_verify_plonk currently builds keys but never
asserts proof validity; update the test to produce a proof and call the verifier
using the generated proving key/verification key: after creating client and pk
(via ProverClient::from_env().await and
client.setup(Elf::Static(dev_elf)).await.unwrap()) use the prover API to create
a proof (e.g., call the method that generates a proof using pk or a Prover
struct), then call the verification method with vk (pk.verifying_key()) or the
client.verify API and assert the result is true (or unwrap/expect on
verification success) so the test fails when proofs are invalid. Ensure the new
calls are awaited and any errors are unwrapped/expect()-ed to fail the test on
invalid proofs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0d49c927-665b-470b-8692-b1d8fa0e602f

📥 Commits

Reviewing files that changed from the base of the PR and between 58c70f9 and ce1e59a.

⛔ Files ignored due to path filters (1)
  • prover/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (16)
  • prover/Cargo.toml
  • prover/bin/host/Cargo.toml
  • prover/bin/host/src/lib.rs
  • prover/bin/host/src/main.rs
  • prover/bin/host/src/vkey.rs
  • prover/bin/server/src/queue.rs
  • prover/bin/server/src/server.rs
  • prover/tests/algebra/host/Cargo.toml
  • prover/tests/algebra/host/src/main.rs
  • prover/tests/bls12381/client/Cargo.toml
  • prover/tests/bls12381/host/Cargo.toml
  • prover/tests/bls12381/host/src/main.rs
  • prover/tests/keccak256/host/Cargo.toml
  • prover/tests/keccak256/host/src/main.rs
  • prover/tests/zstd/host/Cargo.toml
  • prover/tests/zstd/host/src/main.rs

Comment thread prover/bin/host/src/lib.rs Outdated
Comment thread prover/bin/server/src/server.rs Outdated
Comment thread prover/tests/algebra/host/src/main.rs
@chengwenxi chengwenxi requested a review from anylots May 14, 2026 06:43
chengwenxi and others added 7 commits May 14, 2026 15:34
… 0.60.14

- Forward `network` feature to `sp1-sdk/network` so NetworkProver and
  NetworkMode are compiled in when the feature is active
- Downgrade aws-smithy-xml from 0.60.15 to 0.60.14 to support rustc 1.91.0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolves CI fmt failure and CodeRabbit review comments on PR #952.

- Fix fmt: regroup imports and inline prove() chain in lib.rs per
  cargo fmt --all --check rules
- BatchProver::new returns Result<Self, anyhow::Error> instead of
  panicking on setup failure; propagate error in queue.rs and main.rs
- start_prover handles Prover::new failure by logging and setting
  PROVE_RESULT=2 instead of unwrapping
- test_verify_plonk now actually calls client.verify so a broken proof
  fails the test
- Add missing Prover trait import in lib.rs test module
- Rebuild verifier-client ELF with succinct-1.91.1-64bit-v2 toolchain;
  SP1 v6 emits riscv64im. README updated with the toolchain install step.
Update programVkey across all deploy-config networks to match the
verifier-client ELF rebuilt with the succinct-1.91.1-64bit-v2 toolchain
in PR #952. New vkey:
0x00e1bd337c1856e13c8213d0ff3f176cbe3225298140cf6bda0fd0861e9d90d4
SP1 SDK v6 changes the plonk proof byte layout: it adds a 32-byte
exit_code, 32-byte vk_root, and 32-byte proof_nonce after the 4-byte
verifier-hash prefix. The v5.0.0 verifier reads only [4:] as the gnark
proof and would reject every v6 proof.

Pulls SP1VerifierPlonk.sol and PlonkVerifier.sol from
succinctlabs/sp1-contracts at tag v6.1.0 (the latest contract release;
SP1 SDK v6.2.0 ships the same plonk_vk.bin as v6.1.0, so no v6.2.0
contract was published) into:
- contracts/contracts/libraries/verifier/  (pragma =0.8.24)
- prover/contracts/src/                    (pragma ^0.8.20)
- prover/bin/shadow-prove/contracts/src/libs/  (pragma ^0.8.20)

New SP1VerifierPlonk.VERIFIER_HASH:
0x5a093a2fcb46394f5cadfe55c44d4d572fad9cec7aeb38026b0278322ef07fac
New SP1VerifierPlonk.VK_ROOT:
0x002f850ee998974d6cc00e50cd0814b098c05bfade466d28573240d057f25352

ISP1Verifier.verifyProof signature is unchanged, so ZkEvmVerifierV1 and
its callers do not need updates.
The committed plonk-fixture.json was a v5.0.0 PLONK proof with selector
0xd4e8ecd2; after upgrading SP1Verifier to v6.1.0 (selector 0x5a093a2f)
the v5 proof fails the WrongVerifierSelector check.

- Replace fixture with a real v6.1.0 PLONK proof published by
  yx-xyc/zk-solvency. publicValues is no longer guaranteed to be 32
  bytes for arbitrary SP1 programs, so widen the test struct field from
  bytes32 to bytes.
- testRevert_InValidProof: corrupt byte 200 (inside the gnark proof body)
  instead of byte 31 (which lives in the all-zero exit_code field in v6
  and would not actually invalidate the proof).
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.

2 participants