Skip to content

Commit

Permalink
chore: encapsulate IO logic in IO functions (#885)
Browse files Browse the repository at this point in the history
* chore: encapsulate IO logic in IO functions

* chore: replace if-let with match

* chore: add comment explaining serialisation logic

* chore: add doc comment for read_inputs_from_file

* chore: update comment
  • Loading branch information
TomAFrench authored Feb 21, 2023
1 parent 2727b34 commit db5c588
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 33 deletions.
2 changes: 1 addition & 1 deletion crates/nargo/src/cli/execute_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fn execute_with_path<P: AsRef<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,
Expand Down
43 changes: 37 additions & 6 deletions crates/nargo/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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<InputValue>) =
/// read_inputs_from_file(path, "Verifier", Format::Toml, &abi)?;
/// ```
pub fn read_inputs_from_file<P: AsRef<Path>>(
path: P,
file_name: &str,
format: Format,
abi: &Abi,
) -> Result<InputMap, CliError> {
) -> Result<(InputMap, Option<InputValue>), 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);
Expand All @@ -127,11 +142,15 @@ pub fn read_inputs_from_file<P: AsRef<Path>>(
}

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<P: AsRef<Path>>(
w_map: &InputMap,
pub fn write_inputs_to_file<P: AsRef<Path>>(
input_map: &InputMap,
return_value: &Option<InputValue>,
path: P,
file_name: &str,
format: Format,
Expand All @@ -143,7 +162,19 @@ fn write_inputs_to_file<P: AsRef<Path>>(
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(())
Expand Down
24 changes: 9 additions & 15 deletions crates/nargo/src/cli/prove_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -77,7 +77,7 @@ pub fn prove_with_path<P: AsRef<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,
Expand All @@ -90,19 +90,13 @@ pub fn prove_with_path<P: AsRef<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 =
Expand Down
14 changes: 3 additions & 11 deletions crates/nargo/src/cli/verify_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -67,15 +66,8 @@ pub fn verify_with_path<P: AsRef<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,
Expand Down
5 changes: 5 additions & 0 deletions crates/noirc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, AbiType> {
let mut map = BTreeMap::new();
for param in self.parameters.iter() {
Expand Down

0 comments on commit db5c588

Please sign in to comment.