Skip to content

Commit

Permalink
chore: create helper functions for writing programs and contracts to …
Browse files Browse the repository at this point in the history
…file (#2526)
  • Loading branch information
TomAFrench authored Sep 1, 2023
1 parent 6bfac13 commit 0dc73a1
Showing 1 changed file with 83 additions and 62 deletions.
145 changes: 83 additions & 62 deletions crates/nargo_cli/src/cli/compile_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::path::Path;

use acvm::{acir::circuit::Circuit, compiler::AcirTransformationMap};
use iter_extended::{try_vecmap, vecmap};
use nargo::artifacts::contract::PreprocessedContractFunction;
Expand Down Expand Up @@ -72,70 +74,10 @@ pub(crate) fn run(
let optimized_contracts =
try_vecmap(contracts, |contract| optimize_contract(backend, contract))?;

// 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.
// This is due to EACH function needing it's own CRS, PKey, and VKey from the backend.
let preprocessed_contracts: Vec<(PreprocessedContract, Vec<DebugInfo>)> =
vecmap(optimized_contracts, |contract| {
let preprocess_result = vecmap(contract.functions, |func| {
(
PreprocessedContractFunction {
name: func.name,
function_type: func.function_type,
is_internal: func.is_internal,
abi: func.abi,

bytecode: func.bytecode,
},
func.debug,
)
});

let (preprocessed_contract_functions, debug_infos): (Vec<_>, Vec<_>) =
preprocess_result.into_iter().unzip();

(
PreprocessedContract {
name: contract.name,
backend: String::from(BACKEND_IDENTIFIER),
functions: preprocessed_contract_functions,
},
debug_infos,
)
});
for (contract, debug_infos) in preprocessed_contracts {
save_contract_to_file(
&contract,
&format!("{}-{}", package.name, contract.name),
&circuit_dir,
);

if args.output_debug {
let debug_artifact = DebugArtifact::new(debug_infos, &context);
save_debug_artifact_to_file(
&debug_artifact,
&format!("{}-{}", package.name, contract.name),
&circuit_dir,
);
}
}
save_contracts(&context, optimized_contracts, package, &circuit_dir, args.output_debug);
} else {
let (context, program) = compile_package(backend, package, &args.compile_options)?;

let preprocessed_program = PreprocessedProgram {
backend: String::from(BACKEND_IDENTIFIER),
abi: program.abi,
bytecode: program.circuit,
};

save_program_to_file(&preprocessed_program, &package.name, &circuit_dir);

if args.output_debug {
let debug_artifact = DebugArtifact::new(vec![program.debug], &context);
let circuit_name: String = (&package.name).into();
save_debug_artifact_to_file(&debug_artifact, &circuit_name, &circuit_dir);
}
save_program(&context, program, package, &circuit_dir, args.output_debug);
}
}

Expand Down Expand Up @@ -191,6 +133,85 @@ pub(super) fn optimize_contract(
Ok(CompiledContract { functions, ..contract })
}

fn save_program(
context: &Context,
program: CompiledProgram,
package: &Package,
circuit_dir: &Path,
output_debug: bool,
) {
let preprocessed_program = PreprocessedProgram {
backend: String::from(BACKEND_IDENTIFIER),
abi: program.abi,
bytecode: program.circuit,
};

save_program_to_file(&preprocessed_program, &package.name, circuit_dir);

if output_debug {
let debug_artifact = DebugArtifact::new(vec![program.debug], context);
let circuit_name: String = (&package.name).into();
save_debug_artifact_to_file(&debug_artifact, &circuit_name, circuit_dir);
}
}

fn save_contracts(
context: &Context,
contracts: Vec<CompiledContract>,
package: &Package,
circuit_dir: &Path,
output_debug: bool,
) {
// 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.
// This is due to EACH function needing it's own CRS, PKey, and VKey from the backend.
let preprocessed_contracts: Vec<(PreprocessedContract, Vec<DebugInfo>)> =
vecmap(contracts, |contract| {
let preprocess_result = vecmap(contract.functions, |func| {
(
PreprocessedContractFunction {
name: func.name,
function_type: func.function_type,
is_internal: func.is_internal,
abi: func.abi,

bytecode: func.bytecode,
},
func.debug,
)
});

let (preprocessed_contract_functions, debug_infos): (Vec<_>, Vec<_>) =
preprocess_result.into_iter().unzip();

(
PreprocessedContract {
name: contract.name,
backend: String::from(BACKEND_IDENTIFIER),
functions: preprocessed_contract_functions,
},
debug_infos,
)
});
for (contract, debug_infos) in preprocessed_contracts {
save_contract_to_file(
&contract,
&format!("{}-{}", package.name, contract.name),
circuit_dir,
);

if output_debug {
let debug_artifact = DebugArtifact::new(debug_infos, context);
save_debug_artifact_to_file(
&debug_artifact,
&format!("{}-{}", package.name, contract.name),
circuit_dir,
);
}
}
}

/// Helper function for reporting any errors in a Result<(T, Warnings), ErrorsAndWarnings>
/// structure that is commonly used as a return result in this file.
pub(crate) fn report_errors<T>(
Expand Down

0 comments on commit 0dc73a1

Please sign in to comment.