1use std::marker::PhantomData;
2
3use mina_curves::pasta::Fp;
4use mina_signer::CompressedPubKey;
5
6use crate::proofs::{
7 field::{Boolean, FieldWitness},
8 to_field_elements::ToFieldElements,
9 transaction::Check,
10};
11
12use crate::{
13 scan_state::currency::{self, SlotSpan, TxnVersion},
14 zkapps::zkapp_logic,
15};
16
17use crate::{
18 scan_state::transaction_logic::{
19 zkapp_command::{self, CheckAuthorizationResult, SetOrKeep},
20 TimingValidation, TransactionFailure,
21 },
22 sparse_ledger::LedgerIntf,
23 AccountId, AuthRequired, MyCow, ReceiptChainHash, TokenId, ZkAppAccount,
24};
25
26pub trait WitnessGenerator<F: FieldWitness>
27where
28 Self: Sized,
29{
30 type Bool: BoolInterface;
31
32 fn exists<T>(&mut self, data: T) -> T
33 where
34 T: ToFieldElements<F> + Check<F>;
35
36 fn exists_no_check<T>(&mut self, data: T) -> T
37 where
38 T: ToFieldElements<F>;
39
40 fn exists_no_check_on_bool<T>(&mut self, b: Self::Bool, data: T) -> T
47 where
48 T: ToFieldElements<F>;
49
50 fn on_if<T, Fun, Fun2>(&mut self, b: Self::Bool, param: BranchParam<T, Self, Fun, Fun2>) -> T
51 where
52 T: ToFieldElements<F>,
53 Fun: FnOnce(&mut Self) -> T,
54 Fun2: FnOnce(&mut Self) -> T,
55 {
56 let BranchParam { on_true, on_false } = param;
57 let value = match b.as_boolean() {
58 Boolean::True => on_true.eval(self),
59 Boolean::False => on_false.eval(self),
60 };
61 self.exists_no_check_on_bool(b, value)
62 }
63}
64
65pub trait ZkappHandler {
66 type Z: ZkappApplication;
67 type AccountUpdate: AccountUpdateInterface;
68 type Account: AccountInterface;
69 type Bool: BoolInterface;
70 type W: WitnessGenerator<Fp>;
71 type GlobalState: GlobalStateInterface;
72
73 fn check_account_precondition(
74 account_update: &Self::AccountUpdate,
75 account: &Self::Account,
76 new_account: Self::Bool,
77 local_state: &mut zkapp_logic::LocalState<Self::Z>,
78 w: &mut Self::W,
79 );
80 fn check_protocol_state_precondition(
81 protocol_state_predicate: &zkapp_command::ZkAppPreconditions,
82 global_state: &mut Self::GlobalState,
83 w: &mut Self::W,
84 ) -> Self::Bool;
85 fn check_valid_while_precondition(
86 valid_while: &zkapp_command::Numeric<crate::scan_state::currency::Slot>,
87 global_state: &mut Self::GlobalState,
88 w: &mut Self::W,
89 ) -> Self::Bool;
90 fn init_account(account_update: &Self::AccountUpdate, account: Self::Account) -> Self::Account;
91}
92
93pub struct Opt<T> {
94 pub is_some: Boolean,
95 pub data: T,
96}
97
98impl<T: Default> Opt<T> {
99 pub fn from_option(opt: Option<T>) -> Self {
100 match opt {
101 Some(data) => Self {
102 is_some: Boolean::True,
103 data,
104 },
105 None => Self {
106 is_some: Boolean::False,
107 data: T::default(),
108 },
109 }
110 }
111}
112
113impl<A, B> Opt<(A, B)> {
114 pub fn unzip(self) -> (Opt<A>, Opt<B>) {
115 let Self {
116 is_some,
117 data: (a, b),
118 } = self;
119 let a = Opt { is_some, data: a };
120 let b = Opt { is_some, data: b };
121 (a, b)
122 }
123}
124
125pub trait AmountInterface
126where
127 Self: Sized,
128{
129 type W: WitnessGenerator<Fp>;
130 type Bool: BoolInterface;
131
132 fn zero() -> Self;
133 fn of_constant_fee(fee: currency::Fee) -> Self;
134}
135
136pub trait SignedAmountInterface
137where
138 Self: Sized,
139{
140 type W: WitnessGenerator<Fp>;
141 type Bool: BoolInterface;
142 type Amount: AmountInterface;
143
144 fn zero() -> Self;
145 fn is_neg(&self) -> Self::Bool;
146 fn equal(&self, other: &Self, w: &mut Self::W) -> Self::Bool;
147 fn is_non_neg(&self) -> Self::Bool;
148 fn negate(&self) -> Self;
149 fn add_flagged(&self, other: &Self, w: &mut Self::W) -> (Self, Self::Bool);
150 fn of_unsigned(unsigned: Self::Amount) -> Self;
151 fn on_if(b: Self::Bool, param: SignedAmountBranchParam<&Self>, w: &mut Self::W) -> Self;
152}
153
154pub trait BalanceInterface
155where
156 Self: Sized,
157{
158 type W: WitnessGenerator<Fp>;
159 type Bool: BoolInterface;
160 type Amount: AmountInterface;
161 type SignedAmount: SignedAmountInterface;
162
163 fn add_signed_amount_flagged(
164 &self,
165 signed_amount: Self::SignedAmount,
166 w: &mut Self::W,
167 ) -> (Self, Self::Bool);
168}
169
170pub trait IndexInterface
171where
172 Self: Sized,
173{
174 fn zero() -> Self;
175 fn succ(&self) -> Self;
176}
177
178pub trait ReceiptChainHashElementInterface
179where
180 Self: Sized,
181{
182 fn of_commitment(commitment: impl ReceiptChainHashInterface) -> Self;
183}
184
185pub trait ReceiptChainHashInterface {
186 type W: WitnessGenerator<Fp>;
187 type Index;
188 fn cons_zkapp_command_commitment(
189 index: Self::Index,
190 element: Fp,
191 other: ReceiptChainHash,
192 w: &mut Self::W,
193 ) -> ReceiptChainHash;
194}
195
196pub trait GlobalSlotSinceGenesisInterface {
197 type W: WitnessGenerator<Fp>;
198 type Bool: BoolInterface;
199
200 fn equal(&self, other: &Self, w: &mut Self::W) -> Self::Bool;
201 fn exists_no_check(self, w: &mut Self::W) -> Self;
202}
203
204pub trait GlobalSlotSpanInterface {
205 type W: WitnessGenerator<Fp>;
206 type Bool: BoolInterface;
207 type SlotSpan;
208
209 fn greater_than(this: &Self::SlotSpan, other: &Self::SlotSpan, w: &mut Self::W) -> Self::Bool;
210}
211
212pub trait CallForestInterface
213where
214 Self: Sized,
215{
216 type W: WitnessGenerator<Fp>;
217 type AccountUpdate: AccountUpdateInterface;
218 type Bool: BoolInterface;
219
220 fn empty() -> Self;
221 fn is_empty(&self, w: &mut Self::W) -> Self::Bool;
222 fn pop_exn(&self, w: &mut Self::W) -> ((Self::AccountUpdate, Self), Self);
223}
224
225pub struct StackFrameMakeParams<'a, Calls> {
226 pub caller: TokenId,
227 pub caller_caller: TokenId,
228 pub calls: &'a Calls,
229}
230
231#[derive(Debug)]
232pub struct SignedAmountBranchParam<T> {
233 pub on_true: T,
234 pub on_false: T,
235}
236
237pub struct BranchParam<T, W, F: FnOnce(&mut W) -> T, F2: FnOnce(&mut W) -> T> {
238 pub on_true: BranchEvaluation<T, W, F>,
239 pub on_false: BranchEvaluation<T, W, F2>,
240}
241
242pub trait StackFrameInterface
243where
244 Self: Sized,
245{
246 type Calls: CallForestInterface<W = Self::W>;
247 type W: WitnessGenerator<Fp>;
248 type Bool: BoolInterface;
249
250 fn caller(&self) -> TokenId;
251 fn caller_caller(&self) -> TokenId;
252 fn calls(&self) -> &Self::Calls;
253 fn make(params: StackFrameMakeParams<'_, Self::Calls>) -> Self;
254 fn make_default(params: StackFrameMakeParams<'_, Self::Calls>) -> Self;
255 fn on_if<F, F2>(
256 b: Self::Bool,
257 param: BranchParam<Self, Self::W, F, F2>,
258 w: &mut Self::W,
259 ) -> Self
260 where
261 F: FnOnce(&mut Self::W) -> Self,
262 F2: FnOnce(&mut Self::W) -> Self;
263}
264
265pub trait StackInterface
266where
267 Self: Sized,
268{
269 type Elt;
270 type W: WitnessGenerator<Fp>;
271 type Bool: BoolInterface;
272
273 fn empty() -> Self;
274 fn is_empty(&self, w: &mut Self::W) -> Self::Bool;
275 fn pop(&self, w: &mut Self::W) -> Opt<(Self::Elt, Self)>;
276 fn push(elt: Self::Elt, onto: Self, w: &mut Self::W) -> Self;
277}
278
279pub trait CallStackInterface
280where
281 Self: Sized + StackInterface,
282{
283 type StackFrame: StackFrameInterface;
284}
285
286pub trait GlobalStateInterface {
287 type Ledger;
288 type W: WitnessGenerator<Fp>;
289 type Bool: BoolInterface;
290 type SignedAmount: SignedAmountInterface;
291 type GlobalSlotSinceGenesis: GlobalSlotSinceGenesisInterface;
292
293 fn first_pass_ledger(&self) -> Self::Ledger;
294 fn set_first_pass_ledger(
295 &mut self,
296 should_update: Self::Bool,
297 ledger: &Self::Ledger,
298 w: &mut Self::W,
299 );
300
301 fn second_pass_ledger(&self) -> Self::Ledger;
302 fn set_second_pass_ledger(
303 &mut self,
304 should_update: Self::Bool,
305 ledger: &Self::Ledger,
306 w: &mut Self::W,
307 );
308
309 fn fee_excess(&self) -> Self::SignedAmount;
310 fn set_fee_excess(&mut self, fee_excess: Self::SignedAmount);
311
312 fn supply_increase(&self) -> Self::SignedAmount;
313 fn set_supply_increase(&mut self, supply_increase: Self::SignedAmount);
314
315 fn block_global_slot(&self) -> Self::GlobalSlotSinceGenesis;
316}
317
318pub trait LocalStateInterface {
319 type Z: ZkappApplication;
320 type W: WitnessGenerator<Fp>;
321 type Bool: BoolInterface;
322
323 fn add_check(
324 local: &mut zkapp_logic::LocalState<Self::Z>,
325 failure: TransactionFailure,
326 b: Self::Bool,
327 w: &mut Self::W,
328 );
329 fn add_new_failure_status_bucket(local: &mut zkapp_logic::LocalState<Self::Z>);
330}
331
332pub trait AccountUpdateInterface
333where
334 Self: Sized,
335{
336 type W: WitnessGenerator<Fp>;
337 type SingleData;
338 type CallForest: CallForestInterface;
339 type Bool: BoolInterface;
340 type SignedAmount: SignedAmountInterface;
341 type VerificationKeyHash: VerificationKeyHashInterface;
342
343 fn body(&self) -> &crate::scan_state::transaction_logic::zkapp_command::Body;
345 fn verification_key_hash(&self) -> Self::VerificationKeyHash;
346 fn is_proved(&self) -> Self::Bool;
347 fn is_signed(&self) -> Self::Bool;
348 fn check_authorization(
349 &self,
350 will_succeed: Self::Bool,
351 commitment: Fp,
352 calls: &Self::CallForest,
353 single_data: &Self::SingleData,
354 w: &mut Self::W,
355 ) -> CheckAuthorizationResult<Self::Bool>;
356 fn increment_nonce(&self) -> Self::Bool;
357 fn use_full_commitment(&self) -> Self::Bool;
358 fn account_precondition_nonce_is_constant(&self, w: &mut Self::W) -> Self::Bool;
359 fn implicit_account_creation_fee(&self) -> Self::Bool;
360 fn balance_change(&self) -> Self::SignedAmount;
361}
362
363pub trait AccountIdInterface
364where
365 Self: Sized,
366{
367 type W: WitnessGenerator<Fp>;
368
369 fn derive_token_id(account_id: &AccountId, w: &mut Self::W) -> TokenId;
370}
371
372pub trait TokenIdInterface
373where
374 Self: Sized,
375{
376 type W: WitnessGenerator<Fp>;
377 type Bool: BoolInterface;
378
379 fn equal(a: &TokenId, b: &TokenId, w: &mut Self::W) -> Self::Bool;
380}
381
382pub trait ControllerInterface {
383 type W: WitnessGenerator<Fp>;
384 type Bool: BoolInterface;
385 type SingleData;
386
387 fn check(
388 proof_verifies: Self::Bool,
389 signature_verifies: Self::Bool,
390 auth: &AuthRequired,
391 single_data: &Self::SingleData,
392 w: &mut Self::W,
393 ) -> Result<Self::Bool, String>;
394
395 fn verification_key_perm_fallback_to_signature_with_older_version(
396 auth: &AuthRequired,
397 w: &mut Self::W,
398 ) -> AuthRequired;
399}
400
401pub trait TxnVersionInterface {
402 type W: WitnessGenerator<Fp>;
403 type Bool: BoolInterface;
404
405 fn equal_to_current(version: TxnVersion, w: &mut Self::W) -> Self::Bool;
406 fn older_than_current(version: TxnVersion, w: &mut Self::W) -> Self::Bool;
407}
408
409pub trait BoolInterface
410where
411 Self: Sized,
412{
413 type W: WitnessGenerator<Fp>;
414 type FailureStatusTable;
415
416 fn as_boolean(&self) -> Boolean;
417 fn of_boolean(b: Boolean) -> Self;
418 fn true_() -> Self;
419 fn false_() -> Self;
420 fn neg(&self) -> Self;
421 fn or(a: Self, b: Self, w: &mut Self::W) -> Self;
422 fn and(a: Self, b: Self, w: &mut Self::W) -> Self;
423 fn equal(a: Self, b: Self, w: &mut Self::W) -> Self;
424 fn all(bs: &[Self], w: &mut Self::W) -> Self;
425 fn assert_any(bs: &[Self], w: &mut Self::W) -> Result<(), String>;
426 fn assert_with_failure_status_tbl(
427 b: Self,
428 table: &Self::FailureStatusTable,
429 ) -> Result<(), String>;
430}
431
432pub trait TransactionCommitmentInterface {
433 type AccountUpdate: AccountUpdateInterface;
434 type CallForest: CallForestInterface;
435 type W: WitnessGenerator<Fp>;
436
437 fn empty() -> Fp;
438 fn commitment(account_updates: &Self::CallForest) -> Fp;
439 fn full_commitment(
440 account_updates: &Self::AccountUpdate,
441 memo_hash: Fp,
442 commitment: Fp,
443 w: &mut Self::W,
444 ) -> Fp;
445}
446
447pub trait AccountInterface
448where
449 Self: Sized,
450{
451 type W: WitnessGenerator<Fp>;
452 type Bool: BoolInterface;
453 type Balance: BalanceInterface;
454 type GlobalSlot: GlobalSlotSinceGenesisInterface;
455 type VerificationKeyHash: VerificationKeyHashInterface;
456 type D;
457
458 fn register_verification_key(&self, data: &Self::D, w: &mut Self::W);
459 fn get(&self) -> &crate::Account;
460 fn get_mut(&mut self) -> &mut crate::Account;
461 fn set_delegate(&mut self, new: CompressedPubKey);
462 fn zkapp(&self) -> MyCow<'_, ZkAppAccount>;
463 fn zkapp_mut(&mut self) -> &mut ZkAppAccount;
464 fn verification_key_hash(&self) -> Self::VerificationKeyHash;
465 fn set_token_id(&mut self, token_id: TokenId);
466 fn is_timed(&self) -> Self::Bool;
467 fn balance(&self) -> Self::Balance;
468 fn set_balance(&mut self, balance: Self::Balance);
469 fn check_timing(
470 &self,
471 txn_global_slot: &Self::GlobalSlot,
472 w: &mut Self::W,
473 ) -> (TimingValidation<Self::Bool>, crate::Timing);
474 fn make_zkapp(&mut self);
475 fn unmake_zkapp(&mut self);
476 fn proved_state(&self) -> Self::Bool;
477 fn set_proved_state(&mut self, proved_state: Self::Bool);
478 fn app_state(&self) -> [Fp; 8];
479 fn last_action_slot(&self) -> Self::GlobalSlot;
480 fn set_last_action_slot(&mut self, slot: Self::GlobalSlot);
481}
482
483pub trait LedgerInterface: LedgerIntf + Clone {
484 type W: WitnessGenerator<Fp>;
485 type AccountUpdate: AccountUpdateInterface;
486 type Account: AccountInterface;
487 type Bool: BoolInterface;
488 type InclusionProof;
489
490 fn empty(depth: usize) -> Self;
491 fn get_account(
492 &self,
493 account_update: &Self::AccountUpdate,
494 w: &mut Self::W,
495 ) -> Result<(Self::Account, Self::InclusionProof), String>;
496 fn set_account(
497 &mut self,
498 account: (Self::Account, Self::InclusionProof),
499 w: &mut Self::W,
500 ) -> Result<(), String>;
501 fn check_inclusion(&self, account: &(Self::Account, Self::InclusionProof), w: &mut Self::W);
502 fn check_account(
503 public_key: &CompressedPubKey,
504 token_id: &TokenId,
505 account: (&Self::Account, &Self::InclusionProof),
506 w: &mut Self::W,
507 ) -> Result<Self::Bool, String>;
508 fn exists_no_check(self, _w: &mut Self::W) -> Self {
509 self
510 }
511 fn exists_no_check_on_bool(self, _b: Self::Bool, _w: &mut Self::W) -> Self {
512 self
513 }
514}
515
516pub trait VerificationKeyHashInterface {
517 type W: WitnessGenerator<Fp>;
518 type Bool: BoolInterface;
519
520 fn equal(a: &Self, b: &Self, w: &mut Self::W) -> Self::Bool;
521}
522
523pub trait SetOrKeepInterface {
524 type Bool: BoolInterface;
525 fn is_keep<T: Clone>(set_or_keep: &SetOrKeep<T>) -> Self::Bool;
526 fn is_set<T: Clone>(set_or_keep: &SetOrKeep<T>) -> Self::Bool;
527}
528
529pub trait ActionsInterface {
530 type W: WitnessGenerator<Fp>;
531 type Bool: BoolInterface;
532
533 fn is_empty(actions: &zkapp_command::Actions, w: &mut Self::W) -> Self::Bool;
534 fn push_events(event: Fp, actions: &zkapp_command::Actions, w: &mut Self::W) -> Fp;
535}
536
537pub enum BranchEvaluation<T, W, F: FnOnce(&mut W) -> T> {
538 Evaluated(T, PhantomData<W>),
539 Pending(F),
540}
541
542impl<T, W, F> BranchEvaluation<T, W, F>
543where
544 F: FnOnce(&mut W) -> T,
545{
546 pub fn eval(self, w: &mut W) -> T {
547 match self {
548 Self::Evaluated(v, _) => {
549 v
551 }
552 Self::Pending(fun) => {
553 fun(w)
555 }
556 }
557 }
558}
559
560pub trait BranchInterface {
570 type W: WitnessGenerator<Fp>;
571
572 fn make<T, F>(w: &mut Self::W, run: F) -> BranchEvaluation<T, Self::W, F>
573 where
574 F: FnOnce(&mut Self::W) -> T;
575}
576
577pub trait ZkappApplication
578where
579 Self: Sized,
580{
581 type Ledger: LedgerInterface<
582 W = Self::WitnessGenerator,
583 AccountUpdate = Self::AccountUpdate,
584 Account = Self::Account,
585 Bool = Self::Bool,
586 >;
587 type SignedAmount: SignedAmountInterface<W = Self::WitnessGenerator, Bool = Self::Bool, Amount = Self::Amount>
588 + std::fmt::Debug
589 + Clone;
590 type Amount: AmountInterface<W = Self::WitnessGenerator, Bool = Self::Bool> + Clone;
591 type Balance: BalanceInterface<
592 W = Self::WitnessGenerator,
593 Bool = Self::Bool,
594 Amount = Self::Amount,
595 SignedAmount = Self::SignedAmount,
596 >;
597 type Index: IndexInterface + Clone + ToFieldElements<Fp>;
598 type GlobalSlotSinceGenesis: GlobalSlotSinceGenesisInterface<
599 W = Self::WitnessGenerator,
600 Bool = Self::Bool,
601 >;
602 type StackFrame: StackFrameInterface<W = Self::WitnessGenerator, Calls = Self::CallForest, Bool = Self::Bool>
603 + std::fmt::Debug
604 + Clone;
605 type CallForest: CallForestInterface<
606 W = Self::WitnessGenerator,
607 AccountUpdate = Self::AccountUpdate,
608 Bool = Self::Bool,
609 >;
610 type CallStack: CallStackInterface<W = Self::WitnessGenerator, Elt = Self::StackFrame, Bool = Self::Bool>
611 + ToFieldElements<Fp>
612 + Clone;
613 type GlobalState: GlobalStateInterface<
614 Ledger = Self::Ledger,
615 W = Self::WitnessGenerator,
616 SignedAmount = Self::SignedAmount,
617 GlobalSlotSinceGenesis = Self::GlobalSlotSinceGenesis,
618 Bool = Self::Bool,
619 >;
620 type AccountUpdate: AccountUpdateInterface<
621 W = Self::WitnessGenerator,
622 CallForest = Self::CallForest,
623 SingleData = Self::SingleData,
624 Bool = Self::Bool,
625 SignedAmount = Self::SignedAmount,
626 VerificationKeyHash = Self::VerificationKeyHash,
627 >;
628 type AccountId: AccountIdInterface<W = Self::WitnessGenerator>;
629 type TokenId: TokenIdInterface<W = Self::WitnessGenerator, Bool = Self::Bool>;
630 type Bool: BoolInterface<W = Self::WitnessGenerator, FailureStatusTable = Self::FailureStatusTable>
631 + ToFieldElements<Fp>
632 + Clone
633 + Copy
634 + std::fmt::Debug;
635 type TransactionCommitment: TransactionCommitmentInterface<
636 W = Self::WitnessGenerator,
637 AccountUpdate = Self::AccountUpdate,
638 CallForest = Self::CallForest,
639 >;
640 type FailureStatusTable;
641 type LocalState: LocalStateInterface<W = Self::WitnessGenerator, Z = Self, Bool = Self::Bool>;
642 type Account: AccountInterface<
643 W = Self::WitnessGenerator,
644 D = Self::SingleData,
645 Bool = Self::Bool,
646 Balance = Self::Balance,
647 GlobalSlot = Self::GlobalSlotSinceGenesis,
648 VerificationKeyHash = Self::VerificationKeyHash,
649 >;
650 type VerificationKeyHash: VerificationKeyHashInterface<
651 W = Self::WitnessGenerator,
652 Bool = Self::Bool,
653 >;
654 type Controller: ControllerInterface<
655 W = Self::WitnessGenerator,
656 Bool = Self::Bool,
657 SingleData = Self::SingleData,
658 >;
659 type TxnVersion: TxnVersionInterface<W = Self::WitnessGenerator, Bool = Self::Bool>;
660 type SetOrKeep: SetOrKeepInterface<Bool = Self::Bool>;
661 type GlobalSlotSpan: GlobalSlotSpanInterface<
662 W = Self::WitnessGenerator,
663 Bool = Self::Bool,
664 SlotSpan = SlotSpan,
665 >;
666 type Actions: ActionsInterface<W = Self::WitnessGenerator, Bool = Self::Bool>;
667 type ReceiptChainHash: ReceiptChainHashInterface<
668 W = Self::WitnessGenerator,
669 Index = Self::Index,
670 >;
671 type SingleData;
672 type Handler: ZkappHandler<
673 Z = Self,
674 AccountUpdate = Self::AccountUpdate,
675 Account = Self::Account,
676 Bool = Self::Bool,
677 W = Self::WitnessGenerator,
678 GlobalState = Self::GlobalState,
679 >;
680 type Branch: BranchInterface<W = Self::WitnessGenerator>;
681 type WitnessGenerator: WitnessGenerator<Fp, Bool = Self::Bool>;
682}