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>, Field<A>),
36 ExternalRecord(Field<A>),
38}
39
40impl<A: Aleo> Inject for InputID<A> {
41 type Primitive = console::InputID<A::Network>;
42
43 fn new(_: Mode, input: Self::Primitive) -> Self {
45 match input {
46 console::InputID::Constant(field) => Self::Constant(Field::new(Mode::Public, field)),
48 console::InputID::Public(field) => Self::Public(Field::new(Mode::Public, field)),
50 console::InputID::Private(field) => Self::Private(Field::new(Mode::Public, field)),
52 console::InputID::Record(commitment, gamma, record_view_key, serial_number, tag) => Self::Record(
54 Field::new(Mode::Private, commitment),
55 Box::new(Group::new(Mode::Private, gamma)),
56 Field::new(Mode::Private, record_view_key),
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
66impl<A: Aleo> Eject for InputID<A> {
67 type Primitive = console::InputID<A::Network>;
68
69 fn eject_mode(&self) -> Mode {
71 match self {
72 Self::Constant(field) => field.eject_mode(),
73 Self::Public(field) => field.eject_mode(),
74 Self::Private(field) => field.eject_mode(),
75 Self::Record(commitment, gamma, record_view_key, serial_number, tag) => {
76 Mode::combine(commitment.eject_mode(), [
77 gamma.eject_mode(),
78 record_view_key.eject_mode(),
79 serial_number.eject_mode(),
80 tag.eject_mode(),
81 ])
82 }
83 Self::ExternalRecord(field) => field.eject_mode(),
84 }
85 }
86
87 fn eject_value(&self) -> Self::Primitive {
89 match self {
90 Self::Constant(field) => console::InputID::Constant(field.eject_value()),
91 Self::Public(field) => console::InputID::Public(field.eject_value()),
92 Self::Private(field) => console::InputID::Private(field.eject_value()),
93 Self::Record(commitment, gamma, record_view_key, serial_number, tag) => console::InputID::Record(
94 commitment.eject_value(),
95 gamma.eject_value(),
96 record_view_key.eject_value(),
97 serial_number.eject_value(),
98 tag.eject_value(),
99 ),
100 Self::ExternalRecord(field) => console::InputID::ExternalRecord(field.eject_value()),
101 }
102 }
103}
104
105impl<A: Aleo> ToFields for InputID<A> {
106 type Field = Field<A>;
107
108 fn to_fields(&self) -> Vec<Self::Field> {
110 match self {
111 InputID::Constant(field) => vec![field.clone()],
112 InputID::Public(field) => vec![field.clone()],
113 InputID::Private(field) => vec![field.clone()],
114 InputID::Record(commitment, gamma, record_view_key, serial_number, tag) => {
115 vec![
116 commitment.clone(),
117 gamma.to_x_coordinate(),
118 record_view_key.clone(),
119 serial_number.clone(),
120 tag.clone(),
121 ]
122 }
123 InputID::ExternalRecord(field) => vec![field.clone()],
124 }
125 }
126}
127
128pub struct Request<A: Aleo> {
129 signer: Address<A>,
131 network_id: U16<A>,
133 program_id: ProgramID<A>,
135 function_name: Identifier<A>,
137 input_ids: Vec<InputID<A>>,
139 inputs: Vec<Value<A>>,
141 signature: Signature<A>,
143 sk_tag: Field<A>,
145 tvk: Field<A>,
147 tcm: Field<A>,
149 scm: Field<A>,
151}
152
153impl<A: Aleo> Inject for Request<A> {
154 type Primitive = console::Request<A::Network>;
155
156 fn new(mode: Mode, request: Self::Primitive) -> Self {
158 let tcm = Field::new(Mode::Public, *request.tcm());
160
161 let scm = Field::new(Mode::Public, *request.scm());
163
164 let inputs = match request
166 .input_ids()
167 .iter()
168 .zip_eq(request.inputs())
169 .map(|(input_id, input)| {
170 match input_id {
171 console::InputID::Constant(..) => {
173 let input = Value::new(Mode::Constant, input.clone());
175 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
177 Ok(input)
179 }
180 console::InputID::Public(..) => {
182 let input = Value::new(Mode::Private, input.clone());
184 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
186 Ok(input)
188 }
189 console::InputID::Private(..) => {
191 let input = Value::new(Mode::Private, input.clone());
193 ensure!(matches!(input, Value::Plaintext(..)), "Expected a plaintext input");
195 Ok(input)
197 }
198 console::InputID::Record(..) => {
200 let input = Value::new(Mode::Private, input.clone());
202 ensure!(matches!(input, Value::Record(..)), "Expected a record input");
204 Ok(input)
206 }
207 console::InputID::ExternalRecord(..) => {
209 let input = Value::new(Mode::Private, input.clone());
211 ensure!(matches!(input, Value::Record(..)), "Expected an external record input");
213 Ok(input)
215 }
216 }
217 })
218 .collect::<Result<Vec<_>, _>>()
219 {
220 Ok(inputs) => inputs,
221 Err(error) => A::halt(format!("{error}")),
222 };
223
224 Self {
225 signer: Address::new(mode, *request.signer()),
226 network_id: U16::new(Mode::Constant, *request.network_id()),
227 program_id: ProgramID::new(Mode::Constant, *request.program_id()),
228 function_name: Identifier::new(Mode::Constant, *request.function_name()),
229 input_ids: request.input_ids().iter().map(|input_id| InputID::new(Mode::Public, *input_id)).collect(),
230 inputs,
231 signature: Signature::new(mode, *request.signature()),
232 sk_tag: Field::new(mode, *request.sk_tag()),
233 tvk: Field::new(mode, *request.tvk()),
234 tcm,
235 scm,
236 }
237 }
238}
239
240impl<A: Aleo> Request<A> {
241 pub const fn signer(&self) -> &Address<A> {
243 &self.signer
244 }
245
246 pub const fn network_id(&self) -> &U16<A> {
248 &self.network_id
249 }
250
251 pub const fn program_id(&self) -> &ProgramID<A> {
253 &self.program_id
254 }
255
256 pub const fn function_name(&self) -> &Identifier<A> {
258 &self.function_name
259 }
260
261 pub fn input_ids(&self) -> &[InputID<A>] {
263 &self.input_ids
264 }
265
266 pub fn inputs(&self) -> &[Value<A>] {
268 &self.inputs
269 }
270
271 pub const fn signature(&self) -> &Signature<A> {
273 &self.signature
274 }
275
276 pub const fn sk_tag(&self) -> &Field<A> {
278 &self.sk_tag
279 }
280
281 pub const fn tvk(&self) -> &Field<A> {
283 &self.tvk
284 }
285
286 pub const fn tcm(&self) -> &Field<A> {
288 &self.tcm
289 }
290
291 pub const fn scm(&self) -> &Field<A> {
293 &self.scm
294 }
295}
296
297impl<A: Aleo> Eject for Request<A> {
298 type Primitive = console::Request<A::Network>;
299
300 fn eject_mode(&self) -> Mode {
302 Mode::combine(self.signer.eject_mode(), [
303 self.network_id.eject_mode(),
304 self.program_id.eject_mode(),
305 self.function_name.eject_mode(),
306 self.input_ids.eject_mode(),
307 self.inputs.eject_mode(),
308 self.signature.eject_mode(),
309 self.sk_tag.eject_mode(),
310 self.tvk.eject_mode(),
311 self.tcm.eject_mode(),
312 self.scm.eject_mode(),
313 ])
314 }
315
316 fn eject_value(&self) -> Self::Primitive {
318 Self::Primitive::from((
319 self.signer.eject_value(),
320 self.network_id.eject_value(),
321 self.program_id.eject_value(),
322 self.function_name.eject_value(),
323 self.input_ids.iter().map(|input_id| input_id.eject_value()).collect(),
324 self.inputs.eject_value(),
325 self.signature.eject_value(),
326 self.sk_tag.eject_value(),
327 self.tvk.eject_value(),
328 self.tcm.eject_value(),
329 self.scm.eject_value(),
330 ))
331 }
332}