diff --git a/crates/nargo/src/cli/execute_cmd.rs b/crates/nargo/src/cli/execute_cmd.rs index f47040e1166..11e905990a3 100644 --- a/crates/nargo/src/cli/execute_cmd.rs +++ b/crates/nargo/src/cli/execute_cmd.rs @@ -57,7 +57,7 @@ fn execute_with_path>( let compiled_program = compile_circuit(&program_dir, show_ssa, allow_warnings)?; // Parse the initial witness values from Prover.toml - let inputs_map = read_inputs_from_file( + let (inputs_map, _) = read_inputs_from_file( &program_dir, PROVER_INPUT_FILE, Format::Toml, diff --git a/crates/nargo/src/cli/mod.rs b/crates/nargo/src/cli/mod.rs index a06039c9a5e..2a4183d80fb 100644 --- a/crates/nargo/src/cli/mod.rs +++ b/crates/nargo/src/cli/mod.rs @@ -2,10 +2,14 @@ use acvm::{acir::circuit::Circuit, hash_constraint_system, ProofSystemCompiler}; pub use check_cmd::check_from_path; use clap::{Args, Parser, Subcommand}; use const_format::formatcp; -use noirc_abi::{input_parser::Format, Abi, InputMap}; +use noirc_abi::{ + input_parser::{Format, InputValue}, + Abi, InputMap, MAIN_RETURN_NAME, +}; use noirc_driver::Driver; use noirc_frontend::graph::{CrateName, CrateType}; use std::{ + collections::BTreeMap, fs::File, io::Write, path::{Path, PathBuf}, @@ -110,12 +114,23 @@ fn write_to_file(bytes: &[u8], path: &Path) -> String { } } +/// Returns the circuit's parameters and its return value, if one exists. +/// # Examples +/// +/// ```ignore +/// let (input_map, return_value): (InputMap, Option) = +/// read_inputs_from_file(path, "Verifier", Format::Toml, &abi)?; +/// ``` pub fn read_inputs_from_file>( path: P, file_name: &str, format: Format, abi: &Abi, -) -> Result { +) -> Result<(InputMap, Option), CliError> { + if abi.is_empty() { + return Ok((BTreeMap::new(), None)); + } + let file_path = { let mut dir_path = path.as_ref().to_path_buf(); dir_path.push(file_name); @@ -127,11 +142,15 @@ pub fn read_inputs_from_file>( } let input_string = std::fs::read_to_string(file_path).unwrap(); - Ok(format.parse(&input_string, abi)?) + let mut input_map = format.parse(&input_string, abi)?; + let return_value = input_map.remove(MAIN_RETURN_NAME); + + Ok((input_map, return_value)) } -fn write_inputs_to_file>( - w_map: &InputMap, +pub fn write_inputs_to_file>( + input_map: &InputMap, + return_value: &Option, path: P, file_name: &str, format: Format, @@ -143,7 +162,19 @@ fn write_inputs_to_file>( dir_path }; - let serialized_output = format.serialize(w_map)?; + // We must insert the return value into the `InputMap` in order for it to be written to file. + let serialized_output = match return_value { + // Parameters and return values are kept separate except for when they're being written to file. + // As a result, we don't want to modify the original map and must clone it before insertion. + Some(return_value) => { + let mut input_map = input_map.clone(); + input_map.insert(MAIN_RETURN_NAME.to_owned(), return_value.clone()); + format.serialize(&input_map)? + } + // If no return value exists, then we can serialize the original map directly. + None => format.serialize(input_map)?, + }; + write_to_file(serialized_output.as_bytes(), &file_path); Ok(()) diff --git a/crates/nargo/src/cli/prove_cmd.rs b/crates/nargo/src/cli/prove_cmd.rs index ee7e967ddeb..4f107b2ae0d 100644 --- a/crates/nargo/src/cli/prove_cmd.rs +++ b/crates/nargo/src/cli/prove_cmd.rs @@ -2,7 +2,7 @@ use std::path::{Path, PathBuf}; use acvm::ProofSystemCompiler; use clap::Args; -use noirc_abi::{input_parser::Format, MAIN_RETURN_NAME}; +use noirc_abi::input_parser::Format; use super::{ create_named_dir, fetch_pk_and_vk, read_inputs_from_file, write_inputs_to_file, write_to_file, @@ -77,7 +77,7 @@ pub fn prove_with_path>( fetch_pk_and_vk(&compiled_program.circuit, circuit_build_path.as_ref(), true, check_proof)?; // Parse the initial witness values from Prover.toml - let inputs_map = read_inputs_from_file( + let (inputs_map, _) = read_inputs_from_file( &program_dir, PROVER_INPUT_FILE, Format::Toml, @@ -90,19 +90,13 @@ pub fn prove_with_path>( let public_abi = compiled_program.abi.clone().public_abi(); let (public_inputs, return_value) = public_abi.decode(&solved_witness)?; - if let Some(return_value) = return_value.clone() { - // Insert return value into public inputs so it's written to file. - let mut public_inputs_with_return = public_inputs.clone(); - public_inputs_with_return.insert(MAIN_RETURN_NAME.to_owned(), return_value); - write_inputs_to_file( - &public_inputs_with_return, - &program_dir, - VERIFIER_INPUT_FILE, - Format::Toml, - )?; - } else { - write_inputs_to_file(&public_inputs, &program_dir, VERIFIER_INPUT_FILE, Format::Toml)?; - } + write_inputs_to_file( + &public_inputs, + &return_value, + &program_dir, + VERIFIER_INPUT_FILE, + Format::Toml, + )?; let backend = crate::backends::ConcreteBackend; let proof = diff --git a/crates/nargo/src/cli/verify_cmd.rs b/crates/nargo/src/cli/verify_cmd.rs index f44178b448f..b0558ed44ca 100644 --- a/crates/nargo/src/cli/verify_cmd.rs +++ b/crates/nargo/src/cli/verify_cmd.rs @@ -9,9 +9,8 @@ use crate::{ use acvm::{FieldElement, ProofSystemCompiler}; use clap::Args; use noirc_abi::input_parser::{Format, InputValue}; -use noirc_abi::MAIN_RETURN_NAME; use noirc_driver::CompiledProgram; -use std::{collections::BTreeMap, path::Path}; +use std::path::Path; /// Given a proof and a program, verify whether the proof is valid #[derive(Debug, Clone, Args)] @@ -67,15 +66,8 @@ pub fn verify_with_path>( // Load public inputs (if any) from `VERIFIER_INPUT_FILE`. let public_abi = compiled_program.abi.clone().public_abi(); - let (public_inputs_map, return_value) = if public_abi.has_public_inputs() { - let current_dir = program_dir; - let mut public_inputs_map = - read_inputs_from_file(current_dir, VERIFIER_INPUT_FILE, Format::Toml, &public_abi)?; - let return_value = public_inputs_map.remove(MAIN_RETURN_NAME); - (public_inputs_map, return_value) - } else { - (BTreeMap::new(), None) - }; + let (public_inputs_map, return_value) = + read_inputs_from_file(program_dir, VERIFIER_INPUT_FILE, Format::Toml, &public_abi)?; let valid_proof = verify_proof( compiled_program, diff --git a/crates/noirc_abi/src/lib.rs b/crates/noirc_abi/src/lib.rs index 8894042d900..8c627c8fc28 100644 --- a/crates/noirc_abi/src/lib.rs +++ b/crates/noirc_abi/src/lib.rs @@ -153,6 +153,11 @@ impl Abi { self.return_type.is_some() || self.parameters.iter().any(|param| param.is_public()) } + /// Returns `true` if the ABI contains no parameters or return value. + pub fn is_empty(&self) -> bool { + self.return_type.is_none() && self.parameters.is_empty() + } + pub fn to_btree_map(&self) -> BTreeMap { let mut map = BTreeMap::new(); for param in self.parameters.iter() {