diff --git a/compiler/wasm/src/compile.rs b/compiler/wasm/src/compile.rs index c6ae0ae1f42..54fdccf1369 100644 --- a/compiler/wasm/src/compile.rs +++ b/compiler/wasm/src/compile.rs @@ -2,9 +2,9 @@ use fm::FileManager; use gloo_utils::format::JsValueSerdeExt; use js_sys::{JsString, Object}; use nargo::artifacts::{ - contract::{PreprocessedContract, PreprocessedContractFunction}, + contract::{ContractArtifact, ContractFunctionArtifact}, debug::DebugArtifact, - program::PreprocessedProgram, + program::ProgramArtifact, }; use noirc_driver::{ add_dep, compile_contract, compile_main, file_manager_with_stdlib, prepare_crate, @@ -148,8 +148,8 @@ impl PathToFileSourceMap { } pub enum CompileResult { - Contract { contract: PreprocessedContract, debug: DebugArtifact }, - Program { program: PreprocessedProgram, debug: DebugArtifact }, + Contract { contract: ContractArtifact, debug: DebugArtifact }, + Program { program: ProgramArtifact, debug: DebugArtifact }, } #[wasm_bindgen] @@ -195,7 +195,7 @@ pub fn compile( let optimized_contract = nargo::ops::optimize_contract(compiled_contract, expression_width); - let compile_output = preprocess_contract(optimized_contract); + let compile_output = generate_contract_artifact(optimized_contract); Ok(JsCompileResult::new(compile_output)) } else { let compiled_program = compile_main(&mut context, crate_id, &compile_options, None, true) @@ -210,7 +210,7 @@ pub fn compile( let optimized_program = nargo::ops::optimize_program(compiled_program, expression_width); - let compile_output = preprocess_program(optimized_program); + let compile_output = generate_program_artifact(optimized_program); Ok(JsCompileResult::new(compile_output)) } } @@ -272,50 +272,32 @@ fn add_noir_lib(context: &mut Context, library_name: &CrateName) -> CrateId { prepare_dependency(context, &path_to_lib) } -pub(crate) fn preprocess_program(program: CompiledProgram) -> CompileResult { +pub(crate) fn generate_program_artifact(program: CompiledProgram) -> CompileResult { let debug_artifact = DebugArtifact { - debug_symbols: vec![program.debug], - file_map: program.file_map, - warnings: program.warnings, + debug_symbols: vec![program.debug.clone()], + file_map: program.file_map.clone(), + warnings: program.warnings.clone(), }; - let preprocessed_program = PreprocessedProgram { - hash: program.hash, - abi: program.abi, - noir_version: NOIR_ARTIFACT_VERSION_STRING.to_string(), - bytecode: program.circuit, - }; - - CompileResult::Program { program: preprocessed_program, debug: debug_artifact } + CompileResult::Program { program: program.into(), debug: debug_artifact } } -// TODO: This method should not be doing so much, most of this should be done in nargo or the driver -pub(crate) fn preprocess_contract(contract: CompiledContract) -> CompileResult { +pub(crate) fn generate_contract_artifact(contract: CompiledContract) -> CompileResult { let debug_artifact = DebugArtifact { debug_symbols: contract.functions.iter().map(|function| function.debug.clone()).collect(), file_map: contract.file_map, warnings: contract.warnings, }; - let preprocessed_functions = contract - .functions - .into_iter() - .map(|func| PreprocessedContractFunction { - name: func.name, - function_type: func.function_type, - is_internal: func.is_internal, - abi: func.abi, - bytecode: func.bytecode, - }) - .collect(); - - let preprocessed_contract = PreprocessedContract { + let functions = contract.functions.into_iter().map(ContractFunctionArtifact::from).collect(); + + let contract_artifact = ContractArtifact { noir_version: String::from(NOIR_ARTIFACT_VERSION_STRING), name: contract.name, - functions: preprocessed_functions, + functions, events: contract.events, }; - CompileResult::Contract { contract: preprocessed_contract, debug: debug_artifact } + CompileResult::Contract { contract: contract_artifact, debug: debug_artifact } } #[cfg(test)] diff --git a/compiler/wasm/src/compile_new.rs b/compiler/wasm/src/compile_new.rs index 0cd1a2c50e5..e8a01540ff9 100644 --- a/compiler/wasm/src/compile_new.rs +++ b/compiler/wasm/src/compile_new.rs @@ -1,6 +1,6 @@ use crate::compile::{ - file_manager_with_source_map, preprocess_contract, preprocess_program, JsCompileResult, - PathToFileSourceMap, + file_manager_with_source_map, generate_contract_artifact, generate_program_artifact, + JsCompileResult, PathToFileSourceMap, }; use crate::errors::{CompileError, JsCompileError}; use noirc_driver::{ @@ -108,7 +108,7 @@ impl CompilerContext { let optimized_program = nargo::ops::optimize_program(compiled_program, np_language); - let compile_output = preprocess_program(optimized_program); + let compile_output = generate_program_artifact(optimized_program); Ok(JsCompileResult::new(compile_output)) } @@ -133,7 +133,7 @@ impl CompilerContext { let optimized_contract = nargo::ops::optimize_contract(compiled_contract, np_language); - let compile_output = preprocess_contract(optimized_contract); + let compile_output = generate_contract_artifact(optimized_contract); Ok(JsCompileResult::new(compile_output)) } } diff --git a/tooling/nargo/src/artifacts/contract.rs b/tooling/nargo/src/artifacts/contract.rs index 4ade4f5660e..04699126762 100644 --- a/tooling/nargo/src/artifacts/contract.rs +++ b/tooling/nargo/src/artifacts/contract.rs @@ -1,21 +1,16 @@ use acvm::acir::circuit::Circuit; use noirc_abi::{Abi, ContractEvent}; -use noirc_driver::ContractFunctionType; +use noirc_driver::{ContractFunction, ContractFunctionType}; use serde::{Deserialize, Serialize}; -/// `PreprocessedContract` represents a Noir contract which has been preprocessed by a particular backend proving system. -/// -/// This differs from a generic Noir contract artifact in that: -/// - The ACIR bytecode has had an optimization pass applied to tailor it for the backend. -/// - Proving and verification keys have been pregenerated based on this ACIR. #[derive(Serialize, Deserialize)] -pub struct PreprocessedContract { +pub struct ContractArtifact { /// Version of noir used to compile this contract pub noir_version: String, /// The name of the contract. pub name: String, /// Each of the contract's functions are compiled into a separate program stored in this `Vec`. - pub functions: Vec, + pub functions: Vec, /// All the events defined inside the contract scope. pub events: Vec, } @@ -25,7 +20,7 @@ pub struct PreprocessedContract { /// A contract function unlike a regular Noir program however can have additional properties. /// One of these being a function type. #[derive(Debug, Serialize, Deserialize)] -pub struct PreprocessedContractFunction { +pub struct ContractFunctionArtifact { pub name: String, pub function_type: ContractFunctionType, @@ -40,3 +35,15 @@ pub struct PreprocessedContractFunction { )] pub bytecode: Circuit, } + +impl From for ContractFunctionArtifact { + fn from(func: ContractFunction) -> Self { + ContractFunctionArtifact { + name: func.name, + function_type: func.function_type, + is_internal: func.is_internal, + abi: func.abi, + bytecode: func.bytecode, + } + } +} diff --git a/tooling/nargo/src/artifacts/program.rs b/tooling/nargo/src/artifacts/program.rs index 664db0adca4..96e63e6fe50 100644 --- a/tooling/nargo/src/artifacts/program.rs +++ b/tooling/nargo/src/artifacts/program.rs @@ -1,17 +1,13 @@ use acvm::acir::circuit::Circuit; use noirc_abi::Abi; +use noirc_driver::CompiledProgram; use serde::{Deserialize, Serialize}; -/// `PreprocessedProgram` represents a Noir program which has been preprocessed by a particular backend proving system. -/// -/// This differs from a generic Noir program artifact in that: -/// - The ACIR bytecode has had an optimization pass applied to tailor it for the backend. -/// - Proving and verification keys have been pregenerated based on this ACIR. #[derive(Serialize, Deserialize, Debug)] -pub struct PreprocessedProgram { +pub struct ProgramArtifact { pub noir_version: String, - /// Hash of the [`Program`][noirc_frontend::monomorphization::ast::Program] from which this [`PreprocessedProgram`] + /// Hash of the [`Program`][noirc_frontend::monomorphization::ast::Program] from which this [`ProgramArtifact`] /// was compiled. /// /// Used to short-circuit compilation in the case of the source code not changing since the last compilation. @@ -25,3 +21,14 @@ pub struct PreprocessedProgram { )] pub bytecode: Circuit, } + +impl From for ProgramArtifact { + fn from(program: CompiledProgram) -> Self { + ProgramArtifact { + hash: program.hash, + abi: program.abi, + noir_version: program.noir_version, + bytecode: program.circuit, + } + } +} diff --git a/tooling/nargo_cli/src/cli/compile_cmd.rs b/tooling/nargo_cli/src/cli/compile_cmd.rs index 661081778c3..612261fac53 100644 --- a/tooling/nargo_cli/src/cli/compile_cmd.rs +++ b/tooling/nargo_cli/src/cli/compile_cmd.rs @@ -3,10 +3,9 @@ use std::path::Path; use acvm::ExpressionWidth; use fm::FileManager; use iter_extended::vecmap; -use nargo::artifacts::contract::PreprocessedContract; -use nargo::artifacts::contract::PreprocessedContractFunction; +use nargo::artifacts::contract::{ContractArtifact, ContractFunctionArtifact}; use nargo::artifacts::debug::DebugArtifact; -use nargo::artifacts::program::PreprocessedProgram; +use nargo::artifacts::program::ProgramArtifact; use nargo::errors::CompileError; use nargo::insert_all_files_for_workspace_into_file_manager; use nargo::package::Package; @@ -173,15 +172,15 @@ fn compile_program( let program_artifact_path = workspace.package_build_path(package); let mut debug_artifact_path = program_artifact_path.clone(); debug_artifact_path.set_file_name(format!("debug_{}.json", package.name)); - let cached_program = if let (Ok(preprocessed_program), Ok(mut debug_artifact)) = ( + let cached_program = if let (Ok(program_artifact), Ok(mut debug_artifact)) = ( read_program_from_file(program_artifact_path), read_debug_artifact_from_file(debug_artifact_path), ) { Some(CompiledProgram { - hash: preprocessed_program.hash, - circuit: preprocessed_program.bytecode, - abi: preprocessed_program.abi, - noir_version: preprocessed_program.noir_version, + hash: program_artifact.hash, + circuit: program_artifact.bytecode, + abi: program_artifact.abi, + noir_version: program_artifact.noir_version, debug: debug_artifact.debug_symbols.remove(0), file_map: debug_artifact.file_map, warnings: debug_artifact.warnings, @@ -239,16 +238,11 @@ fn save_program( circuit_dir: &Path, only_acir_opt: bool, ) { - let preprocessed_program = PreprocessedProgram { - hash: program.hash, - abi: program.abi, - noir_version: program.noir_version, - bytecode: program.circuit, - }; + let program_artifact = ProgramArtifact::from(program.clone()); if only_acir_opt { - only_acir(&preprocessed_program, circuit_dir); + only_acir(&program_artifact, circuit_dir); } else { - save_program_to_file(&preprocessed_program, &package.name, circuit_dir); + save_program_to_file(&program_artifact, &package.name, circuit_dir); } let debug_artifact = DebugArtifact { @@ -263,7 +257,7 @@ fn save_program( fn save_contract(contract: CompiledContract, package: &Package, circuit_dir: &Path) { // TODO(#1389): 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. + // are compiled via nargo-core and then the ContractArtifact is constructed here. // This is due to EACH function needing it's own CRS, PKey, and VKey from the backend. let debug_artifact = DebugArtifact { debug_symbols: contract.functions.iter().map(|function| function.debug.clone()).collect(), @@ -271,7 +265,7 @@ fn save_contract(contract: CompiledContract, package: &Package, circuit_dir: &Pa warnings: contract.warnings, }; - let preprocessed_functions = vecmap(contract.functions, |func| PreprocessedContractFunction { + let functions = vecmap(contract.functions, |func| ContractFunctionArtifact { name: func.name, function_type: func.function_type, is_internal: func.is_internal, @@ -279,22 +273,22 @@ fn save_contract(contract: CompiledContract, package: &Package, circuit_dir: &Pa bytecode: func.bytecode, }); - let preprocessed_contract = PreprocessedContract { + let contract_artifact = ContractArtifact { noir_version: contract.noir_version, name: contract.name, - functions: preprocessed_functions, + functions, events: contract.events, }; save_contract_to_file( - &preprocessed_contract, - &format!("{}-{}", package.name, preprocessed_contract.name), + &contract_artifact, + &format!("{}-{}", package.name, contract_artifact.name), circuit_dir, ); save_debug_artifact_to_file( &debug_artifact, - &format!("{}-{}", package.name, preprocessed_contract.name), + &format!("{}-{}", package.name, contract_artifact.name), circuit_dir, ); } diff --git a/tooling/nargo_cli/src/cli/fs/program.rs b/tooling/nargo_cli/src/cli/fs/program.rs index 807df25ba48..1d2f012736e 100644 --- a/tooling/nargo_cli/src/cli/fs/program.rs +++ b/tooling/nargo_cli/src/cli/fs/program.rs @@ -2,7 +2,7 @@ use std::path::{Path, PathBuf}; use acvm::acir::circuit::Circuit; use nargo::artifacts::{ - contract::PreprocessedContract, debug::DebugArtifact, program::PreprocessedProgram, + contract::ContractArtifact, debug::DebugArtifact, program::ProgramArtifact, }; use noirc_frontend::graph::CrateName; @@ -11,29 +11,29 @@ use crate::errors::FilesystemError; use super::{create_named_dir, write_to_file}; pub(crate) fn save_program_to_file>( - compiled_program: &PreprocessedProgram, + program_artifact: &ProgramArtifact, crate_name: &CrateName, circuit_dir: P, ) -> PathBuf { let circuit_name: String = crate_name.into(); - save_build_artifact_to_file(compiled_program, &circuit_name, circuit_dir) + save_build_artifact_to_file(program_artifact, &circuit_name, circuit_dir) } /// Writes the bytecode as acir.gz pub(crate) fn only_acir>( - compiled_program: &PreprocessedProgram, + program_artifact: &ProgramArtifact, circuit_dir: P, ) -> PathBuf { create_named_dir(circuit_dir.as_ref(), "target"); let circuit_path = circuit_dir.as_ref().join("acir").with_extension("gz"); - let bytes = Circuit::serialize_circuit(&compiled_program.bytecode); + let bytes = Circuit::serialize_circuit(&program_artifact.bytecode); write_to_file(&bytes, &circuit_path); circuit_path } pub(crate) fn save_contract_to_file>( - compiled_contract: &PreprocessedContract, + compiled_contract: &ContractArtifact, circuit_name: &str, circuit_dir: P, ) -> PathBuf { @@ -64,7 +64,7 @@ fn save_build_artifact_to_file, T: ?Sized + serde::Serialize>( pub(crate) fn read_program_from_file>( circuit_path: P, -) -> Result { +) -> Result { let file_path = circuit_path.as_ref().with_extension("json"); let input_string =