pub mod builder;
pub mod prove;
use std::sync::Arc;
use prove::CpuProveBuilder;
use sp1_core_executor::ExecutionError;
use sp1_core_machine::io::SP1Stdin;
use sp1_primitives::Elf;
use sp1_prover::worker::{
cpu_worker_builder, SP1LocalNode, SP1LocalNodeBuilder, SP1NodeCore, TaskError,
};
use crate::{
prover::{Prover, SendFutureResult},
SP1ProvingKey,
};
use thiserror::Error;
#[derive(Clone)]
pub struct CpuProver {
pub(crate) prover: Arc<SP1LocalNode>,
}
#[derive(Debug, Error)]
pub enum CPUProverError {
#[error(transparent)]
Prover(#[from] TaskError),
#[error(transparent)]
Execution(#[from] ExecutionError),
#[error("An unexpected error occurred: {:?}", .0)]
Unexpected(#[from] anyhow::Error),
}
impl Prover for CpuProver {
type ProvingKey = SP1ProvingKey;
type Error = CPUProverError;
type ProveRequest<'a> = CpuProveBuilder<'a>;
fn inner(&self) -> &SP1NodeCore {
self.prover.core()
}
fn setup(&self, elf: Elf) -> impl SendFutureResult<Self::ProvingKey, Self::Error> {
async move {
let vk = self.prover.setup(&elf).await?;
Ok(SP1ProvingKey { vk, elf })
}
}
fn prove<'a>(&'a self, pk: &'a Self::ProvingKey, stdin: SP1Stdin) -> Self::ProveRequest<'a> {
CpuProveBuilder::new(self, pk, stdin)
}
}
impl CpuProver {
#[must_use]
pub async fn new() -> Self {
Self::new_with_opts(None).await
}
#[must_use]
pub async fn new_with_opts(core_opts: Option<sp1_core_executor::SP1CoreOpts>) -> Self {
let worker_builder = cpu_worker_builder().with_core_opts(core_opts.unwrap_or_default());
Self {
prover: Arc::new(
SP1LocalNodeBuilder::from_worker_client_builder(worker_builder)
.build()
.await
.unwrap(),
),
}
}
#[cfg(feature = "experimental")]
#[must_use]
pub async fn new_experimental() -> Self {
Self::new_with_opts(None).await
}
}