snarkvm_synthesizer_process/stack/
evaluate.rs1use super::*;
17
18impl<N: Network> StackEvaluate<N> for Stack<N> {
19 #[inline]
24 fn evaluate_closure<A: circuit::Aleo<Network = N>>(
25 &self,
26 closure: &Closure<N>,
27 inputs: &[Value<N>],
28 call_stack: CallStack<N>,
29 signer: Address<N>,
30 caller: Address<N>,
31 tvk: Field<N>,
32 ) -> Result<Vec<Value<N>>> {
33 let timer = timer!("Stack::evaluate_closure");
34
35 if closure.inputs().len() != inputs.len() {
37 bail!("Expected {} inputs, found {}", closure.inputs().len(), inputs.len())
38 }
39
40 let mut registers = Registers::<N, A>::new(call_stack, self.get_register_types(closure.name())?.clone());
42 registers.set_signer(signer);
44 registers.set_caller(caller);
46 registers.set_tvk(tvk);
48 lap!(timer, "Initialize the registers");
49
50 closure.inputs().iter().map(|i| i.register()).zip_eq(inputs).try_for_each(|(register, input)| {
52 registers.store(self, register, input.clone())
54 })?;
55 lap!(timer, "Store the inputs");
56
57 for instruction in closure.instructions() {
59 if let Err(error) = instruction.evaluate(self, &mut registers) {
61 bail!("Failed to evaluate instruction ({instruction}): {error}");
62 }
63 }
64 lap!(timer, "Evaluate the instructions");
65
66 let outputs = closure
68 .outputs()
69 .iter()
70 .map(|output| {
71 match output.operand() {
72 Operand::Literal(literal) => Ok(Value::Plaintext(Plaintext::from(literal))),
74 Operand::Register(register) => registers.load(self, &Operand::Register(register.clone())),
76 Operand::ProgramID(program_id) => {
78 Ok(Value::Plaintext(Plaintext::from(Literal::Address(program_id.to_address()?))))
79 }
80 Operand::Signer => Ok(Value::Plaintext(Plaintext::from(Literal::Address(registers.signer()?)))),
82 Operand::Caller => Ok(Value::Plaintext(Plaintext::from(Literal::Address(registers.caller()?)))),
84 Operand::BlockHeight => bail!("Cannot retrieve the block height from a closure scope."),
86 Operand::NetworkID => bail!("Cannot retrieve the network ID from a closure scope."),
88 }
89 })
90 .collect();
91 lap!(timer, "Load the outputs");
92
93 finish!(timer);
94 outputs
95 }
96
97 #[inline]
102 fn evaluate_function<A: circuit::Aleo<Network = N>>(
103 &self,
104 call_stack: CallStack<N>,
105 caller: Option<ProgramID<N>>,
106 ) -> Result<Response<N>> {
107 let timer = timer!("Stack::evaluate_function");
108
109 let (request, call_stack) = match &call_stack {
111 CallStack::Evaluate(authorization) => (authorization.next()?, call_stack),
112 CallStack::Execute(authorization, _) => {
115 let authorization = authorization.replicate();
118 let request = authorization.next()?;
119 let call_stack = CallStack::Evaluate(authorization);
120 (request, call_stack)
121 }
122 _ => bail!("Illegal operation: call stack must be `Evaluate` or `Execute` in `evaluate_function`."),
123 };
124 lap!(timer, "Retrieve the next request");
125
126 ensure!(
128 **request.network_id() == N::ID,
129 "Network ID mismatch. Expected {}, but found {}",
130 N::ID,
131 request.network_id()
132 );
133
134 let function = self.get_function(request.function_name())?;
136 let inputs = request.inputs();
137 let signer = *request.signer();
138 let (is_root, caller) = match caller {
139 Some(caller) => (false, caller.to_address()?),
141 None => (true, signer),
143 };
144 let tvk = *request.tvk();
145
146 if function.inputs().len() != inputs.len() {
148 bail!(
149 "Function '{}' in the program '{}' expects {} inputs, but {} were provided.",
150 function.name(),
151 self.program.id(),
152 function.inputs().len(),
153 inputs.len()
154 )
155 }
156 lap!(timer, "Perform input checks");
157
158 let mut registers = Registers::<N, A>::new(call_stack, self.get_register_types(function.name())?.clone());
160 registers.set_signer(signer);
162 registers.set_caller(caller);
164 registers.set_tvk(tvk);
166 lap!(timer, "Initialize the registers");
167
168 ensure!(request.verify(&function.input_types(), is_root), "Request is invalid");
170 lap!(timer, "Verify the request");
171
172 function.inputs().iter().map(|i| i.register()).zip_eq(inputs).try_for_each(|(register, input)| {
174 registers.store(self, register, input.clone())
176 })?;
177 lap!(timer, "Store the inputs");
178
179 for instruction in function.instructions() {
182 let result = match instruction {
184 Instruction::Call(call) => CallTrait::evaluate(call, self, &mut registers),
186 _ => instruction.evaluate(self, &mut registers),
188 };
189 if let Err(error) = result {
191 bail!("Failed to evaluate instruction ({instruction}): {error}");
192 }
193 }
194 lap!(timer, "Evaluate the instructions");
195
196 let output_operands = &function.outputs().iter().map(|output| output.operand()).collect::<Vec<_>>();
198 lap!(timer, "Retrieve the output operands");
199
200 let outputs = output_operands
202 .iter()
203 .map(|operand| {
204 match operand {
205 Operand::Literal(literal) => Ok(Value::Plaintext(Plaintext::from(literal))),
207 Operand::Register(register) => registers.load(self, &Operand::Register(register.clone())),
209 Operand::ProgramID(program_id) => {
211 Ok(Value::Plaintext(Plaintext::from(Literal::Address(program_id.to_address()?))))
212 }
213 Operand::Signer => Ok(Value::Plaintext(Plaintext::from(Literal::Address(registers.signer()?)))),
215 Operand::Caller => Ok(Value::Plaintext(Plaintext::from(Literal::Address(registers.caller()?)))),
217 Operand::BlockHeight => bail!("Cannot retrieve the block height from a function scope."),
219 Operand::NetworkID => bail!("Cannot retrieve the network ID from a function scope."),
221 }
222 })
223 .collect::<Result<Vec<_>>>()?;
224 lap!(timer, "Load the outputs");
225
226 let output_registers = output_operands
228 .iter()
229 .map(|operand| match operand {
230 Operand::Register(register) => Some(register.clone()),
231 _ => None,
232 })
233 .collect::<Vec<_>>();
234 lap!(timer, "Loaded the output registers");
235
236 let response = Response::new(
238 request.network_id(),
239 self.program.id(),
240 function.name(),
241 request.inputs().len(),
242 request.tvk(),
243 request.tcm(),
244 outputs,
245 &function.output_types(),
246 &output_registers,
247 );
248 finish!(timer);
249
250 response
251 }
252}