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, ¶ms_reader, &DefaultStaticVerifierPvHandler)?;
54
55 println!("Generating verifier contract...");
56 let verifier = sdk.generate_snark_verifier_contract(¶ms_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}