use std::{
future::{Future, IntoFuture},
pin::Pin,
};
use anyhow::Result;
use sp1_core_machine::io::SP1Stdin;
use super::{CPUProverError, CpuProver};
use crate::{
prover::{BaseProveRequest, ProveRequest},
utils::proof_mode,
SP1ProofWithPublicValues, SP1ProvingKey,
};
pub struct CpuProveBuilder<'a> {
pub(crate) base: BaseProveRequest<'a, CpuProver>,
}
impl<'a> CpuProveBuilder<'a> {
pub(super) const fn new(prover: &'a CpuProver, pk: &'a SP1ProvingKey, stdin: SP1Stdin) -> Self {
Self { base: BaseProveRequest::new(prover, pk, stdin) }
}
async fn run(self) -> Result<SP1ProofWithPublicValues, CPUProverError> {
let BaseProveRequest { prover, pk, stdin, mode, mut context_builder } = self.base;
crate::utils::sp1_dump(&pk.elf, &stdin);
let context = context_builder.build();
Ok(prover.prover.prove_with_mode(&pk.elf, stdin, context, proof_mode(mode)).await?.into())
}
}
impl<'a> ProveRequest<'a, CpuProver> for CpuProveBuilder<'a> {
fn base(&mut self) -> &mut BaseProveRequest<'a, CpuProver> {
&mut self.base
}
}
impl<'a> IntoFuture for CpuProveBuilder<'a> {
type Output = Result<SP1ProofWithPublicValues, CPUProverError>;
type IntoFuture = Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(self.run())
}
}