snarkvm_circuit_program/response/
mod.rs1#[cfg(test)]
17use snarkvm_circuit_types::environment::assert_scope;
18
19mod from_outputs;
20mod process_outputs_from_callback;
21
22use crate::{Identifier, ProgramID, Value, compute_function_id};
23use snarkvm_circuit_network::Aleo;
24use snarkvm_circuit_types::{Address, Field, U16, environment::prelude::*};
25
26pub enum OutputID<A: Aleo> {
27 Constant(Field<A>),
29 Public(Field<A>),
31 Private(Field<A>),
33 Record(Field<A>, Field<A>, Field<A>),
35 ExternalRecord(Field<A>),
37 Future(Field<A>),
39}
40
41#[cfg(feature = "console")]
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 }
65 }
66}
67
68impl<A: Aleo> OutputID<A> {
69 fn constant(expected_hash: Field<A>) -> Self {
71 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
73 A::assert_eq(&output_hash, expected_hash);
75 Self::Constant(output_hash)
77 }
78
79 fn public(expected_hash: Field<A>) -> Self {
81 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
83 A::assert_eq(&output_hash, expected_hash);
85 Self::Public(output_hash)
87 }
88
89 fn private(expected_hash: Field<A>) -> Self {
91 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
93 A::assert_eq(&output_hash, expected_hash);
95 Self::Private(output_hash)
97 }
98
99 fn record(
101 expected_commitment: Field<A>,
102 expected_checksum: Field<A>,
103 expected_sender_ciphertext: Field<A>,
104 ) -> Self {
105 let output_commitment = Field::new(Mode::Public, expected_commitment.eject_value());
107 let output_checksum = Field::new(Mode::Public, expected_checksum.eject_value());
108 let output_sender_ciphertext = Field::new(Mode::Public, expected_sender_ciphertext.eject_value()); A::assert_eq(&output_commitment, expected_commitment);
111 A::assert_eq(&output_checksum, expected_checksum);
112 let is_sender_ciphertext_equal = output_sender_ciphertext.is_equal(&expected_sender_ciphertext);
116 let is_sender_ciphertext_zero = output_sender_ciphertext.is_zero();
117 A::assert(is_sender_ciphertext_equal | is_sender_ciphertext_zero);
118 Self::Record(output_commitment, output_checksum, output_sender_ciphertext)
120 }
121
122 fn external_record(expected_hash: Field<A>) -> Self {
124 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
126 A::assert_eq(&output_hash, expected_hash);
128 Self::ExternalRecord(output_hash)
130 }
131
132 fn future(expected_hash: Field<A>) -> Self {
134 let output_hash = Field::new(Mode::Public, expected_hash.eject_value());
136 A::assert_eq(&output_hash, expected_hash);
138 Self::Future(output_hash)
140 }
141}
142
143#[cfg(feature = "console")]
144impl<A: Aleo> Eject for OutputID<A> {
145 type Primitive = console::OutputID<A::Network>;
146
147 fn eject_mode(&self) -> Mode {
149 match self {
150 Self::Constant(field) => field.eject_mode(),
151 Self::Public(field) => field.eject_mode(),
152 Self::Private(field) => field.eject_mode(),
153 Self::Record(commitment, checksum, sender_ciphertext) => {
154 Mode::combine(commitment.eject_mode(), [checksum.eject_mode(), sender_ciphertext.eject_mode()])
155 }
156 Self::ExternalRecord(hash) => hash.eject_mode(),
157 Self::Future(hash) => hash.eject_mode(),
158 }
159 }
160
161 fn eject_value(&self) -> Self::Primitive {
163 match self {
164 Self::Constant(field) => console::OutputID::Constant(field.eject_value()),
165 Self::Public(field) => console::OutputID::Public(field.eject_value()),
166 Self::Private(field) => console::OutputID::Private(field.eject_value()),
167 Self::Record(commitment, checksum, sender_ciphertext) => console::OutputID::Record(
168 commitment.eject_value(),
169 checksum.eject_value(),
170 sender_ciphertext.eject_value(),
171 ),
172 Self::ExternalRecord(hash) => console::OutputID::ExternalRecord(hash.eject_value()),
173 Self::Future(hash) => console::OutputID::Future(hash.eject_value()),
174 }
175 }
176}
177
178pub struct Response<A: Aleo> {
179 output_ids: Vec<OutputID<A>>,
181 outputs: Vec<Value<A>>,
183}
184
185impl<A: Aleo> Response<A> {
186 pub fn output_ids(&self) -> &[OutputID<A>] {
188 &self.output_ids
189 }
190
191 pub fn outputs(&self) -> &[Value<A>] {
193 &self.outputs
194 }
195}
196
197#[cfg(feature = "console")]
198impl<A: Aleo> Eject for Response<A> {
199 type Primitive = console::Response<A::Network>;
200
201 fn eject_mode(&self) -> Mode {
203 Mode::combine(self.output_ids.eject_mode(), [self.outputs.eject_mode()])
204 }
205
206 fn eject_value(&self) -> Self::Primitive {
208 Self::Primitive::from((
209 self.output_ids.iter().map(|output_id| output_id.eject_value()).collect(),
210 self.outputs.eject_value(),
211 ))
212 }
213}