Skip to content

Commit

Permalink
feat: add nargo preprocess command
Browse files Browse the repository at this point in the history
chore: silence `nargo compile` output

fix: display `nargo prove` doc comment in help
  • Loading branch information
TomAFrench committed Feb 27, 2023
1 parent 2c30f64 commit cfb30c5
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 47 deletions.
48 changes: 7 additions & 41 deletions crates/nargo/src/cli/compile_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use acvm::acir::circuit::Circuit;
use acvm::ProofSystemCompiler;
use std::path::{Path, PathBuf};
use std::path::Path;

use clap::Args;

use crate::{constants::TARGET_DIR, errors::CliError, resolver::Resolver};

use super::fs::{acir::save_acir_to_dir, keys::save_key_to_dir};
use super::fs::acir::save_acir_to_dir;
use super::preprocess_cmd::preprocess_with_path;
use super::{add_std_lib, NargoConfig};

/// Compile the program and its secret execution trace into ACIR format
Expand All @@ -24,30 +24,13 @@ pub(crate) fn run(args: CompileCommand, config: NargoConfig) -> Result<(), CliEr
let mut circuit_path = config.program_dir.clone();
circuit_path.push(TARGET_DIR);

let circuit_path = compile_and_preprocess_circuit(
&args.circuit_name,
config.program_dir,
circuit_path,
args.allow_warnings,
)?;
let compiled_program = compile_circuit(config.program_dir, false, args.allow_warnings)?;

println!("Generated ACIR code into {}", circuit_path.display());
save_acir_to_dir(&compiled_program.circuit, &args.circuit_name, &circuit_path);

Ok(())
}
preprocess_with_path(&args.circuit_name, circuit_path, &compiled_program.circuit)?;

fn compile_and_preprocess_circuit<P: AsRef<Path>>(
circuit_name: &str,
program_dir: P,
circuit_dir: P,
allow_warnings: bool,
) -> Result<PathBuf, CliError> {
let compiled_program = compile_circuit(program_dir, false, allow_warnings)?;
let circuit_path = save_acir_to_dir(&compiled_program.circuit, circuit_name, &circuit_dir);

preprocess_with_path(circuit_name, circuit_dir, &compiled_program.circuit)?;

Ok(circuit_path)
Ok(())
}

