snarkvm_circuit_program/data/dynamic/future/
mod.rs1mod equal;
17mod to_bits;
18mod to_fields;
19
20use snarkvm_circuit_network::Aleo;
21use snarkvm_circuit_types::{Boolean, Field, environment::prelude::*};
22
23#[derive(Clone)]
35pub struct DynamicFuture<A: Aleo> {
36 program_name: Field<A>,
38 program_network: Field<A>,
40 function_name: Field<A>,
42 checksum: Field<A>,
44 arguments: Option<Vec<console::Argument<A::Network>>>,
47}
48
49impl<A: Aleo> Inject for DynamicFuture<A> {
50 type Primitive = console::DynamicFuture<A::Network>;
51
52 fn new(mode: Mode, value: Self::Primitive) -> Self {
54 DynamicFuture {
55 program_name: Inject::new(mode, *value.program_name()),
56 program_network: Inject::new(mode, *value.program_network()),
57 function_name: Inject::new(mode, *value.function_name()),
58 checksum: Inject::new(mode, *value.checksum()),
59 arguments: value.arguments().clone(),
60 }
61 }
62}
63
64impl<A: Aleo> DynamicFuture<A> {
65 pub const fn program_name(&self) -> &Field<A> {
67 &self.program_name
68 }
69
70 pub const fn program_network(&self) -> &Field<A> {
72 &self.program_network
73 }
74
75 pub const fn function_name(&self) -> &Field<A> {
77 &self.function_name
78 }
79
80 pub const fn checksum(&self) -> &Field<A> {
82 &self.checksum
83 }
84
85 pub const fn arguments(&self) -> &Option<Vec<console::Argument<A::Network>>> {
87 &self.arguments
88 }
89}
90
91impl<A: Aleo> Eject for DynamicFuture<A> {
92 type Primitive = console::DynamicFuture<A::Network>;
93
94 fn eject_mode(&self) -> Mode {
96 let program_name_mode = Eject::eject_mode(self.program_name());
97 let program_network_mode = Eject::eject_mode(self.program_network());
98 let function_name_mode = Eject::eject_mode(self.function_name());
99 let checksum_mode = Eject::eject_mode(self.checksum());
100 Mode::combine(program_name_mode, [program_network_mode, function_name_mode, checksum_mode])
101 }
102
103 fn eject_value(&self) -> Self::Primitive {
105 Self::Primitive::new_unchecked(
106 Eject::eject_value(self.program_name()),
107 Eject::eject_value(self.program_network()),
108 Eject::eject_value(self.function_name()),
109 Eject::eject_value(self.checksum()),
110 self.arguments.clone(),
111 )
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118 use crate::{Circuit, console::ToFields as ConsoleToFields};
119 use snarkvm_circuit_types::environment::Inject;
120
121 use core::str::FromStr;
122
123 type CurrentNetwork = <Circuit as Environment>::Network;
124 type ConsoleFuture = console::Future<CurrentNetwork>;
125 type ConsoleDynamicFuture = console::DynamicFuture<CurrentNetwork>;
126
127 fn create_test_future(args: Vec<console::Argument<CurrentNetwork>>) -> ConsoleFuture {
128 ConsoleFuture::new(
129 console::ProgramID::from_str("test.aleo").unwrap(),
130 console::Identifier::from_str("foo").unwrap(),
131 args,
132 )
133 }
134
135 fn check_inject_eject(console_dynamic: &ConsoleDynamicFuture) {
138 let circuit_dynamic = DynamicFuture::<Circuit>::new(Mode::Private, console_dynamic.clone());
139
140 assert_eq!(circuit_dynamic.program_name().eject_value(), *console_dynamic.program_name());
141 assert_eq!(circuit_dynamic.program_network().eject_value(), *console_dynamic.program_network());
142 assert_eq!(circuit_dynamic.function_name().eject_value(), *console_dynamic.function_name());
143 assert_eq!(circuit_dynamic.checksum().eject_value(), *console_dynamic.checksum());
144
145 let ejected = circuit_dynamic.eject_value();
146 assert_eq!(ejected.program_name(), console_dynamic.program_name());
147 assert_eq!(ejected.program_network(), console_dynamic.program_network());
148 assert_eq!(ejected.function_name(), console_dynamic.function_name());
149 assert_eq!(ejected.checksum(), console_dynamic.checksum());
150
151 Circuit::reset();
152 }
153
154 fn check_to_bits_le(console_dynamic: &ConsoleDynamicFuture) {
156 let circuit_dynamic = DynamicFuture::<Circuit>::new(Mode::Private, console_dynamic.clone());
157
158 Circuit::scope("to_bits_le", || {
159 let circuit_bits = circuit_dynamic.to_bits_le();
160 let console_bits = console_dynamic.to_bits_le();
161 for (circuit_bit, console_bit) in circuit_bits.iter().zip_eq(console_bits.iter()) {
162 assert_eq!(circuit_bit.eject_value(), *console_bit, "Circuit and console bits must match");
163 }
164 });
165
166 Circuit::reset();
167 }
168
169 fn check_to_fields(console_dynamic: &ConsoleDynamicFuture) {
171 let circuit_dynamic = DynamicFuture::<Circuit>::new(Mode::Private, console_dynamic.clone());
172
173 Circuit::scope("to_fields", || {
174 let circuit_fields = circuit_dynamic.to_fields();
175 let console_fields = console_dynamic.to_fields().unwrap();
176 for (circuit_field, console_field) in circuit_fields.iter().zip_eq(console_fields.iter()) {
177 assert_eq!(circuit_field.eject_value(), *console_field, "Circuit and console fields must match");
178 }
179 });
180
181 Circuit::reset();
182 }
183
184 #[test]
185 fn test_inject_eject_no_arguments() {
186 let future = create_test_future(vec![]);
187 let dynamic = ConsoleDynamicFuture::from_future(&future).unwrap();
188 check_inject_eject(&dynamic);
189 }
190
191 #[test]
192 fn test_inject_eject_with_arguments() {
193 let args = vec![
194 console::Argument::Plaintext(console::Plaintext::from_str("100u64").unwrap()),
195 console::Argument::Plaintext(console::Plaintext::from_str("true").unwrap()),
196 ];
197 let future = create_test_future(args);
198 let dynamic = ConsoleDynamicFuture::from_future(&future).unwrap();
199 check_inject_eject(&dynamic);
200 }
201
202 #[test]
203 fn test_to_bits_le_console_circuit_equivalence() {
204 let args = vec![console::Argument::Plaintext(console::Plaintext::from_str("42u64").unwrap())];
205 let future = create_test_future(args);
206 let dynamic = ConsoleDynamicFuture::from_future(&future).unwrap();
207 check_to_bits_le(&dynamic);
208 }
209
210 #[test]
211 fn test_to_fields_console_circuit_equivalence() {
212 let args = vec![console::Argument::Plaintext(console::Plaintext::from_str("42u64").unwrap())];
213 let future = create_test_future(args);
214 let dynamic = ConsoleDynamicFuture::from_future(&future).unwrap();
215 check_to_fields(&dynamic);
216 }
217
218 #[test]
219 fn test_to_fields_no_arguments() {
220 let future = create_test_future(vec![]);
221 let dynamic = ConsoleDynamicFuture::from_future(&future).unwrap();
222 check_to_fields(&dynamic);
223 }
224}