diff --git a/compiler/wasm/src/compile.rs b/compiler/wasm/src/compile.rs index 0f7baff4819..12d63db7abd 100644 --- a/compiler/wasm/src/compile.rs +++ b/compiler/wasm/src/compile.rs @@ -17,6 +17,9 @@ use crate::errors::JsCompileError; const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; +const NOIR_ARTIFACT_VERSION_STRING: &str = + concat!(env!("CARGO_PKG_VERSION"), "-", env!("GIT_COMMIT")); + #[wasm_bindgen] extern "C" { #[wasm_bindgen(extends = Array, js_name = "StringArray", typescript_type = "string[]")] @@ -119,6 +122,7 @@ fn preprocess_program(program: CompiledProgram) -> PreprocessedProgram { backend: String::from(BACKEND_IDENTIFIER), abi: program.abi, bytecode: program.circuit, + nargo_version: String::from(NOIR_ARTIFACT_VERSION_STRING), } } @@ -140,6 +144,7 @@ fn preprocess_contract(contract: CompiledContract) -> PreprocessedContract { backend: String::from(BACKEND_IDENTIFIER), functions: preprocessed_functions, events: contract.events, + nargo_version: String::from(NOIR_ARTIFACT_VERSION_STRING), } } diff --git a/tooling/nargo/src/artifacts/contract.rs b/tooling/nargo/src/artifacts/contract.rs index fa161b63a5b..24291e9599d 100644 --- a/tooling/nargo/src/artifacts/contract.rs +++ b/tooling/nargo/src/artifacts/contract.rs @@ -10,6 +10,8 @@ use serde::{Deserialize, Serialize}; /// - Proving and verification keys have been pregenerated based on this ACIR. #[derive(Serialize, Deserialize)] pub struct PreprocessedContract { + /// Version of nargo used to compile this contract + pub nargo_version: String, /// The name of the contract. pub name: String, /// The identifier of the proving backend which this contract has been compiled for. diff --git a/tooling/nargo/src/artifacts/mod.rs b/tooling/nargo/src/artifacts/mod.rs index 33311e0856e..0941a06ee68 100644 --- a/tooling/nargo/src/artifacts/mod.rs +++ b/tooling/nargo/src/artifacts/mod.rs @@ -5,6 +5,7 @@ //! to generate them using these artifacts as a starting point. use acvm::acir::circuit::Circuit; use base64::Engine; +use serde::{de::Error as DeserializationError, ser::Error as SerializationError}; use serde::{Deserializer, Serializer}; pub mod contract; @@ -17,7 +18,7 @@ where S: Serializer, { let mut circuit_bytes: Vec = Vec::new(); - circuit.write(&mut circuit_bytes).unwrap(); + circuit.write(&mut circuit_bytes).map_err(|err| S::Error::custom(err.to_string()))?; let encoded_b64 = base64::engine::general_purpose::STANDARD.encode(circuit_bytes); s.serialize_str(&encoded_b64) } @@ -28,6 +29,7 @@ where { let bytecode_b64: String = serde::Deserialize::deserialize(deserializer)?; let circuit_bytes = base64::engine::general_purpose::STANDARD.decode(bytecode_b64).unwrap(); - let circuit = Circuit::read(&*circuit_bytes).unwrap(); + let circuit = + Circuit::read(&*circuit_bytes).map_err(|err| D::Error::custom(err.to_string()))?; Ok(circuit) } diff --git a/tooling/nargo/src/artifacts/program.rs b/tooling/nargo/src/artifacts/program.rs index 190b4c76897..a12642dc123 100644 --- a/tooling/nargo/src/artifacts/program.rs +++ b/tooling/nargo/src/artifacts/program.rs @@ -15,6 +15,9 @@ pub struct PreprocessedProgram { /// Used to short-circuit compilation in the case of the source code not changing since the last compilation. pub hash: u64, + /// Version of nargo used to compile this contract + pub nargo_version: String, + pub backend: String, pub abi: Abi, diff --git a/tooling/nargo_cli/src/cli/compile_cmd.rs b/tooling/nargo_cli/src/cli/compile_cmd.rs index a332d63e062..6047d5fcf16 100644 --- a/tooling/nargo_cli/src/cli/compile_cmd.rs +++ b/tooling/nargo_cli/src/cli/compile_cmd.rs @@ -28,6 +28,7 @@ use super::fs::program::{ save_contract_to_file, save_debug_artifact_to_file, save_program_to_file, }; use super::NargoConfig; +use super::NOIR_ARTIFACT_VERSION_STRING; use rayon::prelude::*; // TODO(#1388): pull this from backend. @@ -198,14 +199,18 @@ fn compile_program( let cached_program = if let Ok(preprocessed_program) = read_program_from_file(workspace.package_build_path(package)) { - // TODO: Load debug information. - Some(CompiledProgram { - hash: preprocessed_program.hash, - circuit: preprocessed_program.bytecode, - abi: preprocessed_program.abi, - debug: DebugInfo::default(), - file_map: BTreeMap::new(), - }) + if preprocessed_program.nargo_version != NOIR_ARTIFACT_VERSION_STRING { + None + } else { + // TODO: Load debug information. + Some(CompiledProgram { + hash: preprocessed_program.hash, + circuit: preprocessed_program.bytecode, + abi: preprocessed_program.abi, + debug: DebugInfo::default(), + file_map: BTreeMap::new(), + }) + } } else { None }; @@ -271,6 +276,7 @@ fn save_program( output_debug: bool, ) { let preprocessed_program = PreprocessedProgram { + nargo_version: String::from(NOIR_ARTIFACT_VERSION_STRING), hash: program.hash, backend: String::from(BACKEND_IDENTIFIER), abi: program.abi, @@ -311,6 +317,7 @@ fn save_contract( }); let preprocessed_contract = PreprocessedContract { + nargo_version: String::from(NOIR_ARTIFACT_VERSION_STRING), name: contract.name, backend: String::from(BACKEND_IDENTIFIER), functions: preprocessed_functions, diff --git a/tooling/nargo_cli/src/cli/mod.rs b/tooling/nargo_cli/src/cli/mod.rs index a0ef778e1a5..7a5a3d0752e 100644 --- a/tooling/nargo_cli/src/cli/mod.rs +++ b/tooling/nargo_cli/src/cli/mod.rs @@ -28,6 +28,10 @@ const GIT_HASH: &str = env!("GIT_COMMIT"); const IS_DIRTY: &str = env!("GIT_DIRTY"); const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); +/// Version string that gets placed in artifacts that Noir builds +pub(crate) const NOIR_ARTIFACT_VERSION_STRING: &str = + concat!(env!("CARGO_PKG_VERSION"), "-", env!("GIT_COMMIT")); + static VERSION_STRING: &str = formatcp!("{} (git version hash: {}, is dirty: {})", CARGO_PKG_VERSION, GIT_HASH, IS_DIRTY);