From b478609435907ef3d1cf271fd2afbdab6b997531 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= <3535019+leruaa@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:07:48 -0800 Subject: [PATCH] feat: clean up NetworkProver environment variables (#1790) --- crates/perf/src/main.rs | 35 +++-- crates/prover/src/types.rs | 11 ++ crates/sdk/src/lib.rs | 200 ++++++++++++++++++++++++---- crates/sdk/src/network-v2/client.rs | 19 ++- crates/sdk/src/network-v2/prover.rs | 36 ++--- crates/sdk/src/network/client.rs | 19 +-- crates/sdk/src/network/prover.rs | 43 +++--- 7 files changed, 262 insertions(+), 101 deletions(-) diff --git a/crates/perf/src/main.rs b/crates/perf/src/main.rs index df53c04bf3..31a34c52ed 100644 --- a/crates/perf/src/main.rs +++ b/crates/perf/src/main.rs @@ -1,9 +1,12 @@ -use std::time::{Duration, Instant}; +use std::{ + env, + time::{Duration, Instant}, +}; -use clap::{command, Parser, ValueEnum}; +use clap::{command, Parser}; use sp1_cuda::SP1CudaProver; -use sp1_prover::components::DefaultProverComponents; use sp1_prover::HashableKey; +use sp1_prover::{components::DefaultProverComponents, ProverMode}; use sp1_sdk::{self, ProverClient, SP1Context, SP1Prover, SP1Stdin}; use sp1_stark::SP1ProverOpts; use test_artifacts::VERIFY_PROOF_ELF; @@ -34,13 +37,6 @@ struct PerfResult { pub verify_wrap_duration: Duration, } -#[derive(Debug, Clone, ValueEnum, PartialEq, Eq)] -enum ProverMode { - Cpu, - Cuda, - Network, -} - pub fn time_operation T>(operation: F) -> (T, std::time::Duration) { let start = Instant::now(); let result = operation(); @@ -180,7 +176,23 @@ fn main() { println!("{:?}", result); } ProverMode::Network => { - let prover = ProverClient::network(); + let private_key = env::var("SP1_PRIVATE_KEY") + .expect("SP1_PRIVATE_KEY must be set for remote proving"); + let rpc_url = env::var("PROVER_NETWORK_RPC").ok(); + let skip_simulation = + env::var("SKIP_SIMULATION").map(|val| val == "true").unwrap_or_default(); + + let mut prover_builder = ProverClient::builder().mode(ProverMode::Network); + + if let Some(rpc_url) = rpc_url { + prover_builder = prover_builder.rpc_url(rpc_url); + } + + if skip_simulation { + prover_builder = prover_builder.skip_simulation(); + } + + let prover = prover_builder.private_key(private_key).build(); let (_, _) = time_operation(|| prover.execute(&elf, stdin.clone())); let (proof, _) = @@ -192,5 +204,6 @@ fn main() { let (_, _) = time_operation(|| prover.verify(&proof, &vk)); } + ProverMode::Mock => unreachable!(), }; } diff --git a/crates/prover/src/types.rs b/crates/prover/src/types.rs index dfebfb6c83..b4e362e0fc 100644 --- a/crates/prover/src/types.rs +++ b/crates/prover/src/types.rs @@ -1,6 +1,7 @@ use std::{fs::File, path::Path}; use anyhow::Result; +use clap::ValueEnum; use p3_baby_bear::BabyBear; use p3_bn254_fr::Bn254Fr; use p3_commit::{Pcs, TwoAdicMultiplicativeCoset}; @@ -183,6 +184,16 @@ impl SP1Bn254ProofData { } } +#[derive(Debug, Default, Clone, ValueEnum, PartialEq, Eq)] +pub enum ProverMode { + #[default] + Cpu, + Cuda, + Network, + #[value(skip)] + Mock, +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ProofSystem { Plonk, diff --git a/crates/sdk/src/lib.rs b/crates/sdk/src/lib.rs index 615f36ff0e..6ea715daf7 100644 --- a/crates/sdk/src/lib.rs +++ b/crates/sdk/src/lib.rs @@ -13,6 +13,9 @@ pub mod network; #[cfg(feature = "network-v2")] #[path = "network-v2/mod.rs"] pub mod network_v2; + +use std::env; + #[cfg(feature = "network")] pub use crate::network::prover::NetworkProver as NetworkProverV1; #[cfg(feature = "network-v2")] @@ -31,8 +34,6 @@ pub use proof::*; pub use provers::SP1VerificationError; use sp1_prover::components::DefaultProverComponents; -use std::env; - #[cfg(any(feature = "network", feature = "network-v2"))] use {std::future::Future, tokio::task::block_in_place}; @@ -43,7 +44,7 @@ pub use sp1_core_executor::{ExecutionReport, HookEnv, SP1Context, SP1ContextBuil pub use sp1_core_machine::{io::SP1Stdin, riscv::cost::CostEstimator, SP1_CIRCUIT_VERSION}; pub use sp1_primitives::io::SP1PublicValues; pub use sp1_prover::{ - CoreSC, HashableKey, InnerSC, OuterSC, PlonkBn254Proof, SP1Prover, SP1ProvingKey, + CoreSC, HashableKey, InnerSC, OuterSC, PlonkBn254Proof, ProverMode, SP1Prover, SP1ProvingKey, SP1VerifyingKey, }; @@ -85,14 +86,20 @@ impl ProverClient { } } "network" => { + let private_key = env::var("SP1_PRIVATE_KEY") + .expect("SP1_PRIVATE_KEY must be set for remote proving"); + let rpc_url = env::var("PROVER_NETWORK_RPC").ok(); + let skip_simulation = + env::var("SKIP_SIMULATION").map(|val| val == "true").unwrap_or_default(); + cfg_if! { if #[cfg(feature = "network-v2")] { Self { - prover: Box::new(NetworkProverV2::new()), + prover: Box::new(NetworkProverV2::new(&private_key, rpc_url, skip_simulation)), } } else if #[cfg(feature = "network")] { Self { - prover: Box::new(NetworkProverV1::new()), + prover: Box::new(NetworkProverV1::new(&private_key, rpc_url, skip_simulation)), } } else { panic!("network feature is not enabled") @@ -105,11 +112,13 @@ impl ProverClient { } } + /// Returns a [ProverClientBuilder] to easily create a [ProverClient]. + pub fn builder() -> ProverClientBuilder { + ProverClientBuilder::default() + } + /// Creates a new [ProverClient] with the mock prover. /// - /// Recommended for testing and development. You can also use [ProverClient::new] to set the - /// prover to `mock` with the `SP1_PROVER` environment variable. - /// /// ### Examples /// /// ```no_run @@ -121,10 +130,7 @@ impl ProverClient { Self { prover: Box::new(MockProver::new()) } } - /// Creates a new [ProverClient] with the local prover. - /// - /// Recommended for proving end-to-end locally. You can also use [ProverClient::new] to set the - /// prover to `local` with the `SP1_PROVER` environment variable. + /// Creates a new [ProverClient] with the local prover, using the CPU. /// /// ### Examples /// @@ -133,31 +139,61 @@ impl ProverClient { /// /// let client = ProverClient::local(); /// ``` + #[deprecated(note = "Please use `cpu` instead")] pub fn local() -> Self { Self { prover: Box::new(CpuProver::new()) } } - /// Creates a new [ProverClient] with the network prover. + /// Creates a new [ProverClient] with the local prover, using the CPU. + /// + /// ### Examples + /// + /// ```no_run + /// use sp1_sdk::ProverClient; /// - /// Recommended for outsourcing proof generation to an RPC. You can also use [ProverClient::new] - /// to set the prover to `network` with the `SP1_PROVER` environment variable. + /// let client = ProverClient::cpu(); + /// ``` + pub fn cpu() -> Self { + Self { prover: Box::new(CpuProver::new()) } + } + + /// Creates a new [ProverClient] with the local prover, using the GPU. /// /// ### Examples /// /// ```no_run /// use sp1_sdk::ProverClient; /// - /// let client = ProverClient::network(); + /// let client = ProverClient::cuda(); /// ``` - pub fn network() -> Self { + #[cfg(feature = "cuda")] + pub fn cuda() -> Self { + Self { prover: Box::new(CudaProver::new(SP1Prover::new())) } + } + + /// Creates a new [ProverClient] with the network prover. + /// + /// ### Examples + /// + /// ```no_run + /// use sp1_sdk::ProverClient; + /// + /// let private_key = std::env::var("SP1_PRIVATE_KEY").unwrap(); + /// let rpc_url = std::env::var("PROVER_NETWORK_RPC").ok(); + /// let skip_simulation = + /// std::env::var("SKIP_SIMULATION").map(|val| val == "true").unwrap_or_default(); + /// + /// let client = ProverClient::network(private_key, rpc_url, skip_simulation); + /// ``` + pub fn network(private_key: String, rpc_url: Option, skip_simulation: bool) -> Self { cfg_if! { if #[cfg(feature = "network-v2")] { Self { - prover: Box::new(NetworkProverV2::new()), + prover: Box::new(NetworkProverV2::new(&private_key, rpc_url, skip_simulation)), } } else if #[cfg(feature = "network")] { Self { - prover: Box::new(NetworkProverV1::new()), + prover: Box::new(NetworkProverV1::new(&private_key, rpc_url, skip_simulation)), } } else { panic!("network feature is not enabled") @@ -283,6 +319,120 @@ impl Default for ProverClient { } } +/// Builder type for [`ProverClient`]. +#[derive(Debug, Default)] +pub struct ProverClientBuilder { + mode: Option, + private_key: Option, + rpc_url: Option, + skip_simulation: bool, +} + +impl ProverClientBuilder { + /// Sets the mode of the prover client being created. + pub fn mode(mut self, mode: ProverMode) -> Self { + self.mode = Some(mode); + self + } + + /// Sets the private key. + pub fn private_key(mut self, private_key: String) -> Self { + self.private_key = Some(private_key); + self + } + + /// Sets the RPC URL. + pub fn rpc_url(mut self, rpc_url: String) -> Self { + self.rpc_url = Some(rpc_url); + self + } + + /// Skips simulation. + pub fn skip_simulation(mut self) -> Self { + self.skip_simulation = true; + self + } + + /// Builds a [ProverClient], using the provided private key. + pub fn build(self) -> ProverClient { + match self.mode.expect("The prover mode is required") { + ProverMode::Cpu => ProverClient::cpu(), + ProverMode::Cuda => { + cfg_if! { + if #[cfg(feature = "cuda")] { + ProverClient::cuda() + } else { + panic!("cuda feature is not enabled") + } + } + } + ProverMode::Network => { + let private_key = self.private_key.expect("The private key is required"); + + cfg_if! { + if #[cfg(feature = "network-v2")] { + ProverClient { + prover: Box::new(NetworkProverV2::new(&private_key, self.rpc_url, self.skip_simulation)), + } + } else if #[cfg(feature = "network")] { + ProverClient { + prover: Box::new(NetworkProverV1::new(&private_key, self.rpc_url, self.skip_simulation)), + } + } else { + panic!("network feature is not enabled") + } + } + } + ProverMode::Mock => ProverClient::mock(), + } + } +} + +/// Builder type for network prover. +#[cfg(any(feature = "network", feature = "network-v2"))] +#[derive(Debug, Default)] +pub struct NetworkProverBuilder { + private_key: Option, + rpc_url: Option, + skip_simulation: bool, +} + +impl NetworkProverBuilder { + /// Sets the private key. + pub fn private_key(mut self, private_key: String) -> Self { + self.private_key = Some(private_key); + self + } + + /// Sets the RPC URL. + pub fn rpc_url(mut self, rpc_url: String) -> Self { + self.rpc_url = Some(rpc_url); + self + } + + /// Skips simulation. + pub fn skip_simulation(mut self) -> Self { + self.skip_simulation = true; + self + } + + /// Creates a new [NetworkProverV1]. + #[cfg(feature = "network")] + pub fn build(self) -> NetworkProverV1 { + let private_key = self.private_key.expect("The private key is required"); + + NetworkProverV1::new(&private_key, self.rpc_url, self.skip_simulation) + } + + /// Creates a new [NetworkProverV2]. + #[cfg(feature = "network-v2")] + pub fn build_v2(self) -> NetworkProverV2 { + let private_key = self.private_key.expect("The private key is required"); + + NetworkProverV2::new(&private_key, self.rpc_url, self.skip_simulation) + } +} + /// Utility method for blocking on an async function. /// /// If we're already in a tokio runtime, we'll block in place. Otherwise, we'll create a new @@ -309,7 +459,7 @@ mod tests { #[test] fn test_execute() { utils::setup_logger(); - let client = ProverClient::local(); + let client = ProverClient::cpu(); let elf = test_artifacts::FIBONACCI_ELF; let mut stdin = SP1Stdin::new(); stdin.write(&10usize); @@ -321,7 +471,7 @@ mod tests { #[should_panic] fn test_execute_panic() { utils::setup_logger(); - let client = ProverClient::local(); + let client = ProverClient::cpu(); let elf = test_artifacts::PANIC_ELF; let mut stdin = SP1Stdin::new(); stdin.write(&10usize); @@ -332,7 +482,7 @@ mod tests { #[test] fn test_cycle_limit_fail() { utils::setup_logger(); - let client = ProverClient::local(); + let client = ProverClient::cpu(); let elf = test_artifacts::PANIC_ELF; let mut stdin = SP1Stdin::new(); stdin.write(&10usize); @@ -342,7 +492,7 @@ mod tests { #[test] fn test_e2e_core() { utils::setup_logger(); - let client = ProverClient::local(); + let client = ProverClient::cpu(); let elf = test_artifacts::FIBONACCI_ELF; let (pk, vk) = client.setup(elf); let mut stdin = SP1Stdin::new(); @@ -362,7 +512,7 @@ mod tests { #[test] fn test_e2e_compressed() { utils::setup_logger(); - let client = ProverClient::local(); + let client = ProverClient::cpu(); let elf = test_artifacts::FIBONACCI_ELF; let (pk, vk) = client.setup(elf); let mut stdin = SP1Stdin::new(); @@ -382,7 +532,7 @@ mod tests { #[test] fn test_e2e_prove_plonk() { utils::setup_logger(); - let client = ProverClient::local(); + let client = ProverClient::cpu(); let elf = test_artifacts::FIBONACCI_ELF; let (pk, vk) = client.setup(elf); let mut stdin = SP1Stdin::new(); diff --git a/crates/sdk/src/network-v2/client.rs b/crates/sdk/src/network-v2/client.rs index a428dee332..24e7469a54 100644 --- a/crates/sdk/src/network-v2/client.rs +++ b/crates/sdk/src/network-v2/client.rs @@ -1,4 +1,4 @@ -use std::{env, time::Duration}; +use std::time::Duration; use alloy_signer::SignerSync; use alloy_signer_local::PrivateKeySigner; @@ -31,11 +31,12 @@ pub const DEFAULT_PROVER_NETWORK_RPC: &str = "https://rpc.production.succinct.to pub struct NetworkClient { signer: PrivateKeySigner, http: HttpClientWithMiddleware, + rpc_url: String, } impl NetworkClient { /// Create a new network client with the given private key. - pub fn new(private_key: &str) -> Self { + pub fn new(private_key: &str, rpc_url: Option) -> Self { let signer = PrivateKeySigner::from_str(private_key).unwrap(); let http_client = reqwest::Client::builder() @@ -44,17 +45,21 @@ impl NetworkClient { .build() .unwrap(); - Self { signer, http: http_client.into() } + Self { + signer, + http: http_client.into(), + rpc_url: rpc_url.unwrap_or_else(|| DEFAULT_PROVER_NETWORK_RPC.to_string()), + } } /// Returns the currently configured RPC endpoint for the Succinct prover network. - pub fn rpc_url() -> String { - env::var("PROVER_NETWORK_RPC").unwrap_or_else(|_| DEFAULT_PROVER_NETWORK_RPC.to_string()) + pub fn rpc_url(&self) -> String { + self.rpc_url.clone() } /// Get a connected RPC client. async fn get_rpc(&self) -> Result> { - let rpc_url = Self::rpc_url(); + let rpc_url = self.rpc_url(); let mut endpoint = Channel::from_shared(rpc_url.clone())?; // Check if the URL scheme is HTTPS and configure TLS. @@ -69,7 +74,7 @@ impl NetworkClient { /// Get a connected artifact store client. async fn get_store(&self) -> Result> { - let rpc_url = Self::rpc_url(); + let rpc_url = self.rpc_url(); let mut endpoint = Channel::from_shared(rpc_url.clone())?; // Check if the URL scheme is HTTPS and configure TLS. diff --git a/crates/sdk/src/network-v2/prover.rs b/crates/sdk/src/network-v2/prover.rs index d67ed34386..83a86b55eb 100644 --- a/crates/sdk/src/network-v2/prover.rs +++ b/crates/sdk/src/network-v2/prover.rs @@ -1,12 +1,10 @@ -use std::{ - env, - time::{Duration, Instant}, -}; +use std::time::{Duration, Instant}; use crate::{ network_v2::client::NetworkClient, network_v2::proto::network::{ProofMode, ProofStatus, ProofStrategy}, - Prover, SP1Context, SP1ProofKind, SP1ProofWithPublicValues, SP1ProvingKey, SP1VerifyingKey, + NetworkProverBuilder, Prover, SP1Context, SP1ProofKind, SP1ProofWithPublicValues, + SP1ProvingKey, SP1VerifyingKey, }; use anyhow::Result; use backoff::{future::retry, ExponentialBackoff}; @@ -30,23 +28,22 @@ const DEFAULT_CYCLE_LIMIT: u64 = 100_000_000; pub struct NetworkProver { client: NetworkClient, local_prover: CpuProver, + skip_simulation: bool, } impl NetworkProver { - /// Creates a new [NetworkProver] with the private key set in `SP1_PRIVATE_KEY`. - pub fn new() -> Self { - let private_key = env::var("SP1_PRIVATE_KEY") - .unwrap_or_else(|_| panic!("SP1_PRIVATE_KEY must be set for remote proving")); - Self::new_from_key(&private_key) - } - /// Creates a new [NetworkProver] with the given private key. - pub fn new_from_key(private_key: &str) -> Self { + pub fn new(private_key: &str, rpc_url: Option, skip_simulation: bool) -> Self { let version = SP1_CIRCUIT_VERSION; log::info!("Client circuit version: {}", version); let local_prover = CpuProver::new(); - let client = NetworkClient::new(private_key); - Self { client, local_prover } + let client = NetworkClient::new(private_key, rpc_url); + Self { client, local_prover, skip_simulation } + } + + /// Creates a new network prover builder. See [`NetworkProverBuilder`] for more details. + pub fn builder() -> NetworkProverBuilder { + NetworkProverBuilder::default() } /// Requests a proof from the prover network, returning the request ID. @@ -58,8 +55,7 @@ impl NetworkProver { timeout: Option, ) -> Result> { // Simulate and get the cycle limit. - let skip_simulation = env::var("SKIP_SIMULATION").map(|val| val == "true").unwrap_or(false); - let cycle_limit = if !skip_simulation { + let cycle_limit = if !self.skip_simulation { let (_, report) = self.local_prover.sp1_prover().execute(elf, &stdin, Default::default())?; let cycles = report.total_instruction_count(); @@ -231,12 +227,6 @@ impl Prover for NetworkProver { } } -impl Default for NetworkProver { - fn default() -> Self { - Self::new() - } -} - /// Warns if `opts` or `context` are not default values, since they are currently unsupported. fn warn_if_not_default(opts: &SP1ProverOpts, context: &SP1Context) { let _guard = tracing::warn_span!("network_prover").entered(); diff --git a/crates/sdk/src/network/client.rs b/crates/sdk/src/network/client.rs index 9717c38395..2e39f9b08b 100644 --- a/crates/sdk/src/network/client.rs +++ b/crates/sdk/src/network/client.rs @@ -1,4 +1,4 @@ -use std::{env, time::Duration}; +use std::time::Duration; use crate::{ network::{ @@ -40,16 +40,12 @@ pub struct NetworkClient { pub rpc: TwirpClient, pub http: HttpClientWithMiddleware, pub auth: NetworkAuth, + pub is_using_prover_network: bool, } impl NetworkClient { - /// Returns the currently configured RPC endpoint for the Succinct prover network. - pub fn rpc_url() -> String { - env::var("PROVER_NETWORK_RPC").unwrap_or_else(|_| DEFAULT_PROVER_NETWORK_RPC.to_string()) - } - /// Create a new NetworkClient with the given private key for authentication. - pub fn new(private_key: &str) -> Self { + pub fn new(private_key: &str, rpc_url: Option) -> Self { let auth = NetworkAuth::new(private_key); let twirp_http_client = HttpClient::builder() @@ -59,7 +55,7 @@ impl NetworkClient { .build() .unwrap(); - let rpc_url = Self::rpc_url(); + let rpc_url = rpc_url.unwrap_or_else(|| DEFAULT_PROVER_NETWORK_RPC.to_string()); let rpc = TwirpClient::new(Url::parse(&rpc_url).unwrap(), twirp_http_client, vec![]).unwrap(); @@ -70,7 +66,12 @@ impl NetworkClient { .build() .unwrap(); - Self { auth, rpc, http: http_client.into() } + Self { + auth, + rpc, + http: http_client.into(), + is_using_prover_network: rpc_url == DEFAULT_PROVER_NETWORK_RPC, + } } /// Gets the latest nonce for this auth's account. diff --git a/crates/sdk/src/network/prover.rs b/crates/sdk/src/network/prover.rs index f5939fd2cd..70969adf5b 100644 --- a/crates/sdk/src/network/prover.rs +++ b/crates/sdk/src/network/prover.rs @@ -1,12 +1,12 @@ -use std::{ - env, - time::{Duration, Instant}, -}; +use std::time::{Duration, Instant}; use crate::{ - network::client::{NetworkClient, DEFAULT_PROVER_NETWORK_RPC}, - network::proto::network::{ProofMode, ProofStatus}, - Prover, SP1Context, SP1ProofKind, SP1ProofWithPublicValues, SP1ProvingKey, SP1VerifyingKey, + network::{ + client::NetworkClient, + proto::network::{ProofMode, ProofStatus}, + }, + NetworkProverBuilder, Prover, SP1Context, SP1ProofKind, SP1ProofWithPublicValues, + SP1ProvingKey, SP1VerifyingKey, }; use anyhow::Result; use sp1_core_machine::io::SP1Stdin; @@ -26,23 +26,22 @@ const MAX_CONSECUTIVE_ERRORS: usize = 10; pub struct NetworkProver { client: NetworkClient, local_prover: CpuProver, + skip_simulation: bool, } impl NetworkProver { - /// Creates a new [NetworkProver] with the private key set in `SP1_PRIVATE_KEY`. - pub fn new() -> Self { - let private_key = env::var("SP1_PRIVATE_KEY") - .unwrap_or_else(|_| panic!("SP1_PRIVATE_KEY must be set for remote proving")); - Self::new_from_key(&private_key) - } - /// Creates a new [NetworkProver] with the given private key. - pub fn new_from_key(private_key: &str) -> Self { + pub fn new(private_key: &str, rpc_url: Option, skip_simulation: bool) -> Self { let version = SP1_CIRCUIT_VERSION; log::info!("Client circuit version: {}", version); let local_prover = CpuProver::new(); - Self { client: NetworkClient::new(private_key), local_prover } + Self { client: NetworkClient::new(private_key, rpc_url), local_prover, skip_simulation } + } + + /// Creates a new network prover builder. See [`NetworkProverBuilder`] for more details. + pub fn builder() -> NetworkProverBuilder { + NetworkProverBuilder::default() } /// Requests a proof from the prover network, returning the proof ID. @@ -54,9 +53,7 @@ impl NetworkProver { ) -> Result { let client = &self.client; - let skip_simulation = env::var("SKIP_SIMULATION").map(|val| val == "true").unwrap_or(false); - - if !skip_simulation { + if !self.skip_simulation { let (_, report) = self.local_prover.sp1_prover().execute(elf, &stdin, Default::default())?; log::info!("Simulation complete, cycles: {}", report.total_instruction_count()); @@ -67,7 +64,7 @@ impl NetworkProver { let proof_id = client.create_proof(elf, &stdin, mode, SP1_CIRCUIT_VERSION).await?; log::info!("Created {}", proof_id); - if NetworkClient::rpc_url() == DEFAULT_PROVER_NETWORK_RPC { + if self.client.is_using_prover_network { log::info!("View in explorer: https://explorer.succinct.xyz/{}", proof_id); } Ok(proof_id) @@ -183,12 +180,6 @@ impl Prover for NetworkProver { } } -impl Default for NetworkProver { - fn default() -> Self { - Self::new() - } -} - /// Warns if `opts` or `context` are not default values, since they are currently unsupported. fn warn_if_not_default(opts: &SP1ProverOpts, context: &SP1Context) { if opts != &SP1ProverOpts::default() {