snarkvm_synthesizer_program/traits/
stack_and_registers.rs1use std::sync::Arc;
17
18use crate::{FinalizeGlobalState, Function, Operand, Program};
19use console::{
20 account::Group,
21 network::Network,
22 prelude::{Result, bail},
23 program::{
24 Future,
25 Identifier,
26 Literal,
27 Locator,
28 Plaintext,
29 PlaintextType,
30 ProgramID,
31 Record,
32 RecordType,
33 Register,
34 RegisterType,
35 Value,
36 ValueType,
37 },
38 types::{Address, Field},
39};
40use rand::{CryptoRng, Rng};
41use synthesizer_snark::{ProvingKey, VerifyingKey};
42
43pub trait StackKeys<N: Network> {
44 fn contains_proving_key(&self, function_name: &Identifier<N>) -> bool;
46
47 fn get_proving_key(&self, function_name: &Identifier<N>) -> Result<ProvingKey<N>>;
49
50 fn insert_proving_key(&self, function_name: &Identifier<N>, proving_key: ProvingKey<N>) -> Result<()>;
52
53 fn remove_proving_key(&self, function_name: &Identifier<N>);
55
56 fn contains_verifying_key(&self, function_name: &Identifier<N>) -> bool;
58
59 fn get_verifying_key(&self, function_name: &Identifier<N>) -> Result<VerifyingKey<N>>;
61
62 fn insert_verifying_key(&self, function_name: &Identifier<N>, verifying_key: VerifyingKey<N>) -> Result<()>;
64
65 fn remove_verifying_key(&self, function_name: &Identifier<N>);
67}
68
69pub trait StackMatches<N: Network> {
70 fn matches_value_type(&self, value: &Value<N>, value_type: &ValueType<N>) -> Result<()>;
72
73 fn matches_register_type(&self, stack_value: &Value<N>, register_type: &RegisterType<N>) -> Result<()>;
75
76 fn matches_external_record(&self, record: &Record<N, Plaintext<N>>, locator: &Locator<N>) -> Result<()>;
78
79 fn matches_record(&self, record: &Record<N, Plaintext<N>>, record_name: &Identifier<N>) -> Result<()>;
81
82 fn matches_plaintext(&self, plaintext: &Plaintext<N>, plaintext_type: &PlaintextType<N>) -> Result<()>;
84
85 fn matches_future(&self, future: &Future<N>, locator: &Locator<N>) -> Result<()>;
87}
88
89pub trait StackProgram<N: Network> {
90 fn program(&self) -> &Program<N>;
92
93 fn program_id(&self) -> &ProgramID<N>;
95
96 fn program_depth(&self) -> usize;
98
99 fn program_address(&self) -> &Address<N>;
101
102 fn contains_external_record(&self, locator: &Locator<N>) -> bool;
104
105 fn get_external_stack(&self, program_id: &ProgramID<N>) -> Result<&Arc<Self>>;
107
108 fn get_external_program(&self, program_id: &ProgramID<N>) -> Result<&Program<N>>;
110
111 fn get_external_record(&self, locator: &Locator<N>) -> Result<&RecordType<N>>;
113
114 fn get_finalize_cost(&self, function_name: &Identifier<N>) -> Result<u64>;
116
117 fn get_function(&self, function_name: &Identifier<N>) -> Result<Function<N>>;
119
120 fn get_function_ref(&self, function_name: &Identifier<N>) -> Result<&Function<N>>;
122
123 fn get_number_of_calls(&self, function_name: &Identifier<N>) -> Result<usize>;
125
126 fn sample_value<R: Rng + CryptoRng>(
128 &self,
129 burner_address: &Address<N>,
130 value_type: &ValueType<N>,
131 rng: &mut R,
132 ) -> Result<Value<N>>;
133
134 fn sample_record<R: Rng + CryptoRng>(
136 &self,
137 burner_address: &Address<N>,
138 record_name: &Identifier<N>,
139 record_nonce: Group<N>,
140 rng: &mut R,
141 ) -> Result<Record<N, Plaintext<N>>>;
142
143 fn sample_record_using_tvk<R: Rng + CryptoRng>(
145 &self,
146 burner_address: &Address<N>,
147 record_name: &Identifier<N>,
148 tvk: Field<N>,
149 index: Field<N>,
150 rng: &mut R,
151 ) -> Result<Record<N, Plaintext<N>>>;
152}
153
154pub trait FinalizeRegistersState<N: Network> {
155 fn state(&self) -> &FinalizeGlobalState;
157
158 fn transition_id(&self) -> &N::TransitionID;
160
161 fn function_name(&self) -> &Identifier<N>;
163
164 fn nonce(&self) -> u64;
166}
167
168pub trait RegistersSigner<N: Network> {
169 fn signer(&self) -> Result<Address<N>>;
171
172 fn set_signer(&mut self, signer: Address<N>);
174
175 fn root_tvk(&self) -> Result<Field<N>>;
177
178 fn set_root_tvk(&mut self, root_tvk: Field<N>);
180
181 fn caller(&self) -> Result<Address<N>>;
183
184 fn set_caller(&mut self, caller: Address<N>);
186
187 fn tvk(&self) -> Result<Field<N>>;
189
190 fn set_tvk(&mut self, tvk: Field<N>);
192}
193
194pub trait RegistersSignerCircuit<N: Network, A: circuit::Aleo<Network = N>> {
195 fn signer_circuit(&self) -> Result<circuit::Address<A>>;
197
198 fn set_signer_circuit(&mut self, signer_circuit: circuit::Address<A>);
200
201 fn root_tvk_circuit(&self) -> Result<circuit::Field<A>>;
203
204 fn set_root_tvk_circuit(&mut self, root_tvk_circuit: circuit::Field<A>);
206
207 fn caller_circuit(&self) -> Result<circuit::Address<A>>;
209
210 fn set_caller_circuit(&mut self, caller_circuit: circuit::Address<A>);
212
213 fn tvk_circuit(&self) -> Result<circuit::Field<A>>;
215
216 fn set_tvk_circuit(&mut self, tvk_circuit: circuit::Field<A>);
218}
219
220pub trait RegistersLoad<N: Network> {
221 fn load(&self, stack: &(impl StackMatches<N> + StackProgram<N>), operand: &Operand<N>) -> Result<Value<N>>;
227
228 #[inline]
235 fn load_literal(
236 &self,
237 stack: &(impl StackMatches<N> + StackProgram<N>),
238 operand: &Operand<N>,
239 ) -> Result<Literal<N>> {
240 match self.load(stack, operand)? {
241 Value::Plaintext(Plaintext::Literal(literal, ..)) => Ok(literal),
242 Value::Plaintext(Plaintext::Struct(..))
243 | Value::Plaintext(Plaintext::Array(..))
244 | Value::Record(..)
245 | Value::Future(..) => {
246 bail!("Operand must be a literal")
247 }
248 }
249 }
250
251 #[inline]
258 fn load_plaintext(
259 &self,
260 stack: &(impl StackMatches<N> + StackProgram<N>),
261 operand: &Operand<N>,
262 ) -> Result<Plaintext<N>> {
263 match self.load(stack, operand)? {
264 Value::Plaintext(plaintext) => Ok(plaintext),
265 Value::Record(..) | Value::Future(..) => bail!("Operand must be a plaintext"),
266 }
267 }
268}
269
270pub trait RegistersLoadCircuit<N: Network, A: circuit::Aleo<Network = N>> {
271 fn load_circuit(
277 &self,
278 stack: &(impl StackMatches<N> + StackProgram<N>),
279 operand: &Operand<N>,
280 ) -> Result<circuit::Value<A>>;
281
282 #[inline]
289 fn load_literal_circuit(
290 &self,
291 stack: &(impl StackMatches<N> + StackProgram<N>),
292 operand: &Operand<N>,
293 ) -> Result<circuit::Literal<A>> {
294 match self.load_circuit(stack, operand)? {
295 circuit::Value::Plaintext(circuit::Plaintext::Literal(literal, ..)) => Ok(literal),
296 circuit::Value::Plaintext(circuit::Plaintext::Struct(..))
297 | circuit::Value::Plaintext(circuit::Plaintext::Array(..))
298 | circuit::Value::Record(..)
299 | circuit::Value::Future(..) => bail!("Operand must be a literal"),
300 }
301 }
302
303 #[inline]
310 fn load_plaintext_circuit(
311 &self,
312 stack: &(impl StackMatches<N> + StackProgram<N>),
313 operand: &Operand<N>,
314 ) -> Result<circuit::Plaintext<A>> {
315 match self.load_circuit(stack, operand)? {
316 circuit::Value::Plaintext(plaintext) => Ok(plaintext),
317 circuit::Value::Record(..) | circuit::Value::Future(..) => bail!("Operand must be a plaintext"),
318 }
319 }
320}
321
322pub trait RegistersStore<N: Network> {
323 fn store(
330 &mut self,
331 stack: &(impl StackMatches<N> + StackProgram<N>),
332 register: &Register<N>,
333 stack_value: Value<N>,
334 ) -> Result<()>;
335
336 #[inline]
343 fn store_literal(
344 &mut self,
345 stack: &(impl StackMatches<N> + StackProgram<N>),
346 register: &Register<N>,
347 literal: Literal<N>,
348 ) -> Result<()> {
349 self.store(stack, register, Value::Plaintext(Plaintext::from(literal)))
350 }
351}
352
353pub trait RegistersStoreCircuit<N: Network, A: circuit::Aleo<Network = N>> {
354 fn store_circuit(
361 &mut self,
362 stack: &(impl StackMatches<N> + StackProgram<N>),
363 register: &Register<N>,
364 stack_value: circuit::Value<A>,
365 ) -> Result<()>;
366
367 #[inline]
374 fn store_literal_circuit(
375 &mut self,
376 stack: &(impl StackMatches<N> + StackProgram<N>),
377 register: &Register<N>,
378 literal: circuit::Literal<A>,
379 ) -> Result<()> {
380 self.store_circuit(stack, register, circuit::Value::Plaintext(circuit::Plaintext::from(literal)))
381 }
382}