diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 91fcfc55f07c563d038e7c984c5c8b6b03d436a5..5c1903f5189ef8e9301a054daedabb0465294689 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -6,6 +6,7 @@ (* Copyright (c) 2021-2022 Nomadic Labs *) (* Copyright (c) 2022 Trili Tech *) (* Copyright (c) 2022 DaiLambda, Inc. *) +(* Copyright (c) 2024 Marigold, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -2331,10 +2332,48 @@ let rec parse_data : traced_fail (Invalid_kind (location expr, [Seq_kind], kind expr)) (* Tickets *) | Ticket_t (t, _ty_name), expr -> + (* This local function handles the case of parsing the `Ticket` data constructor. *) + let parse_ticket loc ticketer contents_type contents amount = + (* Ensure that the content type provided in the ticket constructor + matches the ticket type expected by the entrypoint. *) + let*? Ex_ty expected, ctxt = + parse_any_ty ctxt ~stack_depth:(stack_depth + 1) ~legacy contents_type + in + let*? eq, ctxt = + Gas_monad.run ctxt + @@ + let error_details = Informative loc in + ty_eq ~error_details t expected + in + let*? Eq = eq in + let* {destination; entrypoint = _}, ctxt = + non_terminal_recursion ctxt address_t ticketer + in + let* contents, ctxt = non_terminal_recursion ctxt t contents in + let+ amount, ctxt = non_terminal_recursion ctxt nat_t amount in + ((destination, contents, amount), ctxt) + in if allow_forged then - let*? ty = opened_ticket_type (location expr) t in - let* ({destination; entrypoint = _}, (contents, amount)), ctxt = - non_terminal_recursion ctxt ty expr + let* (destination, contents, amount), ctxt = + match expr with + | Prim + ( loc, + D_Ticket, + [ticketer; contents_type; contents; amount], + _annot ) -> + parse_ticket loc ticketer contents_type contents amount + | Prim (_, D_Pair, _, _) -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/6833 + + In the future, this [D_Pair] constructor must + be allowed only when the legacy flag is set to true. *) + let*? ty = opened_ticket_type (location expr) t in + let+ ({destination; entrypoint = _}, (contents, amount)), ctxt = + non_terminal_recursion ctxt ty expr + in + ((destination, contents, amount), ctxt) + | _ -> + tzfail @@ unexpected expr [] Constant_namespace [D_Ticket; D_Pair] in match Ticket_amount.of_n amount with | Some amount -> ( diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_direct_spending.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_direct_spending.ml index 045e6f86fd3c089212d406bc3b3aeed2167d9e41..84e95dca4f7e1e9f99be9b91738c4844426e6075 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_direct_spending.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_direct_spending.ml @@ -2,7 +2,7 @@ (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2023 Nomadic Labs *) -(* Copyright (c) 2023 Marigold *) +(* Copyright (c) 2023-2024 Marigold *) (* *) (*****************************************************************************) @@ -17,6 +17,8 @@ open Protocol open Alpha_context +type constructor = Pair | Ticket + let originate_contract ~code ~storage originator block = let open Lwt_result_syntax in let storage = Script.lazy_expr (Expr.from_string storage) in @@ -97,7 +99,7 @@ code resulting in an updated balance in the ticket table. - If disabled: The transfer attempt should fail, triggering a [Bad_contract_parameter] error. *) -let test_spending ~direct_ticket_spending_enable () = +let test_spending ~direct_ticket_spending_enable ~constructor () = let open Lwt_result_syntax in let constants = let default_constants = @@ -145,7 +147,11 @@ let test_spending ~direct_ticket_spending_enable () = (Destination.Contract implicit) block in - let arg = sf "Pair %S Unit 1" boomerang_str in + let arg = + match constructor with + | Pair -> sf "Pair %S Unit 1" boomerang_str + | Ticket -> sf "Ticket %S unit Unit 1" boomerang_str + in if direct_ticket_spending_enable then let* block = call_contract ~source:implicit ~contract:consumer ~arg block in assert_ticket_balance @@ -163,13 +169,25 @@ let test_spending ~direct_ticket_spending_enable () = let tests = [ Tztest.tztest - "Test ticket spending from implicit accounts (feature enabled)" + "Test ticket spending from implicit accounts (feature enabled) with Pair \ + ticket constructor" + `Quick + (test_spending ~direct_ticket_spending_enable:true ~constructor:Pair); + Tztest.tztest + "Test ticket spending from implicit accounts (feature disabled) with \ + Pair ticket constructor" + `Quick + (test_spending ~direct_ticket_spending_enable:false ~constructor:Pair); + Tztest.tztest + "Test ticket spending from implicit accounts (feature enabled) with \ + Ticket constructor" `Quick - (test_spending ~direct_ticket_spending_enable:true); + (test_spending ~direct_ticket_spending_enable:true ~constructor:Ticket); Tztest.tztest - "Test ticket spending from implicit accounts (feature disabled)" + "Test ticket spending from implicit accounts (feature disabled) with \ + Ticket constructor" `Quick - (test_spending ~direct_ticket_spending_enable:false); + (test_spending ~direct_ticket_spending_enable:false ~constructor:Ticket); ] let () = diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_scanner.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_scanner.ml index f5a6f50d7a3359ae2793eb59026175ddb2ec9d36..69a3271057533fabc566d4d309675a6f21beb4da 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_scanner.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_scanner.ml @@ -3,6 +3,7 @@ (* Open Source License *) (* Copyright (c) 2021 Trili Tech, *) (* Copyright (c) 2022 Nomadic Labs, *) +(* Copyright (c) 2024 Marigold, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -285,7 +286,9 @@ let test_tickets_in_unit_ticket () = let open Lwt_result_wrap_syntax in let* ctxt = new_ctxt () in let type_exp = "ticket(unit)" in - let value_exp = {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" Unit 10|} in + let value_exp = + {|Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" unit Unit 10|} + in let* ex_ticket, ctxt = make_ex_ticket ctxt @@ -317,10 +320,10 @@ let test_tickets_in_list_with_zero_amount () = ~value_exp: {| { - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 3; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "orange" 0; + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1; + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 2; + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "blue" 3; + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "orange" 0; } |} @@ -333,9 +336,9 @@ let test_tickets_in_list () = ~value_exp: {| { - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 3; + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1; + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 2; + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "blue" 3; } |} ~expected: @@ -353,9 +356,9 @@ let test_tickets_in_pair_with_zero_amount () = ~value_exp: {| Pair - (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1) - (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2) - (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 0) + (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1) + (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 2) + (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "blue" 0) |} (** Test that all tickets can be extracted from a pair of tickets *) @@ -367,8 +370,8 @@ let test_tickets_in_pair () = ~value_exp: {| Pair - (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1) - (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2) + (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1) + (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 2) |} ~expected: [ @@ -384,9 +387,9 @@ let test_tickets_in_map_with_zero_amount () = ~value_exp: {| { - Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); - Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2); - Elt 3 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 0); + Elt 1 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1); + Elt 2 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 2); + Elt 3 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "blue" 0); } |} @@ -399,8 +402,8 @@ let test_tickets_in_map () = ~value_exp: {| { - Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); - Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2); + Elt 1 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1); + Elt 2 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 2); } |} ~expected: @@ -424,8 +427,8 @@ let test_tickets_in_big_map () = ~value_exp: {| { - Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); - Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2); + Elt 1 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1); + Elt 2 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 2); } |} @@ -439,9 +442,9 @@ let test_tickets_in_big_map_strict_only () = ~value_exp: {| { - Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); - Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 2); - Elt 3 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 3); + Elt 1 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1); + Elt 2 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 2); + Elt 3 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "blue" 3); } |} ~expected:[] @@ -462,12 +465,12 @@ let test_tickets_in_list_in_big_map () = {| { Elt 1 { - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1 ; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1 + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1; + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 1 }; Elt 2 { - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1 ; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "orange" 1 + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "blue" 1; + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "orange" 1 } } |} @@ -483,12 +486,12 @@ let test_tickets_in_pair_big_map_and_list_strict_only () = {| Pair { - Elt 1 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1); - Elt 2 (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1) + Elt 1 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1); + Elt 2 (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 1) } { - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1; - Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "orange" 1 + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "blue" 1; + Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "orange" 1 } |} ~expected: @@ -503,7 +506,8 @@ let test_tickets_in_or_left () = ~loc:__LOC__ ~include_lazy:false ~type_exp:"or (ticket string) int" - ~value_exp:{| Left (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1) |} + ~value_exp: + {| Left (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1) |} ~expected:[("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1)] (** Test that tickets from the left side of an or-expression with zero amount @@ -513,7 +517,8 @@ let test_tickets_in_or_left_with_zero_amount () = ~loc:__LOC__ ~include_lazy:false ~type_exp:"or (ticket string) int" - ~value_exp:{| Left (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 0) |} + ~value_exp: + {| Left (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 0) |} (** Test that tickets can be extracted from the right side of an or-expression. *) let test_tickets_in_or_right () = @@ -521,7 +526,8 @@ let test_tickets_in_or_right () = ~loc:__LOC__ ~include_lazy:false ~type_exp:"or int (ticket string)" - ~value_exp:{| Right (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1) |} + ~value_exp: + {| Right (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1) |} ~expected:[("KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq", "red", 1)] (* @@ -549,9 +555,9 @@ let test_tickets_in_non_empty_big_map_ref () = ~loc:__LOC__ ~pre_populated: [ - (1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|}); - (2, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1|}); - (3, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1|}); + (1, {|Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1|}); + (2, {|Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 1|}); + (3, {|Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "blue" 1|}); ] ~big_map_exp:(Printf.sprintf "%s") [ @@ -573,7 +579,7 @@ let test_tickets_overlay_in_empty_big_map_ref () = ~pre_populated:[] ~big_map_exp: (Printf.sprintf - {|Pair %s { Elt 1 (Some (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1))}|}) + {|Pair %s { Elt 1 (Some (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1))}|}) (** Test tickets from non-empty big-map when passed as a pair of identifier and overrides. The scanned tickets are contained in the context as well as @@ -588,15 +594,15 @@ let test_tickets_overlay_in_non_empty_in_big_map_ref () = ~loc:__LOC__ ~pre_populated: [ - (1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|}); - (2, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1|}); - (3, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "blue" 1|}); + (1, {|Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1|}); + (2, {|Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 1|}); + (3, {|Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "blue" 1|}); ] ~big_map_exp: (Printf.sprintf {| Pair %s - { Elt 4 (Some (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "orange" 1))} + { Elt 4 (Some (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "orange" 1))} |}) (** Test tickets from non-empty big-map when passed as a pair of identifier @@ -610,12 +616,12 @@ let test_tickets_replace_overlay_in_non_empty_in_big_map_ref () = assert_fail_non_empty_overlay_with_big_map_ref ~loc:__LOC__ ~pre_populated: - [(1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|})] + [(1, {|Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1|})] ~big_map_exp: (Printf.sprintf {| Pair %s - { Elt 1 (Some (Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "green" 1))} + { Elt 1 (Some (Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "green" 1))} |}) (** Test tickets from non-empty big-map when passed as a pair of identifier @@ -629,7 +635,7 @@ let test_tickets_remove_overlay_in_non_empty_in_big_map_ref () = assert_fail_non_empty_overlay_with_big_map_ref ~loc:__LOC__ ~pre_populated: - [(1, {|Pair "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" "red" 1|})] + [(1, {|Ticket "KT1ThEdxfUcWUwqsdergy3QnbCWGHSUHeHJq" string "red" 1|})] ~big_map_exp:(Printf.sprintf {| Pair %s { Elt 1 None} |}) let tests = diff --git a/tezt/tests/expected/tickets.ml/Alpha- Send tickets from implicit account to originated directly (with complex p.out b/tezt/tests/expected/tickets.ml/Alpha- Send Pair tickets (with complex parameters) from implicit account to orig.out similarity index 74% rename from tezt/tests/expected/tickets.ml/Alpha- Send tickets from implicit account to originated directly (with complex p.out rename to tezt/tests/expected/tickets.ml/Alpha- Send Pair tickets (with complex parameters) from implicit account to orig.out index 1a42e9eca0d4707246eabe896634fff81a5ec0ff..2f058a677b5e96f2b59e318340b11278147bb000 100644 --- a/tezt/tests/expected/tickets.ml/Alpha- Send tickets from implicit account to originated directly (with complex p.out +++ b/tezt/tests/expected/tickets.ml/Alpha- Send Pair tickets (with complex parameters) from implicit account to orig.out @@ -1,7 +1,7 @@ -./octez-client --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --entrypoint store --arg 'Pair 99 {Pair "garbage" (Pair 0x01b9ce1609aab1100170d2ea4f94e3407244090b1000 (Pair "Ticket1" 1)) ; Pair "garbage" (Pair 0x01b9ce1609aab1100170d2ea4f94e3407244090b1000 (Pair "Ticket2" 2))}' +./octez-client --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --entrypoint store --arg 'Pair 99 {Pair "garbage" (Ticket "[CONTRACT_HASH]" string "Ticket1" 1) ; Pair "garbage" (Ticket "[CONTRACT_HASH]" string "Ticket2" 2)}' Node is bootstrapped. -Estimated gas: 3992.854 units (will add 100 for safety) +Estimated gas: 4002.105 units (will add 100 for safety) Estimated storage: 222 bytes added (will add 20 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -12,28 +12,28 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.000798 + Fee to the baker: ꜩ0.000843 Expected counter: 4 - Gas limit: 4093 + Gas limit: 4103 Storage limit: 242 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.000798 - payload fees(the block proposer) ....... +ꜩ0.000798 + [PUBLIC_KEY_HASH] ... -ꜩ0.000843 + payload fees(the block proposer) ....... +ꜩ0.000843 Transaction: Amount: ꜩ0 From: [PUBLIC_KEY_HASH] To: [CONTRACT_HASH] Entrypoint: store Parameter: (Pair 99 - { Pair "garbage" (Pair 0x01b9ce1609aab1100170d2ea4f94e3407244090b1000 (Pair "Ticket1" 1)) ; - Pair "garbage" (Pair 0x01b9ce1609aab1100170d2ea4f94e3407244090b1000 (Pair "Ticket2" 2)) }) + { Pair "garbage" (Ticket "[CONTRACT_HASH]" string "Ticket1" 1) ; + Pair "garbage" (Ticket "[CONTRACT_HASH]" string "Ticket2" 2) }) This transaction was successfully applied Updated storage: { Pair 0x01b9ce1609aab1100170d2ea4f94e3407244090b1000 (Pair "Ticket2" 2) ; Pair 0x01b9ce1609aab1100170d2ea4f94e3407244090b1000 (Pair "Ticket1" 1) } Storage size: 287 bytes Paid storage size diff: 222 bytes - Consumed gas: 3992.821 + Consumed gas: 4002.072 Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ0.0555 storage fees ........................... +ꜩ0.0555 diff --git a/tezt/tests/expected/tickets.ml/Alpha- Send tickets from implicit account to originated directly.out b/tezt/tests/expected/tickets.ml/Alpha- Send Pair tickets from implicit account to originated directly.out similarity index 75% rename from tezt/tests/expected/tickets.ml/Alpha- Send tickets from implicit account to originated directly.out rename to tezt/tests/expected/tickets.ml/Alpha- Send Pair tickets from implicit account to originated directly.out index 76db476257d43896f60143ef0b4e2b034fa4280f..389d746909821248ebed51a617d4d1f592040a16 100644 --- a/tezt/tests/expected/tickets.ml/Alpha- Send tickets from implicit account to originated directly.out +++ b/tezt/tests/expected/tickets.ml/Alpha- Send Pair tickets from implicit account to originated directly.out @@ -1,7 +1,7 @@ -./octez-client --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --entrypoint save --arg 'Pair 0x01fb08747351ab3652f772910c4565880d8df616f800 (Pair "Ticket" 1)' +./octez-client --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --entrypoint save --arg 'Pair "[CONTRACT_HASH]" (Pair "Ticket" 1)' Node is bootstrapped. -Estimated gas: 3077.335 units (will add 100 for safety) +Estimated gas: 3081.619 units (will add 100 for safety) Estimated storage: 44 bytes added (will add 20 for safety) Operation successfully injected in the node. Operation hash is '[OPERATION_HASH]' @@ -12,25 +12,25 @@ and/or an external block explorer to make sure that it has been included. This sequence of operations was run: Manager signed operations: From: [PUBLIC_KEY_HASH] - Fee to the baker: ꜩ0.00062 + Fee to the baker: ꜩ0.000635 Expected counter: 4 - Gas limit: 3178 + Gas limit: 3182 Storage limit: 64 bytes Balance updates: - [PUBLIC_KEY_HASH] ... -ꜩ0.00062 - payload fees(the block proposer) ....... +ꜩ0.00062 + [PUBLIC_KEY_HASH] ... -ꜩ0.000635 + payload fees(the block proposer) ....... +ꜩ0.000635 Transaction: Amount: ꜩ0 From: [PUBLIC_KEY_HASH] To: [CONTRACT_HASH] Entrypoint: save - Parameter: (Pair 0x01fb08747351ab3652f772910c4565880d8df616f800 (Pair "Ticket" 1)) + Parameter: (Pair "[CONTRACT_HASH]" (Pair "Ticket" 1)) This transaction was successfully applied Updated storage: { Pair 0x01fb08747351ab3652f772910c4565880d8df616f800 (Pair "Ticket" 1) } Storage size: 238 bytes Paid storage size diff: 44 bytes - Consumed gas: 3077.269 + Consumed gas: 3081.553 Balance updates: [PUBLIC_KEY_HASH] ... -ꜩ0.011 storage fees ........................... +ꜩ0.011 diff --git a/tezt/tests/expected/tickets.ml/Alpha- Send tickets with Ticket constructor (with complex parameters) from impli.out b/tezt/tests/expected/tickets.ml/Alpha- Send tickets with Ticket constructor (with complex parameters) from impli.out new file mode 100644 index 0000000000000000000000000000000000000000..e26b3fd990682d6c9890320b95703cf56b0e3e9d --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Send tickets with Ticket constructor (with complex parameters) from impli.out @@ -0,0 +1,61 @@ + +./octez-client --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --entrypoint store --arg 'Pair 99 {Pair "garbage" (Pair "[CONTRACT_HASH]" (Pair "Ticket1" 1)) ; Pair "garbage" (Pair "[CONTRACT_HASH]" (Pair "Ticket2" 2))}' +Node is bootstrapped. +Estimated gas: 4001.421 units (will add 100 for safety) +Estimated storage: 222 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + octez-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000827 + Expected counter: 4 + Gas limit: 4102 + Storage limit: 242 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000827 + payload fees(the block proposer) ....... +ꜩ0.000827 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Entrypoint: store + Parameter: (Pair 99 + { Pair "garbage" (Pair "[CONTRACT_HASH]" (Pair "Ticket1" 1)) ; + Pair "garbage" (Pair "[CONTRACT_HASH]" (Pair "Ticket2" 2)) }) + This transaction was successfully applied + Updated storage: + { Pair 0x01b9ce1609aab1100170d2ea4f94e3407244090b1000 (Pair "Ticket2" 2) ; + Pair 0x01b9ce1609aab1100170d2ea4f94e3407244090b1000 (Pair "Ticket1" 1) } + Storage size: 287 bytes + Paid storage size diff: 222 bytes + Consumed gas: 4001.388 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0555 + storage fees ........................... +ꜩ0.0555 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket1" + Account updates: + [PUBLIC_KEY_HASH] ... -1 + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket2" + Account updates: + [PUBLIC_KEY_HASH] ... -2 + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket2" + Account updates: + [CONTRACT_HASH] ... +2 + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket1" + Account updates: + [CONTRACT_HASH] ... +1 + diff --git a/tezt/tests/expected/tickets.ml/Alpha- Send tickets with Ticket constructor from implicit account to originated .out b/tezt/tests/expected/tickets.ml/Alpha- Send tickets with Ticket constructor from implicit account to originated .out new file mode 100644 index 0000000000000000000000000000000000000000..f228d2fbf1efa99679990fd69a22d312414d5e8f --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Send tickets with Ticket constructor from implicit account to originated .out @@ -0,0 +1,48 @@ + +./octez-client --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --entrypoint save --arg 'Ticket "[CONTRACT_HASH]" string "Ticket" 1' +Node is bootstrapped. +Estimated gas: 3081.961 units (will add 100 for safety) +Estimated storage: 44 bytes added (will add 20 for safety) +Operation successfully injected in the node. +Operation hash is '[OPERATION_HASH]' +NOT waiting for the operation to be included. +Use command + octez-client wait for [OPERATION_HASH] to be included --confirmations 1 --branch [BLOCK_HASH] +and/or an external block explorer to make sure that it has been included. +This sequence of operations was run: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0.000643 + Expected counter: 4 + Gas limit: 3182 + Storage limit: 64 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000643 + payload fees(the block proposer) ....... +ꜩ0.000643 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Entrypoint: save + Parameter: (Ticket "[CONTRACT_HASH]" string "Ticket" 1) + This transaction was successfully applied + Updated storage: + { Pair 0x01fb08747351ab3652f772910c4565880d8df616f800 (Pair "Ticket" 1) } + Storage size: 238 bytes + Paid storage size diff: 44 bytes + Consumed gas: 3081.895 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.011 + storage fees ........................... +ꜩ0.011 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [PUBLIC_KEY_HASH] ... -1 + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [CONTRACT_HASH] ... +1 + diff --git a/tezt/tests/tickets.ml b/tezt/tests/tickets.ml index 2345c5b9074b668159361d24ecdb7d2eab1a0af6..9d287951c0ae99e3534ee7e4e3c26145f72a4553 100644 --- a/tezt/tests/tickets.ml +++ b/tezt/tests/tickets.ml @@ -2,7 +2,7 @@ (* *) (* Open Source License *) (* Copyright (c) 2020 Nomadic Labs *) -(* Copyright (c) 2022 Marigold *) +(* Copyright (c) 2022-2024 Marigold *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) (* copy of this software and associated documentation files (the "Software"),*) @@ -31,8 +31,6 @@ Subject: Regression tests for tickets *) -open Tezos_protocol_alpha.Protocol - let hooks = Tezos_regression.hooks let setup_node protocol ~direct_ticket_spending_enable = @@ -51,17 +49,11 @@ let setup_node protocol ~direct_ticket_spending_enable = return (node, client) (* Return micheline encoding of ticket. *) -let encode_ticket ~ticketer ~content ~amount = - let ticketer_contract = - Result.get_ok (Alpha_context.Contract.of_b58check ticketer) - in - let ticketer_bytes = - Data_encoding.Binary.to_bytes_exn - Alpha_context.Contract.encoding - ticketer_contract - in - let encoded_ticketer = Hex.show (Hex.of_bytes ticketer_bytes) in - sf {|Pair 0x%s (Pair %S %d)|} encoded_ticketer content amount +let encode_pair_ticket ~ticketer ~content ~amount = + sf {|Pair %S (Pair %S %d)|} ticketer content amount + +let encode_string_ticket ~ticketer ~content ~amount = + sf {|Ticket %S string %S %d|} ticketer content amount let test_create_and_remove_tickets = Protocol.register_regression_test @@ -243,13 +235,8 @@ let test_send_tickets_to_implicit_account = (* Tests that an implicit account can send a single ticket to originated using the [Transfer] manager operation. *) -let test_direct_transfer_tickets_from_implicit_account_to_originated = - Protocol.register_regression_test - ~__FILE__ - ~title:"Send tickets from implicit account to originated directly" - ~tags:["client"; "michelson"; "implicit"; "ticket"; "originated"] - ~supports:(Protocol.From_protocol 19) - @@ fun protocol -> +let test_direct_transfer_tickets_from_implicit_account_to_originated + ~encode_ticket protocol = let* _node, client = setup_node protocol ~direct_ticket_spending_enable:true in @@ -330,19 +317,38 @@ let test_direct_transfer_tickets_from_implicit_account_to_originated = in unit -(* Tests that an implicit account can send a tickets to originated - using the [Transfer] manager operation. The parameter of the - transfer is made complex to check that the [Transfer] properly - scans the parameter and transfers all included tickets. *) -let test_direct_transfer_tickets_from_implicit_account_to_originated_complex = +let test_direct_transfer_tickets_from_implicit_account_to_originated_with_pair_constructor + = + Protocol.register_regression_test + ~__FILE__ + ~title:"Send Pair tickets from implicit account to originated directly" + ~tags:["client"; "michelson"; "implicit"; "ticket"; "originated"] + ~supports:(Protocol.From_protocol 19) + @@ fun protocol -> + test_direct_transfer_tickets_from_implicit_account_to_originated + protocol + ~encode_ticket:encode_pair_ticket + +let test_direct_transfer_tickets_from_implicit_account_to_originated_with_ticket_constructor + = Protocol.register_regression_test ~__FILE__ ~title: - "Send tickets from implicit account to originated directly (with complex \ - parameters)" + "Send tickets with Ticket constructor from implicit account to \ + originated directly" ~tags:["client"; "michelson"; "implicit"; "ticket"; "originated"] ~supports:(Protocol.From_protocol 19) @@ fun protocol -> + test_direct_transfer_tickets_from_implicit_account_to_originated + protocol + ~encode_ticket:encode_string_ticket + +(* Tests that an implicit account can send a tickets to originated + using the [Transfer] manager operation. The parameter of the + transfer is made complex to check that the [Transfer] properly + scans the parameter and transfers all included tickets. *) +let test_direct_transfer_tickets_from_implicit_account_to_originated_complex + ~encode_ticket protocol = let* _node, client = setup_node protocol ~direct_ticket_spending_enable:true in @@ -480,6 +486,34 @@ let test_direct_transfer_tickets_from_implicit_account_to_originated_complex = in unit +let test_direct_transfer_tickets_from_implicit_account_to_originated_complex_with_ticket_constructor + = + Protocol.register_regression_test + ~__FILE__ + ~title: + "Send tickets with Ticket constructor (with complex parameters) from \ + implicit account to originated directly" + ~tags:["client"; "michelson"; "implicit"; "ticket"; "originated"] + ~supports:(Protocol.From_protocol 19) + @@ fun protocol -> + test_direct_transfer_tickets_from_implicit_account_to_originated_complex + protocol + ~encode_ticket:encode_pair_ticket + +let test_direct_transfer_tickets_from_implicit_account_to_originated_complex_with_pair_constructor + = + Protocol.register_regression_test + ~__FILE__ + ~title: + "Send Pair tickets (with complex parameters) from implicit account to \ + originated directly" + ~tags:["client"; "michelson"; "implicit"; "ticket"; "originated"] + ~supports:(Protocol.From_protocol 19) + @@ fun protocol -> + test_direct_transfer_tickets_from_implicit_account_to_originated_complex + protocol + ~encode_ticket:encode_string_ticket + (* This test originates one contract which mints and sends tickets to the address passed in the parameter. In this test, the receiver of the ticket is an implicit account *) @@ -1327,6 +1361,11 @@ let register ~protocols = test_originated_implicit_can_be_equipotent protocols ; test_send_tickets_to_sc_rollup protocols ; test_send_tickets_from_storage_to_sc_rollup protocols ; - test_direct_transfer_tickets_from_implicit_account_to_originated protocols ; - test_direct_transfer_tickets_from_implicit_account_to_originated_complex + test_direct_transfer_tickets_from_implicit_account_to_originated_with_pair_constructor + protocols ; + test_direct_transfer_tickets_from_implicit_account_to_originated_with_ticket_constructor + protocols ; + test_direct_transfer_tickets_from_implicit_account_to_originated_complex_with_pair_constructor + protocols ; + test_direct_transfer_tickets_from_implicit_account_to_originated_complex_with_ticket_constructor protocols