1pub mod builder;
6pub mod prove;
7
8use std::sync::Arc;
9
10use prove::CpuProveBuilder;
11use sp1_core_executor::ExecutionError;
12use sp1_core_machine::io::SP1Stdin;
13use sp1_core_machine::riscv::RiscvAir;
14use sp1_hypercube::Machine;
15use sp1_primitives::{Elf, SP1Field};
16use sp1_prover::worker::{
17 cpu_worker_builder_with_machine, SP1LocalNode, SP1LocalNodeBuilder, SP1NodeCore, TaskError,
18};
19
20use crate::{
21 prover::{Prover, SendFutureResult},
22 SP1ProvingKey,
23};
24
25use thiserror::Error;
26
27#[derive(Clone)]
29pub struct CpuProver {
30 pub(crate) prover: Arc<SP1LocalNode>,
31}
32
33#[derive(Debug, Error)]
35pub enum CPUProverError {
36 #[error(transparent)]
38 Prover(#[from] TaskError),
39
40 #[error(transparent)]
42 Execution(#[from] ExecutionError),
43
44 #[error("An unexpected error occurred: {:?}", .0)]
46 Unexpected(#[from] anyhow::Error),
47}
48
49impl Prover for CpuProver {
50 type ProvingKey = SP1ProvingKey;
51 type Error = CPUProverError;
52 type ProveRequest<'a> = CpuProveBuilder<'a>;
53
54 fn inner(&self) -> &SP1NodeCore {
55 self.prover.core()
56 }
57
58 fn setup(&self, elf: Elf) -> impl SendFutureResult<Self::ProvingKey, Self::Error> {
59 async move {
60 let vk = self.prover.setup(&elf).await?;
61 Ok(SP1ProvingKey { vk, elf })
62 }
63 }
64
65 fn prove<'a>(&'a self, pk: &'a Self::ProvingKey, stdin: SP1Stdin) -> Self::ProveRequest<'a> {
66 CpuProveBuilder::new(self, pk, stdin)
67 }
68}
69
70impl CpuProver {
71 #[must_use]
73 pub async fn new() -> Self {
74 Self::new_with_machine(RiscvAir::machine()).await
75 }
76
77 #[must_use]
79 pub async fn new_with_machine(machine: Machine<SP1Field, RiscvAir<SP1Field>>) -> Self {
80 Self::new_with_opts_and_machine(None, machine).await
81 }
82
83 #[must_use]
85 pub async fn new_with_opts(core_opts: Option<sp1_core_executor::SP1CoreOpts>) -> Self {
86 Self::new_with_opts_and_machine(core_opts, RiscvAir::machine()).await
87 }
88
89 #[must_use]
91 pub async fn new_with_opts_and_machine(
92 core_opts: Option<sp1_core_executor::SP1CoreOpts>,
93 machine: Machine<SP1Field, RiscvAir<SP1Field>>,
94 ) -> Self {
95 tracing::info!("initializing cpu prover");
96 let worker_builder =
97 cpu_worker_builder_with_machine(machine).with_core_opts(core_opts.unwrap_or_default());
98 Self {
99 prover: Arc::new(
100 SP1LocalNodeBuilder::from_worker_client_builder(worker_builder)
101 .build()
102 .await
103 .unwrap(),
104 ),
105 }
106 }
107
108 #[cfg(feature = "experimental")]
115 #[must_use]
116 pub async fn new_experimental() -> Self {
117 Self::new_experimental_with_machine(RiscvAir::machine()).await
118 }
119
120 #[cfg(feature = "experimental")]
122 #[must_use]
123 pub async fn new_experimental_with_machine(
124 machine: Machine<SP1Field, RiscvAir<SP1Field>>,
125 ) -> Self {
126 Self::new_with_opts_and_machine(None, machine).await
127 }
128}