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 Register,
33 RegisterType,
34 Value,
35 ValueType,
36 },
37 types::{Address, Field},
38};
39use rand::{CryptoRng, Rng};
40use synthesizer_snark::{ProvingKey, VerifyingKey};
41
42pub trait StackKeys<N: Network> {
43 fn contains_proving_key(&self, function_name: &Identifier<N>) -> bool;
45
46 fn get_proving_key(&self, function_name: &Identifier<N>) -> Result<ProvingKey<N>>;
48
49 fn insert_proving_key(&self, function_name: &Identifier<N>, proving_key: ProvingKey<N>) -> Result<()>;
51
52 fn remove_proving_key(&self, function_name: &Identifier<N>);
54
55 fn contains_verifying_key(&self, function_name: &Identifier<N>) -> bool;
57
58 fn get_verifying_key(&self, function_name: &Identifier<N>) -> Result<VerifyingKey<N>>;
60
61 fn insert_verifying_key(&self, function_name: &Identifier<N>, verifying_key: VerifyingKey<N>) -> Result<()>;
63
64 fn remove_verifying_key(&self, function_name: &Identifier<N>);
66}
67
68pub trait StackMatches<N: Network> {
69 fn matches_value_type(&self, value: &Value<N>, value_type: &ValueType<N>) -> Result<()>;
71
72 fn matches_register_type(&self, stack_value: &Value<N>, register_type: &RegisterType<N>) -> Result<()>;
74
75 fn matches_external_record(&self, record: &Record<N, Plaintext<N>>, locator: &Locator<N>) -> Result<()>;
77
78 fn matches_record(&self, record: &Record<N, Plaintext<N>>, record_name: &Identifier<N>) -> Result<()>;
80
81 fn matches_plaintext(&self, plaintext: &Plaintext<N>, plaintext_type: &PlaintextType<N>) -> Result<()>;
83
84 fn matches_future(&self, future: &Future<N>, locator: &Locator<N>) -> Result<()>;
86}
87
88pub trait StackProgram<N: Network> {
89 fn program(&self) -> &Program<N>;
91
92 fn program_id(&self) -> &ProgramID<N>;
94
95 fn program_depth(&self) -> usize;
97
98 fn program_address(&self) -> &Address<N>;
100
101 fn get_external_stack(&self, program_id: &ProgramID<N>) -> Result<Arc<Self>>;
103
104 fn get_finalize_cost(&self, function_name: &Identifier<N>) -> Result<u64>;
106
107 fn get_function(&self, function_name: &Identifier<N>) -> Result<Function<N>>;
109
110 fn get_function_ref(&self, function_name: &Identifier<N>) -> Result<&Function<N>>;
112
113 fn get_number_of_calls(&self, function_name: &Identifier<N>) -> Result<usize>;
115
116 fn sample_value<R: Rng + CryptoRng>(
118 &self,
119 burner_address: &Address<N>,
120 value_type: &ValueType<N>,
121 rng: &mut R,
122 ) -> Result<Value<N>>;
123
124 fn sample_record<R: Rng + CryptoRng>(
126 &self,
127 burner_address: &Address<N>,
128 record_name: &Identifier<N>,
129 record_nonce: Group<N>,
130 rng: &mut R,
131 ) -> Result<Record<N, Plaintext<N>>>;
132
133 fn sample_record_using_tvk<R: Rng + CryptoRng>(
135 &self,
136 burner_address: &Address<N>,
137 record_name: &Identifier<N>,
138 tvk: Field<N>,
139 index: Field<N>,
140 rng: &mut R,
141 ) -> Result<Record<N, Plaintext<N>>>;
142}
143
144pub trait FinalizeRegistersState<N: Network> {
145 fn state(&self) -> &FinalizeGlobalState;
147
148 fn transition_id(&self) -> &N::TransitionID;
150
151 fn function_name(&self) -> &Identifier<N>;
153
154 fn nonce(&self) -> u64;
156}
157
158pub trait RegistersSigner<N: Network> {
159 fn signer(&self) -> Result<Address<N>>;
161
162 fn set_signer(&mut self, signer: Address<N>);
164
165 fn root_tvk(&self) -> Result<Field<N>>;
167
168 fn set_root_tvk(&mut self, root_tvk: Field<N>);
170
171 fn caller(&self) -> Result<Address<N>>;
173
174 fn set_caller(&mut self, caller: Address<N>);
176
177 fn tvk(&self) -> Result<Field<N>>;
179
180 fn set_tvk(&mut self, tvk: Field<N>);
182}
183
184pub trait RegistersSignerCircuit<N: Network, A: circuit::Aleo<Network = N>> {
185 fn signer_circuit(&self) -> Result<circuit::Address<A>>;
187
188 fn set_signer_circuit(&mut self, signer_circuit: circuit::Address<A>);
190
191 fn root_tvk_circuit(&self) -> Result<circuit::Field<A>>;
193
194 fn set_root_tvk_circuit(&mut self, root_tvk_circuit: circuit::Field<A>);
196
197 fn caller_circuit(&self) -> Result<circuit::Address<A>>;
199
200 fn set_caller_circuit(&mut self, caller_circuit: circuit::Address<A>);
202
203 fn tvk_circuit(&self) -> Result<circuit::Field<A>>;
205
206 fn set_tvk_circuit(&mut self, tvk_circuit: circuit::Field<A>);
208}
209
210pub trait RegistersLoad<N: Network> {
211 fn load(&self, stack: &(impl StackMatches<N> + StackProgram<N>), operand: &Operand<N>) -> Result<Value<N>>;
217
218 #[inline]
225 fn load_literal(
226 &self,
227 stack: &(impl StackMatches<N> + StackProgram<N>),
228 operand: &Operand<N>,
229 ) -> Result<Literal<N>> {
230 match self.load(stack, operand)? {
231 Value::Plaintext(Plaintext::Literal(literal, ..)) => Ok(literal),
232 Value::Plaintext(Plaintext::Struct(..))
233 | Value::Plaintext(Plaintext::Array(..))
234 | Value::Record(..)
235 | Value::Future(..) => {
236 bail!("Operand must be a literal")
237 }
238 }
239 }
240
241 #[inline]
248 fn load_plaintext(
249 &self,
250 stack: &(impl StackMatches<N> + StackProgram<N>),
251 operand: &Operand<N>,
252 ) -> Result<Plaintext<N>> {
253 match self.load(stack, operand)? {
254 Value::Plaintext(plaintext) => Ok(plaintext),
255 Value::Record(..) | Value::Future(..) => bail!("Operand must be a plaintext"),
256 }
257 }
258}
259
260pub trait RegistersLoadCircuit<N: Network, A: circuit::Aleo<Network = N>> {
261 fn load_circuit(
267 &self,
268 stack: &(impl StackMatches<N> + StackProgram<N>),
269 operand: &Operand<N>,
270 ) -> Result<circuit::Value<A>>;
271
272 #[inline]
279 fn load_literal_circuit(
280 &self,
281 stack: &(impl StackMatches<N> + StackProgram<N>),
282 operand: &Operand<N>,
283 ) -> Result<circuit::Literal<A>> {
284 match self.load_circuit(stack, operand)? {
285 circuit::Value::Plaintext(circuit::Plaintext::Literal(literal, ..)) => Ok(literal),
286 circuit::Value::Plaintext(circuit::Plaintext::Struct(..))
287 | circuit::Value::Plaintext(circuit::Plaintext::Array(..))
288 | circuit::Value::Record(..)
289 | circuit::Value::Future(..) => bail!("Operand must be a literal"),
290 }
291 }
292
293 #[inline]
300 fn load_plaintext_circuit(
301 &self,
302 stack: &(impl StackMatches<N> + StackProgram<N>),
303 operand: &Operand<N>,
304 ) -> Result<circuit::Plaintext<A>> {
305 match self.load_circuit(stack, operand)? {
306 circuit::Value::Plaintext(plaintext) => Ok(plaintext),
307 circuit::Value::Record(..) | circuit::Value::Future(..) => bail!("Operand must be a plaintext"),
308 }
309 }
310}
311
312pub trait RegistersStore<N: Network> {
313 fn store(
320 &mut self,
321 stack: &(impl StackMatches<N> + StackProgram<N>),
322 register: &Register<N>,
323 stack_value: Value<N>,
324 ) -> Result<()>;
325
326 #[inline]
333 fn store_literal(
334 &mut self,
335 stack: &(impl StackMatches<N> + StackProgram<N>),
336 register: &Register<N>,
337 literal: Literal<N>,
338 ) -> Result<()> {
339 self.store(stack, register, Value::Plaintext(Plaintext::from(literal)))
340 }
341}
342
343pub trait RegistersStoreCircuit<N: Network, A: circuit::Aleo<Network = N>> {
344 fn store_circuit(
351 &mut self,
352 stack: &(impl StackMatches<N> + StackProgram<N>),
353 register: &Register<N>,
354 stack_value: circuit::Value<A>,
355 ) -> Result<()>;
356
357 #[inline]
364 fn store_literal_circuit(
365 &mut self,
366 stack: &(impl StackMatches<N> + StackProgram<N>),
367 register: &Register<N>,
368 literal: circuit::Literal<A>,
369 ) -> Result<()> {
370 self.store_circuit(stack, register, circuit::Value::Plaintext(circuit::Plaintext::from(literal)))
371 }
372}