@@ -11,23 +11,25 @@ use crate::{
11
11
to_field_elements:: ToFieldElements ,
12
12
transaction:: Check ,
13
13
witness:: Witness ,
14
+ zkapp:: StartDataSkeleton ,
14
15
} ,
15
16
scan_state:: {
16
17
currency:: { Amount , Balance , Index , Magnitude , Signed , Slot , SlotSpan , TxnVersion } ,
17
18
transaction_logic:: {
18
19
account_check_timing,
19
20
local_state:: { CallStack , StackFrame } ,
20
21
protocol_state:: GlobalStateSkeleton ,
22
+ set_with_location,
21
23
zkapp_command:: {
22
24
self , AccountPreconditions , AccountUpdate , CallForest , CheckAuthorizationResult ,
23
25
SetOrKeep ,
24
26
} ,
25
27
zkapp_statement:: TransactionCommitment ,
26
- TimingValidation , TransactionFailure ,
28
+ ExistingOrNew , TimingValidation , TransactionFailure ,
27
29
} ,
28
30
zkapp_logic:: controller_check,
29
31
} ,
30
- sparse_ledger:: LedgerIntf ,
32
+ sparse_ledger:: { LedgerIntf , SparseLedger } ,
31
33
zkapps:: checks:: ZkappCheck ,
32
34
Account , AccountId , Mask , MyCow , TokenId , ZkAppAccount , TXN_VERSION_CURRENT ,
33
35
} ;
@@ -45,7 +47,7 @@ use super::{
45
47
TxnVersionInterface , VerificationKeyHashInterface , WitnessGenerator , ZkappApplication ,
46
48
ZkappHandler ,
47
49
} ,
48
- zkapp_logic,
50
+ zkapp_logic:: { self , ApplyZkappParams } ,
49
51
} ;
50
52
51
53
pub type GlobalStateForNonSnark < L > = GlobalStateSkeleton <
@@ -864,3 +866,182 @@ impl BranchInterface for NonSnarkBranch {
864
866
BranchEvaluation :: Pending ( run)
865
867
}
866
868
}
869
+
870
+ fn get_with_location < L > (
871
+ ledger : & L ,
872
+ account_id : & AccountId ,
873
+ ) -> Result < ( ExistingOrNew < L :: Location > , Box < Account > ) , String >
874
+ where
875
+ L : LedgerIntf ,
876
+ {
877
+ match ledger. location_of_account ( account_id) {
878
+ Some ( location) => match ledger. get ( & location) {
879
+ Some ( account) => Ok ( ( ExistingOrNew :: Existing ( location) , account) ) ,
880
+ None => Err ( "Ledger location with no account" . to_string ( ) ) ,
881
+ } ,
882
+ None => Ok ( (
883
+ ExistingOrNew :: New ,
884
+ Box :: new ( Account :: create_with ( account_id. clone ( ) , Balance :: zero ( ) ) ) ,
885
+ ) ) ,
886
+ }
887
+ }
888
+
889
+ mod ledger {
890
+ use super :: * ;
891
+
892
+ type InclusionProof < L > = ExistingOrNew < <L as LedgerIntf >:: Location > ;
893
+
894
+ pub ( super ) fn get_account < L : LedgerIntf > (
895
+ ledger : & L ,
896
+ account_update : & AccountUpdate ,
897
+ ) -> Result < ( Account , InclusionProof < L > ) , String > {
898
+ let ( loc, account) = get_with_location ( ledger, & account_update. account_id ( ) ) ?;
899
+ Ok ( ( * account, loc) )
900
+ }
901
+ pub ( super ) fn set_account < L : LedgerIntf > (
902
+ ledger : & mut L ,
903
+ account : ( Account , InclusionProof < L > ) ,
904
+ ) -> Result < ( ) , String > {
905
+ let ( account, location) = account;
906
+ set_with_location ( ledger, & location, Box :: new ( account) )
907
+ }
908
+ pub ( super ) fn check_account < L : LedgerIntf > (
909
+ public_key : & CompressedPubKey ,
910
+ token_id : & TokenId ,
911
+ account : ( & Account , & InclusionProof < L > ) ,
912
+ ) -> Result < bool , String > {
913
+ let ( account, loc) = account;
914
+ if public_key != & account. public_key {
915
+ return Err ( "check_account: public_key != &account.public_key" . to_string ( ) ) ;
916
+ }
917
+ if token_id != & account. token_id {
918
+ return Err ( "check_account: token_id != &account.token_id" . to_string ( ) ) ;
919
+ }
920
+ match loc {
921
+ ExistingOrNew :: Existing ( _) => Ok ( false ) ,
922
+ ExistingOrNew :: New => Ok ( true ) ,
923
+ }
924
+ }
925
+ }
926
+
927
+ impl LedgerInterface for Mask {
928
+ type W = ( ) ;
929
+ type AccountUpdate = AccountUpdate ;
930
+ type Account = Account ;
931
+ type Bool = bool ;
932
+ type InclusionProof = ExistingOrNew < <Mask as LedgerIntf >:: Location > ;
933
+
934
+ fn empty ( depth : usize ) -> Self {
935
+ <Self as LedgerIntf >:: empty ( depth)
936
+ }
937
+ fn get_account (
938
+ & self ,
939
+ account_update : & Self :: AccountUpdate ,
940
+ _w : & mut Self :: W ,
941
+ ) -> Result < ( Self :: Account , Self :: InclusionProof ) , String > {
942
+ ledger:: get_account ( self , account_update)
943
+ }
944
+ fn set_account (
945
+ & mut self ,
946
+ account : ( Self :: Account , Self :: InclusionProof ) ,
947
+ _w : & mut Self :: W ,
948
+ ) -> Result < ( ) , String > {
949
+ ledger:: set_account ( self , account)
950
+ }
951
+ fn check_inclusion ( & self , _account : & ( Self :: Account , Self :: InclusionProof ) , _w : & mut Self :: W ) {
952
+ // Nothing
953
+ }
954
+ fn check_account (
955
+ public_key : & CompressedPubKey ,
956
+ token_id : & TokenId ,
957
+ account : ( & Self :: Account , & Self :: InclusionProof ) ,
958
+ _w : & mut Self :: W ,
959
+ ) -> Result < Self :: Bool , String > {
960
+ ledger:: check_account :: < Self > ( public_key, token_id, account)
961
+ }
962
+ }
963
+ impl LedgerInterface for SparseLedger {
964
+ type W = ( ) ;
965
+ type AccountUpdate = AccountUpdate ;
966
+ type Account = Account ;
967
+ type Bool = bool ;
968
+ type InclusionProof = ExistingOrNew < <Mask as LedgerIntf >:: Location > ;
969
+
970
+ fn empty ( depth : usize ) -> Self {
971
+ <Self as LedgerIntf >:: empty ( depth)
972
+ }
973
+ fn get_account (
974
+ & self ,
975
+ account_update : & Self :: AccountUpdate ,
976
+ _w : & mut Self :: W ,
977
+ ) -> Result < ( Self :: Account , Self :: InclusionProof ) , String > {
978
+ ledger:: get_account ( self , account_update)
979
+ }
980
+ fn set_account (
981
+ & mut self ,
982
+ account : ( Self :: Account , Self :: InclusionProof ) ,
983
+ _w : & mut Self :: W ,
984
+ ) -> Result < ( ) , String > {
985
+ ledger:: set_account ( self , account)
986
+ }
987
+ fn check_inclusion ( & self , _account : & ( Self :: Account , Self :: InclusionProof ) , _w : & mut Self :: W ) {
988
+ // Nothing
989
+ }
990
+ fn check_account (
991
+ public_key : & CompressedPubKey ,
992
+ token_id : & TokenId ,
993
+ account : ( & Self :: Account , & Self :: InclusionProof ) ,
994
+ _w : & mut Self :: W ,
995
+ ) -> Result < Self :: Bool , String > {
996
+ ledger:: check_account :: < Self > ( public_key, token_id, account)
997
+ }
998
+ }
999
+
1000
+ pub fn step < L > (
1001
+ global_state : & mut GlobalStateForNonSnark < L > ,
1002
+ local_state : & mut zkapp_logic:: LocalState < ZkappNonSnark < L > > ,
1003
+ ) -> Result < ( ) , String >
1004
+ where
1005
+ L : LedgerInterface <
1006
+ W = ( ) ,
1007
+ AccountUpdate = AccountUpdate ,
1008
+ Account = crate :: Account ,
1009
+ Bool = bool ,
1010
+ > ,
1011
+ {
1012
+ zkapp_logic:: apply (
1013
+ ApplyZkappParams {
1014
+ is_start : zkapp_logic:: IsStart :: No ,
1015
+ global_state,
1016
+ local_state,
1017
+ single_data : ( ) ,
1018
+ } ,
1019
+ & mut ( ) ,
1020
+ )
1021
+ }
1022
+
1023
+ type StartData = StartDataSkeleton < CallForest < AccountUpdate > , bool > ;
1024
+
1025
+ pub fn start < L > (
1026
+ global_state : & mut GlobalStateForNonSnark < L > ,
1027
+ local_state : & mut zkapp_logic:: LocalState < ZkappNonSnark < L > > ,
1028
+ start_data : StartData ,
1029
+ ) -> Result < ( ) , String >
1030
+ where
1031
+ L : LedgerInterface <
1032
+ W = ( ) ,
1033
+ AccountUpdate = AccountUpdate ,
1034
+ Account = crate :: Account ,
1035
+ Bool = bool ,
1036
+ > ,
1037
+ {
1038
+ zkapp_logic:: apply (
1039
+ ApplyZkappParams {
1040
+ is_start : zkapp_logic:: IsStart :: Yes ( start_data) ,
1041
+ global_state,
1042
+ local_state,
1043
+ single_data : ( ) ,
1044
+ } ,
1045
+ & mut ( ) ,
1046
+ )
1047
+ }
0 commit comments