risc0_zkvm/host/client/prove/
local.rs

1// Copyright 2025 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,
20    host::server::{exec::executor::ExecutorImpl, session::NullSegmentRef},
21    ExecutorEnv, ProveInfo, Receipt, SegmentInfo, SessionInfo, VerifierContext,
22};
23
24/// A [Prover] implementation that selects a [ProverServer][crate::ProverServer] by calling
25/// [get_prover_server].
26pub struct LocalProver {
27    name: String,
28}
29
30impl LocalProver {
31    /// Construct a [LocalProver].
32    pub fn new(name: &str) -> Self {
33        Self {
34            name: name.to_string(),
35        }
36    }
37}
38
39impl Prover for LocalProver {
40    fn prove_with_ctx(
41        &self,
42        env: ExecutorEnv<'_>,
43        ctx: &VerifierContext,
44        elf: &[u8],
45        opts: &ProverOpts,
46    ) -> Result<ProveInfo> {
47        get_prover_server(opts)?.prove_with_ctx(env, ctx, elf)
48    }
49
50    fn get_name(&self) -> String {
51        self.name.clone()
52    }
53
54    fn compress(&self, opts: &ProverOpts, receipt: &Receipt) -> Result<Receipt> {
55        get_prover_server(opts)?.compress(opts, receipt)
56    }
57}
58
59impl Executor for LocalProver {
60    fn execute(&self, env: ExecutorEnv<'_>, elf: &[u8]) -> Result<SessionInfo> {
61        let mut segments = Vec::new();
62        let session = ExecutorImpl::from_elf(env, elf)
63            .unwrap()
64            .run_with_callback(|segment| {
65                segments.push(SegmentInfo {
66                    po2: segment.po2() as u32,
67                    cycles: segment.user_cycles(),
68                });
69                Ok(Box::new(NullSegmentRef))
70            })?;
71
72        let receipt_claim = session.claim()?;
73        Ok(SessionInfo {
74            segments,
75            journal: session.journal.unwrap_or_default(),
76            exit_code: session.exit_code,
77            receipt_claim: Some(receipt_claim),
78        })
79    }
80}