From da2525d740c7170fd5213867c6a590e03cd4e590 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 11 May 2023 17:04:40 -0700 Subject: [PATCH 1/5] feat(nargo): Only download as much CRS as you need --- Cargo.lock | 118 +++++++++++------- Cargo.toml | 4 +- crates/nargo/Cargo.toml | 1 - crates/nargo/src/ops/codegen_verifier.rs | 3 +- crates/nargo/src/ops/mod.rs | 2 +- crates/nargo/src/ops/preprocess.rs | 50 ++++---- crates/nargo/src/ops/prove.rs | 3 +- crates/nargo/src/ops/verify.rs | 3 +- crates/nargo_cli/Cargo.toml | 1 + .../nargo_cli/src/cli/codegen_verifier_cmd.rs | 28 +++-- crates/nargo_cli/src/cli/compile_cmd.rs | 42 +++++-- .../src/cli/fs/common_reference_string.rs | 42 +++++++ crates/nargo_cli/src/cli/fs/mod.rs | 1 + crates/nargo_cli/src/cli/prove_cmd.rs | 36 ++++-- crates/nargo_cli/src/cli/verify_cmd.rs | 42 +++++-- crates/nargo_cli/src/errors.rs | 9 +- crates/noirc_driver/src/lib.rs | 3 +- flake.nix | 34 +++-- 18 files changed, 290 insertions(+), 132 deletions(-) create mode 100644 crates/nargo_cli/src/cli/fs/common_reference_string.rs diff --git a/Cargo.lock b/Cargo.lock index 88237d6b6d0..aeaa9e45f96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ version = 3 [[package]] name = "acir" version = "0.11.0" -source = "git+https://github.com/noir-lang/acvm?rev=bbd9ab7ca5be3fb31f3e141fee2522704852f5de#bbd9ab7ca5be3fb31f3e141fee2522704852f5de" +source = "git+https://github.com/noir-lang/acvm?rev=44604f872126602787e38794026d86345380f2bb#44604f872126602787e38794026d86345380f2bb" dependencies = [ "acir_field", "flate2", @@ -17,7 +17,7 @@ dependencies = [ [[package]] name = "acir_field" version = "0.11.0" -source = "git+https://github.com/noir-lang/acvm?rev=bbd9ab7ca5be3fb31f3e141fee2522704852f5de#bbd9ab7ca5be3fb31f3e141fee2522704852f5de" +source = "git+https://github.com/noir-lang/acvm?rev=44604f872126602787e38794026d86345380f2bb#44604f872126602787e38794026d86345380f2bb" dependencies = [ "ark-bn254", "ark-ff", @@ -30,10 +30,11 @@ dependencies = [ [[package]] name = "acvm" version = "0.11.0" -source = "git+https://github.com/noir-lang/acvm?rev=bbd9ab7ca5be3fb31f3e141fee2522704852f5de#bbd9ab7ca5be3fb31f3e141fee2522704852f5de" +source = "git+https://github.com/noir-lang/acvm?rev=44604f872126602787e38794026d86345380f2bb#44604f872126602787e38794026d86345380f2bb" dependencies = [ "acir", "acvm_stdlib", + "async-trait", "blake2", "crc32fast", "indexmap", @@ -48,26 +49,27 @@ dependencies = [ [[package]] name = "acvm-backend-barretenberg" version = "0.1.2" -source = "git+https://github.com/noir-lang/acvm-backend-barretenberg?rev=4f622b58144330ebc53d8458bd9e456a8efb147c#4f622b58144330ebc53d8458bd9e456a8efb147c" +source = "git+https://github.com/noir-lang/acvm-backend-barretenberg?rev=5647a7f329865ec4c12e468f40d6cdb38fb921a2#5647a7f329865ec4c12e468f40d6cdb38fb921a2" dependencies = [ "acvm", "barretenberg-sys", - "dirs 3.0.2", + "bincode", + "bytes", "futures-util", "getrandom", "indicatif", "pkg-config", "reqwest", "rust-embed", + "serde", "thiserror", - "tokio", "wasmer", ] [[package]] name = "acvm_stdlib" version = "0.11.0" -source = "git+https://github.com/noir-lang/acvm?rev=bbd9ab7ca5be3fb31f3e141fee2522704852f5de#bbd9ab7ca5be3fb31f3e141fee2522704852f5de" +source = "git+https://github.com/noir-lang/acvm?rev=44604f872126602787e38794026d86345380f2bb#44604f872126602787e38794026d86345380f2bb" dependencies = [ "acir", ] @@ -195,7 +197,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d6873aaba7959593d89babed381d33e2329453368f1bf3c67e07686a1c1056f" dependencies = [ "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -208,7 +210,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -244,7 +246,7 @@ checksum = "fd34f0920d995d2c932f38861c416f70de89a6de9875876b012557079603e6cc" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -287,6 +289,17 @@ dependencies = [ "tempfile", ] +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.12", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -328,6 +341,15 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bindgen" version = "0.64.0" @@ -346,7 +368,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn", + "syn 1.0.109", "which", ] @@ -442,7 +464,7 @@ checksum = "e31225543cb46f81a7e224762764f4a6a0f097b1db0b175f69e8065efaa42de5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -544,7 +566,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -844,7 +866,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn", + "syn 1.0.109", ] [[package]] @@ -861,7 +883,7 @@ checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -884,7 +906,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -895,7 +917,7 @@ checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" dependencies = [ "darling_core", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -915,7 +937,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -944,15 +966,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "dirs" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" -dependencies = [ - "dirs-sys", -] - [[package]] name = "dirs" version = "4.0.0" @@ -1046,7 +1059,7 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1067,7 +1080,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1213,7 +1226,7 @@ checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1748,7 +1761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" dependencies = [ "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1837,7 +1850,6 @@ name = "nargo" version = "0.5.1" dependencies = [ "acvm", - "iter-extended", "noirc_abi", "noirc_driver", "rustc_version", @@ -1859,7 +1871,7 @@ dependencies = [ "clap", "color-eyre", "const_format", - "dirs 4.0.0", + "dirs", "hex", "iter-extended", "nargo", @@ -1873,6 +1885,7 @@ dependencies = [ "tempdir", "termcolor", "thiserror", + "tokio", "toml", "url", ] @@ -2184,7 +2197,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -2234,7 +2247,7 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2509,7 +2522,7 @@ checksum = "ff26ed6c7c4dfc2aa9480b86a60e3c7233543a270a680e10758a507c5a4ce476" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2555,7 +2568,7 @@ dependencies = [ "quote", "rust-embed-utils", "shellexpand", - "syn", + "syn 1.0.109", "walkdir", ] @@ -2760,7 +2773,7 @@ checksum = "d071a94a3fac4aff69d023a7f411e33f40f3483f8c5190b1953822b6b76d7630" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2844,7 +2857,7 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" dependencies = [ - "dirs 4.0.0", + "dirs", ] [[package]] @@ -2959,7 +2972,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 1.0.109", ] [[package]] @@ -2979,6 +2992,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "synstructure" version = "0.12.6" @@ -2987,7 +3011,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", "unicode-xid", ] @@ -3052,7 +3076,7 @@ checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -3193,7 +3217,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -3366,7 +3390,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-shared", ] @@ -3400,7 +3424,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3531,7 +3555,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -3938,6 +3962,6 @@ checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", "synstructure", ] diff --git a/Cargo.toml b/Cargo.toml index 4563a629043..4f56b550cae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,5 +52,5 @@ wasm-bindgen = { version = "0.2.83", features = ["serde-serialize"] } wasm-bindgen-test = "0.3.33" [patch.crates-io] -acvm = { package = "acvm", git = "https://github.com/noir-lang/acvm", rev = "bbd9ab7ca5be3fb31f3e141fee2522704852f5de" } -acvm-backend-barretenberg = { git = "https://github.com/noir-lang/acvm-backend-barretenberg", rev = "4f622b58144330ebc53d8458bd9e456a8efb147c" } +acvm = { package = "acvm", git = "https://github.com/noir-lang/acvm", rev = "44604f872126602787e38794026d86345380f2bb" } +acvm-backend-barretenberg = { git = "https://github.com/noir-lang/acvm-backend-barretenberg", rev = "5647a7f329865ec4c12e468f40d6cdb38fb921a2" } diff --git a/crates/nargo/Cargo.toml b/crates/nargo/Cargo.toml index 8d3c9fbd3cd..77c881835dc 100644 --- a/crates/nargo/Cargo.toml +++ b/crates/nargo/Cargo.toml @@ -14,7 +14,6 @@ rustc_version = "0.4.0" acvm.workspace = true noirc_abi.workspace = true noirc_driver.workspace = true -iter-extended.workspace = true toml.workspace = true serde.workspace = true thiserror.workspace = true diff --git a/crates/nargo/src/ops/codegen_verifier.rs b/crates/nargo/src/ops/codegen_verifier.rs index 2a0b54df865..4db3d53f7aa 100644 --- a/crates/nargo/src/ops/codegen_verifier.rs +++ b/crates/nargo/src/ops/codegen_verifier.rs @@ -2,7 +2,8 @@ use acvm::SmartContract; pub fn codegen_verifier( backend: &B, + common_reference_string: &[u8], verification_key: &[u8], ) -> Result { - backend.eth_contract_from_vk(verification_key) + backend.eth_contract_from_vk(common_reference_string, verification_key) } diff --git a/crates/nargo/src/ops/mod.rs b/crates/nargo/src/ops/mod.rs index 5d1f096ecf4..8a0cce4b8c5 100644 --- a/crates/nargo/src/ops/mod.rs +++ b/crates/nargo/src/ops/mod.rs @@ -1,6 +1,6 @@ pub use self::codegen_verifier::codegen_verifier; pub use self::execute::execute_circuit; -pub use self::preprocess::{preprocess_contract, preprocess_program}; +pub use self::preprocess::{preprocess_contract_function, preprocess_program}; pub use self::prove::prove_execution; pub use self::verify::verify_proof; diff --git a/crates/nargo/src/ops/preprocess.rs b/crates/nargo/src/ops/preprocess.rs index 3be8151f9c9..f2c3629e701 100644 --- a/crates/nargo/src/ops/preprocess.rs +++ b/crates/nargo/src/ops/preprocess.rs @@ -1,23 +1,21 @@ use acvm::ProofSystemCompiler; -use iter_extended::try_vecmap; -use noirc_driver::{CompiledContract, CompiledProgram}; +use noirc_driver::{CompiledProgram, ContractFunction}; -use crate::artifacts::{ - contract::{PreprocessedContract, PreprocessedContractFunction}, - program::PreprocessedProgram, -}; +use crate::artifacts::{contract::PreprocessedContractFunction, program::PreprocessedProgram}; // TODO: pull this from backend. const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; pub fn preprocess_program( backend: &B, + common_reference_string: &[u8], compiled_program: CompiledProgram, ) -> Result { // TODO: currently `compiled_program`'s bytecode is already optimized for the backend. // In future we'll need to apply those optimizations here. let optimized_bytecode = compiled_program.circuit; - let (proving_key, verification_key) = backend.preprocess(&optimized_bytecode)?; + let (proving_key, verification_key) = + backend.preprocess(common_reference_string, &optimized_bytecode)?; Ok(PreprocessedProgram { backend: String::from(BACKEND_IDENTIFIER), @@ -28,30 +26,24 @@ pub fn preprocess_program( }) } -pub fn preprocess_contract( +pub fn preprocess_contract_function( backend: &B, - compiled_contract: CompiledContract, -) -> Result { - let preprocessed_contract_functions = try_vecmap(compiled_contract.functions, |func| { - // TODO: currently `func`'s bytecode is already optimized for the backend. - // In future we'll need to apply those optimizations here. - let optimized_bytecode = func.bytecode; - let (proving_key, verification_key) = backend.preprocess(&optimized_bytecode)?; - - Ok(PreprocessedContractFunction { - name: func.name, - function_type: func.function_type, - abi: func.abi, + common_reference_string: &[u8], + func: ContractFunction, +) -> Result { + // TODO: currently `func`'s bytecode is already optimized for the backend. + // In future we'll need to apply those optimizations here. + let optimized_bytecode = func.bytecode; + let (proving_key, verification_key) = + backend.preprocess(common_reference_string, &optimized_bytecode)?; - bytecode: optimized_bytecode, - proving_key, - verification_key, - }) - })?; + Ok(PreprocessedContractFunction { + name: func.name, + function_type: func.function_type, + abi: func.abi, - Ok(PreprocessedContract { - name: compiled_contract.name, - backend: String::from(BACKEND_IDENTIFIER), - functions: preprocessed_contract_functions, + bytecode: optimized_bytecode, + proving_key, + verification_key, }) } diff --git a/crates/nargo/src/ops/prove.rs b/crates/nargo/src/ops/prove.rs index 523b2ed5ed4..e2c70739a35 100644 --- a/crates/nargo/src/ops/prove.rs +++ b/crates/nargo/src/ops/prove.rs @@ -3,9 +3,10 @@ use acvm::ProofSystemCompiler; pub fn prove_execution( backend: &B, + common_reference_string: &[u8], circuit: &Circuit, solved_witness: WitnessMap, proving_key: &[u8], ) -> Result, B::Error> { - backend.prove_with_pk(circuit, solved_witness, proving_key) + backend.prove_with_pk(common_reference_string, circuit, solved_witness, proving_key) } diff --git a/crates/nargo/src/ops/verify.rs b/crates/nargo/src/ops/verify.rs index f2145e3cf87..1d2d3bbbd6f 100644 --- a/crates/nargo/src/ops/verify.rs +++ b/crates/nargo/src/ops/verify.rs @@ -3,10 +3,11 @@ use acvm::ProofSystemCompiler; pub fn verify_proof( backend: &B, + common_reference_string: &[u8], circuit: &Circuit, proof: &[u8], public_inputs: WitnessMap, verification_key: &[u8], ) -> Result { - backend.verify_with_vk(proof, public_inputs, circuit, verification_key) + backend.verify_with_vk(common_reference_string, proof, public_inputs, circuit, verification_key) } diff --git a/crates/nargo_cli/Cargo.toml b/crates/nargo_cli/Cargo.toml index 74db54c8ef7..4b0c96e0eb9 100644 --- a/crates/nargo_cli/Cargo.toml +++ b/crates/nargo_cli/Cargo.toml @@ -35,6 +35,7 @@ hex = "0.4.2" serde_json = "1.0" termcolor = "1.1.2" color-eyre = "0.6.2" +tokio = "1.0" # Backends acvm-backend-barretenberg = { version = "0.1.2", default-features = false } diff --git a/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs b/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs index d38433e2d1c..5f7358d6c2c 100644 --- a/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs +++ b/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs @@ -1,4 +1,7 @@ -use super::fs::{create_named_dir, program::read_program_from_file, write_to_file}; +use super::fs::{ + common_reference_string::get_common_reference_string, create_named_dir, + program::read_program_from_file, write_to_file, +}; use super::NargoConfig; use crate::{ cli::compile_cmd::compile_circuit, constants::CONTRACT_DIR, constants::TARGET_DIR, @@ -29,18 +32,27 @@ pub(crate) fn run( .circuit_name .map(|circuit_name| config.program_dir.join(TARGET_DIR).join(circuit_name)); - let preprocessed_program = match circuit_build_path { - Some(circuit_build_path) => read_program_from_file(circuit_build_path)?, + let (common_reference_string, preprocessed_program) = match circuit_build_path { + Some(circuit_build_path) => { + let program = read_program_from_file(circuit_build_path)?; + let common_reference_string = get_common_reference_string(backend, &program.bytecode) + .map_err(CliError::CommonReferenceStringError)?; + (common_reference_string, program) + } None => { - let compiled_program = + let program = compile_circuit(backend, config.program_dir.as_ref(), &args.compile_options)?; - preprocess_program(backend, compiled_program) - .map_err(CliError::ProofSystemCompilerError)? + let common_reference_string = get_common_reference_string(backend, &program.circuit) + .map_err(CliError::CommonReferenceStringError)?; + let program = preprocess_program(backend, &common_reference_string, program) + .map_err(CliError::ProofSystemCompilerError)?; + (common_reference_string, program) } }; - let smart_contract_string = codegen_verifier(backend, &preprocessed_program.verification_key) - .map_err(CliError::SmartContractError)?; + let smart_contract_string = + codegen_verifier(backend, &common_reference_string, &preprocessed_program.verification_key) + .map_err(CliError::SmartContractError)?; let contract_dir = config.program_dir.join(CONTRACT_DIR); create_named_dir(&contract_dir, "contract"); diff --git a/crates/nargo_cli/src/cli/compile_cmd.rs b/crates/nargo_cli/src/cli/compile_cmd.rs index 531560b87db..04d44057ee4 100644 --- a/crates/nargo_cli/src/cli/compile_cmd.rs +++ b/crates/nargo_cli/src/cli/compile_cmd.rs @@ -1,18 +1,25 @@ use acvm::Backend; use iter_extended::try_vecmap; +use nargo::artifacts::contract::PreprocessedContract; use noirc_driver::{CompileOptions, CompiledProgram, Driver}; use std::path::Path; use clap::Args; -use nargo::ops::{preprocess_contract, preprocess_program}; +use nargo::ops::{preprocess_contract_function, preprocess_program}; use crate::resolver::DependencyResolutionError; use crate::{constants::TARGET_DIR, errors::CliError, resolver::Resolver}; -use super::fs::program::{save_contract_to_file, save_program_to_file}; +use super::fs::{ + common_reference_string::get_common_reference_string, + program::{save_contract_to_file, save_program_to_file}, +}; use super::NargoConfig; +// TODO: pull this from backend. +const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; + /// Compile the program and its secret execution trace into ACIR format #[derive(Debug, Clone, Args)] pub(crate) struct CompileCommand { @@ -40,10 +47,27 @@ pub(crate) fn run( let compiled_contracts = driver .compile_contracts(&args.compile_options) .map_err(|_| CliError::CompilationError)?; - let preprocessed_contracts = try_vecmap(compiled_contracts, |contract| { - preprocess_contract(backend, contract).map_err(CliError::ProofSystemCompilerError) - })?; - for contract in preprocessed_contracts { + // TODO: I wonder if it is incorrect for nargo-core to know anything about contracts. + // As can be seen here, It seems like a leaky abstraction where ContractFunctions (essentially CompiledPrograms) + // are compiled via nargo-core and then the PreprocessedContract is constructed here. + // This is due to EACH function needing it's own CRS, PKey, and VKey from the backend. + let preprocessed_contracts: Result, CliError> = + try_vecmap(compiled_contracts, |contract| { + let preprocessed_contract_functions = try_vecmap(contract.functions, |func| { + let common_reference_string = + get_common_reference_string(backend, &func.bytecode) + .map_err(CliError::CommonReferenceStringError)?; + preprocess_contract_function(backend, &common_reference_string, func) + .map_err(CliError::ProofSystemCompilerError) + })?; + + Ok(PreprocessedContract { + name: contract.name, + backend: String::from(BACKEND_IDENTIFIER), + functions: preprocessed_contract_functions, + }) + }); + for contract in preprocessed_contracts? { save_contract_to_file( &contract, &format!("{}-{}", &args.circuit_name, contract.name), @@ -52,8 +76,10 @@ pub(crate) fn run( } } else { let program = compile_circuit(backend, &config.program_dir, &args.compile_options)?; - let preprocessed_program = - preprocess_program(backend, program).map_err(CliError::ProofSystemCompilerError)?; + let common_reference_string = get_common_reference_string(backend, &program.circuit) + .map_err(CliError::CommonReferenceStringError)?; + let preprocessed_program = preprocess_program(backend, &common_reference_string, program) + .map_err(CliError::ProofSystemCompilerError)?; save_program_to_file(&preprocessed_program, &args.circuit_name, circuit_dir); } Ok(()) diff --git a/crates/nargo_cli/src/cli/fs/common_reference_string.rs b/crates/nargo_cli/src/cli/fs/common_reference_string.rs new file mode 100644 index 00000000000..b6fa1a28349 --- /dev/null +++ b/crates/nargo_cli/src/cli/fs/common_reference_string.rs @@ -0,0 +1,42 @@ +use std::{env, path::PathBuf}; + +use acvm::{acir::circuit::Circuit, CommonReferenceString}; + +use super::{create_named_dir, write_to_file}; + +// TODO: pull this from backend. +const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; +const TRANSCRIPT_NAME: &str = "common-reference-string.bin"; + +fn common_reference_string_location() -> PathBuf { + let cache_dir = match env::var("BACKEND_CACHE_DIR") { + Ok(cache_dir) => PathBuf::from(cache_dir), + Err(_) => dirs::home_dir().unwrap().join(".nargo").join("backends"), + }; + cache_dir.join(BACKEND_IDENTIFIER).join(TRANSCRIPT_NAME) +} + +pub(crate) fn get_common_reference_string( + backend: &Backend, + circuit: &Circuit, +) -> Result, Backend::Error> { + use tokio::runtime::Builder; + + let crs_path = common_reference_string_location(); + + let runtime = Builder::new_current_thread().enable_all().build().unwrap(); + + // TODO: Implement retries + let crs = match std::fs::read(&crs_path) { + // If the read data is empty, we don't have a CRS and need to generate one + Ok(common_reference_string) if !common_reference_string.is_empty() => runtime + .block_on(backend.update_common_reference_string(common_reference_string, circuit))?, + Ok(_) | Err(_) => runtime.block_on(backend.generate_common_reference_string(circuit))?, + }; + + create_named_dir(crs_path.parent().unwrap(), "crs"); + + write_to_file(crs.as_slice(), &crs_path); + + Ok(crs) +} diff --git a/crates/nargo_cli/src/cli/fs/mod.rs b/crates/nargo_cli/src/cli/fs/mod.rs index 4ebce3b3325..73229e0476c 100644 --- a/crates/nargo_cli/src/cli/fs/mod.rs +++ b/crates/nargo_cli/src/cli/fs/mod.rs @@ -6,6 +6,7 @@ use std::{ use crate::errors::FilesystemError; +pub(super) mod common_reference_string; pub(super) mod inputs; pub(super) mod program; pub(super) mod proof; diff --git a/crates/nargo_cli/src/cli/prove_cmd.rs b/crates/nargo_cli/src/cli/prove_cmd.rs index d2adc8d4af1..7589dd4bba3 100644 --- a/crates/nargo_cli/src/cli/prove_cmd.rs +++ b/crates/nargo_cli/src/cli/prove_cmd.rs @@ -11,6 +11,7 @@ use super::NargoConfig; use super::{ compile_cmd::compile_circuit, fs::{ + common_reference_string::get_common_reference_string, inputs::{read_inputs_from_file, write_inputs_to_file}, program::read_program_from_file, proof::save_proof_to_dir, @@ -72,12 +73,20 @@ pub(crate) fn prove_with_path>( check_proof: bool, compile_options: &CompileOptions, ) -> Result, CliError> { - let preprocessed_program = match circuit_build_path { - Some(circuit_build_path) => read_program_from_file(circuit_build_path)?, + let (common_reference_string, preprocessed_program) = match circuit_build_path { + Some(circuit_build_path) => { + let program = read_program_from_file(circuit_build_path)?; + let common_reference_string = get_common_reference_string(backend, &program.bytecode) + .map_err(CliError::CommonReferenceStringError)?; + (common_reference_string, program) + } None => { - let compiled_program = compile_circuit(backend, program_dir.as_ref(), compile_options)?; - preprocess_program(backend, compiled_program) - .map_err(CliError::ProofSystemCompilerError)? + let program = compile_circuit(backend, program_dir.as_ref(), compile_options)?; + let common_reference_string = get_common_reference_string(backend, &program.circuit) + .map_err(CliError::CommonReferenceStringError)?; + let program = preprocess_program(backend, &common_reference_string, program) + .map_err(CliError::ProofSystemCompilerError)?; + (common_reference_string, program) } }; @@ -102,14 +111,21 @@ pub(crate) fn prove_with_path>( Format::Toml, )?; - let proof = prove_execution(backend, &bytecode, solved_witness, &proving_key) - .map_err(CliError::ProofSystemCompilerError)?; + let proof = + prove_execution(backend, &common_reference_string, &bytecode, solved_witness, &proving_key) + .map_err(CliError::ProofSystemCompilerError)?; if check_proof { let public_inputs = public_abi.encode(&public_inputs, return_value)?; - let valid_proof = - verify_proof(backend, &bytecode, &proof, public_inputs, &verification_key) - .map_err(CliError::ProofSystemCompilerError)?; + let valid_proof = verify_proof( + backend, + &common_reference_string, + &bytecode, + &proof, + public_inputs, + &verification_key, + ) + .map_err(CliError::ProofSystemCompilerError)?; if !valid_proof { return Err(CliError::InvalidProof("".into())); diff --git a/crates/nargo_cli/src/cli/verify_cmd.rs b/crates/nargo_cli/src/cli/verify_cmd.rs index 07ba12d3899..62333ff0bdf 100644 --- a/crates/nargo_cli/src/cli/verify_cmd.rs +++ b/crates/nargo_cli/src/cli/verify_cmd.rs @@ -1,5 +1,8 @@ use super::compile_cmd::compile_circuit; -use super::fs::{inputs::read_inputs_from_file, load_hex_data, program::read_program_from_file}; +use super::fs::{ + common_reference_string::get_common_reference_string, inputs::read_inputs_from_file, + load_hex_data, program::read_program_from_file, +}; use super::NargoConfig; use crate::{ constants::{PROOFS_DIR, PROOF_EXT, TARGET_DIR, VERIFIER_INPUT_FILE}, @@ -9,7 +12,7 @@ use crate::{ use acvm::Backend; use clap::Args; use nargo::artifacts::program::PreprocessedProgram; -use nargo::ops::preprocess_program; +use nargo::ops::{preprocess_program, verify_proof}; use noirc_abi::input_parser::Format; use noirc_driver::CompileOptions; use std::path::{Path, PathBuf}; @@ -44,7 +47,7 @@ pub(crate) fn run( &config.program_dir, proof_path, circuit_build_path.as_ref(), - args.compile_options, + &args.compile_options, ) } @@ -53,15 +56,22 @@ fn verify_with_path>( program_dir: P, proof_path: PathBuf, circuit_build_path: Option

, - compile_options: CompileOptions, + compile_options: &CompileOptions, ) -> Result<(), CliError> { - let preprocessed_program = match circuit_build_path { - Some(circuit_build_path) => read_program_from_file(circuit_build_path)?, + let (common_reference_string, preprocessed_program) = match circuit_build_path { + Some(circuit_build_path) => { + let program = read_program_from_file(circuit_build_path)?; + let common_reference_string = get_common_reference_string(backend, &program.bytecode) + .map_err(CliError::CommonReferenceStringError)?; + (common_reference_string, program) + } None => { - let compiled_program = - compile_circuit(backend, program_dir.as_ref(), &compile_options)?; - preprocess_program(backend, compiled_program) - .map_err(CliError::ProofSystemCompilerError)? + let program = compile_circuit(backend, program_dir.as_ref(), compile_options)?; + let common_reference_string = get_common_reference_string(backend, &program.circuit) + .map_err(CliError::CommonReferenceStringError)?; + let program = preprocess_program(backend, &common_reference_string, program) + .map_err(CliError::ProofSystemCompilerError)?; + (common_reference_string, program) } }; @@ -75,9 +85,15 @@ fn verify_with_path>( let public_inputs = public_abi.encode(&public_inputs_map, return_value)?; let proof = load_hex_data(&proof_path)?; - let valid_proof = - nargo::ops::verify_proof(backend, &bytecode, &proof, public_inputs, &verification_key) - .map_err(CliError::ProofSystemCompilerError)?; + let valid_proof = verify_proof( + backend, + &common_reference_string, + &bytecode, + &proof, + public_inputs, + &verification_key, + ) + .map_err(CliError::ProofSystemCompilerError)?; if valid_proof { Ok(()) diff --git a/crates/nargo_cli/src/errors.rs b/crates/nargo_cli/src/errors.rs index 94772b578b4..02bc5b031a9 100644 --- a/crates/nargo_cli/src/errors.rs +++ b/crates/nargo_cli/src/errors.rs @@ -1,4 +1,7 @@ -use acvm::{acir::native_types::WitnessMapError, Backend, ProofSystemCompiler, SmartContract}; +use acvm::{ + acir::native_types::WitnessMapError, Backend, CommonReferenceString, ProofSystemCompiler, + SmartContract, +}; use hex::FromHexError; use nargo::NargoError; use noirc_abi::errors::{AbiError, InputParserError}; @@ -63,4 +66,8 @@ pub(crate) enum CliError { /// Backend error caused by a function on the ProofSystemCompiler trait #[error(transparent)] ProofSystemCompilerError(::Error), // Unfortunately, Rust won't let us `impl From` over an Associated Type on a generic + + /// Backend error caused by a function on the CommonReferenceString trait + #[error(transparent)] + CommonReferenceStringError(::Error), // Unfortunately, Rust won't let us `impl From` over an Associated Type on a generic } diff --git a/crates/noirc_driver/src/lib.rs b/crates/noirc_driver/src/lib.rs index a2fbed21885..bff5a7d6943 100644 --- a/crates/noirc_driver/src/lib.rs +++ b/crates/noirc_driver/src/lib.rs @@ -5,7 +5,6 @@ use acvm::Language; use clap::Args; -use contract::ContractFunction; use fm::FileType; use iter_extended::try_vecmap; use noirc_abi::FunctionSignature; @@ -22,7 +21,7 @@ use std::path::{Path, PathBuf}; mod contract; mod program; -pub use contract::{CompiledContract, ContractFunctionType}; +pub use contract::{CompiledContract, ContractFunction, ContractFunctionType}; pub use program::CompiledProgram; pub struct Driver { diff --git a/flake.nix b/flake.nix index 7109e266e0f..d5df9c4b122 100644 --- a/flake.nix +++ b/flake.nix @@ -84,10 +84,6 @@ # We set the environment variable because barretenberg must be compiled in a special way for wasm BARRETENBERG_BIN_DIR = "${pkgs.barretenberg-wasm}/bin"; - - # We provide `barretenberg-transcript00` from the overlay to the build. - # This is necessary because the Nix sandbox disables the $HOME so downloading during tests would fail - BARRETENBERG_TRANSCRIPT = pkgs.barretenberg-transcript00; }; # The `self.rev` property is only available when the working tree is not dirty @@ -138,6 +134,31 @@ inherit GIT_DIRTY; }; + # The `port` is parameterized to support parallel test runs without colliding static servers + testArgs = port: { + # We provide `barretenberg-transcript00` from the overlay to the tests as a URL hosted via a static server + # This is necessary because the Nix sandbox has no network access and downloading during tests would fail + TRANSCRIPT_URL = "http://0.0.0.0:${toString port}/${builtins.baseNameOf pkgs.barretenberg-transcript00}"; + + # This copies the `barretenberg-transcript00` from the Nix store into this sandbox + # which avoids exposing the entire Nix store to the static server it starts + # The static server is moved to the background and killed after checks are completed + # + # We also set the BACKEND_CACHE_DIR environment variable to the $TMP directory so we can successfully cache + # the transcript; which isn't possible with the default path because the Nix sandbox disabled $HOME + preCheck = '' + export BACKEND_CACHE_DIR=$TMP + cp ${pkgs.barretenberg-transcript00} . + echo "Starting simple static server" + ${pkgs.simple-http-server}/bin/simple-http-server --port ${toString port} --silent & + HTTP_SERVER_PID=$! + ''; + + postCheck = '' + kill $HTTP_SERVER_PID + ''; + }; + # Build *just* the cargo dependencies, so we can reuse all of that work between runs cargoArtifacts = craneLib.buildDepsOnly commonArgs; @@ -152,16 +173,15 @@ # TODO(#1198): It'd be nice to include these flags when running `cargo clippy` in a devShell. cargoClippyExtraArgs = "--all-targets -- -D warnings"; - - doCheck = true; }); - cargo-test = craneLib.cargoTest (commonArgs // { + cargo-test = craneLib.cargoTest (commonArgs // (testArgs 8000) // { inherit cargoArtifacts; # TODO(#1198): It'd be nice to include this flag when running `cargo test` in a devShell. cargoTestExtraArgs = "--workspace"; + # It's unclear why doCheck needs to be enabled for tests to run but not clippy doCheck = true; }); }; From b6b2c6c89c29d59b6a29c6ad470b450d73589110 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 16 May 2023 08:55:38 -0700 Subject: [PATCH 2/5] update references --- Cargo.lock | 10 +++++----- Cargo.toml | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aeaa9e45f96..3ce02ca2667 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ version = 3 [[package]] name = "acir" version = "0.11.0" -source = "git+https://github.com/noir-lang/acvm?rev=44604f872126602787e38794026d86345380f2bb#44604f872126602787e38794026d86345380f2bb" +source = "git+https://github.com/noir-lang/acvm?rev=eeddcf179880f246383f7f67a11e589269c4e3ff#eeddcf179880f246383f7f67a11e589269c4e3ff" dependencies = [ "acir_field", "flate2", @@ -17,7 +17,7 @@ dependencies = [ [[package]] name = "acir_field" version = "0.11.0" -source = "git+https://github.com/noir-lang/acvm?rev=44604f872126602787e38794026d86345380f2bb#44604f872126602787e38794026d86345380f2bb" +source = "git+https://github.com/noir-lang/acvm?rev=eeddcf179880f246383f7f67a11e589269c4e3ff#eeddcf179880f246383f7f67a11e589269c4e3ff" dependencies = [ "ark-bn254", "ark-ff", @@ -30,7 +30,7 @@ dependencies = [ [[package]] name = "acvm" version = "0.11.0" -source = "git+https://github.com/noir-lang/acvm?rev=44604f872126602787e38794026d86345380f2bb#44604f872126602787e38794026d86345380f2bb" +source = "git+https://github.com/noir-lang/acvm?rev=eeddcf179880f246383f7f67a11e589269c4e3ff#eeddcf179880f246383f7f67a11e589269c4e3ff" dependencies = [ "acir", "acvm_stdlib", @@ -49,7 +49,7 @@ dependencies = [ [[package]] name = "acvm-backend-barretenberg" version = "0.1.2" -source = "git+https://github.com/noir-lang/acvm-backend-barretenberg?rev=5647a7f329865ec4c12e468f40d6cdb38fb921a2#5647a7f329865ec4c12e468f40d6cdb38fb921a2" +source = "git+https://github.com/noir-lang/acvm-backend-barretenberg?rev=04c9d0f6b5e0f3625fd7d1e2bb5bacb020ae279d#04c9d0f6b5e0f3625fd7d1e2bb5bacb020ae279d" dependencies = [ "acvm", "barretenberg-sys", @@ -69,7 +69,7 @@ dependencies = [ [[package]] name = "acvm_stdlib" version = "0.11.0" -source = "git+https://github.com/noir-lang/acvm?rev=44604f872126602787e38794026d86345380f2bb#44604f872126602787e38794026d86345380f2bb" +source = "git+https://github.com/noir-lang/acvm?rev=eeddcf179880f246383f7f67a11e589269c4e3ff#eeddcf179880f246383f7f67a11e589269c4e3ff" dependencies = [ "acir", ] diff --git a/Cargo.toml b/Cargo.toml index 4f56b550cae..94754c65b8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,5 +52,5 @@ wasm-bindgen = { version = "0.2.83", features = ["serde-serialize"] } wasm-bindgen-test = "0.3.33" [patch.crates-io] -acvm = { package = "acvm", git = "https://github.com/noir-lang/acvm", rev = "44604f872126602787e38794026d86345380f2bb" } -acvm-backend-barretenberg = { git = "https://github.com/noir-lang/acvm-backend-barretenberg", rev = "5647a7f329865ec4c12e468f40d6cdb38fb921a2" } +acvm = { package = "acvm", git = "https://github.com/noir-lang/acvm", rev = "eeddcf179880f246383f7f67a11e589269c4e3ff" } +acvm-backend-barretenberg = { git = "https://github.com/noir-lang/acvm-backend-barretenberg", rev = "04c9d0f6b5e0f3625fd7d1e2bb5bacb020ae279d" } From 7439e399778dea719d6d8c975fd3f3327166412a Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 17 May 2023 08:34:50 -0700 Subject: [PATCH 3/5] code review --- crates/nargo_cli/src/cli/fs/common_reference_string.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/nargo_cli/src/cli/fs/common_reference_string.rs b/crates/nargo_cli/src/cli/fs/common_reference_string.rs index b6fa1a28349..a8bfdb50ec1 100644 --- a/crates/nargo_cli/src/cli/fs/common_reference_string.rs +++ b/crates/nargo_cli/src/cli/fs/common_reference_string.rs @@ -16,10 +16,10 @@ fn common_reference_string_location() -> PathBuf { cache_dir.join(BACKEND_IDENTIFIER).join(TRANSCRIPT_NAME) } -pub(crate) fn get_common_reference_string( - backend: &Backend, +pub(crate) fn get_common_reference_string( + backend: &B, circuit: &Circuit, -) -> Result, Backend::Error> { +) -> Result, B::Error> { use tokio::runtime::Builder; let crs_path = common_reference_string_location(); From 4e66b8201dbb9009b3bdb886a9f2dc5800f6a980 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 18 May 2023 09:09:16 -0700 Subject: [PATCH 4/5] split crs utilities into 3 functions to isolate read and write ops --- .../nargo_cli/src/cli/codegen_verifier_cmd.rs | 26 ++++++++++---- crates/nargo_cli/src/cli/compile_cmd.rs | 27 ++++++++++---- .../src/cli/fs/common_reference_string.rs | 35 +++++++++++++------ crates/nargo_cli/src/cli/prove_cmd.rs | 22 +++++++++--- crates/nargo_cli/src/cli/verify_cmd.rs | 26 ++++++++++---- 5 files changed, 102 insertions(+), 34 deletions(-) diff --git a/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs b/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs index 5f7358d6c2c..b65d64bb917 100644 --- a/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs +++ b/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs @@ -1,6 +1,11 @@ use super::fs::{ - common_reference_string::get_common_reference_string, create_named_dir, - program::read_program_from_file, write_to_file, + common_reference_string::{ + read_cached_common_reference_string, update_common_reference_string, + write_cached_common_reference_string, + }, + create_named_dir, + program::read_program_from_file, + write_to_file, }; use super::NargoConfig; use crate::{ @@ -32,18 +37,25 @@ pub(crate) fn run( .circuit_name .map(|circuit_name| config.program_dir.join(TARGET_DIR).join(circuit_name)); + let common_reference_string = read_cached_common_reference_string(); + let (common_reference_string, preprocessed_program) = match circuit_build_path { Some(circuit_build_path) => { let program = read_program_from_file(circuit_build_path)?; - let common_reference_string = get_common_reference_string(backend, &program.bytecode) - .map_err(CliError::CommonReferenceStringError)?; + let common_reference_string = update_common_reference_string( + backend, + &common_reference_string, + &program.bytecode, + ) + .map_err(CliError::CommonReferenceStringError)?; (common_reference_string, program) } None => { let program = compile_circuit(backend, config.program_dir.as_ref(), &args.compile_options)?; - let common_reference_string = get_common_reference_string(backend, &program.circuit) - .map_err(CliError::CommonReferenceStringError)?; + let common_reference_string = + update_common_reference_string(backend, &common_reference_string, &program.circuit) + .map_err(CliError::CommonReferenceStringError)?; let program = preprocess_program(backend, &common_reference_string, program) .map_err(CliError::ProofSystemCompilerError)?; (common_reference_string, program) @@ -54,6 +66,8 @@ pub(crate) fn run( codegen_verifier(backend, &common_reference_string, &preprocessed_program.verification_key) .map_err(CliError::SmartContractError)?; + write_cached_common_reference_string(&common_reference_string); + let contract_dir = config.program_dir.join(CONTRACT_DIR); create_named_dir(&contract_dir, "contract"); let contract_path = contract_dir.join("plonk_vk").with_extension("sol"); diff --git a/crates/nargo_cli/src/cli/compile_cmd.rs b/crates/nargo_cli/src/cli/compile_cmd.rs index a41eb439ac8..a1cfca8b6ea 100644 --- a/crates/nargo_cli/src/cli/compile_cmd.rs +++ b/crates/nargo_cli/src/cli/compile_cmd.rs @@ -12,7 +12,10 @@ use crate::resolver::DependencyResolutionError; use crate::{constants::TARGET_DIR, errors::CliError, resolver::Resolver}; use super::fs::{ - common_reference_string::get_common_reference_string, + common_reference_string::{ + read_cached_common_reference_string, update_common_reference_string, + write_cached_common_reference_string, + }, program::{save_contract_to_file, save_program_to_file}, }; use super::NargoConfig; @@ -41,12 +44,15 @@ pub(crate) fn run( ) -> Result<(), CliError> { let circuit_dir = config.program_dir.join(TARGET_DIR); + let mut common_reference_string = read_cached_common_reference_string(); + // If contracts is set we're compiling every function in a 'contract' rather than just 'main'. if args.contracts { let mut driver = setup_driver(backend, &config.program_dir)?; let compiled_contracts = driver .compile_contracts(&args.compile_options) .map_err(|_| CliError::CompilationError)?; + // TODO: I wonder if it is incorrect for nargo-core to know anything about contracts. // As can be seen here, It seems like a leaky abstraction where ContractFunctions (essentially CompiledPrograms) // are compiled via nargo-core and then the PreprocessedContract is constructed here. @@ -54,9 +60,13 @@ pub(crate) fn run( let preprocessed_contracts: Result, CliError> = try_vecmap(compiled_contracts, |contract| { let preprocessed_contract_functions = try_vecmap(contract.functions, |func| { - let common_reference_string = - get_common_reference_string(backend, &func.bytecode) - .map_err(CliError::CommonReferenceStringError)?; + common_reference_string = update_common_reference_string( + backend, + &common_reference_string, + &func.bytecode, + ) + .map_err(CliError::CommonReferenceStringError)?; + preprocess_contract_function(backend, &common_reference_string, func) .map_err(CliError::ProofSystemCompilerError) })?; @@ -76,12 +86,17 @@ pub(crate) fn run( } } else { let program = compile_circuit(backend, &config.program_dir, &args.compile_options)?; - let common_reference_string = get_common_reference_string(backend, &program.circuit) - .map_err(CliError::CommonReferenceStringError)?; + common_reference_string = + update_common_reference_string(backend, &common_reference_string, &program.circuit) + .map_err(CliError::CommonReferenceStringError)?; + let preprocessed_program = preprocess_program(backend, &common_reference_string, program) .map_err(CliError::ProofSystemCompilerError)?; save_program_to_file(&preprocessed_program, &args.circuit_name, circuit_dir); } + + write_cached_common_reference_string(&common_reference_string); + Ok(()) } diff --git a/crates/nargo_cli/src/cli/fs/common_reference_string.rs b/crates/nargo_cli/src/cli/fs/common_reference_string.rs index a8bfdb50ec1..e57a379b607 100644 --- a/crates/nargo_cli/src/cli/fs/common_reference_string.rs +++ b/crates/nargo_cli/src/cli/fs/common_reference_string.rs @@ -16,27 +16,40 @@ fn common_reference_string_location() -> PathBuf { cache_dir.join(BACKEND_IDENTIFIER).join(TRANSCRIPT_NAME) } -pub(crate) fn get_common_reference_string( +pub(crate) fn read_cached_common_reference_string() -> Vec { + let crs_path = common_reference_string_location(); + + // TODO: Implement checksum + match std::fs::read(crs_path) { + Ok(common_reference_string) => common_reference_string, + Err(_) => vec![], + } +} + +pub(crate) fn update_common_reference_string( backend: &B, + common_reference_string: &[u8], circuit: &Circuit, ) -> Result, B::Error> { use tokio::runtime::Builder; - let crs_path = common_reference_string_location(); - let runtime = Builder::new_current_thread().enable_all().build().unwrap(); // TODO: Implement retries - let crs = match std::fs::read(&crs_path) { - // If the read data is empty, we don't have a CRS and need to generate one - Ok(common_reference_string) if !common_reference_string.is_empty() => runtime - .block_on(backend.update_common_reference_string(common_reference_string, circuit))?, - Ok(_) | Err(_) => runtime.block_on(backend.generate_common_reference_string(circuit))?, + // If the read data is empty, we don't have a CRS and need to generate one + let fut = if common_reference_string.is_empty() { + backend.generate_common_reference_string(circuit) + } else { + backend.update_common_reference_string(common_reference_string.to_vec(), circuit) }; - create_named_dir(crs_path.parent().unwrap(), "crs"); + runtime.block_on(fut) +} - write_to_file(crs.as_slice(), &crs_path); +pub(crate) fn write_cached_common_reference_string(common_reference_string: &[u8]) { + let crs_path = common_reference_string_location(); + + create_named_dir(crs_path.parent().unwrap(), "crs"); - Ok(crs) + write_to_file(common_reference_string, &crs_path); } diff --git a/crates/nargo_cli/src/cli/prove_cmd.rs b/crates/nargo_cli/src/cli/prove_cmd.rs index 7589dd4bba3..1238dbd9f8e 100644 --- a/crates/nargo_cli/src/cli/prove_cmd.rs +++ b/crates/nargo_cli/src/cli/prove_cmd.rs @@ -11,7 +11,10 @@ use super::NargoConfig; use super::{ compile_cmd::compile_circuit, fs::{ - common_reference_string::get_common_reference_string, + common_reference_string::{ + read_cached_common_reference_string, update_common_reference_string, + write_cached_common_reference_string, + }, inputs::{read_inputs_from_file, write_inputs_to_file}, program::read_program_from_file, proof::save_proof_to_dir, @@ -73,23 +76,32 @@ pub(crate) fn prove_with_path>( check_proof: bool, compile_options: &CompileOptions, ) -> Result, CliError> { + let common_reference_string = read_cached_common_reference_string(); + let (common_reference_string, preprocessed_program) = match circuit_build_path { Some(circuit_build_path) => { let program = read_program_from_file(circuit_build_path)?; - let common_reference_string = get_common_reference_string(backend, &program.bytecode) - .map_err(CliError::CommonReferenceStringError)?; + let common_reference_string = update_common_reference_string( + backend, + &common_reference_string, + &program.bytecode, + ) + .map_err(CliError::CommonReferenceStringError)?; (common_reference_string, program) } None => { let program = compile_circuit(backend, program_dir.as_ref(), compile_options)?; - let common_reference_string = get_common_reference_string(backend, &program.circuit) - .map_err(CliError::CommonReferenceStringError)?; + let common_reference_string = + update_common_reference_string(backend, &common_reference_string, &program.circuit) + .map_err(CliError::CommonReferenceStringError)?; let program = preprocess_program(backend, &common_reference_string, program) .map_err(CliError::ProofSystemCompilerError)?; (common_reference_string, program) } }; + write_cached_common_reference_string(&common_reference_string); + let PreprocessedProgram { abi, bytecode, proving_key, verification_key, .. } = preprocessed_program; diff --git a/crates/nargo_cli/src/cli/verify_cmd.rs b/crates/nargo_cli/src/cli/verify_cmd.rs index 62333ff0bdf..26eb39f3f81 100644 --- a/crates/nargo_cli/src/cli/verify_cmd.rs +++ b/crates/nargo_cli/src/cli/verify_cmd.rs @@ -1,7 +1,12 @@ use super::compile_cmd::compile_circuit; use super::fs::{ - common_reference_string::get_common_reference_string, inputs::read_inputs_from_file, - load_hex_data, program::read_program_from_file, + common_reference_string::{ + read_cached_common_reference_string, update_common_reference_string, + write_cached_common_reference_string, + }, + inputs::read_inputs_from_file, + load_hex_data, + program::read_program_from_file, }; use super::NargoConfig; use crate::{ @@ -58,23 +63,32 @@ fn verify_with_path>( circuit_build_path: Option

, compile_options: &CompileOptions, ) -> Result<(), CliError> { + let common_reference_string = read_cached_common_reference_string(); + let (common_reference_string, preprocessed_program) = match circuit_build_path { Some(circuit_build_path) => { let program = read_program_from_file(circuit_build_path)?; - let common_reference_string = get_common_reference_string(backend, &program.bytecode) - .map_err(CliError::CommonReferenceStringError)?; + let common_reference_string = update_common_reference_string( + backend, + &common_reference_string, + &program.bytecode, + ) + .map_err(CliError::CommonReferenceStringError)?; (common_reference_string, program) } None => { let program = compile_circuit(backend, program_dir.as_ref(), compile_options)?; - let common_reference_string = get_common_reference_string(backend, &program.circuit) - .map_err(CliError::CommonReferenceStringError)?; + let common_reference_string = + update_common_reference_string(backend, &common_reference_string, &program.circuit) + .map_err(CliError::CommonReferenceStringError)?; let program = preprocess_program(backend, &common_reference_string, program) .map_err(CliError::ProofSystemCompilerError)?; (common_reference_string, program) } }; + write_cached_common_reference_string(&common_reference_string); + let PreprocessedProgram { abi, bytecode, verification_key, .. } = preprocessed_program; // Load public inputs (if any) from `VERIFIER_INPUT_FILE`. From ecc880648e7cccc83dce375af0e4fce886a1688d Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Thu, 18 May 2023 09:10:16 -0700 Subject: [PATCH 5/5] change env var to include nargo name --- crates/nargo_cli/src/cli/fs/common_reference_string.rs | 2 +- flake.nix | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/nargo_cli/src/cli/fs/common_reference_string.rs b/crates/nargo_cli/src/cli/fs/common_reference_string.rs index e57a379b607..15991f6d0c5 100644 --- a/crates/nargo_cli/src/cli/fs/common_reference_string.rs +++ b/crates/nargo_cli/src/cli/fs/common_reference_string.rs @@ -9,7 +9,7 @@ const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; const TRANSCRIPT_NAME: &str = "common-reference-string.bin"; fn common_reference_string_location() -> PathBuf { - let cache_dir = match env::var("BACKEND_CACHE_DIR") { + let cache_dir = match env::var("NARGO_BACKEND_CACHE_DIR") { Ok(cache_dir) => PathBuf::from(cache_dir), Err(_) => dirs::home_dir().unwrap().join(".nargo").join("backends"), }; diff --git a/flake.nix b/flake.nix index 4191d1d11a3..696c38623ed 100644 --- a/flake.nix +++ b/flake.nix @@ -144,10 +144,10 @@ # which avoids exposing the entire Nix store to the static server it starts # The static server is moved to the background and killed after checks are completed # - # We also set the BACKEND_CACHE_DIR environment variable to the $TMP directory so we can successfully cache + # We also set the NARGO_BACKEND_CACHE_DIR environment variable to the $TMP directory so we can successfully cache # the transcript; which isn't possible with the default path because the Nix sandbox disabled $HOME preCheck = '' - export BACKEND_CACHE_DIR=$TMP + export NARGO_BACKEND_CACHE_DIR=$TMP cp ${pkgs.barretenberg-transcript00} . echo "Starting simple static server" ${pkgs.simple-http-server}/bin/simple-http-server --port ${toString port} --silent &