Skip to main content

sp1_prover/worker/node/
core.rs

1use std::sync::Arc;
2
3use sp1_core_executor::{ExecutionReport, Program, SP1Context, SP1CoreOpts};
4use sp1_core_machine::io::SP1Stdin;
5
6use sp1_hypercube::SP1VerifyingKey;
7use sp1_primitives::io::SP1PublicValues;
8use sp1_verifier::SP1Proof;
9use tracing::instrument;
10
11use crate::{
12    verify::{SP1Verifier, VerifierRecursionVks},
13    worker::{execute_with_options, SP1ExecutorConfig},
14    SP1CoreProofData,
15};
16
17struct SP1NodeCoreInner {
18    verifier: SP1Verifier,
19    opts: SP1CoreOpts,
20}
21
22pub struct SP1NodeCore {
23    inner: Arc<SP1NodeCoreInner>,
24}
25
26impl Clone for SP1NodeCore {
27    fn clone(&self) -> Self {
28        Self { inner: self.inner.clone() }
29    }
30}
31
32impl SP1NodeCore {
33    pub fn new(verifier: SP1Verifier, opts: SP1CoreOpts) -> Self {
34        Self { inner: Arc::new(SP1NodeCoreInner { verifier, opts }) }
35    }
36
37    #[instrument(name = "execute_program", skip_all)]
38    pub async fn execute(
39        &self,
40        elf: &[u8],
41        stdin: SP1Stdin,
42        context: SP1Context<'static>,
43    ) -> anyhow::Result<(SP1PublicValues, [u8; 32], ExecutionReport)> {
44        let program = Program::from(elf)
45            .map_err(|e| anyhow::anyhow!("failed to dissassemble program: {}", e))?;
46        let program = Arc::new(program);
47        let (public_values, public_value_digest, report) = execute_with_options(
48            program,
49            stdin,
50            context,
51            self.inner.opts.clone(),
52            SP1ExecutorConfig::default(),
53        )
54        .await?;
55        Ok((public_values, public_value_digest, report))
56    }
57
58    pub fn verify(&self, vk: &SP1VerifyingKey, proof: &SP1Proof) -> anyhow::Result<()> {
59        // Verify the underlying proof.
60        match proof {
61            SP1Proof::Core(proof) => {
62                let core_proof = SP1CoreProofData(proof.clone());
63                self.inner.verifier.verify(&core_proof, vk)?;
64            }
65            SP1Proof::Compressed(proof) => {
66                self.inner.verifier.verify_compressed(proof, vk)?;
67            }
68            SP1Proof::Plonk(proof) => {
69                self.inner.verifier.verify_plonk_bn254(proof, vk)?;
70            }
71            SP1Proof::Groth16(proof) => {
72                self.inner.verifier.verify_groth16_bn254(proof, vk)?;
73            }
74        }
75
76        Ok(())
77    }
78
79    pub fn recursion_vks(&self) -> VerifierRecursionVks {
80        self.inner.verifier.recursion_vks.clone()
81    }
82
83    pub fn vk_verification(&self) -> bool {
84        self.inner.verifier.vk_verification()
85    }
86
87    pub fn allowed_vk_height(&self) -> usize {
88        let num_shapes = self.inner.verifier.recursion_vks.num_keys();
89        num_shapes.next_power_of_two().ilog2() as usize
90    }
91
92    #[cfg(test)]
93    pub(crate) fn wrap_vk(
94        &self,
95    ) -> &sp1_hypercube::MachineVerifyingKey<sp1_primitives::SP1OuterGlobalContext> {
96        &self.inner.verifier.wrap_vk
97    }
98}