From cb2f2ebf5d8d78d54ebdb18db3c4f72b1031d9a9 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 31 Aug 2023 17:32:59 +0100 Subject: [PATCH 1/4] chore: only install `tokio-util` dependency on windows (#2425) --- crates/nargo_cli/Cargo.toml | 4 +++- crates/nargo_cli/src/main.rs | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/nargo_cli/Cargo.toml b/crates/nargo_cli/Cargo.toml index da3eac653c5..e10fde13d7b 100644 --- a/crates/nargo_cli/Cargo.toml +++ b/crates/nargo_cli/Cargo.toml @@ -46,11 +46,13 @@ hex = "0.4.2" termcolor = "1.1.2" color-eyre = "0.6.2" tokio = { version = "1.0", features = ["io-std"] } -tokio-util = { version = "0.7.8", features = ["compat"] } # Backends acvm-backend-barretenberg = { path = "../acvm_backend_barretenberg" } +[target.'cfg(not(unix))'.dependencies] +tokio-util = { version = "0.7.8", features = ["compat"] } + [dev-dependencies] tempdir = "0.3.7" assert_cmd = "2.0.8" diff --git a/crates/nargo_cli/src/main.rs b/crates/nargo_cli/src/main.rs index 734dbdca2e7..f4d1e1862fc 100644 --- a/crates/nargo_cli/src/main.rs +++ b/crates/nargo_cli/src/main.rs @@ -1,7 +1,7 @@ #![forbid(unsafe_code)] -#![warn(unused_extern_crates)] #![warn(unreachable_pub)] #![warn(clippy::semicolon_if_nothing_returned)] +#![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))] //! Nargo is the package manager for Noir //! This name was used because it sounds like `cargo` and From 3a7c2e83c837cf0aff92d2fb22f1f3baf88c28d7 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 31 Aug 2023 23:48:54 +0100 Subject: [PATCH 2/4] chore: Remove dead code from `acvm_backend_barretenberg` (#2512) --- crates/acvm_backend_barretenberg/src/lib.rs | 15 --------------- .../acvm_backend_barretenberg/src/proof_system.rs | 14 ++++++-------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/crates/acvm_backend_barretenberg/src/lib.rs b/crates/acvm_backend_barretenberg/src/lib.rs index 46867a6aeb4..704d2b4c7b0 100644 --- a/crates/acvm_backend_barretenberg/src/lib.rs +++ b/crates/acvm_backend_barretenberg/src/lib.rs @@ -1,25 +1,10 @@ #![warn(unused_crate_dependencies, unused_extern_crates)] #![warn(unreachable_pub)] -// `acvm-backend-barretenberg` can either interact with the Barretenberg backend through a static library -// or through an embedded wasm binary. It does not make sense to include both of these backends at the same time. -// We then throw a compilation error if both flags are set. -#[cfg(all(feature = "native", feature = "wasm"))] -compile_error!("feature \"native\" and feature \"wasm\" cannot be enabled at the same time"); - -#[cfg(all(feature = "native", target_arch = "wasm32"))] -compile_error!("feature \"native\" cannot be enabled for a \"wasm32\" target"); - -#[cfg(all(feature = "wasm", target_arch = "wasm32"))] -compile_error!("feature \"wasm\" cannot be enabled for a \"wasm32\" target"); - mod bb; mod proof_system; mod smart_contract; -/// The number of bytes necessary to store a `FieldElement`. -const FIELD_BYTES: usize = 32; - #[derive(Debug, Default)] pub struct Barretenberg; diff --git a/crates/acvm_backend_barretenberg/src/proof_system.rs b/crates/acvm_backend_barretenberg/src/proof_system.rs index 33ec8457a43..6b5916c7def 100644 --- a/crates/acvm_backend_barretenberg/src/proof_system.rs +++ b/crates/acvm_backend_barretenberg/src/proof_system.rs @@ -9,7 +9,7 @@ use acvm::{Language, ProofSystemCompiler}; use tempfile::tempdir; use crate::bb::{GatesCommand, ProveCommand, VerifyCommand, WriteVkCommand}; -use crate::{BackendError, Barretenberg, FIELD_BYTES}; +use crate::{BackendError, Barretenberg}; impl ProofSystemCompiler for Barretenberg { type Error = BackendError; @@ -76,9 +76,8 @@ impl ProofSystemCompiler for Barretenberg { let temp_dir_path_str = temp_directory.to_str().unwrap(); // Create a temporary file for the witness - let serialized_witnesses: Vec = witness_values - .try_into() - .expect("could not serialize witness map"); + let serialized_witnesses: Vec = + witness_values.try_into().expect("could not serialize witness map"); let witness_path = temp_directory.join("witness").with_extension("tr"); write_to_file(&serialized_witnesses, &witness_path); @@ -222,7 +221,7 @@ pub(super) fn read_bytes_from_file(path: &str) -> std::io::Result> { fn remove_public_inputs(num_pub_inputs: usize, proof: &[u8]) -> Vec { // Barretenberg prepends the public inputs onto the proof so we need to remove // the first `num_pub_inputs` field elements. - let num_bytes_to_remove = num_pub_inputs * FIELD_BYTES; + let num_bytes_to_remove = num_pub_inputs * (FieldElement::max_num_bytes() as usize); proof[num_bytes_to_remove..].to_vec() } @@ -232,9 +231,8 @@ fn prepend_public_inputs(proof: Vec, public_inputs: Vec) -> Ve return proof; } - let public_inputs_bytes = public_inputs - .into_iter() - .flat_map(|assignment| assignment.to_be_bytes()); + let public_inputs_bytes = + public_inputs.into_iter().flat_map(|assignment| assignment.to_be_bytes()); public_inputs_bytes.chain(proof.into_iter()).collect() } From 3157a544ad4c937aa693161765daae6e7c5569ee Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 1 Sep 2023 00:29:41 +0100 Subject: [PATCH 3/4] chore: delete `ProveAndVerifyCommand` (#2520) --- .../acvm_backend_barretenberg/src/bb/mod.rs | 1 - .../src/bb/prove_and_verify.rs | 65 ------------------- 2 files changed, 66 deletions(-) delete mode 100644 crates/acvm_backend_barretenberg/src/bb/prove_and_verify.rs diff --git a/crates/acvm_backend_barretenberg/src/bb/mod.rs b/crates/acvm_backend_barretenberg/src/bb/mod.rs index 3f80c538bf5..7eed61154d7 100644 --- a/crates/acvm_backend_barretenberg/src/bb/mod.rs +++ b/crates/acvm_backend_barretenberg/src/bb/mod.rs @@ -3,7 +3,6 @@ mod contract; mod gates; mod prove; -mod prove_and_verify; mod verify; mod write_vk; diff --git a/crates/acvm_backend_barretenberg/src/bb/prove_and_verify.rs b/crates/acvm_backend_barretenberg/src/bb/prove_and_verify.rs deleted file mode 100644 index 08fe0f10ea9..00000000000 --- a/crates/acvm_backend_barretenberg/src/bb/prove_and_verify.rs +++ /dev/null @@ -1,65 +0,0 @@ -use super::{assert_binary_exists, get_binary_path}; - -/// ProveAndVerifyCommand will call the barretenberg binary -/// to create a proof and then verify the proof once created. -/// -/// Note: Functions like this are useful for testing. In a real workflow, -/// ProveCommand and VerifyCommand will be used separately. -#[allow(dead_code)] -struct ProveAndVerifyCommand { - verbose: bool, - path_to_crs: String, - is_recursive: bool, - path_to_bytecode: String, - path_to_witness: String, -} - -#[allow(dead_code)] -impl ProveAndVerifyCommand { - fn run(self) -> bool { - assert_binary_exists(); - let mut command = std::process::Command::new(get_binary_path()); - - command - .arg("prove_and_verify") - .arg("-c") - .arg(self.path_to_crs) - .arg("-b") - .arg(self.path_to_bytecode) - .arg("-w") - .arg(self.path_to_witness); - if self.verbose { - command.arg("-v"); - } - if self.is_recursive { - command.arg("-r"); - } - - command.output().expect("Failed to execute command").status.success() - } -} - -#[test] -#[serial_test::serial] -fn prove_and_verify_command() { - use tempfile::tempdir; - - let path_to_1_mul = "./src/1_mul.bytecode"; - let path_to_1_mul_witness = "./src/witness.tr"; - - let temp_directory = tempdir().expect("could not create a temporary directory"); - let temp_directory_path = temp_directory.path(); - let path_to_crs = temp_directory_path.join("crs"); - - let prove_and_verify_command = ProveAndVerifyCommand { - verbose: true, - path_to_crs: path_to_crs.to_str().unwrap().to_string(), - is_recursive: false, - path_to_bytecode: path_to_1_mul.to_string(), - path_to_witness: path_to_1_mul_witness.to_string(), - }; - - let output = prove_and_verify_command.run(); - assert!(output); - drop(temp_directory); -} From f1d09ca1ebfff6944b41ea5a397e2b83ac840455 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 1 Sep 2023 00:44:22 +0100 Subject: [PATCH 4/4] chore: remove usage of `Backend` trait (#2514) --- crates/acvm_backend_barretenberg/src/lib.rs | 21 +++++----- .../src/proof_system.rs | 42 +++++-------------- .../src/smart_contract.rs | 33 +++++---------- crates/nargo_cli/src/backends.rs | 2 +- crates/nargo_cli/src/cli/check_cmd.rs | 9 ++-- .../nargo_cli/src/cli/codegen_verifier_cmd.rs | 20 ++++----- crates/nargo_cli/src/cli/compile_cmd.rs | 27 ++++++------ crates/nargo_cli/src/cli/execute_cmd.rs | 20 ++++----- crates/nargo_cli/src/cli/info_cmd.rs | 37 ++++++++-------- crates/nargo_cli/src/cli/init_cmd.rs | 8 ++-- crates/nargo_cli/src/cli/lsp_cmd.rs | 8 ++-- crates/nargo_cli/src/cli/mod.rs | 2 +- crates/nargo_cli/src/cli/new_cmd.rs | 8 ++-- crates/nargo_cli/src/cli/prove_cmd.rs | 22 ++++------ crates/nargo_cli/src/cli/test_cmd.rs | 14 +++---- crates/nargo_cli/src/cli/verify_cmd.rs | 19 ++++----- crates/nargo_cli/src/errors.rs | 13 +++--- 17 files changed, 130 insertions(+), 175 deletions(-) diff --git a/crates/acvm_backend_barretenberg/src/lib.rs b/crates/acvm_backend_barretenberg/src/lib.rs index 704d2b4c7b0..e5da8577406 100644 --- a/crates/acvm_backend_barretenberg/src/lib.rs +++ b/crates/acvm_backend_barretenberg/src/lib.rs @@ -6,20 +6,19 @@ mod proof_system; mod smart_contract; #[derive(Debug, Default)] -pub struct Barretenberg; +pub struct Backend {} -impl Barretenberg { - pub fn new() -> Barretenberg { - Barretenberg +impl Backend { + pub fn new() -> Backend { + Backend {} } } -impl acvm::Backend for Barretenberg {} - #[derive(Debug, thiserror::Error)] -#[error(transparent)] -pub struct BackendError(#[from] Error); +pub struct BackendError(String); -#[allow(clippy::upper_case_acronyms)] -#[derive(Debug, thiserror::Error)] -enum Error {} +impl std::fmt::Display for BackendError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} diff --git a/crates/acvm_backend_barretenberg/src/proof_system.rs b/crates/acvm_backend_barretenberg/src/proof_system.rs index 6b5916c7def..93f40666f6c 100644 --- a/crates/acvm_backend_barretenberg/src/proof_system.rs +++ b/crates/acvm_backend_barretenberg/src/proof_system.rs @@ -5,20 +5,18 @@ use std::path::Path; use acvm::acir::circuit::Opcode; use acvm::acir::{circuit::Circuit, native_types::WitnessMap, BlackBoxFunc}; use acvm::FieldElement; -use acvm::{Language, ProofSystemCompiler}; +use acvm::Language; use tempfile::tempdir; use crate::bb::{GatesCommand, ProveCommand, VerifyCommand, WriteVkCommand}; -use crate::{BackendError, Barretenberg}; +use crate::{Backend, BackendError}; -impl ProofSystemCompiler for Barretenberg { - type Error = BackendError; - - fn np_language(&self) -> Language { +impl Backend { + pub fn np_language(&self) -> Language { Language::PLONKCSat { width: 3 } } - fn get_exact_circuit_size(&self, circuit: &Circuit) -> Result { + pub fn get_exact_circuit_size(&self, circuit: &Circuit) -> Result { let temp_directory = tempdir().expect("could not create a temporary directory"); let temp_directory = temp_directory.path(); let temp_dir_path_str = temp_directory.to_str().unwrap(); @@ -38,7 +36,7 @@ impl ProofSystemCompiler for Barretenberg { Ok(number_of_gates_needed) } - fn supports_opcode(&self, opcode: &Opcode) -> bool { + pub fn supports_opcode(&self, opcode: &Opcode) -> bool { match opcode { Opcode::Arithmetic(_) => true, Opcode::Directive(_) => true, @@ -63,14 +61,12 @@ impl ProofSystemCompiler for Barretenberg { } } - fn prove_with_pk( + pub fn prove( &self, - _common_reference_string: &[u8], circuit: &Circuit, witness_values: WitnessMap, - _proving_key: &[u8], is_recursive: bool, - ) -> Result, Self::Error> { + ) -> Result, BackendError> { let temp_directory = tempdir().expect("could not create a temporary directory"); let temp_directory = temp_directory.path(); let temp_dir_path_str = temp_directory.to_str().unwrap(); @@ -116,15 +112,13 @@ impl ProofSystemCompiler for Barretenberg { Ok(proof) } - fn verify_with_vk( + pub fn verify( &self, - _common_reference_string: &[u8], proof: &[u8], public_inputs: WitnessMap, circuit: &Circuit, - _verification_key: &[u8], is_recursive: bool, - ) -> Result { + ) -> Result { let temp_directory = tempdir().expect("could not create a temporary directory"); let temp_directory = temp_directory.path(); let temp_dir_path = temp_directory.to_str().unwrap(); @@ -172,22 +166,6 @@ impl ProofSystemCompiler for Barretenberg { } .run()) } - - fn proof_as_fields( - &self, - _proof: &[u8], - _public_inputs: WitnessMap, - ) -> Result, Self::Error> { - panic!("vk_as_fields not supported in this backend"); - } - - fn vk_as_fields( - &self, - _common_reference_string: &[u8], - _verification_key: &[u8], - ) -> Result<(Vec, FieldElement), Self::Error> { - panic!("vk_as_fields not supported in this backend"); - } } pub(super) fn write_to_file(bytes: &[u8], path: &Path) -> String { diff --git a/crates/acvm_backend_barretenberg/src/smart_contract.rs b/crates/acvm_backend_barretenberg/src/smart_contract.rs index 167a00e9cd2..29633ef6bfc 100644 --- a/crates/acvm_backend_barretenberg/src/smart_contract.rs +++ b/crates/acvm_backend_barretenberg/src/smart_contract.rs @@ -2,23 +2,16 @@ use super::proof_system::{serialize_circuit, write_to_file}; use crate::{ bb::{ContractCommand, WriteVkCommand}, proof_system::read_bytes_from_file, - BackendError, Barretenberg, + Backend, BackendError, }; -use acvm::{acir::circuit::Circuit, SmartContract}; +use acvm::acir::circuit::Circuit; use tempfile::tempdir; /// Embed the Solidity verifier file const ULTRA_VERIFIER_CONTRACT: &str = include_str!("contract.sol"); -impl SmartContract for Barretenberg { - type Error = BackendError; - - fn eth_contract_from_vk( - &self, - _common_reference_string: &[u8], - circuit: &Circuit, - _verification_key: &[u8], - ) -> Result { +impl Backend { + pub fn eth_contract(&self, circuit: &Circuit) -> Result { let temp_directory = tempdir().expect("could not create a temporary directory"); let temp_directory_path = temp_directory.path(); let temp_dir_path = temp_directory_path.to_str().unwrap(); @@ -62,18 +55,15 @@ impl SmartContract for Barretenberg { mod tests { use std::collections::BTreeSet; - use acvm::{ - acir::{ - circuit::{Circuit, Opcode, PublicInputs}, - native_types::{Expression, Witness}, - }, - SmartContract, + use acvm::acir::{ + circuit::{Circuit, Opcode, PublicInputs}, + native_types::{Expression, Witness}, }; #[test] #[serial_test::serial] fn test_smart_contract() { - use crate::Barretenberg; + use crate::Backend; let expression = &(Witness(1) + Witness(2)) - &Expression::from(Witness(3)); let constraint = Opcode::Arithmetic(expression); @@ -86,12 +76,9 @@ mod tests { return_values: PublicInputs::default(), }; - let bb = Barretenberg; + let bb = Backend::default(); - let common_reference_string = Vec::new(); - let verification_key = Vec::new(); - let contract = - bb.eth_contract_from_vk(&common_reference_string, &circuit, &verification_key).unwrap(); + let contract = bb.eth_contract(&circuit).unwrap(); assert!(contract.contains("contract BaseUltraVerifier")); assert!(contract.contains("contract UltraVerifier")); diff --git a/crates/nargo_cli/src/backends.rs b/crates/nargo_cli/src/backends.rs index 71ff5a0c73a..feaded3971d 100644 --- a/crates/nargo_cli/src/backends.rs +++ b/crates/nargo_cli/src/backends.rs @@ -1 +1 @@ -pub(crate) use acvm_backend_barretenberg::Barretenberg as ConcreteBackend; +pub(crate) use acvm_backend_barretenberg::Backend; diff --git a/crates/nargo_cli/src/cli/check_cmd.rs b/crates/nargo_cli/src/cli/check_cmd.rs index 29864521380..955687da9de 100644 --- a/crates/nargo_cli/src/cli/check_cmd.rs +++ b/crates/nargo_cli/src/cli/check_cmd.rs @@ -1,5 +1,6 @@ +use crate::backends::Backend; use crate::errors::{CliError, CompileError}; -use acvm::Backend; + use clap::Args; use iter_extended::btree_map; use nargo::{package::Package, prepare_package}; @@ -29,11 +30,11 @@ pub(crate) struct CheckCommand { compile_options: CompileOptions, } -pub(crate) fn run( - _backend: &B, +pub(crate) fn run( + _backend: &Backend, args: CheckCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let toml_path = get_package_manifest(&config.program_dir)?; let default_selection = if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; diff --git a/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs b/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs index 04c7114a565..15e8b236bc8 100644 --- a/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs +++ b/crates/nargo_cli/src/cli/codegen_verifier_cmd.rs @@ -5,11 +5,12 @@ use super::{ compile_cmd::compile_package, fs::{create_named_dir, program::read_program_from_file, write_to_file}, }; +use crate::backends::Backend; use crate::errors::CliError; -use acvm::Backend; + use clap::Args; use nargo::artifacts::program::PreprocessedProgram; -use nargo::{ops::codegen_verifier, package::Package}; +use nargo::package::Package; use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; use noirc_driver::CompileOptions; use noirc_frontend::graph::CrateName; @@ -32,11 +33,11 @@ pub(crate) struct CodegenVerifierCommand { compile_options: CompileOptions, } -pub(crate) fn run( - backend: &B, +pub(crate) fn run( + backend: &Backend, args: CodegenVerifierCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let toml_path = get_package_manifest(&config.program_dir)?; let default_selection = if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; @@ -64,12 +65,12 @@ pub(crate) fn run( Ok(()) } -fn smart_contract_for_package( - backend: &B, +fn smart_contract_for_package( + backend: &Backend, package: &Package, circuit_build_path: PathBuf, compile_options: &CompileOptions, -) -> Result> { +) -> Result { let preprocessed_program = if circuit_build_path.exists() { read_program_from_file(circuit_build_path)? } else { @@ -82,8 +83,7 @@ fn smart_contract_for_package( } }; - let smart_contract_string = codegen_verifier(backend, &preprocessed_program.bytecode) - .map_err(CliError::SmartContractError)?; + let smart_contract_string = backend.eth_contract(&preprocessed_program.bytecode)?; Ok(smart_contract_string) } diff --git a/crates/nargo_cli/src/cli/compile_cmd.rs b/crates/nargo_cli/src/cli/compile_cmd.rs index ba6da305721..906e65ae353 100644 --- a/crates/nargo_cli/src/cli/compile_cmd.rs +++ b/crates/nargo_cli/src/cli/compile_cmd.rs @@ -1,4 +1,4 @@ -use acvm::{acir::circuit::Circuit, compiler::AcirTransformationMap, Backend}; +use acvm::{acir::circuit::Circuit, compiler::AcirTransformationMap}; use iter_extended::{try_vecmap, vecmap}; use nargo::artifacts::contract::PreprocessedContractFunction; use nargo::artifacts::debug::DebugArtifact; @@ -17,6 +17,7 @@ use noirc_frontend::hir::Context; use clap::Args; +use crate::backends::Backend; use crate::errors::{CliError, CompileError}; use super::fs::program::{ @@ -50,11 +51,11 @@ pub(crate) struct CompileCommand { compile_options: CompileOptions, } -pub(crate) fn run( - backend: &B, +pub(crate) fn run( + backend: &Backend, args: CompileCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let toml_path = get_package_manifest(&config.program_dir)?; let default_selection = if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; @@ -141,8 +142,8 @@ pub(crate) fn run( Ok(()) } -pub(crate) fn compile_package( - backend: &B, +pub(crate) fn compile_package( + backend: &Backend, package: &Package, compile_options: &CompileOptions, ) -> Result<(Context, CompiledProgram), CompileError> { @@ -164,10 +165,10 @@ pub(crate) fn compile_package( Ok((context, program)) } -pub(super) fn optimize_circuit( - backend: &B, +pub(super) fn optimize_circuit( + backend: &Backend, circuit: Circuit, -) -> Result<(Circuit, AcirTransformationMap), CliError> { +) -> Result<(Circuit, AcirTransformationMap), CliError> { let result = acvm::compiler::compile(circuit, backend.np_language(), |opcode| { backend.supports_opcode(opcode) }) @@ -176,15 +177,15 @@ pub(super) fn optimize_circuit( Ok(result) } -pub(super) fn optimize_contract( - backend: &B, +pub(super) fn optimize_contract( + backend: &Backend, contract: CompiledContract, -) -> Result> { +) -> Result { let functions = try_vecmap(contract.functions, |mut func| { let (optimized_bytecode, location_map) = optimize_circuit(backend, func.bytecode)?; func.bytecode = optimized_bytecode; func.debug.update_acir(location_map); - Ok::<_, CliError>(func) + Ok::<_, CliError>(func) })?; Ok(CompiledContract { functions, ..contract }) diff --git a/crates/nargo_cli/src/cli/execute_cmd.rs b/crates/nargo_cli/src/cli/execute_cmd.rs index 30ba6e28322..159e7987992 100644 --- a/crates/nargo_cli/src/cli/execute_cmd.rs +++ b/crates/nargo_cli/src/cli/execute_cmd.rs @@ -1,7 +1,6 @@ use acvm::acir::circuit::OpcodeLocation; use acvm::acir::{circuit::Circuit, native_types::WitnessMap}; use acvm::pwg::ErrorLocation; -use acvm::Backend; use clap::Args; use nargo::constants::PROVER_INPUT_FILE; use nargo::package::Package; @@ -17,6 +16,7 @@ use noirc_frontend::hir::Context; use super::compile_cmd::compile_package; use super::fs::{inputs::read_inputs_from_file, witness::save_witness_to_dir}; use super::NargoConfig; +use crate::backends::Backend; use crate::errors::CliError; /// Executes a circuit to calculate its return value @@ -41,11 +41,11 @@ pub(crate) struct ExecuteCommand { compile_options: CompileOptions, } -pub(crate) fn run( - backend: &B, +pub(crate) fn run( + backend: &Backend, args: ExecuteCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let toml_path = get_package_manifest(&config.program_dir)?; let default_selection = if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; @@ -70,12 +70,12 @@ pub(crate) fn run( Ok(()) } -fn execute_package( - backend: &B, +fn execute_package( + backend: &Backend, package: &Package, prover_name: &str, compile_options: &CompileOptions, -) -> Result<(Option, WitnessMap), CliError> { +) -> Result<(Option, WitnessMap), CliError> { let (context, compiled_program) = compile_package(backend, package, compile_options)?; let CompiledProgram { abi, circuit, debug } = compiled_program; @@ -161,13 +161,13 @@ fn report_error_with_opcode_location( } } -pub(crate) fn execute_program( - _backend: &B, +pub(crate) fn execute_program( + _backend: &Backend, circuit: Circuit, abi: &Abi, inputs_map: &InputMap, debug_data: Option<(DebugInfo, Context)>, -) -> Result> { +) -> Result { #[allow(deprecated)] let blackbox_solver = acvm::blackbox_solver::BarretenbergSolver::new(); diff --git a/crates/nargo_cli/src/cli/info_cmd.rs b/crates/nargo_cli/src/cli/info_cmd.rs index a761c376973..bc652636d82 100644 --- a/crates/nargo_cli/src/cli/info_cmd.rs +++ b/crates/nargo_cli/src/cli/info_cmd.rs @@ -1,4 +1,4 @@ -use acvm::Backend; +use acvm_backend_barretenberg::BackendError; use clap::Args; use iter_extended::try_vecmap; use nargo::{package::Package, prepare_package}; @@ -7,6 +7,7 @@ use noirc_driver::{compile_contracts, CompileOptions}; use noirc_frontend::graph::CrateName; use prettytable::{row, Table}; +use crate::backends::Backend; use crate::{cli::compile_cmd::compile_package, errors::CliError}; use super::{ @@ -33,11 +34,11 @@ pub(crate) struct InfoCommand { compile_options: CompileOptions, } -pub(crate) fn run( - backend: &B, +pub(crate) fn run( + backend: &Backend, args: InfoCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let toml_path = get_package_manifest(&config.program_dir)?; let default_selection = if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; @@ -85,18 +86,16 @@ pub(crate) fn run( Ok(()) } -fn count_opcodes_and_gates_in_package( - backend: &B, +fn count_opcodes_and_gates_in_package( + backend: &Backend, package: &Package, compile_options: &CompileOptions, table: &mut Table, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let (_, compiled_program) = compile_package(backend, package, compile_options)?; let num_opcodes = compiled_program.circuit.opcodes.len(); - let exact_circuit_size = backend - .get_exact_circuit_size(&compiled_program.circuit) - .map_err(CliError::ProofSystemCompilerError)?; + let exact_circuit_size = backend.get_exact_circuit_size(&compiled_program.circuit)?; table.add_row(row![ Fm->format!("{}", package.name), @@ -108,12 +107,12 @@ fn count_opcodes_and_gates_in_package( Ok(()) } -fn count_opcodes_and_gates_in_contracts( - backend: &B, +fn count_opcodes_and_gates_in_contracts( + backend: &Backend, package: &Package, compile_options: &CompileOptions, table: &mut Table, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let (mut context, crate_id) = prepare_package(package); let result = compile_contracts(&mut context, crate_id, compile_options); let contracts = report_errors(result, &context, compile_options.deny_warnings)?; @@ -121,13 +120,13 @@ fn count_opcodes_and_gates_in_contracts( try_vecmap(contracts, |contract| optimize_contract(backend, contract))?; for contract in optimized_contracts { - let function_info: Vec<(String, usize, u32)> = try_vecmap(contract.functions, |function| { - let num_opcodes = function.bytecode.opcodes.len(); - let exact_circuit_size = backend.get_exact_circuit_size(&function.bytecode)?; + let function_info: Vec<(String, usize, u32)> = + try_vecmap(contract.functions, |function| { + let num_opcodes = function.bytecode.opcodes.len(); + let exact_circuit_size = backend.get_exact_circuit_size(&function.bytecode)?; - Ok((function.name, num_opcodes, exact_circuit_size)) - }) - .map_err(CliError::ProofSystemCompilerError)?; + Ok::<_, BackendError>((function.name, num_opcodes, exact_circuit_size)) + })?; for info in function_info { table.add_row(row![ diff --git a/crates/nargo_cli/src/cli/init_cmd.rs b/crates/nargo_cli/src/cli/init_cmd.rs index e6020e3cfd9..2091ac89f9c 100644 --- a/crates/nargo_cli/src/cli/init_cmd.rs +++ b/crates/nargo_cli/src/cli/init_cmd.rs @@ -1,8 +1,8 @@ +use crate::backends::Backend; use crate::errors::CliError; use super::fs::{create_named_dir, write_to_file}; use super::{NargoConfig, CARGO_PKG_VERSION}; -use acvm::Backend; use clap::Args; use nargo::constants::{PKG_FILE, SRC_DIR}; use nargo::package::PackageType; @@ -62,12 +62,12 @@ fn test_my_util() { } "#; -pub(crate) fn run( +pub(crate) fn run( // Backend is currently unused, but we might want to use it to inform the "new" template in the future - _backend: &B, + _backend: &Backend, args: InitCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let package_name = match args.name { Some(name) => name, None => { diff --git a/crates/nargo_cli/src/cli/lsp_cmd.rs b/crates/nargo_cli/src/cli/lsp_cmd.rs index ac15f4f8a9f..7350c5c3099 100644 --- a/crates/nargo_cli/src/cli/lsp_cmd.rs +++ b/crates/nargo_cli/src/cli/lsp_cmd.rs @@ -1,4 +1,3 @@ -use acvm::Backend; use async_lsp::{ client_monitor::ClientProcessMonitorLayer, concurrency::ConcurrencyLayer, panic::CatchUnwindLayer, server::LifecycleLayer, tracing::TracingLayer, @@ -8,6 +7,7 @@ use noir_lsp::NargoLspService; use tower::ServiceBuilder; use super::NargoConfig; +use crate::backends::Backend; use crate::errors::CliError; /// Starts the Noir LSP server @@ -18,12 +18,12 @@ use crate::errors::CliError; #[derive(Debug, Clone, Args)] pub(crate) struct LspCommand; -pub(crate) fn run( +pub(crate) fn run( // Backend is currently unused, but we might want to use it to inform the lsp in the future - _backend: &B, + _backend: &Backend, _args: LspCommand, _config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { use tokio::runtime::Builder; let runtime = Builder::new_current_thread().enable_all().build().unwrap(); diff --git a/crates/nargo_cli/src/cli/mod.rs b/crates/nargo_cli/src/cli/mod.rs index 030eb114541..0a1fc059ff4 100644 --- a/crates/nargo_cli/src/cli/mod.rs +++ b/crates/nargo_cli/src/cli/mod.rs @@ -74,7 +74,7 @@ pub(crate) fn start_cli() -> eyre::Result<()> { config.program_dir = find_package_root(&config.program_dir)?; } - let backend = crate::backends::ConcreteBackend; + let backend = crate::backends::Backend::default(); match command { NargoCommand::New(args) => new_cmd::run(&backend, args, config), diff --git a/crates/nargo_cli/src/cli/new_cmd.rs b/crates/nargo_cli/src/cli/new_cmd.rs index d6a9d00257b..b4c823d0c1e 100644 --- a/crates/nargo_cli/src/cli/new_cmd.rs +++ b/crates/nargo_cli/src/cli/new_cmd.rs @@ -1,7 +1,7 @@ +use crate::backends::Backend; use crate::errors::CliError; use super::{init_cmd::initialize_project, NargoConfig}; -use acvm::Backend; use clap::Args; use nargo::package::PackageType; use noirc_frontend::graph::CrateName; @@ -30,12 +30,12 @@ pub(crate) struct NewCommand { pub(crate) contract: bool, } -pub(crate) fn run( +pub(crate) fn run( // Backend is currently unused, but we might want to use it to inform the "new" template in the future - _backend: &B, + _backend: &Backend, args: NewCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let package_dir = config.program_dir.join(&args.path); if package_dir.exists() { diff --git a/crates/nargo_cli/src/cli/prove_cmd.rs b/crates/nargo_cli/src/cli/prove_cmd.rs index 2ec1df2fdd4..5a7cff62078 100644 --- a/crates/nargo_cli/src/cli/prove_cmd.rs +++ b/crates/nargo_cli/src/cli/prove_cmd.rs @@ -1,10 +1,8 @@ use std::path::{Path, PathBuf}; -use acvm::Backend; use clap::Args; use nargo::artifacts::program::PreprocessedProgram; use nargo::constants::{PROVER_INPUT_FILE, VERIFIER_INPUT_FILE}; -use nargo::ops::{prove_execution, verify_proof}; use nargo::package::Package; use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; use noirc_abi::input_parser::Format; @@ -18,7 +16,7 @@ use super::fs::{ proof::save_proof_to_dir, }; use super::NargoConfig; -use crate::{cli::execute_cmd::execute_program, errors::CliError}; +use crate::{backends::Backend, cli::execute_cmd::execute_program, errors::CliError}; // TODO(#1388): pull this from backend. const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; @@ -50,11 +48,11 @@ pub(crate) struct ProveCommand { compile_options: CompileOptions, } -pub(crate) fn run( - backend: &B, +pub(crate) fn run( + backend: &Backend, args: ProveCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let toml_path = get_package_manifest(&config.program_dir)?; let default_selection = if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; @@ -81,8 +79,8 @@ pub(crate) fn run( } #[allow(clippy::too_many_arguments)] -pub(crate) fn prove_package( - backend: &B, +pub(crate) fn prove_package( + backend: &Backend, package: &Package, prover_name: &str, verifier_name: &str, @@ -90,7 +88,7 @@ pub(crate) fn prove_package( circuit_build_path: PathBuf, check_proof: bool, compile_options: &CompileOptions, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let (preprocessed_program, debug_data) = if circuit_build_path.exists() { let program = read_program_from_file(circuit_build_path)?; @@ -126,13 +124,11 @@ pub(crate) fn prove_package( Format::Toml, )?; - let proof = prove_execution(backend, &bytecode, solved_witness) - .map_err(CliError::ProofSystemCompilerError)?; + let proof = backend.prove(&bytecode, solved_witness, false)?; if check_proof { let public_inputs = public_abi.encode(&public_inputs, return_value)?; - let valid_proof = verify_proof(backend, &bytecode, &proof, public_inputs) - .map_err(CliError::ProofSystemCompilerError)?; + let valid_proof = backend.verify(&proof, public_inputs, &bytecode, false)?; if !valid_proof { return Err(CliError::InvalidProof("".into())); diff --git a/crates/nargo_cli/src/cli/test_cmd.rs b/crates/nargo_cli/src/cli/test_cmd.rs index a37766ad152..1b4f37a4528 100644 --- a/crates/nargo_cli/src/cli/test_cmd.rs +++ b/crates/nargo_cli/src/cli/test_cmd.rs @@ -1,6 +1,6 @@ use std::io::Write; -use acvm::{Backend, BlackBoxFunctionSolver}; +use acvm::BlackBoxFunctionSolver; use clap::Args; use nargo::{ ops::{run_test, TestStatus}, @@ -12,7 +12,7 @@ use noirc_driver::CompileOptions; use noirc_frontend::{graph::CrateName, hir::FunctionNameMatch}; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; -use crate::{cli::check_cmd::check_crate_and_report_errors, errors::CliError}; +use crate::{backends::Backend, cli::check_cmd::check_crate_and_report_errors, errors::CliError}; use super::NargoConfig; @@ -42,11 +42,11 @@ pub(crate) struct TestCommand { compile_options: CompileOptions, } -pub(crate) fn run( - _backend: &B, +pub(crate) fn run( + _backend: &Backend, args: TestCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let toml_path = get_package_manifest(&config.program_dir)?; let default_selection = if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; @@ -75,13 +75,13 @@ pub(crate) fn run( Ok(()) } -fn run_tests( +fn run_tests( blackbox_solver: &S, package: &Package, test_name: FunctionNameMatch, show_output: bool, compile_options: &CompileOptions, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let (mut context, crate_id) = prepare_package(package); check_crate_and_report_errors(&mut context, crate_id, compile_options.deny_warnings)?; diff --git a/crates/nargo_cli/src/cli/verify_cmd.rs b/crates/nargo_cli/src/cli/verify_cmd.rs index dfae743c0c7..187b24123f6 100644 --- a/crates/nargo_cli/src/cli/verify_cmd.rs +++ b/crates/nargo_cli/src/cli/verify_cmd.rs @@ -3,12 +3,10 @@ use super::{ compile_cmd::compile_package, fs::{inputs::read_inputs_from_file, load_hex_data, program::read_program_from_file}, }; -use crate::errors::CliError; +use crate::{backends::Backend, errors::CliError}; -use acvm::Backend; use clap::Args; use nargo::constants::{PROOF_EXT, VERIFIER_INPUT_FILE}; -use nargo::ops::verify_proof; use nargo::{artifacts::program::PreprocessedProgram, package::Package}; use nargo_toml::{get_package_manifest, resolve_workspace_from_toml, PackageSelection}; use noirc_abi::input_parser::Format; @@ -38,11 +36,11 @@ pub(crate) struct VerifyCommand { compile_options: CompileOptions, } -pub(crate) fn run( - backend: &B, +pub(crate) fn run( + backend: &Backend, args: VerifyCommand, config: NargoConfig, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let toml_path = get_package_manifest(&config.program_dir)?; let default_selection = if args.workspace { PackageSelection::All } else { PackageSelection::DefaultOrAll }; @@ -68,14 +66,14 @@ pub(crate) fn run( Ok(()) } -fn verify_package( - backend: &B, +fn verify_package( + backend: &Backend, package: &Package, proof_path: &Path, circuit_build_path: PathBuf, verifier_name: &str, compile_options: &CompileOptions, -) -> Result<(), CliError> { +) -> Result<(), CliError> { let preprocessed_program = if circuit_build_path.exists() { read_program_from_file(circuit_build_path)? } else { @@ -98,8 +96,7 @@ fn verify_package( let public_inputs = public_abi.encode(&public_inputs_map, return_value)?; let proof = load_hex_data(proof_path)?; - let valid_proof = verify_proof(backend, &bytecode, &proof, public_inputs) - .map_err(CliError::ProofSystemCompilerError)?; + let valid_proof = backend.verify(&proof, public_inputs, &bytecode, false)?; if valid_proof { Ok(()) diff --git a/crates/nargo_cli/src/errors.rs b/crates/nargo_cli/src/errors.rs index ac59576692b..24faff632b1 100644 --- a/crates/nargo_cli/src/errors.rs +++ b/crates/nargo_cli/src/errors.rs @@ -1,4 +1,5 @@ -use acvm::{acir::native_types::WitnessMapError, Backend, ProofSystemCompiler, SmartContract}; +use acvm::acir::native_types::WitnessMapError; +use acvm_backend_barretenberg::BackendError; use hex::FromHexError; use nargo::NargoError; use nargo_toml::ManifestError; @@ -29,7 +30,7 @@ pub(crate) enum FilesystemError { } #[derive(Debug, Error)] -pub(crate) enum CliError { +pub(crate) enum CliError { #[error("{0}")] Generic(String), #[error("Error: destination {} already exists", .0.display())] @@ -64,13 +65,9 @@ pub(crate) enum CliError { #[error(transparent)] CompileError(#[from] CompileError), - /// Backend error caused by a function on the SmartContract trait + /// Backend error #[error(transparent)] - SmartContractError(::Error), // Unfortunately, Rust won't let us `impl From` over an Associated Type on a generic - - /// 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 + SmartContractError(#[from] BackendError), } /// Errors covering situations where a package cannot be compiled.