snarkvm_circuit_program/response/
mod.rs1mod from_outputs;
17mod process_outputs_from_callback;
18
19use crate::{Identifier, ProgramID, Value, compute_function_id};
20use snarkvm_circuit_network::Aleo;
21use snarkvm_circuit_types::{Address, Field, U16, environment::prelude::*};
22
23pub enum OutputID<A: Aleo> {
24 Constant(Field<A>),
26 Public(Field<A>),
28 Private(Field<A>),
30 Record(Field<A>, Field<A>, Field<A>),
32 ExternalRecord(Field<A>),
34 Future(Field<A>),
36 DynamicRecord(Field<A>),
38 DynamicFuture(Field<A>),
40}
41
42impl<A: Aleo> Inject for OutputID<A> {
43 type Primitive = console::OutputID<A::Network>;
44
45 fn new(_: Mode, output: Self::Primitive) -> Self {
47 match output {
48 console::OutputID::Constant(field) => Self::Constant(Field::new(Mode::Public, field)),
50 console::OutputID::Public(field) => Self::Public(Field::new(Mode::Public, field)),
52 console::OutputID::Private(field) => Self::Private(Field::new(Mode::Public, field)),
54 console::OutputID::Record(commitment, checksum, sender_ciphertext) => Self::Record(
56 Field::new(Mode::Public, commitment),
57 Field::new(Mode::Public, checksum),
58 Field::new(Mode::Public, sender_ciphertext),
59 ),
60 console::OutputID::ExternalRecord(hash) => Self::ExternalRecord(Field::new(Mode::Public, hash)),
62 console::OutputID::Future(hash) => Self::Future(Field::new(Mode::Public, hash)),
64 console::OutputID::DynamicRecord(hash) => Self::DynamicRecord(Field::new(Mode::Public, hash)),
66 console::OutputID::DynamicFuture(hash) => Self::DynamicFuture(Field::new(Mode::Public, hash)),
68 }
69 }
70}
71
72impl<A: Aleo> OutputID<A> {
73 fn constant(expected_hash: Field<A>) -> Self {
75 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
77 A::assert_eq(&output_hash, expected_hash).expect("Constant output hash mismatch");
79 Self::Constant(output_hash)
81 }
82
83 fn public(expected_hash: Field<A>) -> Self {
85 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
87 A::assert_eq(&output_hash, expected_hash).expect("Public output hash mismatch");
89 Self::Public(output_hash)
91 }
92
93 fn private(expected_hash: Field<A>) -> Self {
95 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
97 A::assert_eq(&output_hash, expected_hash).expect("Private output hash mismatch");
99 Self::Private(output_hash)
101 }
102
103 fn record(
105 expected_commitment: Field<A>,
106 expected_checksum: Field<A>,
107 expected_sender_ciphertext: Field<A>,
108 ) -> Self {
109 let output_commitment = Field::new(Mode::Public, expected_commitment.eject_value());
111 let output_checksum = Field::new(Mode::Public, expected_checksum.eject_value());
112 let output_sender_ciphertext = Field::new(Mode::Public, expected_sender_ciphertext.eject_value()); A::assert_eq(&output_commitment, expected_commitment).expect("Record output commitment mismatch");
115 A::assert_eq(&output_checksum, expected_checksum).expect("Record output checksum mismatch");
116 let is_sender_ciphertext_equal = output_sender_ciphertext.is_equal(&expected_sender_ciphertext);
120 let is_sender_ciphertext_zero = output_sender_ciphertext.is_zero();
121 A::assert(is_sender_ciphertext_equal | is_sender_ciphertext_zero).expect("Record sender ciphertext mismatch");
122 Self::Record(output_commitment, output_checksum, output_sender_ciphertext)
124 }
125
126 fn external_record(expected_hash: Field<A>) -> Self {
128 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
130 A::assert_eq(&output_hash, expected_hash).expect("ExternalRecord output hash mismatch");
132 Self::ExternalRecord(output_hash)
134 }
135
136 fn future(expected_hash: Field<A>) -> Self {
138 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
140 A::assert_eq(&output_hash, expected_hash).expect("Future output hash mismatch");
142 Self::Future(output_hash)
144 }
145
146 fn dynamic_record(expected_hash: Field<A>) -> Self {
148 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
150 A::assert_eq(&output_hash, expected_hash).expect("DynamicRecord output hash mismatch");
152 Self::DynamicRecord(output_hash)
154 }
155
156 fn dynamic_future(expected_hash: Field<A>) -> Self {
158 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
160 A::assert_eq(&output_hash, expected_hash).expect("DynamicFuture output hash mismatch");
162 Self::DynamicFuture(output_hash)
164 }
165}
166
167impl<A: Aleo> Eject for OutputID<A> {
168 type Primitive = console::OutputID<A::Network>;
169
170 fn eject_mode(&self) -> Mode {
172 match self {
173 Self::Constant(field) => field.eject_mode(),
174 Self::Public(field) => field.eject_mode(),
175 Self::Private(field) => field.eject_mode(),
176 Self::Record(commitment, checksum, sender_ciphertext) => {
177 Mode::combine(commitment.eject_mode(), [checksum.eject_mode(), sender_ciphertext.eject_mode()])
178 }
179 Self::ExternalRecord(hash) => hash.eject_mode(),
180 Self::Future(hash) => hash.eject_mode(),
181 Self::DynamicRecord(hash) => hash.eject_mode(),
182 Self::DynamicFuture(hash) => hash.eject_mode(),
183 }
184 }
185
186 fn eject_value(&self) -> Self::Primitive {
188 match self {
189 Self::Constant(field) => console::OutputID::Constant(field.eject_value()),
190 Self::Public(field) => console::OutputID::Public(field.eject_value()),
191 Self::Private(field) => console::OutputID::Private(field.eject_value()),
192 Self::Record(commitment, checksum, sender_ciphertext) => console::OutputID::Record(
193 commitment.eject_value(),
194 checksum.eject_value(),
195 sender_ciphertext.eject_value(),
196 ),
197 Self::ExternalRecord(hash) => console::OutputID::ExternalRecord(hash.eject_value()),
198 Self::Future(hash) => console::OutputID::Future(hash.eject_value()),
199 Self::DynamicRecord(hash) => console::OutputID::DynamicRecord(hash.eject_value()),
200 Self::DynamicFuture(hash) => console::OutputID::DynamicFuture(hash.eject_value()),
201 }
202 }
203}
204
205pub struct Response<A: Aleo> {
206 output_ids: Vec<OutputID<A>>,
208 outputs: Vec<Value<A>>,
210}
211
212impl<A: Aleo> Response<A> {
213 pub fn output_ids(&self) -> &[OutputID<A>] {
215 &self.output_ids
216 }
217
218 pub fn outputs(&self) -> &[Value<A>] {
220 &self.outputs
221 }
222}
223
224impl<A: Aleo> Eject for Response<A> {
225 type Primitive = console::Response<A::Network>;
226
227 fn eject_mode(&self) -> Mode {
229 Mode::combine(self.output_ids.eject_mode(), [self.outputs.eject_mode()])
230 }
231
232 fn eject_value(&self) -> Self::Primitive {
234 Self::Primitive::from((
235 self.output_ids.iter().map(|output_id| output_id.eject_value()).collect(),
236 self.outputs.eject_value(),
237 ))
238 }
239}