use super::*;
use snarkvm_synthesizer::CallMetrics;
impl<N: Network> Package<N> {
#[allow(clippy::type_complexity)]
pub fn run<A: crate::circuit::Aleo<Network = N, BaseField = N::Field>, R: Rng + CryptoRng>(
&self,
endpoint: Option<String>,
private_key: &PrivateKey<N>,
function_name: Identifier<N>,
inputs: &[Value<N>],
rng: &mut R,
) -> Result<(Response<N>, Execution<N>, Inclusion<N>, Vec<CallMetrics<N>>)> {
let program = self.program();
let program_id = program.id();
if !program.contains_function(&function_name) {
bail!("Function '{function_name}' does not exist.")
}
self.build::<A>(endpoint)?;
let _locator = Locator::<N>::from_str(&format!("{program_id}/{function_name}"))?;
#[cfg(feature = "aleo-cli")]
println!("🚀 Executing '{}'...\n", _locator.to_string().bold());
let process = self.get_process()?;
let authorization = process.authorize::<A, R>(private_key, program_id, function_name, inputs.iter(), rng)?;
let program = process.get_program(program_id)?;
let function = program.get_function(&function_name)?;
for instruction in function.instructions() {
if let Instruction::Call(call) = instruction {
let (program, resource) = match call.operator() {
CallOperator::Locator(locator) => (process.get_program(locator.program_id())?, locator.resource()),
CallOperator::Resource(resource) => (program, resource),
};
if program.contains_function(resource) {
let function_name = resource;
let import_build_directory =
self.build_directory().join(format!("{}-{}", program.id().name(), program.id().network()));
let prover = ProverFile::open(&import_build_directory, function_name)?;
process.insert_proving_key(program.id(), function_name, prover.proving_key().clone())?;
let verifier = VerifierFile::open(&import_build_directory, function_name)?;
process.insert_verifying_key(program.id(), function_name, verifier.verifying_key().clone())?;
}
}
}
let build_directory = self.build_directory();
let prover = ProverFile::open(&build_directory, &function_name)?;
let verifier = VerifierFile::open(&build_directory, &function_name)?;
process.insert_proving_key(program_id, &function_name, prover.proving_key().clone())?;
process.insert_verifying_key(program_id, &function_name, verifier.verifying_key().clone())?;
let (response, execution, inclusion, metrics) = process.execute::<A, R>(authorization, rng)?;
Ok((response, execution, inclusion, metrics))
}
}
#[cfg(test)]
mod tests {
use snarkvm_utilities::TestRng;
type CurrentAleo = snarkvm_circuit::network::AleoV0;
#[test]
fn test_run() {
let (directory, package) = crate::package::test_helpers::sample_package();
assert!(!package.build_directory().exists());
package.build::<CurrentAleo>(None).unwrap();
assert!(package.build_directory().exists());
let rng = &mut TestRng::default();
let (private_key, function_name, inputs) =
crate::package::test_helpers::sample_package_run(package.program_id());
let (_response, _execution, _inclusion, _metrics) =
package.run::<CurrentAleo, _>(None, &private_key, function_name, &inputs, rng).unwrap();
std::fs::remove_dir_all(directory).unwrap();
}
#[test]
fn test_run_with_import() {
let (directory, package) = crate::package::test_helpers::sample_package_with_import();
assert!(!package.build_directory().exists());
package.build::<CurrentAleo>(None).unwrap();
assert!(package.build_directory().exists());
let rng = &mut TestRng::default();
let (private_key, function_name, inputs) =
crate::package::test_helpers::sample_package_run(package.program_id());
let (_response, _execution, _inclusion, _metrics) =
package.run::<CurrentAleo, _>(None, &private_key, function_name, &inputs, rng).unwrap();
std::fs::remove_dir_all(directory).unwrap();
}
}