diff --git a/crates/cli/src/noir.rs b/crates/cli/src/noir.rs index 4cd6394f3b..2b7e1bad16 100644 --- a/crates/cli/src/noir.rs +++ b/crates/cli/src/noir.rs @@ -19,13 +19,7 @@ pub enum NoirCommands { } pub async fn execute(command: NoirCommands, config: &AppConfig) -> Result<()> { - let zk_config = e3_zk_prover::ZkConfig::fetch_or_default().await; - let backend = ZkBackend::new( - config.bb_binary(), - config.circuits_dir(), - config.work_dir(), - zk_config, - ); + let backend = ZkBackend::new(config.bb_binary(), config.circuits_dir(), config.work_dir()); match command { NoirCommands::Status => { @@ -41,7 +35,6 @@ pub async fn execute(command: NoirCommands, config: &AppConfig) -> Result<()> { pub async fn execute_without_config(command: NoirCommands) -> Result<()> { let backend = ZkBackend::with_default_dir("default") - .await .map_err(|e| anyhow!("Failed to initialize ZK backend: {}", e))?; match command { diff --git a/crates/entrypoint/src/start/start.rs b/crates/entrypoint/src/start/start.rs index 6a16d9d5cd..25449a3cd9 100644 --- a/crates/entrypoint/src/start/start.rs +++ b/crates/entrypoint/src/start/start.rs @@ -18,13 +18,7 @@ use tracing::instrument; pub async fn execute(config: &AppConfig) -> Result { let rng = Arc::new(Mutex::new(rand_chacha::ChaCha20Rng::from_rng(OsRng)?)); let cipher = Arc::new(Cipher::from_file(&config.key_file()).await?); - let zk_config = e3_zk_prover::ZkConfig::fetch_or_default().await; - let backend = ZkBackend::new( - config.bb_binary(), - config.circuits_dir(), - config.work_dir(), - zk_config, - ); + let backend = ZkBackend::new(config.bb_binary(), config.circuits_dir(), config.work_dir()); backend.ensure_installed().await?; let node = CiphernodeBuilder::new(rng.clone(), cipher.clone()) diff --git a/crates/tests/tests/integration.rs b/crates/tests/tests/integration.rs index ad27ea2a9e..fc2cf56de7 100644 --- a/crates/tests/tests/integration.rs +++ b/crates/tests/tests/integration.rs @@ -31,7 +31,7 @@ use e3_trbfv::helpers::calculate_error_size; use e3_utils::rand_eth_addr; use e3_utils::utility_types::ArcBytes; use e3_zk_prover::test_utils::get_tempdir; -use e3_zk_prover::{ZkBackend, ZkConfig}; +use e3_zk_prover::ZkBackend; use fhe::bfv::PublicKey; use fhe_traits::{DeserializeParametrized, Serialize}; use num_bigint::BigUint; @@ -168,21 +168,11 @@ async fn setup_test_zk_backend() -> (ZkBackend, tempfile::TempDir) { .await .unwrap(); - let backend = ZkBackend::new( - BBPath::Default(bb_binary), - circuits_dir, - work_dir, - ZkConfig::default(), - ); + let backend = ZkBackend::new(BBPath::Default(bb_binary), circuits_dir, work_dir); (backend, temp) } else { println!("bb binary not found locally, downloading via ensure_installed()..."); - let backend = ZkBackend::new( - BBPath::Default(bb_binary), - circuits_dir, - work_dir, - ZkConfig::default(), - ); + let backend = ZkBackend::new(BBPath::Default(bb_binary), circuits_dir, work_dir); backend .ensure_installed() .await diff --git a/crates/zk-prover/build.rs b/crates/zk-prover/build.rs index 22d5a15c5f..2ca2452033 100644 --- a/crates/zk-prover/build.rs +++ b/crates/zk-prover/build.rs @@ -7,6 +7,7 @@ use std::process::Command; fn main() { println!("cargo:rerun-if-env-changed=FORCE_BUILD"); + println!("cargo:rerun-if-changed=versions.json"); assert!(Command::new("bash") .arg("./scripts/build_fixtures.sh") diff --git a/crates/zk-prover/src/backend/mod.rs b/crates/zk-prover/src/backend/mod.rs index 916759bc70..4058972b89 100644 --- a/crates/zk-prover/src/backend/mod.rs +++ b/crates/zk-prover/src/backend/mod.rs @@ -39,7 +39,13 @@ pub struct ZkBackend { } impl ZkBackend { - pub fn new( + pub fn new(bb_binary: BBPath, circuits_dir: PathBuf, work_dir: PathBuf) -> Self { + Self::with_config(bb_binary, circuits_dir, work_dir, ZkConfig::default()) + } + + /// Construct with an explicit config — primarily for tests that need to + /// override versions or checksums. + pub fn with_config( bb_binary: BBPath, circuits_dir: PathBuf, work_dir: PathBuf, @@ -60,7 +66,7 @@ impl ZkBackend { } } - pub async fn with_default_dir(node_name: &str) -> Result { + pub fn with_default_dir(node_name: &str) -> Result { let base_dirs = directories::BaseDirs::new().ok_or_else(|| { ZkError::IoError(std::io::Error::new( std::io::ErrorKind::NotFound, @@ -74,8 +80,7 @@ impl ZkBackend { let circuits_dir = noir_dir.join("circuits"); let work_dir = noir_dir.join("work").join(node_name); - let config = ZkConfig::fetch_or_default().await; - Ok(Self::new(bb_binary, circuits_dir, work_dir, config)) + Ok(Self::new(bb_binary, circuits_dir, work_dir)) } fn sanitize_e3_id(e3_id: &str) -> Result<&str, ZkError> { diff --git a/crates/zk-prover/src/backend/tests.rs b/crates/zk-prover/src/backend/tests.rs index 5f478141f2..855512dba4 100644 --- a/crates/zk-prover/src/backend/tests.rs +++ b/crates/zk-prover/src/backend/tests.rs @@ -13,7 +13,7 @@ fn test_backend(temp_path: &std::path::Path, config: ZkConfig) -> ZkBackend { let bb_binary = BBPath::Default(noir_dir.join("bin").join("bb")); let circuits_dir = noir_dir.join("circuits"); let work_dir = noir_dir.join("work").join("test_node"); - ZkBackend::new(bb_binary, circuits_dir, work_dir, config) + ZkBackend::with_config(bb_binary, circuits_dir, work_dir, config) } #[tokio::test] diff --git a/crates/zk-prover/src/config.rs b/crates/zk-prover/src/config.rs index 59face281c..a89b7e4074 100644 --- a/crates/zk-prover/src/config.rs +++ b/crates/zk-prover/src/config.rs @@ -9,15 +9,10 @@ use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use std::collections::HashMap; use std::path::Path; -use std::time::Duration; use tokio::fs; -use tracing::{debug, warn}; +use tracing::debug; -const VERSIONS_MANIFEST_URL: &str = - "https://raw.githubusercontent.com/gnosisguild/enclave/refactor/recursion-proof-crisp/crates/zk-prover/versions.json"; - -const BB_VERSION: &str = "3.0.0-nightly.20260102"; -const CIRCUITS_VERSION: &str = "0.1.15"; +const VERSIONS_JSON: &str = include_str!("../versions.json"); /// Supported bb binary targets #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -80,66 +75,13 @@ pub struct ZkConfig { impl Default for ZkConfig { fn default() -> Self { - Self { - bb_download_url: "https://github.com/AztecProtocol/aztec-packages/releases/download/v{version}/barretenberg-{arch}-{os}.tar.gz".to_string(), - circuits_download_url: "https://github.com/gnosisguild/enclave/releases/download/v{version}/circuits-{version}.tar.gz".to_string(), - bb_checksums: HashMap::new(), - circuits_checksums: HashMap::new(), - required_bb_version: BB_VERSION.to_string(), - required_circuits_version: CIRCUITS_VERSION.to_string(), - } + serde_json::from_str(VERSIONS_JSON) + .expect("versions.json is invalid — this is a build-time bug") } } impl ZkConfig { - pub async fn fetch_latest() -> Result { - let client = reqwest::Client::new(); - let response = client - .get(VERSIONS_MANIFEST_URL) - .timeout(Duration::from_secs(10)) - .send() - .await - .map_err(|e| { - ZkError::DownloadFailed(VERSIONS_MANIFEST_URL.to_string(), e.to_string()) - })?; - - if !response.status().is_success() { - return Err(ZkError::DownloadFailed( - VERSIONS_MANIFEST_URL.to_string(), - format!("HTTP {}", response.status()), - )); - } - - let config: ZkConfig = response.json().await.map_err(|e| { - ZkError::DownloadFailed(VERSIONS_MANIFEST_URL.to_string(), e.to_string()) - })?; - - Ok(config) - } - - pub async fn fetch_or_default() -> Self { - match Self::fetch_latest().await { - Ok(config) => { - debug!( - "fetched versions manifest: bb={}, circuits={}", - config.required_bb_version, config.required_circuits_version - ); - config - } - Err(e) => { - warn!("could not fetch versions manifest ({}), using defaults", e); - Self::default() - } - } - } - - pub async fn load(path: &Path) -> std::io::Result { - let contents = fs::read_to_string(path).await?; - serde_json::from_str(&contents) - .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e)) - } - - /// Get checksum for a specific target from the remote manifest + /// Get checksum for a specific target pub fn bb_checksum_for(&self, target: BbTarget) -> Option<&str> { self.bb_checksums.get(target.as_str()).map(|s| s.as_str()) } @@ -221,6 +163,7 @@ pub fn verify_checksum(file: &str, data: &[u8], expected: Option<&str>) -> Resul #[cfg(test)] mod tests { use crate::test_utils::get_tempdir; + use std::time::Duration; use super::*; @@ -393,8 +336,16 @@ mod tests { let config = ZkConfig::default(); assert!(config.bb_download_url.contains("{version}")); - assert!(config.bb_checksums.is_empty()); - assert_eq!(config.required_bb_version, BB_VERSION); + assert!(!config.bb_checksums.is_empty()); + assert!(!config.required_bb_version.is_empty()); + } + + #[test] + fn test_default_matches_versions_json() { + let config = ZkConfig::default(); + assert!(!config.required_bb_version.is_empty()); + assert!(!config.required_circuits_version.is_empty()); + assert!(!config.bb_checksums.is_empty()); } /// Integration test that downloads a real bb binary and verifies checksum. @@ -405,30 +356,8 @@ mod tests { return; }; - // Known good checksums for bb v0.82.2 - // Update these when bumping BB_VERSION - let checksums: HashMap<&str, &str> = [ - ( - "amd64-linux", - "4847ae82a1d25f9489057da2c33d1abdee3ba457e8219028a2c2336f850f8cd7", - ), - ( - "amd64-darwin", - "9137b49be56bfea5b62203b7ae4cb67c9ecc12fe1692a89badf2cf4b57323fdc", - ), - ( - "arm64-linux", - "a675221a823f6fada6d01b09a1c26c0f7356567f31a912a2475b6e3b63d438a2", - ), - ( - "arm64-darwin", - "6a448b089b43918787dbfd201b32a757f562c80bf542d1b75aaf6fc9dba42b0c", - ), - ] - .into_iter() - .collect(); - - let version = BB_VERSION; + let config = ZkConfig::default(); + let version = &config.required_bb_version; let (arch, os) = target.url_parts(); let url = format!( "https://github.com/AztecProtocol/aztec-packages/releases/download/v{version}/barretenberg-{arch}-{os}.tar.gz" @@ -456,12 +385,10 @@ mod tests { .expect("failed to read response body"); println!("downloaded {} bytes", bytes.len()); - // Verify checksum - let expected = checksums - .get(target.as_str()) + let expected = config + .bb_checksum_for(target) .expect("no checksum for target"); let result = verify_checksum(&format!("bb-{}", target), &bytes, Some(expected)); - assert!(result.is_ok(), "checksum verification failed: {:?}", result); println!("checksum verified for {}", target); @@ -474,15 +401,13 @@ mod tests { .expect("failed to write tarball"); assert!(tarball_path.exists()); - // Verify VersionInfo checksum method works let info = VersionInfo { - bb_version: Some(version.to_string()), + bb_version: Some(version.clone()), bb_checksum: Some(expected.to_string()), ..Default::default() }; assert!(info.verify_bb_checksum(&bytes).is_ok()); - // Cleanup happens automatically when temp goes out of scope println!("test passed, temp dir cleaned up"); } @@ -494,7 +419,8 @@ mod tests { return; }; - let version = BB_VERSION; + let config = ZkConfig::default(); + let version = &config.required_bb_version; let (arch, os) = target.url_parts(); let url = format!( "https://github.com/AztecProtocol/aztec-packages/releases/download/v{version}/barretenberg-{arch}-{os}.tar.gz" diff --git a/crates/zk-prover/src/prover.rs b/crates/zk-prover/src/prover.rs index 03a3fb53fd..7a9c9c6e46 100644 --- a/crates/zk-prover/src/prover.rs +++ b/crates/zk-prover/src/prover.rs @@ -219,7 +219,7 @@ impl ZkProver { #[cfg(test)] mod tests { use super::*; - use crate::{config::ZkConfig, test_utils::get_tempdir}; + use crate::test_utils::get_tempdir; use e3_config::BBPath; #[test] @@ -230,12 +230,7 @@ mod tests { let bb_binary = noir_dir.join("bin").join("bb"); let circuits_dir = noir_dir.join("circuits"); let work_dir = noir_dir.join("work").join("test_node"); - let backend = ZkBackend::new( - BBPath::Default(bb_binary), - circuits_dir, - work_dir, - ZkConfig::default(), - ); + let backend = ZkBackend::new(BBPath::Default(bb_binary), circuits_dir, work_dir); let prover = ZkProver::new(&backend); let result = prover.generate_proof(CircuitName::PkBfv, b"witness", "e3-1"); diff --git a/crates/zk-prover/tests/common/helpers.rs b/crates/zk-prover/tests/common/helpers.rs index a157f88d08..47fb0c4838 100644 --- a/crates/zk-prover/tests/common/helpers.rs +++ b/crates/zk-prover/tests/common/helpers.rs @@ -95,12 +95,7 @@ pub async fn setup_test_prover(bb: &PathBuf) -> (ZkBackend, TempDir) { let bb_binary = BBPath::Default(noir_dir.join("bin").join("bb")); let circuits_dir = noir_dir.join("circuits"); let work_dir = noir_dir.join("work").join("test_node"); - let backend = ZkBackend::new( - bb_binary.clone(), - circuits_dir.clone(), - work_dir.clone(), - ZkConfig::default(), - ); + let backend = ZkBackend::new(bb_binary.clone(), circuits_dir.clone(), work_dir.clone()); fs::create_dir_all(&backend.circuits_dir).await.unwrap(); fs::create_dir_all(backend.circuits_dir.join("vk")) @@ -117,7 +112,7 @@ pub async fn setup_test_prover(bb: &PathBuf) -> (ZkBackend, TempDir) { (backend, temp) } -/// Lightweight backend for tests that don't need a real bb binary. +/// Lightweight backend for tests that need to override config (e.g. inject bad checksums). pub fn test_backend(temp_path: &std::path::Path, config: ZkConfig) -> ZkBackend { let noir_dir = temp_path.join("noir"); let bb_binary = match env::var("E3_CUSTOM_BB") { @@ -126,5 +121,5 @@ pub fn test_backend(temp_path: &std::path::Path, config: ZkConfig) -> ZkBackend }; let circuits_dir = noir_dir.join("circuits"); let work_dir = noir_dir.join("work").join("test_node"); - ZkBackend::new(bb_binary, circuits_dir, work_dir, config) + ZkBackend::with_config(bb_binary, circuits_dir, work_dir, config) } diff --git a/crates/zk-prover/tests/integration_tests.rs b/crates/zk-prover/tests/integration_tests.rs index 46a4740a17..eac1265615 100644 --- a/crates/zk-prover/tests/integration_tests.rs +++ b/crates/zk-prover/tests/integration_tests.rs @@ -15,19 +15,11 @@ use common::test_backend; use e3_fhe_params::BfvPreset; use e3_zk_helpers::circuits::dkg::pk::circuit::{PkCircuit, PkCircuitData}; use e3_zk_prover::{test_utils::get_tempdir, BbTarget, Provable, SetupStatus, ZkConfig, ZkProver}; -use std::{env, path::PathBuf}; - -fn versions_json_path() -> PathBuf { - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("versions.json") -} +use std::env; #[tokio::test] async fn test_full_flow_download_circuits_prove_and_verify() { - eprintln!(">>> Loading config..."); - let config = ZkConfig::load(&versions_json_path()) - .await - .expect("versions.json should exist"); - eprintln!(">>> Config loaded"); + let config = ZkConfig::default(); let temp = get_tempdir().unwrap(); let backend = test_backend(temp.path(), config); @@ -162,9 +154,7 @@ async fn test_download_bb_rejects_wrong_checksum() { return; } - let mut config = ZkConfig::load(&versions_json_path()) - .await - .expect("versions.json should exist"); + let mut config = ZkConfig::default(); for checksum in config.bb_checksums.values_mut() { *checksum = "0".repeat(64);