risc0_zkvm/host/client/prove/
local.rs

1// Copyright 2024 RISC Zero, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use anyhow::Result;
16
17use super::{Executor, Prover, ProverOpts};
18use crate::{
19    get_prover_server, host::server::session::NullSegmentRef, ExecutorEnv, ExecutorImpl, ProveInfo,
20    Receipt, SegmentInfo, SessionInfo, VerifierContext,
21};
22
23/// A [Prover] implementation that selects a [ProverServer][crate::ProverServer] by calling
24/// [get_prover_server].
25pub struct LocalProver {
26    name: String,
27}
28
29impl LocalProver {
30    /// Construct a [LocalProver].
31    pub fn new(name: &str) -> Self {
32        Self {
33            name: name.to_string(),
34        }
35    }
36}
37
38impl Prover for LocalProver {
39    fn prove_with_ctx(
40        &self,
41        env: ExecutorEnv<'_>,
42        ctx: &VerifierContext,
43        elf: &[u8],
44        opts: &ProverOpts,
45    ) -> Result<ProveInfo> {
46        get_prover_server(opts)?.prove_with_ctx(env, ctx, elf)
47    }
48
49    fn get_name(&self) -> String {
50        self.name.clone()
51    }
52
53    fn compress(&self, opts: &ProverOpts, receipt: &Receipt) -> Result<Receipt> {
54        get_prover_server(opts)?.compress(opts, receipt)
55    }
56}
57
58impl Executor for LocalProver {
59    fn execute(&self, env: ExecutorEnv<'_>, elf: &[u8]) -> Result<SessionInfo> {
60        let mut exec = ExecutorImpl::from_elf(env, elf)?;
61        let mut segments = Vec::new();
62        let session = exec.run_with_callback(|segment| {
63            segments.push(SegmentInfo {
64                po2: segment.inner.po2 as u32,
65                cycles: segment.inner.insn_cycles as u32,
66            });
67            Ok(Box::new(NullSegmentRef))
68        })?;
69        let receipt_claim = session.claim()?;
70        Ok(SessionInfo {
71            segments,
72            journal: session.journal.unwrap_or_default(),
73            exit_code: session.exit_code,
74            receipt_claim: Some(receipt_claim),
75        })
76    }
77}