From 6453b045367924e9434b9aac8ab0f4adb0fcba5c Mon Sep 17 00:00:00 2001 From: Tang Jiawei Date: Fri, 15 Sep 2023 04:38:15 +0800 Subject: [PATCH 1/7] new unit tests for skipping invalid commands --- src/lib/staged_ledger/staged_ledger.ml | 145 +++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/src/lib/staged_ledger/staged_ledger.ml b/src/lib/staged_ledger/staged_ledger.ml index cd79450438b..f1180b4b37b 100644 --- a/src/lib/staged_ledger/staged_ledger.ml +++ b/src/lib/staged_ledger/staged_ledger.ml @@ -4249,6 +4249,151 @@ let%test_module "staged ledger tests" = and global_slot = Quickcheck.Generator.small_positive_int in (test_spec, kp, global_slot) + let%test_unit "When creating diff, invalid commands would be skipped" = + let gen = + let open Quickcheck.Generator.Let_syntax in + let%bind spec_keypair_and_slot = gen_spec_keypair_and_global_slot in + let%map signed_commands_or_zkapps = + List.gen_with_length 5 Bool.quickcheck_generator + in + + (spec_keypair_and_slot, signed_commands_or_zkapps |> List.to_array) + in + Async.Thread_safe.block_on_async_exn @@ fun () -> + Async.Quickcheck.async_test ~trials:2 gen + ~f:(fun + ( ({ init_ledger; _ }, new_kp, global_slot) + , signed_commands_or_zkapps ) + -> + let open Transaction_snark.For_tests in + let fee = Fee.of_nanomina_int_exn 1_000_000 in + let amount = Amount.of_mina_int_exn 10 in + let mk_signed_command ~(fee_payer : Keypair.t) + ~(receiver : Keypair.t) ~(nonce : Account.Nonce.t) = + let body = + Signed_command_payload.Body.Payment + Payment_payload.Poly. + { receiver_pk = Public_key.compress receiver.public_key + ; amount + } + in + let payload = + Signed_command.Payload.create ~fee + ~fee_payer_pk:Public_key.(compress fee_payer.public_key) + ~nonce ~memo:Signed_command_memo.dummy ~valid_until:None + ~body + in + User_command.Signed_command + (Signed_command.sign fee_payer payload) + in + let zkapp_pk = Public_key.compress new_kp.public_key in + let ledger = + Ledger.create ~depth:constraint_constants.ledger_depth () + in + Mina_transaction_logic.For_tests.Init_ledger.init + (module Ledger.Ledger_inner) + init_ledger ledger ; + Transaction_snark.For_tests.create_trivial_zkapp_account + ~permissions:Permissions.user_default ~vk ~ledger zkapp_pk ; + let sl = Sl.create_exn ~constraint_constants ~ledger in + let mk_zkapp_command ~(fee_payer : Keypair.t) + ~(nonce : Account.Nonce.t) = + let spec : Update_states_spec.t = + { sender = (new_kp, Account.Nonce.zero) + ; fee + ; fee_payer = Some (fee_payer, nonce) + ; receivers = [] + ; amount + ; zkapp_account_keypairs = [ new_kp ] + ; memo = Signed_command_memo.dummy + ; new_zkapp_account = false + ; snapp_update = + { Account_update.Update.dummy with + delegate = Zkapp_basic.Set_or_keep.Set zkapp_pk + } + ; current_auth = Permissions.Auth_required.Signature + ; call_data = Snark_params.Tick.Field.zero + ; events = [] + ; actions = [] + ; preconditions = None + } + in + let%map zkapp_command = + Transaction_snark.For_tests.update_states + ~zkapp_prover_and_vk:(zkapp_prover, vk) + ~constraint_constants spec + in + let valid_zkapp_command = + Zkapp_command.Valid.to_valid ~status:Applied + ~find_vk: + (Zkapp_command.Verifiable.find_vk_via_ledger ~ledger + ~get:Ledger.get + ~location_of_account:Ledger.location_of_account ) + zkapp_command + |> Or_error.ok_exn + in + User_command.Zkapp_command valid_zkapp_command + in + let mk_user_command ~signed_command_or_zkapp ~fee_payer ~receiver + ~nonce = + match signed_command_or_zkapp with + | true -> + return @@ mk_signed_command ~fee_payer ~receiver ~nonce + | false -> + mk_zkapp_command ~fee_payer ~nonce + in + let fee_payer, _ = init_ledger.(0) in + let receiver, _ = init_ledger.(1) in + let%map valid_command_1 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(0) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 0) + and valid_command_2 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(1) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 1) + and invalid_command_3 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(2) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 99) + and valid_command_4 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(3) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 2) + and invalid_command_5 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(4) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 98) + in + let global_slot = + Mina_numbers.Global_slot_since_genesis.of_int global_slot + in + let _current_state, current_state_view = + dummy_state_and_view ~global_slot () + in + match + Sl.create_diff ~constraint_constants ~global_slot sl ~logger + ~current_state_view + ~transactions_by_fee: + (Sequence.of_list + [ valid_command_1 + ; valid_command_2 + ; invalid_command_3 + ; valid_command_4 + ; invalid_command_5 + ] ) + ~get_completed_work:(stmt_to_work_zero_fee ~prover:self_pk) + ~coinbase_receiver ~supercharge_coinbase:false + with + | Error e -> + Error.raise (Pre_diff_info.Error.to_error e) + | Ok (diff, invalid_txns) -> + let valid_commands = Staged_ledger_diff.With_valid_signatures_and_proofs.commands diff in + assert ( + List.length valid_commands + = 3 ) ; + assert (List.length invalid_txns = 2) ) + let%test_unit "Mismatched verification keys in zkApp accounts and \ transactions" = let open Transaction_snark.For_tests in From e1db594604ff8fe75034cb7cde7aae6e0fe06d9a Mon Sep 17 00:00:00 2001 From: Tang Jiawei Date: Tue, 19 Sep 2023 01:49:36 +0800 Subject: [PATCH 2/7] add unit tests for failed zkapp commands --- src/lib/staged_ledger/staged_ledger.ml | 43 ++++++++++++++++++++------ 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/lib/staged_ledger/staged_ledger.ml b/src/lib/staged_ledger/staged_ledger.ml index f1180b4b37b..39fa921a019 100644 --- a/src/lib/staged_ledger/staged_ledger.ml +++ b/src/lib/staged_ledger/staged_ledger.ml @@ -1,7 +1,7 @@ [%%import "/src/config.mlh"] (* Only show stdout for failed inline tests. *) -open Inline_test_quiet_logs + open Core_kernel open Async open Mina_base @@ -2163,7 +2163,7 @@ let%test_module "staged ledger tests" = let constraint_constants = Genesis_constants.Constraint_constants.for_unit_tests - let logger = Logger.null () + let logger = Logger.create () let `VK vk, `Prover zkapp_prover = Transaction_snark.For_tests.create_trivial_snapp ~constraint_constants () @@ -4254,20 +4254,29 @@ let%test_module "staged ledger tests" = let open Quickcheck.Generator.Let_syntax in let%bind spec_keypair_and_slot = gen_spec_keypair_and_global_slot in let%map signed_commands_or_zkapps = + (* + return [false;true;false;true;true] + *) List.gen_with_length 5 Bool.quickcheck_generator + in (spec_keypair_and_slot, signed_commands_or_zkapps |> List.to_array) in Async.Thread_safe.block_on_async_exn @@ fun () -> - Async.Quickcheck.async_test ~trials:2 gen + Async.Quickcheck.async_test ~trials:10 gen ~f:(fun ( ({ init_ledger; _ }, new_kp, global_slot) , signed_commands_or_zkapps ) -> let open Transaction_snark.For_tests in - let fee = Fee.of_nanomina_int_exn 1_000_000 in - let amount = Amount.of_mina_int_exn 10 in + [%log info] + "signed commands or zkapps" + ~metadata:[ + ("signed_commands_or_zkapps", `List (List.map (Array.to_list signed_commands_or_zkapps) ~f:(fun b -> `Bool b))) + ] ; + let fee = Fee.of_nanomina_int_exn 2_000_000 in + let amount = Amount.of_mina_int_exn 2 in let mk_signed_command ~(fee_payer : Keypair.t) ~(receiver : Keypair.t) ~(nonce : Account.Nonce.t) = let body = @@ -4344,7 +4353,7 @@ let%test_module "staged ledger tests" = in let fee_payer, _ = init_ledger.(0) in let receiver, _ = init_ledger.(1) in - let%map valid_command_1 = + let%bind valid_command_1 = mk_user_command ~signed_command_or_zkapp:signed_commands_or_zkapps.(0) ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 0) @@ -4368,9 +4377,16 @@ let%test_module "staged ledger tests" = let global_slot = Mina_numbers.Global_slot_since_genesis.of_int global_slot in - let _current_state, current_state_view = + let current_state, current_state_view = dummy_state_and_view ~global_slot () in + let _state_and_body_hash = + let state_hashes = + Mina_state.Protocol_state.hashes current_state + in + ( state_hashes.state_hash + , state_hashes.state_body_hash |> Option.value_exn ) + in match Sl.create_diff ~constraint_constants ~global_slot sl ~logger ~current_state_view @@ -4391,8 +4407,17 @@ let%test_module "staged ledger tests" = let valid_commands = Staged_ledger_diff.With_valid_signatures_and_proofs.commands diff in assert ( List.length valid_commands - = 3 ) ; - assert (List.length invalid_txns = 2) ) + = 3) ; + assert (List.length invalid_txns = 2) ; + Deferred.unit + (* + match%map Sl.apply ~constraint_constants ~global_slot sl (Staged_ledger_diff.forget diff) + ~logger ~verifier ~current_state_view ~state_and_body_hash ~coinbase_receiver ~supercharge_coinbase:false + with + | Ok _x -> () + | Error e -> + [%log info] "Error %s" (Staged_ledger_error.to_string e) ; () + *) ) let%test_unit "Mismatched verification keys in zkApp accounts and \ transactions" = From 121dc2e092f03ba967bbbe974e32d11c01a49e59 Mon Sep 17 00:00:00 2001 From: Tang Jiawei Date: Wed, 20 Sep 2023 02:42:08 +0800 Subject: [PATCH 3/7] tidy things up --- src/lib/staged_ledger/staged_ledger.ml | 318 +++++++++++++------------ 1 file changed, 166 insertions(+), 152 deletions(-) diff --git a/src/lib/staged_ledger/staged_ledger.ml b/src/lib/staged_ledger/staged_ledger.ml index 39fa921a019..1457f73a04c 100644 --- a/src/lib/staged_ledger/staged_ledger.ml +++ b/src/lib/staged_ledger/staged_ledger.ml @@ -1,7 +1,7 @@ [%%import "/src/config.mlh"] (* Only show stdout for failed inline tests. *) - +open Inline_test_quiet_logs open Core_kernel open Async open Mina_base @@ -2163,7 +2163,7 @@ let%test_module "staged ledger tests" = let constraint_constants = Genesis_constants.Constraint_constants.for_unit_tests - let logger = Logger.create () + let logger = Logger.null () let `VK vk, `Prover zkapp_prover = Transaction_snark.For_tests.create_trivial_snapp ~constraint_constants () @@ -4254,170 +4254,184 @@ let%test_module "staged ledger tests" = let open Quickcheck.Generator.Let_syntax in let%bind spec_keypair_and_slot = gen_spec_keypair_and_global_slot in let%map signed_commands_or_zkapps = - (* + (* return [false;true;false;true;true] *) List.gen_with_length 5 Bool.quickcheck_generator - in (spec_keypair_and_slot, signed_commands_or_zkapps |> List.to_array) in - Async.Thread_safe.block_on_async_exn @@ fun () -> - Async.Quickcheck.async_test ~trials:10 gen - ~f:(fun - ( ({ init_ledger; _ }, new_kp, global_slot) - , signed_commands_or_zkapps ) - -> - let open Transaction_snark.For_tests in - [%log info] - "signed commands or zkapps" - ~metadata:[ - ("signed_commands_or_zkapps", `List (List.map (Array.to_list signed_commands_or_zkapps) ~f:(fun b -> `Bool b))) - ] ; - let fee = Fee.of_nanomina_int_exn 2_000_000 in - let amount = Amount.of_mina_int_exn 2 in - let mk_signed_command ~(fee_payer : Keypair.t) - ~(receiver : Keypair.t) ~(nonce : Account.Nonce.t) = - let body = - Signed_command_payload.Body.Payment - Payment_payload.Poly. - { receiver_pk = Public_key.compress receiver.public_key - ; amount - } - in - let payload = - Signed_command.Payload.create ~fee - ~fee_payer_pk:Public_key.(compress fee_payer.public_key) - ~nonce ~memo:Signed_command_memo.dummy ~valid_until:None - ~body - in - User_command.Signed_command - (Signed_command.sign fee_payer payload) - in - let zkapp_pk = Public_key.compress new_kp.public_key in - let ledger = - Ledger.create ~depth:constraint_constants.ledger_depth () - in - Mina_transaction_logic.For_tests.Init_ledger.init - (module Ledger.Ledger_inner) - init_ledger ledger ; - Transaction_snark.For_tests.create_trivial_zkapp_account - ~permissions:Permissions.user_default ~vk ~ledger zkapp_pk ; - let sl = Sl.create_exn ~constraint_constants ~ledger in - let mk_zkapp_command ~(fee_payer : Keypair.t) - ~(nonce : Account.Nonce.t) = - let spec : Update_states_spec.t = - { sender = (new_kp, Account.Nonce.zero) - ; fee - ; fee_payer = Some (fee_payer, nonce) - ; receivers = [] + Async.Thread_safe.block_on_async_exn + @@ fun () -> + Async.Quickcheck.async_test ~trials:20 gen + ~f:(fun + ( ({ init_ledger; _ }, new_kp, global_slot) + , signed_commands_or_zkapps ) + -> + let open Transaction_snark.For_tests in + [%log info] "signed commands or zkapps" + ~metadata: + [ ( "signed_commands_or_zkapps" + , `List + (List.map (Array.to_list signed_commands_or_zkapps) + ~f:(fun b -> `Bool b) ) ) + ] ; + let fee = Fee.of_nanomina_int_exn 2_000_000 in + let amount = Amount.of_mina_int_exn 2 in + let mk_signed_command ~(fee_payer : Keypair.t) ~(receiver : Keypair.t) + ~(nonce : Account.Nonce.t) = + let body = + Signed_command_payload.Body.Payment + Payment_payload.Poly. + { receiver_pk = Public_key.compress receiver.public_key ; amount - ; zkapp_account_keypairs = [ new_kp ] - ; memo = Signed_command_memo.dummy - ; new_zkapp_account = false - ; snapp_update = - { Account_update.Update.dummy with - delegate = Zkapp_basic.Set_or_keep.Set zkapp_pk - } - ; current_auth = Permissions.Auth_required.Signature - ; call_data = Snark_params.Tick.Field.zero - ; events = [] - ; actions = [] - ; preconditions = None } - in - let%map zkapp_command = - Transaction_snark.For_tests.update_states - ~zkapp_prover_and_vk:(zkapp_prover, vk) - ~constraint_constants spec - in - let valid_zkapp_command = - Zkapp_command.Valid.to_valid ~status:Applied - ~find_vk: - (Zkapp_command.Verifiable.find_vk_via_ledger ~ledger - ~get:Ledger.get - ~location_of_account:Ledger.location_of_account ) - zkapp_command - |> Or_error.ok_exn - in - User_command.Zkapp_command valid_zkapp_command - in - let mk_user_command ~signed_command_or_zkapp ~fee_payer ~receiver - ~nonce = - match signed_command_or_zkapp with - | true -> - return @@ mk_signed_command ~fee_payer ~receiver ~nonce - | false -> - mk_zkapp_command ~fee_payer ~nonce - in - let fee_payer, _ = init_ledger.(0) in - let receiver, _ = init_ledger.(1) in - let%bind valid_command_1 = - mk_user_command - ~signed_command_or_zkapp:signed_commands_or_zkapps.(0) - ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 0) - and valid_command_2 = - mk_user_command - ~signed_command_or_zkapp:signed_commands_or_zkapps.(1) - ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 1) - and invalid_command_3 = - mk_user_command - ~signed_command_or_zkapp:signed_commands_or_zkapps.(2) - ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 99) - and valid_command_4 = - mk_user_command - ~signed_command_or_zkapp:signed_commands_or_zkapps.(3) - ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 2) - and invalid_command_5 = - mk_user_command - ~signed_command_or_zkapp:signed_commands_or_zkapps.(4) - ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 98) - in - let global_slot = - Mina_numbers.Global_slot_since_genesis.of_int global_slot - in - let current_state, current_state_view = - dummy_state_and_view ~global_slot () + in + let payload = + Signed_command.Payload.create ~fee + ~fee_payer_pk:Public_key.(compress fee_payer.public_key) + ~nonce ~memo:Signed_command_memo.dummy ~valid_until:None ~body + in + User_command.Signed_command (Signed_command.sign fee_payer payload) + in + let zkapp_pk = Public_key.compress new_kp.public_key in + let ledger = + Ledger.create ~depth:constraint_constants.ledger_depth () + in + Mina_transaction_logic.For_tests.Init_ledger.init + (module Ledger.Ledger_inner) + init_ledger ledger ; + Transaction_snark.For_tests.create_trivial_zkapp_account + ~permissions:Permissions.user_default ~vk ~ledger zkapp_pk ; + let sl = Sl.create_exn ~constraint_constants ~ledger in + let mk_zkapp_command ~(fee_payer : Keypair.t) + ~(nonce : Account.Nonce.t) = + let spec : Update_states_spec.t = + { sender = (new_kp, Account.Nonce.zero) + ; fee + ; fee_payer = Some (fee_payer, nonce) + ; receivers = [] + ; amount + ; zkapp_account_keypairs = [ new_kp ] + ; memo = Signed_command_memo.dummy + ; new_zkapp_account = false + ; snapp_update = + { Account_update.Update.dummy with + delegate = Zkapp_basic.Set_or_keep.Set zkapp_pk + } + ; current_auth = Permissions.Auth_required.Signature + ; call_data = Snark_params.Tick.Field.zero + ; events = [] + ; actions = [] + ; preconditions = None + } + in + let%map zkapp_command = + Transaction_snark.For_tests.update_states + ~zkapp_prover_and_vk:(zkapp_prover, vk) ~constraint_constants + spec + in + let valid_zkapp_command = + Zkapp_command.Valid.to_valid ~status:Applied + ~find_vk: + (Zkapp_command.Verifiable.find_vk_via_ledger ~ledger + ~get:Ledger.get + ~location_of_account:Ledger.location_of_account ) + zkapp_command + |> Or_error.ok_exn + in + User_command.Zkapp_command valid_zkapp_command + in + let mk_user_command ~signed_command_or_zkapp ~fee_payer ~receiver + ~nonce = + match signed_command_or_zkapp with + | true -> + return @@ mk_signed_command ~fee_payer ~receiver ~nonce + | false -> + mk_zkapp_command ~fee_payer ~nonce + in + let fee_payer, _ = init_ledger.(0) in + let receiver, _ = init_ledger.(1) in + let%bind valid_command_1 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(0) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 0) + and valid_command_2 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(1) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 1) + and invalid_command_3 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(2) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 99) + and valid_command_4 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(3) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 2) + and invalid_command_5 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(4) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 98) + in + let global_slot = + Mina_numbers.Global_slot_since_genesis.of_int global_slot + in + let current_state, current_state_view = + dummy_state_and_view ~global_slot () + in + let state_and_body_hash = + let state_hashes = Mina_state.Protocol_state.hashes current_state in + ( state_hashes.state_hash + , state_hashes.state_body_hash |> Option.value_exn ) + in + match + Sl.create_diff ~constraint_constants ~global_slot sl ~logger + ~current_state_view + ~transactions_by_fee: + (Sequence.of_list + [ valid_command_1 + ; valid_command_2 + ; invalid_command_3 + ; valid_command_4 + ; invalid_command_5 + ] ) + ~get_completed_work:(stmt_to_work_zero_fee ~prover:self_pk) + ~coinbase_receiver ~supercharge_coinbase:false + with + | Error e -> + Error.raise (Pre_diff_info.Error.to_error e) + | Ok (diff, invalid_txns) -> ( + let valid_commands = + Staged_ledger_diff.With_valid_signatures_and_proofs.commands + diff + |> List.map ~f:(fun { data; _ } -> + User_command.forget_check data ) in - let _state_and_body_hash = - let state_hashes = - Mina_state.Protocol_state.hashes current_state - in - ( state_hashes.state_hash - , state_hashes.state_body_hash |> Option.value_exn ) + assert ( + List.equal User_command.equal valid_commands + ( [ valid_command_1; valid_command_2; valid_command_4 ] + |> List.map ~f:(fun cmd -> User_command.forget_check cmd) ) ) ; + let invalid_commands = + List.map invalid_txns ~f:(fun (cmd, _) -> + User_command.forget_check cmd ) in - match - Sl.create_diff ~constraint_constants ~global_slot sl ~logger - ~current_state_view - ~transactions_by_fee: - (Sequence.of_list - [ valid_command_1 - ; valid_command_2 - ; invalid_command_3 - ; valid_command_4 - ; invalid_command_5 - ] ) - ~get_completed_work:(stmt_to_work_zero_fee ~prover:self_pk) + assert ( + List.equal User_command.equal invalid_commands + ( [ invalid_command_3; invalid_command_5 ] + |> List.map ~f:(fun cmd -> User_command.forget_check cmd) ) ) ; + + match%map + Sl.apply ~constraint_constants ~global_slot sl + (Staged_ledger_diff.forget diff) + ~logger ~verifier ~current_state_view ~state_and_body_hash ~coinbase_receiver ~supercharge_coinbase:false with + | Ok _x -> + () | Error e -> - Error.raise (Pre_diff_info.Error.to_error e) - | Ok (diff, invalid_txns) -> - let valid_commands = Staged_ledger_diff.With_valid_signatures_and_proofs.commands diff in - assert ( - List.length valid_commands - = 3) ; - assert (List.length invalid_txns = 2) ; - Deferred.unit - (* - match%map Sl.apply ~constraint_constants ~global_slot sl (Staged_ledger_diff.forget diff) - ~logger ~verifier ~current_state_view ~state_and_body_hash ~coinbase_receiver ~supercharge_coinbase:false - with - | Ok _x -> () - | Error e -> - [%log info] "Error %s" (Staged_ledger_error.to_string e) ; () - *) ) + [%log info] "Error %s" (Staged_ledger_error.to_string e) ; + () ) ) let%test_unit "Mismatched verification keys in zkApp accounts and \ transactions" = From 0de226a83e29de43188573025b818791e87ad776 Mon Sep 17 00:00:00 2001 From: Tang Jiawei Date: Wed, 20 Sep 2023 04:05:05 +0800 Subject: [PATCH 4/7] add one more txn to the staged_ledger_diff --- src/lib/staged_ledger/staged_ledger.ml | 60 ++++++++++++++------------ 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/src/lib/staged_ledger/staged_ledger.ml b/src/lib/staged_ledger/staged_ledger.ml index 1457f73a04c..d3bffb95418 100644 --- a/src/lib/staged_ledger/staged_ledger.ml +++ b/src/lib/staged_ledger/staged_ledger.ml @@ -4254,10 +4254,7 @@ let%test_module "staged ledger tests" = let open Quickcheck.Generator.Let_syntax in let%bind spec_keypair_and_slot = gen_spec_keypair_and_global_slot in let%map signed_commands_or_zkapps = - (* - return [false;true;false;true;true] - *) - List.gen_with_length 5 Bool.quickcheck_generator + List.gen_with_length 6 Bool.quickcheck_generator in (spec_keypair_and_slot, signed_commands_or_zkapps |> List.to_array) @@ -4277,10 +4274,10 @@ let%test_module "staged ledger tests" = (List.map (Array.to_list signed_commands_or_zkapps) ~f:(fun b -> `Bool b) ) ) ] ; - let fee = Fee.of_nanomina_int_exn 2_000_000 in - let amount = Amount.of_mina_int_exn 2 in + let default_fee = Fee.of_nanomina_int_exn 2_000_000 in + let default_amount = Amount.of_mina_int_exn 1 in let mk_signed_command ~(fee_payer : Keypair.t) ~(receiver : Keypair.t) - ~(nonce : Account.Nonce.t) = + ?(amount = default_amount) ~(nonce : Account.Nonce.t) () = let body = Signed_command_payload.Body.Payment Payment_payload.Poly. @@ -4289,7 +4286,7 @@ let%test_module "staged ledger tests" = } in let payload = - Signed_command.Payload.create ~fee + Signed_command.Payload.create ~fee:default_fee ~fee_payer_pk:Public_key.(compress fee_payer.public_key) ~nonce ~memo:Signed_command_memo.dummy ~valid_until:None ~body in @@ -4305,14 +4302,14 @@ let%test_module "staged ledger tests" = Transaction_snark.For_tests.create_trivial_zkapp_account ~permissions:Permissions.user_default ~vk ~ledger zkapp_pk ; let sl = Sl.create_exn ~constraint_constants ~ledger in - let mk_zkapp_command ~(fee_payer : Keypair.t) - ~(nonce : Account.Nonce.t) = + let mk_zkapp_command ~(fee_payer : Keypair.t) ?(fee = default_fee) + ~(nonce : Account.Nonce.t) () = let spec : Update_states_spec.t = { sender = (new_kp, Account.Nonce.zero) ; fee ; fee_payer = Some (fee_payer, nonce) ; receivers = [] - ; amount + ; amount = default_amount ; zkapp_account_keypairs = [ new_kp ] ; memo = Signed_command_memo.dummy ; new_zkapp_account = false @@ -4344,35 +4341,44 @@ let%test_module "staged ledger tests" = User_command.Zkapp_command valid_zkapp_command in let mk_user_command ~signed_command_or_zkapp ~fee_payer ~receiver - ~nonce = + ?amount ~nonce () = match signed_command_or_zkapp with | true -> - return @@ mk_signed_command ~fee_payer ~receiver ~nonce + return + @@ mk_signed_command ~fee_payer ~receiver ?amount ~nonce () | false -> - mk_zkapp_command ~fee_payer ~nonce + mk_zkapp_command ~fee_payer + ?fee: + (Option.map amount ~f:(fun amount -> Amount.to_fee amount)) + ~nonce () in let fee_payer, _ = init_ledger.(0) in let receiver, _ = init_ledger.(1) in let%bind valid_command_1 = mk_user_command ~signed_command_or_zkapp:signed_commands_or_zkapps.(0) - ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 0) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 0) () and valid_command_2 = mk_user_command ~signed_command_or_zkapp:signed_commands_or_zkapps.(1) - ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 1) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 1) () and invalid_command_3 = mk_user_command ~signed_command_or_zkapp:signed_commands_or_zkapps.(2) - ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 99) - and valid_command_4 = + ~fee_payer ~receiver ~amount:Amount.max_int + ~nonce:(Account.Nonce.of_int 2) () + and invalid_command_4 = mk_user_command ~signed_command_or_zkapp:signed_commands_or_zkapps.(3) - ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 2) - and invalid_command_5 = + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 3) () + and valid_command_5 = mk_user_command ~signed_command_or_zkapp:signed_commands_or_zkapps.(4) - ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 98) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 2) () + and invalid_command_6 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(5) + ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 4) () in let global_slot = Mina_numbers.Global_slot_since_genesis.of_int global_slot @@ -4393,8 +4399,9 @@ let%test_module "staged ledger tests" = [ valid_command_1 ; valid_command_2 ; invalid_command_3 - ; valid_command_4 - ; invalid_command_5 + ; invalid_command_4 + ; valid_command_5 + ; invalid_command_6 ] ) ~get_completed_work:(stmt_to_work_zero_fee ~prover:self_pk) ~coinbase_receiver ~supercharge_coinbase:false @@ -4410,16 +4417,13 @@ let%test_module "staged ledger tests" = in assert ( List.equal User_command.equal valid_commands - ( [ valid_command_1; valid_command_2; valid_command_4 ] + ( [ valid_command_1; valid_command_2; valid_command_5 ] |> List.map ~f:(fun cmd -> User_command.forget_check cmd) ) ) ; let invalid_commands = List.map invalid_txns ~f:(fun (cmd, _) -> User_command.forget_check cmd ) in - assert ( - List.equal User_command.equal invalid_commands - ( [ invalid_command_3; invalid_command_5 ] - |> List.map ~f:(fun cmd -> User_command.forget_check cmd) ) ) ; + assert (List.length invalid_commands = 3) ; match%map Sl.apply ~constraint_constants ~global_slot sl From 166b6ba62b0b5c23946a8ad0cc96537433448179 Mon Sep 17 00:00:00 2001 From: Tang Jiawei Date: Wed, 20 Sep 2023 04:18:43 +0800 Subject: [PATCH 5/7] clean up a little bit --- src/lib/staged_ledger/staged_ledger.ml | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/lib/staged_ledger/staged_ledger.ml b/src/lib/staged_ledger/staged_ledger.ml index d3bffb95418..a7e0c93d67c 100644 --- a/src/lib/staged_ledger/staged_ledger.ml +++ b/src/lib/staged_ledger/staged_ledger.ml @@ -4256,7 +4256,6 @@ let%test_module "staged ledger tests" = let%map signed_commands_or_zkapps = List.gen_with_length 6 Bool.quickcheck_generator in - (spec_keypair_and_slot, signed_commands_or_zkapps |> List.to_array) in Async.Thread_safe.block_on_async_exn @@ -4267,6 +4266,16 @@ let%test_module "staged ledger tests" = , signed_commands_or_zkapps ) -> let open Transaction_snark.For_tests in + let zkapp_pk = Public_key.compress new_kp.public_key in + let ledger = + Ledger.create ~depth:constraint_constants.ledger_depth () + in + Mina_transaction_logic.For_tests.Init_ledger.init + (module Ledger.Ledger_inner) + init_ledger ledger ; + Transaction_snark.For_tests.create_trivial_zkapp_account + ~permissions:Permissions.user_default ~vk ~ledger zkapp_pk ; + let sl = Sl.create_exn ~constraint_constants ~ledger in [%log info] "signed commands or zkapps" ~metadata: [ ( "signed_commands_or_zkapps" @@ -4292,16 +4301,6 @@ let%test_module "staged ledger tests" = in User_command.Signed_command (Signed_command.sign fee_payer payload) in - let zkapp_pk = Public_key.compress new_kp.public_key in - let ledger = - Ledger.create ~depth:constraint_constants.ledger_depth () - in - Mina_transaction_logic.For_tests.Init_ledger.init - (module Ledger.Ledger_inner) - init_ledger ledger ; - Transaction_snark.For_tests.create_trivial_zkapp_account - ~permissions:Permissions.user_default ~vk ~ledger zkapp_pk ; - let sl = Sl.create_exn ~constraint_constants ~ledger in let mk_zkapp_command ~(fee_payer : Keypair.t) ?(fee = default_fee) ~(nonce : Account.Nonce.t) () = let spec : Update_states_spec.t = From 32a6423464f67ee71e3ab59008cab1953f1386f9 Mon Sep 17 00:00:00 2001 From: Tang Jiawei Date: Fri, 22 Sep 2023 03:54:52 +0800 Subject: [PATCH 6/7] add cases for invalid blocks --- src/lib/staged_ledger/staged_ledger.ml | 76 ++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/src/lib/staged_ledger/staged_ledger.ml b/src/lib/staged_ledger/staged_ledger.ml index a7e0c93d67c..db81bd7325a 100644 --- a/src/lib/staged_ledger/staged_ledger.ml +++ b/src/lib/staged_ledger/staged_ledger.ml @@ -4254,7 +4254,7 @@ let%test_module "staged ledger tests" = let open Quickcheck.Generator.Let_syntax in let%bind spec_keypair_and_slot = gen_spec_keypair_and_global_slot in let%map signed_commands_or_zkapps = - List.gen_with_length 6 Bool.quickcheck_generator + List.gen_with_length 7 Bool.quickcheck_generator in (spec_keypair_and_slot, signed_commands_or_zkapps |> List.to_array) in @@ -4352,6 +4352,7 @@ let%test_module "staged ledger tests" = ~nonce () in let fee_payer, _ = init_ledger.(0) in + let fee_payer1, _ = init_ledger.(2) in let receiver, _ = init_ledger.(1) in let%bind valid_command_1 = mk_user_command @@ -4378,6 +4379,10 @@ let%test_module "staged ledger tests" = mk_user_command ~signed_command_or_zkapp:signed_commands_or_zkapps.(5) ~fee_payer ~receiver ~nonce:(Account.Nonce.of_int 4) () + and valid_command_7 = + mk_user_command + ~signed_command_or_zkapp:signed_commands_or_zkapps.(6) + ~fee_payer:fee_payer1 ~receiver ~nonce:(Account.Nonce.of_int 0) () in let global_slot = Mina_numbers.Global_slot_since_genesis.of_int global_slot @@ -4401,6 +4406,7 @@ let%test_module "staged ledger tests" = ; invalid_command_4 ; valid_command_5 ; invalid_command_6 + ; valid_command_7 ] ) ~get_completed_work:(stmt_to_work_zero_fee ~prover:self_pk) ~coinbase_receiver ~supercharge_coinbase:false @@ -4416,25 +4422,71 @@ let%test_module "staged ledger tests" = in assert ( List.equal User_command.equal valid_commands - ( [ valid_command_1; valid_command_2; valid_command_5 ] + ( [ valid_command_1 + ; valid_command_2 + ; valid_command_5 + ; valid_command_7 + ] |> List.map ~f:(fun cmd -> User_command.forget_check cmd) ) ) ; - let invalid_commands = - List.map invalid_txns ~f:(fun (cmd, _) -> - User_command.forget_check cmd ) - in - assert (List.length invalid_commands = 3) ; - - match%map + assert (List.length invalid_txns = 3) ; + match%bind Sl.apply ~constraint_constants ~global_slot sl (Staged_ledger_diff.forget diff) ~logger ~verifier ~current_state_view ~state_and_body_hash ~coinbase_receiver ~supercharge_coinbase:false with - | Ok _x -> - () + | Ok _x -> ( + let valid_command_1_with_status = + With_status. + { data = valid_command_1 + ; status = Transaction_status.Applied + } + in + let invalid_command_3_with_status = + With_status. + { data = invalid_command_3 + ; status = Transaction_status.Applied + } + in + let invalid_command_4_with_status = + With_status. + { data = invalid_command_4 + ; status = Transaction_status.Applied + } + in + let valid_command_7_with_status = + With_status. + { data = valid_command_7 + ; status = Transaction_status.Applied + } + in + let f, s = diff.diff in + let diff = + { Staged_ledger_diff.With_valid_signatures_and_proofs.diff = + ( { f with + commands = + [ valid_command_1_with_status + ; invalid_command_3_with_status + ; invalid_command_4_with_status + ; valid_command_7_with_status + ] + } + , s ) + } + in + match%map + Sl.apply ~constraint_constants ~global_slot sl + (Staged_ledger_diff.forget diff) + ~logger ~verifier ~current_state_view ~state_and_body_hash + ~coinbase_receiver ~supercharge_coinbase:false + with + | Ok _x -> + assert false + | Error _e -> + assert true ) | Error e -> [%log info] "Error %s" (Staged_ledger_error.to_string e) ; - () ) ) + assert false ) ) let%test_unit "Mismatched verification keys in zkApp accounts and \ transactions" = From 9a93042884424e12738664f6ec9cc0e1dd4e704f Mon Sep 17 00:00:00 2001 From: Tang Jiawei Date: Fri, 22 Sep 2023 04:25:45 +0800 Subject: [PATCH 7/7] fix compilation error --- src/lib/staged_ledger/staged_ledger.ml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib/staged_ledger/staged_ledger.ml b/src/lib/staged_ledger/staged_ledger.ml index 5ff9d29e173..54f53f8c705 100644 --- a/src/lib/staged_ledger/staged_ledger.ml +++ b/src/lib/staged_ledger/staged_ledger.ml @@ -4490,8 +4490,9 @@ let%test_module "staged ledger tests" = match%bind Sl.apply ~constraint_constants ~global_slot sl (Staged_ledger_diff.forget diff) - ~logger ~verifier ~current_state_view ~state_and_body_hash - ~coinbase_receiver ~supercharge_coinbase:false + ~logger ~verifier ~get_completed_work:(Fn.const None) + ~current_state_view ~state_and_body_hash ~coinbase_receiver + ~supercharge_coinbase:false with | Ok _x -> ( let valid_command_1_with_status = @@ -4535,7 +4536,8 @@ let%test_module "staged ledger tests" = match%map Sl.apply ~constraint_constants ~global_slot sl (Staged_ledger_diff.forget diff) - ~logger ~verifier ~current_state_view ~state_and_body_hash + ~logger ~verifier ~get_completed_work:(Fn.const None) + ~current_state_view ~state_and_body_hash ~coinbase_receiver ~supercharge_coinbase:false with | Ok _x ->