From 321ec209e70013dd9c1fbbe2e11b417765c2e13e Mon Sep 17 00:00:00 2001 From: Alejandro Cabeza Romero Date: Fri, 29 May 2026 22:08:58 +0200 Subject: [PATCH] Add runtime validation to paths. --- .../src/lib.rs | 11 ++++- .../src/artifacts.rs | 40 ++++++++++++++----- .../src/lib.rs | 29 +++++++++----- 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/rust/logos-blockchain-circuits-build/src/lib.rs b/rust/logos-blockchain-circuits-build/src/lib.rs index b445c70..b1c2be6 100644 --- a/rust/logos-blockchain-circuits-build/src/lib.rs +++ b/rust/logos-blockchain-circuits-build/src/lib.rs @@ -115,6 +115,10 @@ mod prebuilt { } } +// Called once per build function (build_circuit, build_rapidsnark). If a build +// script calls both, cargo:rustc-env=LBC_ROOT_DIR is emitted twice. Cargo takes +// last-wins for duplicate rustc-env keys; the value is always identical so this +// is benign, but callers should be aware. fn resolve_root() -> PathBuf { println!("cargo:rerun-if-env-changed={LBC_ROOT_DIR}"); println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION"); @@ -188,8 +192,13 @@ pub fn build_circuit(circuit_name: &str) { pub fn build_rapidsnark() { let root = resolve_root(); + let extension = if std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("windows") { + ".exe" + } else { + "" + }; for binary in ["prover", "verifier"] { - let path = root.join(binary); + let path = root.join(format!("{binary}{extension}")); println!("cargo:rerun-if-changed={}", path.display()); } } diff --git a/rust/logos-blockchain-circuits-common/src/artifacts.rs b/rust/logos-blockchain-circuits-common/src/artifacts.rs index bb1e600..267048d 100644 --- a/rust/logos-blockchain-circuits-common/src/artifacts.rs +++ b/rust/logos-blockchain-circuits-common/src/artifacts.rs @@ -6,14 +6,14 @@ /// /// # Generated items /// -/// | Item | Description | -/// |-------------------------|-----------------------------------------| -/// | `PROVING_KEY_PATH` | Path to the proving key (`.zkey`) | -/// | `PROVING_KEY` | Proving key bytes | -/// | `VERIFICATION_KEY_PATH` | Path to the verification key (`.json`) | -/// | `VERIFICATION_KEY` | Verification key bytes | -/// | `CIRCUIT_DAT_PATH` | Path to the witness generator data | -/// | `CIRCUIT_DAT` | Witness generator data bytes | +/// | Item | Description | +/// |-------------------------|----------------------------------------------------------------| +/// | `PROVING_KEY_PATH` | Path to the proving key (`.zkey`), exists at runtime | +/// | `PROVING_KEY` | Proving key bytes | +/// | `VERIFICATION_KEY_PATH` | Path to the verification key (`.json`), exists at runtime | +/// | `VERIFICATION_KEY` | Verification key bytes | +/// | `CIRCUIT_DAT_PATH` | Path to the witness generator data (`.dat`), exists at runtime | +/// | `CIRCUIT_DAT` | Witness generator data bytes | /// /// # Example /// @@ -24,6 +24,8 @@ macro_rules! circuit_artifacts { ($circuit_dir:literal) => { pub mod artifacts { + use std::{path::PathBuf, sync::LazyLock}; + macro_rules! __circuit_file { ($file:literal) => { // "LBC_ROOT_DIR" must stay in sync with the constant in `lbc-build`. @@ -32,14 +34,30 @@ macro_rules! circuit_artifacts { }; } - pub const PROVING_KEY_PATH: &str = __circuit_file!("proving_key.zkey"); + macro_rules! __circuit_path { + ($file:literal) => { + LazyLock::new(|| { + let path = PathBuf::from(__circuit_file!($file)); + assert!( + path.is_file(), + "Circuit artifact not found: {}", + path.display() + ); + path + }) + }; + } + + pub static PROVING_KEY_PATH: LazyLock = __circuit_path!("proving_key.zkey"); pub static PROVING_KEY: &[u8] = include_bytes!(__circuit_file!("proving_key.zkey")); - pub const VERIFICATION_KEY_PATH: &str = __circuit_file!("verification_key.json"); + pub static VERIFICATION_KEY_PATH: LazyLock = + __circuit_path!("verification_key.json"); pub static VERIFICATION_KEY: &[u8] = include_bytes!(__circuit_file!("verification_key.json")); - pub const CIRCUIT_DAT_PATH: &str = __circuit_file!("witness_generator.dat"); + pub static CIRCUIT_DAT_PATH: LazyLock = + __circuit_path!("witness_generator.dat"); pub static CIRCUIT_DAT: &[u8] = include_bytes!(__circuit_file!("witness_generator.dat")); } diff --git a/rust/logos-blockchain-circuits-rapidsnark-sys/src/lib.rs b/rust/logos-blockchain-circuits-rapidsnark-sys/src/lib.rs index 72411e4..cbfdf2c 100644 --- a/rust/logos-blockchain-circuits-rapidsnark-sys/src/lib.rs +++ b/rust/logos-blockchain-circuits-rapidsnark-sys/src/lib.rs @@ -1,4 +1,4 @@ -use std::path::PathBuf; +use std::{path::PathBuf, sync::LazyLock}; #[cfg(target_os = "windows")] const PROVER_BINARY: &str = "prover.exe"; @@ -10,17 +10,26 @@ const VERIFIER_BINARY: &str = "verifier.exe"; #[cfg(not(target_os = "windows"))] const VERIFIER_BINARY: &str = "verifier"; -#[must_use] fn lbc_root_dir() -> PathBuf { PathBuf::from(env!("LBC_ROOT_DIR")) } -#[must_use] -pub fn prover() -> PathBuf { - lbc_root_dir().join(PROVER_BINARY) -} +pub static PROVER: LazyLock = LazyLock::new(|| { + let path = lbc_root_dir().join(PROVER_BINARY); + assert!( + path.is_file(), + "Rapidsnark prover not found: {}", + path.display() + ); + path +}); -#[must_use] -pub fn verifier() -> PathBuf { - lbc_root_dir().join(VERIFIER_BINARY) -} +pub static VERIFIER: LazyLock = LazyLock::new(|| { + let path = lbc_root_dir().join(VERIFIER_BINARY); + assert!( + path.is_file(), + "Rapidsnark verifier not found: {}", + path.display() + ); + path +});