use super::*;
impl<N: Network> Package<N> {
#[allow(clippy::type_complexity)]
pub fn execute<A: crate::circuit::Aleo<Network = N, BaseField = N::Field>, R: Rng + CryptoRng>(
&self,
endpoint: String,
private_key: &PrivateKey<N>,
function_name: Identifier<N>,
inputs: &[Value<N>],
rng: &mut R,
) -> Result<(Response<N>, Execution<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>(None)?;
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, mut trace) = process.execute::<A, R>(authorization, rng)?;
let call_metrics = trace.call_metrics().to_vec();
trace.prepare(Query::<_, BlockMemory<_>>::from(endpoint))?;
let execution = trace.prove_execution::<A, R>(&locator.to_string(), rng)?;
Ok((response, execution, call_metrics))
}
}
#[cfg(test)]
mod tests {
use super::*;
use snarkvm_utilities::TestRng;
type CurrentAleo = snarkvm_circuit::network::AleoV0;
#[test]
#[ignore]
fn test_execute() {
let (directory, package) = crate::package::test_helpers::sample_token_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 endpoint = "https://api.explorer.aleo.org/v1".to_string();
let (_response, _execution, _metrics) =
package.execute::<CurrentAleo, _>(endpoint, &private_key, function_name, &inputs, rng).unwrap();
std::fs::remove_dir_all(directory).unwrap();
}
#[test]
#[ignore]
fn test_execute_with_import() {
let (directory, package) = crate::package::test_helpers::sample_wallet_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 endpoint = "https://api.explorer.aleo.org/v1".to_string();
let (_response, _execution, _metrics) =
package.execute::<CurrentAleo, _>(endpoint, &private_key, function_name, &inputs, rng).unwrap();
std::fs::remove_dir_all(directory).unwrap();
}
#[ignore]
#[test]
fn test_profiler() -> Result<()> {
let (directory, package) = crate::package::test_helpers::sample_token_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 endpoint = "https://api.explorer.aleo.org/v1".to_string();
let (_response, _execution, _metrics) =
package.execute::<CurrentAleo, _>(endpoint, &private_key, function_name, &inputs, rng).unwrap();
std::fs::remove_dir_all(directory).unwrap();
bail!("\n\nRemember to #[ignore] this test!\n\n")
}
}