setup.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the alphavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use alphavm_algorithms::crypto_hash::sha256::sha256; 17 use alphavm_circuit::Alpha; 18 use alphavm_console::network::{CanaryV0, MainnetV0, Network, TestnetV0, prelude::ToBytes}; 19 use alphavm_synthesizer::{Process, Program}; 20 21 use anyhow::Result; 22 use serde_json::{Value, json}; 23 use std::{ 24 fs, 25 fs::File, 26 io::{BufWriter, Read, Write}, 27 path::PathBuf, 28 }; 29 30 fn checksum(bytes: &[u8]) -> String { 31 hex::encode(sha256(bytes)) 32 } 33 34 fn versioned_filename(filename: &str, checksum: &str) -> String { 35 match checksum.get(0..7) { 36 Some(sum) => format!("{filename}.{sum}"), 37 _ => filename.to_string(), 38 } 39 } 40 41 /// Writes the given bytes to the given versioned filename. 42 fn write_remote(filename: &str, version: &str, bytes: &[u8]) -> Result<()> { 43 let mut file = BufWriter::new(File::create(PathBuf::from(&versioned_filename(filename, version)))?); 44 file.write_all(bytes)?; 45 Ok(()) 46 } 47 48 /// Writes the given bytes to the given filename. 49 fn write_local(filename: &str, bytes: &[u8]) -> Result<()> { 50 let mut file = BufWriter::new(File::create(PathBuf::from(filename))?); 51 file.write_all(bytes)?; 52 Ok(()) 53 } 54 55 /// Writes the given metadata as JSON to the given filename. 56 fn write_metadata(filename: &str, metadata: &Value) -> Result<()> { 57 let mut file = BufWriter::new(File::create(PathBuf::from(filename))?); 58 file.write_all(&serde_json::to_vec_pretty(metadata)?)?; 59 Ok(()) 60 } 61 62 /// (Do not use) Writes the metadata files. (cargo run --release --example setup usrs) 63 pub fn usrs() -> Result<()> { 64 let paths = fs::read_dir("../src/mainnet/resources/").unwrap(); 65 for path in paths { 66 let path = path?.path(); 67 if let Some("usrs") = path.extension().and_then(|s| s.to_str()) { 68 let metadata_path = path.with_extension("metadata"); 69 let mut file = File::open(&path)?; 70 let file_size = file.metadata().unwrap().len() as usize; 71 let mut file_bytes = Vec::with_capacity(file_size); 72 file.read_to_end(&mut file_bytes)?; 73 let checksum = checksum(&file_bytes); 74 75 let metadata = json!({ 76 "checksum": checksum, 77 "size": file_size, 78 }); 79 80 write_metadata(metadata_path.to_str().unwrap(), &metadata)?; 81 write_remote(path.to_str().unwrap(), &checksum, &file_bytes)?; 82 } 83 } 84 Ok(()) 85 } 86 87 /// Synthesizes the circuit keys for the credits program. (cargo run --release --example setup credits) 88 pub fn credits_program<N: Network, A: Alpha<Network = N>>() -> Result<()> { 89 // Initialize an RNG. 90 let rng = &mut alphavm_utilities::TestRng::fixed(1245897092); 91 // Initialize the process. 92 let process = Process::setup::<A, _>(rng)?; 93 // Initialize the program. 94 let program = Program::<N>::credits()?; 95 let program_id = program.id(); 96 97 // Initialize a vector for the commands. 98 let mut commands = vec![]; 99 100 // Store the 'credits.alpha' circuit keys. 101 for (function_name, _) in program.functions().iter() { 102 // let timer = std::time::Instant::now(); 103 // process.synthesize_key::<A, _>(program_id, function_name, rng)?; 104 // println!("Synthesized '{}': {} ms", function_name, timer.elapsed().as_millis()); 105 106 let proving_key = process.get_proving_key(program_id, function_name)?; 107 let proving_key_bytes = proving_key.to_bytes_le()?; 108 let proving_key_checksum = checksum(&proving_key_bytes); 109 110 let verifying_key = process.get_verifying_key(program_id, function_name)?; 111 let verifying_key_bytes = verifying_key.to_bytes_le()?; 112 let verifying_key_checksum = checksum(&verifying_key_bytes); 113 114 let metadata = json!({ 115 "prover_checksum": proving_key_checksum, 116 "prover_size": proving_key_bytes.len(), 117 "verifier_checksum": verifying_key_checksum, 118 "verifier_size": verifying_key_bytes.len(), 119 }); 120 121 println!("{}", serde_json::to_string_pretty(&metadata)?); 122 write_metadata(&format!("{function_name}.metadata"), &metadata)?; 123 write_remote(&format!("{function_name}.prover"), &proving_key_checksum, &proving_key_bytes)?; 124 write_local(&format!("{function_name}.verifier"), &verifying_key_bytes)?; 125 126 commands.push(format!("upload \"{}\"", versioned_filename(&format!("{function_name}.prover"), &proving_key_checksum))); 127 } 128 129 // Print the commands. 130 println!("\nNow, perform the following operations:\n"); 131 for command in commands { 132 println!("{command}"); 133 } 134 println!(); 135 136 Ok(()) 137 } 138 139 /// Run the following command to perform a setup. 140 /// `cargo run --example setup [variant]` 141 pub fn main() -> Result<()> { 142 let args: Vec<String> = std::env::args().collect(); 143 if args.len() < 3 { 144 eprintln!("Invalid number of arguments. Given: {} - Required: 2", args.len() - 1); 145 return Ok(()); 146 } 147 148 match args[1].as_str() { 149 "usrs" => usrs()?, 150 "credits" => match args[2].as_str() { 151 "mainnet" => credits_program::<MainnetV0, alphavm_circuit::AlphaV0>(), 152 "testnet" => credits_program::<TestnetV0, alphavm_circuit::AlphaTestnetV0>(), 153 "canary" => credits_program::<CanaryV0, alphavm_circuit::AlphaCanaryV0>(), 154 _ => panic!("Invalid network"), 155 }?, 156 _ => panic!("Invalid parameter"), 157 }; 158 159 Ok(()) 160 }