Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions crates/cli/src/noir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand All @@ -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 {
Expand Down
8 changes: 1 addition & 7 deletions crates/entrypoint/src/start/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,7 @@ use tracing::instrument;
pub async fn execute(config: &AppConfig) -> Result<CiphernodeHandle> {
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())
Expand Down
16 changes: 3 additions & 13 deletions crates/tests/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions crates/zk-prover/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
13 changes: 9 additions & 4 deletions crates/zk-prover/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -60,7 +66,7 @@ impl ZkBackend {
}
}

pub async fn with_default_dir(node_name: &str) -> Result<Self, ZkError> {
pub fn with_default_dir(node_name: &str) -> Result<Self, ZkError> {
let base_dirs = directories::BaseDirs::new().ok_or_else(|| {
ZkError::IoError(std::io::Error::new(
std::io::ErrorKind::NotFound,
Expand All @@ -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> {
Expand Down
2 changes: 1 addition & 1 deletion crates/zk-prover/src/backend/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
120 changes: 23 additions & 97 deletions crates/zk-prover/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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<Self, ZkError> {
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<Self> {
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())
}
Expand Down Expand Up @@ -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::*;

Expand Down Expand Up @@ -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.
Expand All @@ -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"
Expand Down Expand Up @@ -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);

Expand All @@ -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");
}

Expand All @@ -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"
Expand Down
9 changes: 2 additions & 7 deletions crates/zk-prover/src/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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");
Expand Down
11 changes: 3 additions & 8 deletions crates/zk-prover/tests/common/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand All @@ -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") {
Expand All @@ -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)
}
16 changes: 3 additions & 13 deletions crates/zk-prover/tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
Loading