snarkvm_circuit_program/request/
mod.rs1#[cfg(test)]
17use snarkvm_circuit_types::environment::assert_scope;
18
19mod to_tpk;
20mod verify;
21
22use crate::{Identifier, Plaintext, ProgramID, Record, Value, compute_function_id};
23use snarkvm_circuit_account::Signature;
24use snarkvm_circuit_network::Aleo;
25use snarkvm_circuit_types::{Address, Boolean, Field, Group, U16, environment::prelude::*};
26
27pub enum InputID<A: Aleo> {
28 Constant(Field<A>),
30 Public(Field<A>),
32 Private(Field<A>),
34 Record(Field<A>, Box<Group<A>>, Field<A>, Field<A>),
36 ExternalRecord(Field<A>),
38}
39
40#[cfg(feature = "console")]
41impl<A: Aleo> Inject for InputID<A> {
42 type Primitive = console::InputID<A::Network>;
43
44 fn new(_: Mode, input: Self::Primitive) -> Self {
46 match input {
47 console::InputID::Constant(field) => Self::Constant(Field::new(Mode::Public, field)),
49 console::InputID::Public(field) => Self::Public(Field::new(Mode::Public, field)),
51 console::InputID::Private(field) => Self::Private(Field::new(Mode::Public, field)),
53 console::InputID::Record(commitment, gamma, serial_number, tag) => Self::Record(
55 Field::new(Mode::Private, commitment),
56 Box::new(Group::new(Mode::Private, gamma)),
57 Field::new(Mode::Public, serial_number),
58 Field::new(Mode::Public, tag),
59 ),
60 console::InputID::ExternalRecord(field) => Self::ExternalRecord(Field::new(Mode::Public, field)),
62 }
63 }
64}
65
66#[cfg(feature = "console")]
67impl<A: Aleo> Eject for InputID<A> {
68 type Primitive = console::InputID<A::Network>;
69
70 fn eject_mode(&self) -> Mode {
72 match self {
73 Self::Constant(field) => field.eject_mode(),
74 Self::Public(field) => field.eject_mode(),
75 Self::Private(field) => field.eject_mode(),
76 Self::Record(commitment, gamma, serial_number, tag) => Mode::combine(commitment.eject_mode(), [
77 gamma.eject_mode(),
78 serial_number.eject_mode(),
79 tag.eject_mode(),
80 ]),
81 Self::ExternalRecord(field) => field.eject_mode(),
82 }
83 }
84
85 fn eject_value(&self) -> Self::Primitive {
87 match self {
88 Self::Constant(field) => console::InputID::Constant(field.eject_value()),
89 Self::Public(field) => console::InputID::Public(field.eject_value()),
90 Self::Private(field) => console::InputID::Private(field.eject_value()),
91 Self::Record(commitment, gamma, serial_number, tag) => console::InputID::Record(
92 commitment.eject_value(),
93 gamma.eject_value(),
94 serial_number.eject_value(),
95 tag.eject_value(),
96 ),
97 Self::ExternalRecord(field) => console::InputID::ExternalRecord(field.eject_value()),
98 }
99 }
100}
101
102impl<A: Aleo> ToFields for InputID<A> {
103 type Field = Field<A>;
104
105 fn to_fields(&self) -> Vec<Self::Field> {
107 match self {
108 InputID::Constant(field) => vec![field.clone()],
109 InputID::Public(field) => vec![field.clone()],
110 InputID::Private(field) => vec![field.clone()],
111 InputID::Record(commitment, gamma, serial_number, tag) => {
112 vec![commitment.clone(), gamma.to_x_coordinate(), serial_number.clone(), tag.clone()]
113 }
114 InputID::ExternalRecord(field) => vec![field.clone()],
115 }
116 }
117}
118
119pub struct Request<A: Aleo> {
120 signer: Address<A>,
122 network_id: U16<A>,
124 program_id: ProgramID<A>,
126 function_name: Identifier<A>,
128 input_ids: Vec<InputID<A>>,
130 inputs: Vec<Value<A>>,
132 signature: Signature<A>,
134 sk_tag: Field<A>,
136 tvk: Field<A>,
138 tcm: Field<A>,
140 scm: Field<A>,
142}
143
144#[cfg(feature = "console")]
145impl<A: Aleo> Inject for Request<A> {
146 type Primitive = console::Request<A::Network>;
147
148 fn new(mode: Mode, request: Self::Primitive) -> Self {
150 let tcm = Field::new(Mode::Public, *request.tcm());
152
153 let scm = Field::new(Mode::Public, *request.scm());
155
156 let inputs = match request
158 .input_ids()
159 .iter()
160 .zip_eq(request.inputs())
161 .map(|(input_id, input)| {
162 match input_id {
163 console::InputID::Constant(..) => {
165 let input = Value::new(Mode::Constant, input.clone());
167 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
169 Ok(input)
171 }
172 console::InputID::Public(..) => {
174 let input = Value::new(Mode::Private, input.clone());
176 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
178 Ok(input)
180 }
181 console::InputID::Private(..) => {
183 let input = Value::new(Mode::Private, input.clone());
185 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
187 Ok(input)
189 }
190 console::InputID::Record(..) => {
192 let input = Value::new(Mode::Private, input.clone());
194 ensure!(matches!(input, Value::Record(..)), "Expected a record input");
196 Ok(input)
198 }
199 console::InputID::ExternalRecord(..) => {
201 let input = Value::new(Mode::Private, input.clone());
203 ensure!(matches!(input, Value::Record(..)), "Expected an external record input");
205 Ok(input)
207 }
208 }
209 })
210 .collect::<Result<Vec<_>, _>>()
211 {
212 Ok(inputs) => inputs,
213 Err(error) => A::halt(format!("{error}")),
214 };
215
216 Self {
217 signer: Address::new(mode, *request.signer()),
218 network_id: U16::new(Mode::Constant, *request.network_id()),
219 program_id: ProgramID::new(Mode::Constant, *request.program_id()),
220 function_name: Identifier::new(Mode::Constant, *request.function_name()),
221 input_ids: request.input_ids().iter().map(|input_id| InputID::new(Mode::Public, *input_id)).collect(),
222 inputs,
223 signature: Signature::new(mode, *request.signature()),
224 sk_tag: Field::new(mode, *request.sk_tag()),
225 tvk: Field::new(mode, *request.tvk()),
226 tcm,
227 scm,
228 }
229 }
230}
231
232impl<A: Aleo> Request<A> {
233 pub const fn signer(&self) -> &Address<A> {
235 &self.signer
236 }
237
238 pub const fn network_id(&self) -> &U16<A> {
240 &self.network_id
241 }
242
243 pub const fn program_id(&self) -> &ProgramID<A> {
245 &self.program_id
246 }
247
248 pub const fn function_name(&self) -> &Identifier<A> {
250 &self.function_name
251 }
252
253 pub fn input_ids(&self) -> &[InputID<A>] {
255 &self.input_ids
256 }
257
258 pub fn inputs(&self) -> &[Value<A>] {
260 &self.inputs
261 }
262
263 pub const fn signature(&self) -> &Signature<A> {
265 &self.signature
266 }
267
268 pub const fn sk_tag(&self) -> &Field<A> {
270 &self.sk_tag
271 }
272
273 pub const fn tvk(&self) -> &Field<A> {
275 &self.tvk
276 }
277
278 pub const fn tcm(&self) -> &Field<A> {
280 &self.tcm
281 }
282
283 pub const fn scm(&self) -> &Field<A> {
285 &self.scm
286 }
287}
288
289#[cfg(feature = "console")]
290impl<A: Aleo> Eject for Request<A> {
291 type Primitive = console::Request<A::Network>;
292
293 fn eject_mode(&self) -> Mode {
295 Mode::combine(self.signer.eject_mode(), [
296 self.network_id.eject_mode(),
297 self.program_id.eject_mode(),
298 self.function_name.eject_mode(),
299 self.input_ids.eject_mode(),
300 self.inputs.eject_mode(),
301 self.signature.eject_mode(),
302 self.sk_tag.eject_mode(),
303 self.tvk.eject_mode(),
304 self.tcm.eject_mode(),
305 self.scm.eject_mode(),
306 ])
307 }
308
309 fn eject_value(&self) -> Self::Primitive {
311 Self::Primitive::from((
312 self.signer.eject_value(),
313 self.network_id.eject_value(),
314 self.program_id.eject_value(),
315 self.function_name.eject_value(),
316 self.input_ids.iter().map(|input_id| input_id.eject_value()).collect(),
317 self.inputs.eject_value(),
318 self.signature.eject_value(),
319 self.sk_tag.eject_value(),
320 self.tvk.eject_value(),
321 self.tcm.eject_value(),
322 self.scm.eject_value(),
323 ))
324 }
325}