cargo_openvm/commands/
setup.rs

1use std::{
2    fs::{create_dir_all, write},
3    path::PathBuf,
4};
5
6use aws_config::{defaults, BehaviorVersion, Region};
7use aws_sdk_s3::Client;
8use clap::Parser;
9use eyre::{eyre, Result};
10use openvm_native_recursion::halo2::utils::CacheHalo2ParamsReader;
11use openvm_sdk::{
12    config::AggConfig,
13    fs::{
14        write_agg_pk_to_file, write_evm_verifier_to_folder, EVM_VERIFIER_ARTIFACT_FILENAME,
15        EVM_VERIFIER_SOL_FILENAME,
16    },
17    DefaultStaticVerifierPvHandler, Sdk,
18};
19
20use crate::default::{DEFAULT_AGG_PK_PATH, DEFAULT_PARAMS_DIR, DEFAULT_VERIFIER_FOLDER};
21
22#[derive(Parser)]
23#[command(
24    name = "evm-proving-setup",
25    about = "Set up for generating EVM proofs. ATTENTION: this requires large amounts of computation and memory. "
26)]
27pub struct EvmProvingSetupCmd {}
28
29impl EvmProvingSetupCmd {
30    pub async fn run(&self) -> Result<()> {
31        if PathBuf::from(DEFAULT_AGG_PK_PATH).exists()
32            && PathBuf::from(DEFAULT_VERIFIER_FOLDER)
33                .join(EVM_VERIFIER_ARTIFACT_FILENAME)
34                .exists()
35            && PathBuf::from(DEFAULT_VERIFIER_FOLDER)
36                .join(EVM_VERIFIER_SOL_FILENAME)
37                .exists()
38        {
39            println!("Aggregation proving key and verifier contract already exist");
40            return Ok(());
41        } else if !Self::check_solc_installed() {
42            return Err(eyre!(
43                "solc is not installed, please install solc to continue"
44            ));
45        }
46
47        Self::download_params(10, 24).await?;
48        let params_reader = CacheHalo2ParamsReader::new(DEFAULT_PARAMS_DIR);
49        let agg_config = AggConfig::default();
50        let sdk = Sdk::new();
51
52        println!("Generating proving key...");
53        let agg_pk = sdk.agg_keygen(agg_config, &params_reader, &DefaultStaticVerifierPvHandler)?;
54
55        println!("Generating verifier contract...");
56        let verifier = sdk.generate_snark_verifier_contract(&params_reader, &agg_pk)?;
57
58        println!("Writing proving key to file...");
59        write_agg_pk_to_file(agg_pk, DEFAULT_AGG_PK_PATH)?;
60
61        println!("Writing verifier contract to file...");
62        write_evm_verifier_to_folder(verifier, DEFAULT_VERIFIER_FOLDER)?;
63
64        Ok(())
65    }
66
67    fn check_solc_installed() -> bool {
68        std::process::Command::new("solc")
69            .arg("--version")
70            .output()
71            .is_ok()
72    }
73
74    async fn download_params(min_k: u32, max_k: u32) -> Result<()> {
75        create_dir_all(DEFAULT_PARAMS_DIR)?;
76        let config = defaults(BehaviorVersion::latest())
77            .region(Region::new("us-east-1"))
78            .no_credentials()
79            .load()
80            .await;
81        let client = Client::new(&config);
82
83        for k in min_k..=max_k {
84            let file_name = format!("kzg_bn254_{}.srs", k);
85            let local_file_path = PathBuf::from(DEFAULT_PARAMS_DIR).join(&file_name);
86            if !local_file_path.exists() {
87                println!("Downloading {}", file_name);
88                let key = format!("challenge_0085/{}", file_name);
89                let resp = client
90                    .get_object()
91                    .bucket("axiom-crypto")
92                    .key(&key)
93                    .send()
94                    .await?;
95                let data = resp.body.collect().await?;
96                write(local_file_path, data.into_bytes())?;
97            }
98        }
99
100        Ok(())
101    }
102}