pub(crate) fn compile_circuit<P: AsRef<Path>>(
Expand All @@ -61,20 +44,3 @@ pub(crate) fn compile_circuit<P: AsRef<Path>>(

driver.into_compiled_program(show_ssa, allow_warnings).map_err(|_| std::process::exit(1))
}

fn preprocess_with_path<P: AsRef<Path>>(
key_name: &str,
preprocess_dir: P,
circuit: &Circuit,
) -> Result<(PathBuf, PathBuf), CliError> {
let backend = crate::backends::ConcreteBackend;

let (proving_key, verification_key) = backend.preprocess(circuit);

let pk_path = save_key_to_dir(proving_key, key_name, &preprocess_dir, true)?;
println!("Proving key saved to {}", pk_path.display());
let vk_path = save_key_to_dir(verification_key, key_name, preprocess_dir, false)?;
println!("Verification key saved to {}", vk_path.display());

Ok((pk_path, vk_path))
}
29 changes: 24 additions & 5 deletions crates/nargo/src/cli/fs/acir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::path::{Path, PathBuf};

use acvm::{acir::circuit::Circuit, hash_constraint_system};

use crate::constants::ACIR_EXT;
use crate::{constants::ACIR_EXT, errors::CliError};

use super::{create_named_dir, write_to_file};

Expand All @@ -20,10 +20,29 @@ pub(crate) fn save_acir_to_dir<P: AsRef<Path>>(
circuit_path.set_extension(ACIR_EXT);
write_to_file(serialized.as_slice(), &circuit_path);

// Save a checksum of the circuit to compare against during proving and verification
circuit_path
}

pub(crate) fn save_acir_hash_to_dir<P: AsRef<Path>>(
circuit: &Circuit,
hash_name: &str,
hash_dir: P,
) -> PathBuf {
let acir_hash = hash_constraint_system(circuit);
circuit_path.set_extension(ACIR_EXT.to_owned() + ".sha256");
write_to_file(hex::encode(acir_hash).as_bytes(), &circuit_path);
let hash_path =
hash_dir.as_ref().join(hash_name).with_extension(ACIR_EXT.to_owned() + ".sha256");
write_to_file(hex::encode(acir_hash).as_bytes(), &hash_path);

circuit_path
hash_path
}

pub(crate) fn read_acir_from_file<P: AsRef<Path>>(circuit_path: P) -> Result<Circuit, CliError> {
let circuit_path = circuit_path.as_ref().with_extension(ACIR_EXT);

let serialized: Vec<u8> =
std::fs::read(&circuit_path).map_err(|_| CliError::PathNotValid(circuit_path))?;

let circuit = Circuit::read(&*serialized).expect("could not deserialize circuit");

Ok(circuit)
}
3 changes: 3 additions & 0 deletions crates/nargo/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod contract_cmd;
mod execute_cmd;
mod gates_cmd;
mod new_cmd;
mod preprocess_cmd;
mod prove_cmd;
mod test_cmd;
mod verify_cmd;
Expand Down Expand Up @@ -53,6 +54,7 @@ enum NargoCommand {
Execute(execute_cmd::ExecuteCommand),
Prove(prove_cmd::ProveCommand),
Verify(verify_cmd::VerifyCommand),
Preprocess(preprocess_cmd::PreprocessCommand),
Test(test_cmd::TestCommand),
Gates(gates_cmd::GatesCommand),
}
Expand All @@ -67,6 +69,7 @@ pub fn start_cli() {
NargoCommand::Execute(args) => execute_cmd::run(args, matches.config),
NargoCommand::Prove(args) => prove_cmd::run(args, matches.config),
NargoCommand::Verify(args) => verify_cmd::run(args, matches.config),
NargoCommand::Preprocess(args) => preprocess_cmd::run(args, matches.config),
NargoCommand::Test(args) => test_cmd::run(args, matches.config),
NargoCommand::Gates(args) => gates_cmd::run(args, matches.config),
NargoCommand::Contract(args) => contract_cmd::run(args, matches.config),
Expand Down
48 changes: 48 additions & 0 deletions crates/nargo/src/cli/preprocess_cmd.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use acvm::acir::circuit::Circuit;
use acvm::ProofSystemCompiler;
use std::path::{Path, PathBuf};

use clap::Args;

use crate::{constants::TARGET_DIR, errors::CliError};

use super::fs::{
acir::{read_acir_from_file, save_acir_hash_to_dir},
keys::save_key_to_dir,
};
use super::NargoConfig;

/// Generate proving and verification keys for a circuit.
#[derive(Debug, Clone, Args)]
pub(crate) struct PreprocessCommand {
/// The name of the circuit ACIR build file.
circuit_name: String,
}

pub(crate) fn run(args: PreprocessCommand, config: NargoConfig) -> Result<(), CliError> {
let circuit_dir = config.program_dir.join(TARGET_DIR);

let circuit = read_acir_from_file(circuit_dir.join(&args.circuit_name))?;

preprocess_with_path(&args.circuit_name, circuit_dir, &circuit)?;

Ok(())
}

pub(crate) fn preprocess_with_path<P: AsRef<Path>>(
key_name: &str,
preprocess_dir: P,
circuit: &Circuit,
) -> Result<(PathBuf, PathBuf), CliError> {
let backend = crate::backends::ConcreteBackend;
let (proving_key, verification_key) = backend.preprocess(circuit);

// Save a checksum of the circuit to compare against during proving and verification.
// If hash doesn't match then the circuit has been updated and keys are stale.
save_acir_hash_to_dir(circuit, key_name, &preprocess_dir);

let pk_path = save_key_to_dir(proving_key, key_name, &preprocess_dir, true)?;
let vk_path = save_key_to_dir(verification_key, key_name, preprocess_dir, false)?;

Ok((pk_path, vk_path))
}
2 changes: 1 addition & 1 deletion crates/nargo/src/cli/prove_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
errors::CliError,
};

// Create proof for this program. The proof is returned as a hex encoded string.
/// Create proof for this program. The proof is returned as a hex encoded string.
#[derive(Debug, Clone, Args)]
pub(crate) struct ProveCommand {
/// The name of the proof
Expand Down

0 comments on commit cfb30c5

Please sign in to comment.