sp1_sdk/env/
mod.rs

1//! # SP1 Environment Prover
2//!
3//! A prover that can execute programs and generate proofs with a different implementation based on
4//! the value of certain environment variables.
5
6pub mod prove;
7
8use std::env;
9
10use anyhow::Result;
11use prove::EnvProveBuilder;
12use sp1_core_executor::SP1ContextBuilder;
13use sp1_core_machine::io::SP1Stdin;
14use sp1_cuda::MoongateServer;
15use sp1_prover::{components::CpuProverComponents, SP1Prover, SP1ProvingKey, SP1VerifyingKey};
16
17use super::{Prover, SP1VerificationError};
18#[cfg(feature = "network")]
19use crate::network::builder::NetworkProverBuilder;
20use crate::{
21    cpu::{execute::CpuExecuteBuilder, CpuProver},
22    cuda::CudaProver,
23    utils::{check_release_build, setup_memory_usage_monitoring},
24    SP1ProofMode, SP1ProofWithPublicValues,
25};
26
27/// A prover that can execute programs and generate proofs with a different implementation based on
28/// the value of certain environment variables.
29///
30/// The environment variables are described in [`EnvProver::new`].
31pub struct EnvProver {
32    pub(crate) prover: Box<dyn Prover<CpuProverComponents>>,
33}
34
35impl EnvProver {
36    /// Creates a new [`EnvProver`] with the given configuration.
37    ///
38    /// The following environment variables are used to configure the prover:
39    /// - `SP1_PROVER`: The type of prover to use. Must be one of `mock`, `local`, `cuda`, or
40    ///   `network`.
41    /// - `NETWORK_PRIVATE_KEY`: The private key to use for the network prover.
42    /// - `NETWORK_RPC_URL`: The RPC URL to use for the network prover.
43    #[must_use]
44    pub fn new() -> Self {
45        let mode = if let Ok(mode) = env::var("SP1_PROVER") {
46            mode
47        } else {
48            tracing::warn!("SP1_PROVER environment variable not set, defaulting to 'cpu'");
49            "cpu".to_string()
50        };
51
52        let prover: Box<dyn Prover<CpuProverComponents>> = match mode.as_str() {
53            "mock" => Box::new(CpuProver::mock()),
54            "cpu" => {
55                check_release_build();
56                setup_memory_usage_monitoring();
57                Box::new(CpuProver::new())
58            },
59            "cuda" => {
60                check_release_build();
61                setup_memory_usage_monitoring();
62                Box::new(CudaProver::new(SP1Prover::new(), MoongateServer::default()))
63            }
64            "network" => {
65                #[cfg(not(feature = "network"))]
66                panic!(
67                    r#"The network prover requires the 'network' feature to be enabled.
68                    Please enable it in your Cargo.toml with:
69                    sp1-sdk = {{ version = "...", features = ["network"] }}"#
70                );
71
72                #[cfg(feature = "network")]
73                {
74                    Box::new(NetworkProverBuilder::default().build())
75                }
76            }
77            _ => panic!(
78                "Invalid SP1_PROVER value. Expected one of: mock, cpu, cuda, or network. Got: '{mode}'.\n\
79                Please set the SP1_PROVER environment variable to one of the supported values."
80            ),
81        };
82        EnvProver { prover }
83    }
84
85    /// Creates a new [`CpuExecuteBuilder`] for simulating the execution of a program on the CPU.
86    ///
87    /// # Details
88    /// The builder is used for both the [`crate::cpu::CpuProver`] and [`crate::CudaProver`] client
89    /// types.
90    ///
91    /// # Example
92    /// ```rust,no_run
93    /// use sp1_sdk::{Prover, ProverClient, SP1Stdin};
94    ///
95    /// let elf = &[1, 2, 3];
96    /// let stdin = SP1Stdin::new();
97    ///
98    /// let client = ProverClient::from_env();
99    /// let (public_values, execution_report) = client.execute(elf, &stdin).run().unwrap();
100    /// ```
101    #[must_use]
102    pub fn execute<'a>(&'a self, elf: &'a [u8], stdin: &SP1Stdin) -> CpuExecuteBuilder<'a> {
103        CpuExecuteBuilder {
104            prover: self.prover.inner(),
105            elf,
106            stdin: stdin.clone(),
107            context_builder: SP1ContextBuilder::default(),
108        }
109    }
110
111    /// Creates a new [`EnvProveBuilder`] for proving a program on the CPU.
112    ///
113    /// # Details
114    /// The builder is used for only the [`crate::cpu::CpuProver`] client type.
115    ///
116    /// # Example
117    /// ```rust,no_run
118    /// use sp1_sdk::{Prover, ProverClient, SP1Stdin};
119    ///
120    /// let elf = &[1, 2, 3];
121    /// let stdin = SP1Stdin::new();
122    ///
123    /// let client = ProverClient::from_env();
124    /// let (pk, vk) = client.setup(elf);
125    /// let builder = client.prove(&pk, &stdin).core().run();
126    /// ```
127    #[must_use]
128    pub fn prove<'a>(&'a self, pk: &'a SP1ProvingKey, stdin: &'a SP1Stdin) -> EnvProveBuilder<'a> {
129        EnvProveBuilder {
130            prover: self.prover.as_ref(),
131            mode: SP1ProofMode::Core,
132            pk,
133            stdin: stdin.clone(),
134        }
135    }
136
137    /// Verifies that the given proof is valid and matches the given verification key produced by
138    /// [`Self::setup`].
139    ///
140    /// ### Examples
141    /// ```no_run
142    /// use sp1_sdk::{ProverClient, SP1Stdin};
143    ///
144    /// let elf = test_artifacts::FIBONACCI_ELF;
145    /// let stdin = SP1Stdin::new();
146    ///
147    /// let client = ProverClient::from_env();
148    /// let (pk, vk) = client.setup(elf);
149    /// let proof = client.prove(&pk, &stdin).run().unwrap();
150    /// client.verify(&proof, &vk).unwrap();
151    /// ```
152    pub fn verify(
153        &self,
154        proof: &SP1ProofWithPublicValues,
155        vk: &SP1VerifyingKey,
156    ) -> Result<(), SP1VerificationError> {
157        self.prover.verify(proof, vk)
158    }
159
160    /// Setup a program to be proven and verified by the SP1 RISC-V zkVM by computing the proving
161    /// and verifying keys.
162    #[must_use]
163    pub fn setup(&self, elf: &[u8]) -> (SP1ProvingKey, SP1VerifyingKey) {
164        self.prover.setup(elf)
165    }
166}
167
168impl Default for EnvProver {
169    fn default() -> Self {
170        Self::new()
171    }
172}
173
174impl Prover<CpuProverComponents> for EnvProver {
175    fn inner(&self) -> &SP1Prover<CpuProverComponents> {
176        self.prover.inner()
177    }
178
179    fn setup(&self, elf: &[u8]) -> (SP1ProvingKey, SP1VerifyingKey) {
180        self.prover.setup(elf)
181    }
182
183    fn prove(
184        &self,
185        pk: &SP1ProvingKey,
186        stdin: &SP1Stdin,
187        mode: SP1ProofMode,
188    ) -> Result<SP1ProofWithPublicValues> {
189        self.prover.prove(pk, stdin, mode)
190    }
191
192    fn verify(
193        &self,
194        bundle: &SP1ProofWithPublicValues,
195        vkey: &SP1VerifyingKey,
196    ) -> Result<(), SP1VerificationError> {
197        self.prover.verify(bundle, vkey)
198    }
199}