From 0d0be23e2923e0077ceadeb880a0cdc9ae2e5a95 Mon Sep 17 00:00:00 2001 From: guipublic <47281315+guipublic@users.noreply.github.com> Date: Tue, 24 Oct 2023 10:22:36 +0200 Subject: [PATCH] fix: recompile artefacts from a different noir version (#3248) Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: kek kek kek Co-authored-by: kevaundray --- Cargo.lock | 1 + compiler/noirc_driver/Cargo.toml | 3 +++ compiler/noirc_driver/build.rs | 14 ++++++++++++++ compiler/noirc_driver/src/contract.rs | 2 ++ compiler/noirc_driver/src/lib.rs | 19 ++++++++++++++++++- compiler/noirc_driver/src/program.rs | 1 + compiler/wasm/build.rs | 10 ---------- compiler/wasm/src/compile.rs | 4 +++- compiler/wasm/src/lib.rs | 8 +++----- release-tests/test/version.test.js | 5 ++++- tooling/nargo/src/artifacts/contract.rs | 2 ++ tooling/nargo/src/artifacts/program.rs | 2 ++ tooling/nargo_cli/src/cli/compile_cmd.rs | 8 +++++++- tooling/nargo_cli/src/cli/init_cmd.rs | 5 +++-- tooling/nargo_cli/src/cli/mod.rs | 14 ++++++++++---- 15 files changed, 73 insertions(+), 25 deletions(-) create mode 100644 compiler/noirc_driver/build.rs diff --git a/Cargo.lock b/Cargo.lock index 8fb282dda98..4cc03fcfdcb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2623,6 +2623,7 @@ version = "0.17.0" dependencies = [ "acvm", "base64", + "build-data", "clap", "fm", "fxhash", diff --git a/compiler/noirc_driver/Cargo.toml b/compiler/noirc_driver/Cargo.toml index f1c21f74aab..f1c120e1687 100644 --- a/compiler/noirc_driver/Cargo.toml +++ b/compiler/noirc_driver/Cargo.toml @@ -7,6 +7,9 @@ license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[build-dependencies] +build-data = "0.1.3" + [dependencies] clap.workspace = true noirc_errors.workspace = true diff --git a/compiler/noirc_driver/build.rs b/compiler/noirc_driver/build.rs new file mode 100644 index 00000000000..7b5a645c026 --- /dev/null +++ b/compiler/noirc_driver/build.rs @@ -0,0 +1,14 @@ +const GIT_COMMIT: &&str = &"GIT_COMMIT"; + +fn main() { + // Rebuild if the tests have changed + println!("cargo:rerun-if-changed=tests"); + + // Only use build_data if the environment variable isn't set + // The environment variable is always set when working via Nix + if std::env::var(GIT_COMMIT).is_err() { + build_data::set_GIT_COMMIT(); + build_data::set_GIT_DIRTY(); + build_data::no_debug_rebuilds(); + } +} diff --git a/compiler/noirc_driver/src/contract.rs b/compiler/noirc_driver/src/contract.rs index a16da313ff6..da097d4cb86 100644 --- a/compiler/noirc_driver/src/contract.rs +++ b/compiler/noirc_driver/src/contract.rs @@ -28,6 +28,8 @@ pub enum ContractFunctionType { #[derive(Serialize, Deserialize)] pub struct CompiledContract { + pub noir_version: String, + /// The name of the contract. pub name: String, /// Each of the contract's functions are compiled into a separate `CompiledProgram` diff --git a/compiler/noirc_driver/src/lib.rs b/compiler/noirc_driver/src/lib.rs index 44e50f94874..f8908efc596 100644 --- a/compiler/noirc_driver/src/lib.rs +++ b/compiler/noirc_driver/src/lib.rs @@ -28,6 +28,15 @@ pub use program::CompiledProgram; const STD_CRATE_NAME: &str = "std"; +pub const GIT_COMMIT: &str = env!("GIT_COMMIT"); +pub const GIT_DIRTY: &str = env!("GIT_DIRTY"); +pub const NOIRC_VERSION: &str = env!("CARGO_PKG_VERSION"); + +/// Version string that gets placed in artifacts that Noir builds. This is semver compatible. +/// Note: You can't directly use the value of a constant produced with env! inside a concat! macro. +pub const NOIR_ARTIFACT_VERSION_STRING: &str = + concat!(env!("CARGO_PKG_VERSION"), "+", env!("GIT_COMMIT")); + #[derive(Args, Clone, Debug, Default, Serialize, Deserialize)] pub struct CompileOptions { /// Emit debug information for the intermediate SSA IR @@ -305,6 +314,7 @@ fn compile_contract_inner( .collect(), functions, file_map, + noir_version: NOIR_ARTIFACT_VERSION_STRING.to_string(), }) } else { Err(errors) @@ -342,5 +352,12 @@ pub fn compile_no_check( let file_map = filter_relevant_files(&[debug.clone()], &context.file_manager); - Ok(CompiledProgram { hash, circuit, debug, abi, file_map }) + Ok(CompiledProgram { + hash, + circuit, + debug, + abi, + file_map, + noir_version: NOIR_ARTIFACT_VERSION_STRING.to_string(), + }) } diff --git a/compiler/noirc_driver/src/program.rs b/compiler/noirc_driver/src/program.rs index 8a13092aeb6..fe991567180 100644 --- a/compiler/noirc_driver/src/program.rs +++ b/compiler/noirc_driver/src/program.rs @@ -12,6 +12,7 @@ use super::debug::DebugFile; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct CompiledProgram { + pub noir_version: String, /// Hash of the [`Program`][noirc_frontend::monomorphization::ast::Program] from which this [`CompiledProgram`] /// was compiled. /// diff --git a/compiler/wasm/build.rs b/compiler/wasm/build.rs index 3b96be74ef3..dc46037a1d9 100644 --- a/compiler/wasm/build.rs +++ b/compiler/wasm/build.rs @@ -1,14 +1,4 @@ -const GIT_COMMIT: &&str = &"GIT_COMMIT"; - fn main() { - // Only use build_data if the environment variable isn't set - // The environment variable is always set when working via Nix - if std::env::var(GIT_COMMIT).is_err() { - build_data::set_GIT_COMMIT(); - build_data::set_GIT_DIRTY(); - build_data::no_debug_rebuilds(); - } - build_data::set_SOURCE_TIMESTAMP(); build_data::no_debug_rebuilds(); } diff --git a/compiler/wasm/src/compile.rs b/compiler/wasm/src/compile.rs index 0f7baff4819..66f08dbabf5 100644 --- a/compiler/wasm/src/compile.rs +++ b/compiler/wasm/src/compile.rs @@ -7,7 +7,7 @@ use nargo::artifacts::{ }; use noirc_driver::{ add_dep, compile_contract, compile_main, prepare_crate, prepare_dependency, CompileOptions, - CompiledContract, CompiledProgram, + CompiledContract, CompiledProgram, NOIR_ARTIFACT_VERSION_STRING, }; use noirc_frontend::{graph::CrateGraph, hir::Context}; use std::path::Path; @@ -118,6 +118,7 @@ fn preprocess_program(program: CompiledProgram) -> PreprocessedProgram { hash: program.hash, backend: String::from(BACKEND_IDENTIFIER), abi: program.abi, + noir_version: NOIR_ARTIFACT_VERSION_STRING.to_string(), bytecode: program.circuit, } } @@ -136,6 +137,7 @@ fn preprocess_contract(contract: CompiledContract) -> PreprocessedContract { .collect(); PreprocessedContract { + noir_version: String::from(NOIR_ARTIFACT_VERSION_STRING), name: contract.name, backend: String::from(BACKEND_IDENTIFIER), functions: preprocessed_functions, diff --git a/compiler/wasm/src/lib.rs b/compiler/wasm/src/lib.rs index 3a8e00bc6dd..9f2f558f85c 100644 --- a/compiler/wasm/src/lib.rs +++ b/compiler/wasm/src/lib.rs @@ -7,6 +7,7 @@ use getrandom as _; use gloo_utils::format::JsValueSerdeExt; use log::Level; +use noirc_driver::{GIT_COMMIT, GIT_DIRTY, NOIRC_VERSION}; use serde::{Deserialize, Serialize}; use std::str::FromStr; use wasm_bindgen::prelude::*; @@ -37,11 +38,8 @@ pub fn init_log_level(level: String) { }); } -const BUILD_INFO: BuildInfo = BuildInfo { - git_hash: env!("GIT_COMMIT"), - version: env!("CARGO_PKG_VERSION"), - dirty: env!("GIT_DIRTY"), -}; +const BUILD_INFO: BuildInfo = + BuildInfo { git_hash: GIT_COMMIT, version: NOIRC_VERSION, dirty: GIT_DIRTY }; #[wasm_bindgen] pub fn build_info() -> JsValue { diff --git a/release-tests/test/version.test.js b/release-tests/test/version.test.js index 07051d1edce..7a70639d83e 100644 --- a/release-tests/test/version.test.js +++ b/release-tests/test/version.test.js @@ -21,9 +21,12 @@ test("promise resolved", async () => { test("prints version", async () => { const processOutput = (await $`${NARGO_BIN} --version`).toString(); - assert.match(processOutput, /nargo\s\d{1,2}.\d{1,2}/); + + // Regex to match the "nargo version" part of the output + assert.match(processOutput, /nargo version = \d{1,2}\.\d{1,2}\.\d{1,2}/); }); + test("reports a clean commit", async () => { const processOutput = (await $`${NARGO_BIN} --version`).toString(); assert.not.match(processOutput, /is dirty: true/) diff --git a/tooling/nargo/src/artifacts/contract.rs b/tooling/nargo/src/artifacts/contract.rs index fa161b63a5b..4f1ae0e10a0 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 noir used to compile this contract + pub noir_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/program.rs b/tooling/nargo/src/artifacts/program.rs index 190b4c76897..5988f3f59cb 100644 --- a/tooling/nargo/src/artifacts/program.rs +++ b/tooling/nargo/src/artifacts/program.rs @@ -9,6 +9,8 @@ use serde::{Deserialize, Serialize}; /// - Proving and verification keys have been pregenerated based on this ACIR. #[derive(Serialize, Deserialize, Debug)] pub struct PreprocessedProgram { + pub noir_version: String, + /// Hash of the [`Program`][noirc_frontend::monomorphization::ast::Program] from which this [`PreprocessedProgram`] /// was compiled. /// diff --git a/tooling/nargo_cli/src/cli/compile_cmd.rs b/tooling/nargo_cli/src/cli/compile_cmd.rs index e3161b6d13d..56f91843914 100644 --- a/tooling/nargo_cli/src/cli/compile_cmd.rs +++ b/tooling/nargo_cli/src/cli/compile_cmd.rs @@ -13,6 +13,7 @@ use nargo::package::Package; use nargo::prepare_package; use nargo::workspace::Workspace; use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; +use noirc_driver::NOIR_ARTIFACT_VERSION_STRING; use noirc_driver::{CompilationResult, CompileOptions, CompiledContract, CompiledProgram}; use noirc_frontend::graph::CrateName; @@ -183,6 +184,7 @@ fn compile_program( hash: preprocessed_program.hash, circuit: preprocessed_program.bytecode, abi: preprocessed_program.abi, + noir_version: preprocessed_program.noir_version, debug: debug_artifact.debug_symbols.remove(0), file_map: debug_artifact.file_map, }) @@ -190,12 +192,14 @@ fn compile_program( None }; + let force_recompile = + cached_program.as_ref().map_or(false, |p| p.noir_version != NOIR_ARTIFACT_VERSION_STRING); let (program, warnings) = match noirc_driver::compile_main( &mut context, crate_id, compile_options, cached_program, - false, + force_recompile, ) { Ok(program_and_warnings) => program_and_warnings, Err(errors) => { @@ -241,6 +245,7 @@ fn save_program(program: CompiledProgram, package: &Package, circuit_dir: &Path) hash: program.hash, backend: String::from(BACKEND_IDENTIFIER), abi: program.abi, + noir_version: program.noir_version, bytecode: program.circuit, }; @@ -271,6 +276,7 @@ fn save_contract(contract: CompiledContract, package: &Package, circuit_dir: &Pa }); let preprocessed_contract = PreprocessedContract { + noir_version: contract.noir_version, name: contract.name, backend: String::from(BACKEND_IDENTIFIER), functions: preprocessed_functions, diff --git a/tooling/nargo_cli/src/cli/init_cmd.rs b/tooling/nargo_cli/src/cli/init_cmd.rs index 6dc7b9bd98e..9d7700a6598 100644 --- a/tooling/nargo_cli/src/cli/init_cmd.rs +++ b/tooling/nargo_cli/src/cli/init_cmd.rs @@ -2,10 +2,11 @@ use crate::backends::Backend; use crate::errors::CliError; use super::fs::{create_named_dir, write_to_file}; -use super::{NargoConfig, CARGO_PKG_VERSION}; +use super::NargoConfig; use clap::Args; use nargo::constants::{PKG_FILE, SRC_DIR}; use nargo::package::PackageType; +use noirc_driver::NOIRC_VERSION; use noirc_frontend::graph::CrateName; use std::path::PathBuf; @@ -72,7 +73,7 @@ pub(crate) fn initialize_project( name = "{package_name}" type = "{package_type}" authors = [""] -compiler_version = "{CARGO_PKG_VERSION}" +compiler_version = "{NOIRC_VERSION}" [dependencies]"# ); diff --git a/tooling/nargo_cli/src/cli/mod.rs b/tooling/nargo_cli/src/cli/mod.rs index a0ef778e1a5..8d22fb1b204 100644 --- a/tooling/nargo_cli/src/cli/mod.rs +++ b/tooling/nargo_cli/src/cli/mod.rs @@ -1,6 +1,7 @@ use clap::{Args, Parser, Subcommand}; use const_format::formatcp; use nargo_toml::find_package_root; +use noirc_driver::NOIR_ARTIFACT_VERSION_STRING; use std::path::PathBuf; use color_eyre::eyre; @@ -26,10 +27,15 @@ mod verify_cmd; const GIT_HASH: &str = env!("GIT_COMMIT"); const IS_DIRTY: &str = env!("GIT_DIRTY"); -const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); - -static VERSION_STRING: &str = - formatcp!("{} (git version hash: {}, is dirty: {})", CARGO_PKG_VERSION, GIT_HASH, IS_DIRTY); +const NARGO_VERSION: &str = env!("CARGO_PKG_VERSION"); + +static VERSION_STRING: &str = formatcp!( + "version = {}\nnoirc version = {}\n(git version hash: {}, is dirty: {})", + NARGO_VERSION, + NOIR_ARTIFACT_VERSION_STRING, + GIT_HASH, + IS_DIRTY +); #[derive(Parser, Debug)] #[command(name="nargo", author, version=VERSION_STRING, about, long_about = None)]