run.rs
1 // Copyright (c) 2025 ADnet Contributors 2 // This file is part of the AlphaVM library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use super::*; 17 18 impl<N: Network> Package<N> { 19 /// Runs a program function with the given inputs. 20 pub fn run<A: crate::circuit::Aleo<Network = N, BaseField = N::Field>, R: Rng + CryptoRng>( 21 &self, 22 private_key: &PrivateKey<N>, 23 function_name: Identifier<N>, 24 inputs: &[Value<N>], 25 rng: &mut R, 26 ) -> Result<(Response<N>, Vec<CallMetrics<N>>)> { 27 // Retrieve the main program. 28 let program = self.program(); 29 // Retrieve the program ID. 30 let program_id = program.id(); 31 // Ensure that the function exists. 32 if !program.contains_function(&function_name) { 33 bail!("Function '{function_name}' does not exist.") 34 } 35 36 // Prepare the locator (even if logging is disabled, to sanity check the locator is well-formed). 37 let _locator = Locator::<N>::from_str(&format!("{program_id}/{function_name}"))?; 38 39 dev_println!("🚀 Running '{}'...\n", _locator.to_string()); 40 41 // Construct the process. 42 let process = self.get_process()?; 43 // Authorize the function call. 44 let authorization = process.authorize::<A, R>(private_key, program_id, function_name, inputs.iter(), rng)?; 45 46 // TODO (howardwu): Retrieve the value directly from the authorize call. 47 // Pop the first request. 48 let request = authorization.next()?; 49 // Retrieve the stack. 50 let stack = process.get_stack(program_id)?; 51 // Initialize the assignments. 52 let assignments = Assignments::<N>::default(); 53 // Initialize the call stack. 54 let call_stack = CallStack::PackageRun(vec![request], *private_key, assignments.clone()); 55 // Synthesize the circuit. 56 let response = stack.execute_function::<A, R>(call_stack, None, None, rng)?; 57 // Retrieve the call metrics. 58 let call_metrics = assignments.read().iter().map(|(_, metrics)| *metrics).collect::<Vec<_>>(); 59 // Return the response and call metrics. 60 Ok((response, call_metrics)) 61 } 62 } 63 64 #[cfg(test)] 65 mod tests { 66 use super::*; 67 use alphavm_utilities::TestRng; 68 69 type CurrentAleo = alphavm_circuit::network::AleoV0; 70 71 #[test] 72 #[ignore] // TODO: Requires credits.alpha → credits.alpha migration 73 fn test_run() { 74 // Samples a new package at a temporary directory. 75 let (directory, package) = crate::package::test_helpers::sample_token_package(); 76 77 // Ensure the build directory does *not* exist. 78 assert!(!package.build_directory().exists()); 79 // Build the package. 80 package.build::<CurrentAleo>().unwrap(); 81 // Ensure the build directory exists. 82 assert!(package.build_directory().exists()); 83 84 // Initialize an RNG. 85 let rng = &mut TestRng::default(); 86 // Sample the function inputs. 87 let (private_key, function_name, inputs) = 88 crate::package::test_helpers::sample_package_run(package.program_id()); 89 // Run the program function. 90 let (_response, _metrics) = package.run::<CurrentAleo, _>(&private_key, function_name, &inputs, rng).unwrap(); 91 92 // Proactively remove the temporary directory (to conserve space). 93 std::fs::remove_dir_all(directory).unwrap(); 94 } 95 96 #[test] 97 #[ignore] // TODO: Requires credits.alpha → credits.alpha migration 98 fn test_run_with_import() { 99 // Samples a new package at a temporary directory. 100 let (directory, package) = crate::package::test_helpers::sample_wallet_package(); 101 102 // Ensure the build directory does *not* exist. 103 assert!(!package.build_directory().exists()); 104 // Build the package. 105 package.build::<CurrentAleo>().unwrap(); 106 // Ensure the build directory exists. 107 assert!(package.build_directory().exists()); 108 109 // Initialize an RNG. 110 let rng = &mut TestRng::default(); 111 // Sample the function inputs. 112 let (private_key, function_name, inputs) = 113 crate::package::test_helpers::sample_package_run(package.program_id()); 114 // Run the program function. 115 let (_response, _metrics) = package.run::<CurrentAleo, _>(&private_key, function_name, &inputs, rng).unwrap(); 116 117 // Proactively remove the temporary directory (to conserve space). 118 std::fs::remove_dir_all(directory).unwrap(); 119 } 120 121 #[test] 122 #[ignore] // TODO: Requires credits.alpha → credits.alpha migration 123 fn test_run_with_nested_imports() { 124 // Samples a new package at a temporary directory. 125 let (directory, package) = crate::package::test_helpers::sample_nested_package(); 126 127 // Ensure the build directory does *not* exist. 128 assert!(!package.build_directory().exists()); 129 // Build the package. 130 package.build::<CurrentAleo>().unwrap(); 131 // Ensure the build directory exists. 132 assert!(package.build_directory().exists()); 133 134 // Initialize an RNG. 135 let rng = &mut TestRng::default(); 136 // Sample the function inputs. 137 let (private_key, function_name, inputs) = 138 crate::package::test_helpers::sample_package_run(package.program_id()); 139 // Run the program function. 140 let (_response, _metrics) = package.run::<CurrentAleo, _>(&private_key, function_name, &inputs, rng).unwrap(); 141 142 // Proactively remove the temporary directory (to conserve space). 143 std::fs::remove_dir_all(directory).unwrap(); 144 } 145 146 /// Use `cargo test profiler --features timer` to run this test. 147 #[ignore] 148 #[test] 149 fn test_profiler() -> Result<()> { 150 // Samples a new package at a temporary directory. 151 let (directory, package) = crate::package::test_helpers::sample_token_package(); 152 153 // Ensure the build directory does *not* exist. 154 assert!(!package.build_directory().exists()); 155 // Build the package. 156 package.build::<CurrentAleo>().unwrap(); 157 // Ensure the build directory exists. 158 assert!(package.build_directory().exists()); 159 160 // Initialize an RNG. 161 let rng = &mut TestRng::default(); 162 // Sample the function inputs. 163 let (private_key, function_name, inputs) = 164 crate::package::test_helpers::sample_package_run(package.program_id()); 165 // Run the program function. 166 let (_response, _metrics) = package.run::<CurrentAleo, _>(&private_key, function_name, &inputs, rng).unwrap(); 167 168 // Proactively remove the temporary directory (to conserve space). 169 std::fs::remove_dir_all(directory).unwrap(); 170 171 bail!("\n\nRemember to #[ignore] this test!\n\n") 172 } 173 }