cargo_openvm/commands/
commit.rs

1use std::{
2    fs::{copy, create_dir_all},
3    path::PathBuf,
4};
5
6use clap::Parser;
7use eyre::{Context, Result};
8use openvm_continuations::CommitBytes;
9use openvm_sdk::{
10    fs::write_to_file_json,
11    types::{AppExecutionCommit, VerificationBaselineJson},
12    Sdk,
13};
14
15use super::{prove::load_required_agg_pk, RunArgs, RunCargoArgs};
16use crate::{
17    args::{OpenVmConfigArgs, ProvingKeyArgs},
18    commands::{load_app_pk, load_or_build_exe, ExecutionMode},
19    util::{
20        get_app_baseline_path, get_app_commit_path, get_manifest_path_and_dir,
21        get_single_target_name, get_target_dir, get_target_output_dir,
22    },
23};
24
25#[derive(Parser)]
26#[command(
27    name = "commit",
28    about = "View the Bn254 commit of an OpenVM executable"
29)]
30pub struct CommitCmd {
31    #[arg(
32        long,
33        action,
34        help = "Path to OpenVM executable, if specified build will be skipped",
35        help_heading = "OpenVM Options"
36    )]
37    pub exe: Option<PathBuf>,
38
39    #[command(flatten)]
40    pub keys: ProvingKeyArgs,
41
42    #[clap(flatten)]
43    pub openvm_config: OpenVmConfigArgs,
44
45    #[command(flatten)]
46    cargo_args: RunCargoArgs,
47}
48
49impl CommitCmd {
50    pub fn run(&self) -> Result<()> {
51        let app_pk = load_app_pk(&self.keys.app_pk, &self.cargo_args)?;
52
53        let run_args = RunArgs {
54            exe: self.exe.clone(),
55            openvm_config: self.openvm_config.clone(),
56            input: None,
57            mode: ExecutionMode::Pure,
58        };
59        let (exe, target_name_stem) = load_or_build_exe(&run_args, &self.cargo_args)?;
60        let (manifest_path, _) =
61            get_manifest_path_and_dir(&self.cargo_args.manifest.manifest_path)?;
62        let target_dir = get_target_dir(&self.cargo_args.manifest.target_dir, &manifest_path);
63
64        let agg_pk = load_required_agg_pk(
65            &self.keys.agg_prefix_pk,
66            &self.keys.agg_pk,
67            &self.cargo_args,
68        )?;
69        let sdk = Sdk::builder().app_pk(app_pk).agg_pk(agg_pk).build()?;
70
71        let prover = sdk.prover(exe)?;
72        let baseline = prover.generate_baseline();
73        let app_vm_commit = prover.app_vm_commit();
74
75        let app_commit = AppExecutionCommit {
76            app_exe_commit: CommitBytes::from(baseline.app_exe_commit),
77            app_vm_commit: CommitBytes::from(app_vm_commit),
78        };
79        println!("exe commit: {}", app_commit.app_exe_commit);
80        println!("vm commit: {}", app_commit.app_vm_commit);
81
82        let target_output_dir = get_target_output_dir(&target_dir, &self.cargo_args.profile);
83
84        // target_name_stem does not contain "examples/" prefix
85        let target_name =
86            get_single_target_name(&self.cargo_args).unwrap_or(target_name_stem.into());
87
88        // Write Bn254 commit values
89        let commit_path = get_app_commit_path(&target_output_dir, target_name.clone());
90        println!("Writing app commit to {}", commit_path.display());
91        write_to_file_json(&commit_path, &app_commit)?;
92
93        // Write verification baseline (used by `verify stark`)
94        let baseline_path = get_app_baseline_path(&target_output_dir, target_name);
95        println!("Writing baseline to {}", baseline_path.display());
96        let baseline_json: VerificationBaselineJson = baseline.into();
97        write_to_file_json(&baseline_path, &baseline_json)?;
98
99        if let Some(output_dir) = &self.openvm_config.output_dir {
100            create_dir_all(output_dir)
101                .with_context(|| format!("failed to create directory {}", output_dir.display()))?;
102            let commit_name = commit_path.file_name().unwrap();
103            copy(&commit_path, output_dir.join(commit_name))
104                .with_context(|| format!("failed to copy commit to {}", output_dir.display()))?;
105            let baseline_name = baseline_path.file_name().unwrap();
106            copy(&baseline_path, output_dir.join(baseline_name))
107                .with_context(|| format!("failed to copy baseline to {}", output_dir.display()))?;
108        }
109
110        Ok(())
111    }
112}