From 25922679357981a91f1537d5654c493799e68022 Mon Sep 17 00:00:00 2001 From: Ding Xiang Fei Date: Sun, 27 Nov 2022 22:21:40 +0800 Subject: [PATCH 1/3] Proto: enable ticket transfer originated to implicit --- src/proto_alpha/lib_protocol/apply.ml | 62 +++++++++++++++++++ .../lib_protocol/apply_internal_results.ml | 9 +++ .../lib_protocol/script_interpreter_defs.ml | 14 +++++ .../lib_protocol/script_ir_translator.ml | 34 +++++++--- .../lib_protocol/script_typed_ir.ml | 19 +++++- .../lib_protocol/script_typed_ir.mli | 13 ++++ .../lib_protocol/script_typed_ir_size.ml | 2 + .../lib_protocol/ticket_operations_diff.ml | 15 +++++ 8 files changed, 158 insertions(+), 10 deletions(-) diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index b8a206cb4fbe..285b9d64d1ac 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -316,6 +316,48 @@ let apply_transaction_to_implicit ~ctxt ~source ~amount ~pkh ~before_operation = in return (ctxt, result, []) +let apply_transaction_to_implicit_with_ticket ~source ~destination ~ty ~ticket + ~amount ~before_operation ctxt = + let destination = Contract.Implicit destination in + Contract.allocated ctxt destination >>= fun already_allocated -> + let ex_token, ticket_amount = + Ticket_scanner.ex_token_and_amount_of_ex_ticket + @@ Ticket_scanner.Ex_ticket (ty, ticket) + in + Ticket_token_unparser.unparse ctxt ex_token >>=? fun (ticket_token, ctxt) -> + Token.transfer ctxt (`Contract source) (`Contract destination) amount + >>=? fun (ctxt, balance_updates) -> + let ticket_receipt = + Ticket_receipt. + [ + { + ticket_token; + updates = + [ + { + account = Destination.Contract destination; + amount = Script_int.(to_zint (ticket_amount :> n num)); + }; + ]; + }; + ] + in + return + ( ctxt, + Transaction_to_contract_result + { + storage = None; + lazy_storage_diff = None; + balance_updates; + ticket_receipt; + originated_contracts = []; + consumed_gas = Gas.consumed ~since:before_operation ~until:ctxt; + storage_size = Z.zero; + paid_storage_size_diff = Z.zero; + allocated_destination_contract = not already_allocated; + }, + [] ) + let apply_transaction_to_smart_contract ~ctxt ~source ~contract_hash ~amount ~entrypoint ~before_operation ~payer ~chain_id ~internal ~parameter = let contract = Contract.Originated contract_hash in @@ -579,6 +621,26 @@ let apply_internal_operation_contents : ( ctxt, (ITransaction_result res : kind successful_internal_operation_result), ops ) + | Transaction_to_implicit_with_ticket + { + destination; + ticket_ty = Script_typed_ir.Ticket_t (ty, _ty_metadata); + ticket; + amount; + unparsed_ticket = _; + } -> + apply_transaction_to_implicit_with_ticket + ~source + ~destination + ~ty + ~ticket + ~amount + ~before_operation:ctxt_before_op + ctxt + >|=? fun (ctxt, res, ops) -> + ( ctxt, + (ITransaction_result res : kind successful_internal_operation_result), + ops ) | Transaction_to_smart_contract { amount; diff --git a/src/proto_alpha/lib_protocol/apply_internal_results.ml b/src/proto_alpha/lib_protocol/apply_internal_results.ml index 7986c5877950..1f984ca1083f 100644 --- a/src/proto_alpha/lib_protocol/apply_internal_results.ml +++ b/src/proto_alpha/lib_protocol/apply_internal_results.ml @@ -78,6 +78,15 @@ let internal_operation (type kind) entrypoint = Entrypoint.default; parameters = Script.unit_parameter; } + | Transaction_to_implicit_with_ticket + {destination; unparsed_ticket; amount; ticket_ty = _; ticket = _} -> + Transaction + { + destination = Contract (Implicit destination); + amount; + entrypoint = Entrypoint.default; + parameters = unparsed_ticket; + } | Transaction_to_smart_contract {destination; amount; entrypoint; unparsed_parameters; _} -> Transaction diff --git a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml index 01cc37bb2b8d..3f7bf1c4d445 100644 --- a/src/proto_alpha/lib_protocol/script_interpreter_defs.ml +++ b/src/proto_alpha/lib_protocol/script_interpreter_defs.ml @@ -623,6 +623,20 @@ let transfer (type t) (ctxt, sc) gas amount location | Typed_implicit destination -> let () = parameters in return (Transaction_to_implicit {destination; amount}, None, ctxt) + | Typed_implicit_with_ticket {destination; ticket_ty} -> + unparse_data ctxt Optimized ticket_ty parameters + >>=? fun (unparsed_ticket, ctxt) -> + return + ( Transaction_to_implicit_with_ticket + { + destination; + amount; + ticket_ty; + ticket = parameters; + unparsed_ticket = Script.lazy_expr unparsed_ticket; + }, + None, + ctxt ) | Typed_originated {arg_ty = parameters_ty; contract_hash = destination; entrypoint} -> collect_lazy_storage ctxt parameters_ty parameters diff --git a/src/proto_alpha/lib_protocol/script_ir_translator.ml b/src/proto_alpha/lib_protocol/script_ir_translator.ml index 1e5c2dd0c044..ba7327d566b4 100644 --- a/src/proto_alpha/lib_protocol/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/script_ir_translator.ml @@ -4531,16 +4531,32 @@ and parse_contract : match destination with | Contract contract -> ( match contract with - | Implicit pkh -> + | Implicit destination -> Lwt.return - (if Entrypoint.is_default entrypoint then - (* An implicit account on the "default" entrypoint always exists and has type unit. *) - Gas_monad.run ctxt @@ ty_eq ~error_details arg unit_t - >|? fun (eq, ctxt) -> - (ctxt, eq >|? fun Eq : arg typed_contract -> Typed_implicit pkh) - else - (* An implicit account on any other entrypoint is not a valid contract. *) - ok (error ctxt (fun _loc -> No_such_entrypoint entrypoint))) + @@ + if Entrypoint.is_default entrypoint then + (* An implicit account on the "default" entrypoint always exists and has type unit + or (ticket cty). *) + let typecheck = + let open Gas_monad.Syntax in + let* () = Gas_monad.consume_gas Typecheck_costs.merge_cycle in + match arg with + | Unit_t -> + return (Typed_implicit destination : arg typed_contract) + | Ticket_t _ as ticket_ty -> + return (Typed_implicit_with_ticket {ticket_ty; destination}) + | _ -> + Gas_monad.of_result + @@ Error + (match error_details with + | Fast -> (Inconsistent_types_fast : err) + | Informative loc -> + trace_of_error @@ default_ty_eq_error loc arg unit_t) + in + Gas_monad.run ctxt typecheck >|? fun (v, ctxt) -> (ctxt, v) + else + (* An implicit account on any other entrypoint is not a valid contract. *) + ok @@ error ctxt (fun _loc -> No_such_entrypoint entrypoint) | Originated contract_hash -> trace (Invalid_contract (loc, contract)) diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.ml b/src/proto_alpha/lib_protocol/script_typed_ir.ml index 40c3afe6ca64..e2db2ed197c2 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir.ml @@ -1142,6 +1142,11 @@ and ('arg, 'ret) lambda = and 'arg typed_contract = | Typed_implicit : public_key_hash -> unit typed_contract + | Typed_implicit_with_ticket : { + ticket_ty : ('arg ticket, _) ty; + destination : public_key_hash; + } + -> 'arg ticket typed_contract | Typed_originated : { arg_ty : ('arg, _) ty; contract_hash : Contract_hash.t; @@ -1436,6 +1441,14 @@ and 'kind internal_operation_contents = amount : Tez.tez; } -> Kind.transaction internal_operation_contents + | Transaction_to_implicit_with_ticket : { + destination : Signature.Public_key_hash.t; + ticket_ty : ('content ticket, _) ty; + ticket : 'content ticket; + unparsed_ticket : Script.lazy_expr; + amount : Tez.tez; + } + -> Kind.transaction internal_operation_contents | Transaction_to_smart_contract : { destination : Contract_hash.t; amount : Tez.tez; @@ -1526,6 +1539,7 @@ type ('arg, 'storage) script = let manager_kind : type kind. kind internal_operation_contents -> kind Kind.manager = function | Transaction_to_implicit _ -> Kind.Transaction_manager_kind + | Transaction_to_implicit_with_ticket _ -> Kind.Transaction_manager_kind | Transaction_to_smart_contract _ -> Kind.Transaction_manager_kind | Transaction_to_tx_rollup _ -> Kind.Transaction_manager_kind | Transaction_to_sc_rollup _ -> Kind.Transaction_manager_kind @@ -2256,6 +2270,8 @@ let stack_top_ty : type a b s. (a, b * s) stack_ty -> a ty_ex_c = function module Typed_contract = struct let destination : type a. a typed_contract -> Destination.t = function | Typed_implicit pkh -> Destination.Contract (Implicit pkh) + | Typed_implicit_with_ticket {destination; _} -> + Destination.Contract (Implicit destination) | Typed_originated {contract_hash; _} -> Destination.Contract (Originated contract_hash) | Typed_tx_rollup {tx_rollup; _} -> Destination.Tx_rollup tx_rollup @@ -2264,13 +2280,14 @@ module Typed_contract = struct let arg_ty : type a. a typed_contract -> a ty_ex_c = function | Typed_implicit _ -> (Ty_ex_c Unit_t : a ty_ex_c) + | Typed_implicit_with_ticket {ticket_ty; _} -> Ty_ex_c ticket_ty | Typed_originated {arg_ty; _} -> Ty_ex_c arg_ty | Typed_tx_rollup {arg_ty; _} -> Ty_ex_c arg_ty | Typed_sc_rollup {arg_ty; _} -> Ty_ex_c arg_ty | Typed_zk_rollup {arg_ty; _} -> Ty_ex_c arg_ty let entrypoint : type a. a typed_contract -> Entrypoint.t = function - | Typed_implicit _ -> Entrypoint.default + | Typed_implicit _ | Typed_implicit_with_ticket _ -> Entrypoint.default | Typed_tx_rollup _ -> Entrypoint.deposit | Typed_originated {entrypoint; _} | Typed_sc_rollup {entrypoint; _} -> entrypoint diff --git a/src/proto_alpha/lib_protocol/script_typed_ir.mli b/src/proto_alpha/lib_protocol/script_typed_ir.mli index 01da712c4063..80f0a539d33e 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir.mli +++ b/src/proto_alpha/lib_protocol/script_typed_ir.mli @@ -1162,6 +1162,11 @@ and ('arg, 'ret) lambda = and 'arg typed_contract = | Typed_implicit : public_key_hash -> unit typed_contract + | Typed_implicit_with_ticket : { + ticket_ty : ('arg ticket, _) ty; + destination : public_key_hash; + } + -> 'arg ticket typed_contract | Typed_originated : { arg_ty : ('arg, _) ty; contract_hash : Contract_hash.t; @@ -1585,6 +1590,14 @@ and 'kind internal_operation_contents = amount : Tez.tez; } -> Kind.transaction internal_operation_contents + | Transaction_to_implicit_with_ticket : { + destination : Signature.Public_key_hash.t; + ticket_ty : ('content ticket, _) ty; + ticket : 'content ticket; + unparsed_ticket : Script.lazy_expr; + amount : Tez.tez; + } + -> Kind.transaction internal_operation_contents | Transaction_to_smart_contract : { (* The [unparsed_parameters] field may seem useless since we have access to a typed version of the field (with [parameters_ty] and diff --git a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml index 6a6cae55907b..dc70b78eaeda 100644 --- a/src/proto_alpha/lib_protocol/script_typed_ir_size.ml +++ b/src/proto_alpha/lib_protocol/script_typed_ir_size.ml @@ -191,6 +191,8 @@ let dup_n_gadt_witness_size n (_w : (_, _, _, _) dup_n_gadt_witness) = let contract_size : type t. t typed_contract -> nodes_and_size = function | Typed_implicit _ -> ret_adding zero (h1w +! public_key_hash_in_memory_size) + | Typed_implicit_with_ticket {ticket_ty; destination = _} -> + ret_adding (ty_size ticket_ty) (h2w +! public_key_hash_in_memory_size) | Typed_originated {arg_ty; contract_hash = _; entrypoint} -> ret_adding (ty_size arg_ty) diff --git a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml index 60c7f1fccf18..e17a24ff4dc8 100644 --- a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml +++ b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml @@ -166,6 +166,21 @@ let tickets_of_operation ctxt (Script_typed_ir.Internal_operation {source = _; operation; nonce = _}) = match operation with | Transaction_to_implicit _ -> return (None, ctxt) + | Transaction_to_implicit_with_ticket + { + destination; + ticket; + ticket_ty = Script_typed_ir.Ticket_t (ty, _); + unparsed_ticket = _; + amount = _; + } -> + return + ( Some + { + destination = Destination.Contract (Implicit destination); + tickets = [Ex_ticket (ty, ticket)]; + }, + ctxt ) | Transaction_to_smart_contract { amount = _; -- GitLab From a151c9d8de983b72d4440eeeed689e41721d4e94 Mon Sep 17 00:00:00 2001 From: Ding Xiang Fei Date: Sun, 27 Nov 2022 22:22:25 +0800 Subject: [PATCH 2/3] Test: add protocol integration tests --- .../michelson/test_ticket_balance.ml | 53 +++ .../test/integration/operations/main.ml | 1 + .../operations/test_transfer_ticket.ml | 343 ++++++++++++++++++ 3 files changed, 397 insertions(+) create mode 100644 src/proto_alpha/lib_protocol/test/integration/operations/test_transfer_ticket.ml diff --git a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml index aedf33233b86..c3e8bd9acdbc 100644 --- a/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml +++ b/src/proto_alpha/lib_protocol/test/integration/michelson/test_ticket_balance.ml @@ -718,6 +718,55 @@ let test_send_and_store_zero_amount_tickets () = in return_unit +(** Test sending tickets to an implicit account. *) +let test_send_tickets_to_implicit_account () = + let* block, baker, contract, contract2 = Contract_helpers.init () in + let () = + match (contract, contract2) with + | Contract.Implicit _, Contract.Implicit _ -> () + | _ -> assert false + in + (* A contract that receives an address and mints and sends a ticket to it. *) + let* ticketer, _script, block = + originate + ~baker + ~source_contract:contract + ~script: + {| + { parameter address; + storage unit; + code { CAR ; + CONTRACT (ticket string) ; + IF_NONE + { PUSH string "Contract of type `ticket(string)` not found" ; + FAILWITH } + { PUSH mutez 0; + PUSH nat 1 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR }}} + |} + ~storage:"Unit" + block + in + let* block = + transaction + ~entrypoint:Entrypoint.default + ~baker + ~sender:contract + block + ~recipient:ticketer + ~parameters:(Printf.sprintf {|"%s"|} (Contract.to_b58check contract2)) + in + let token = string_token ~ticketer "Ticket" in + assert_token_balance ~loc:__LOC__ block token contract2 (Some 1) + (** Test sending tickets in a big-map. *) let test_send_tickets_in_big_map () = let* {block; baker; contract = source_contract} = init_env () in @@ -1690,6 +1739,10 @@ let tests = Tztest.tztest "Test add to big-map" `Quick test_add_to_big_map; Tztest.tztest "Test swap big-map" `Quick test_swap_big_map; Tztest.tztest "Test send ticket" `Quick test_send_tickets; + Tztest.tztest + "Test send ticket to implicit" + `Quick + test_send_tickets_to_implicit_account; Tztest.tztest "Test send and store tickets with amount 0" `Quick diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/main.ml b/src/proto_alpha/lib_protocol/test/integration/operations/main.ml index afcec61e65e4..1f33d0e6828c 100644 --- a/src/proto_alpha/lib_protocol/test/integration/operations/main.ml +++ b/src/proto_alpha/lib_protocol/test/integration/operations/main.ml @@ -46,5 +46,6 @@ let () = ("sc rollup", Test_sc_rollup.tests); ("sc rollup transfer", Test_sc_rollup_transfer.tests); ("zk rollup", Test_zk_rollup.tests); + ("transfer ticket", Test_transfer_ticket.tests); ] |> Lwt_main.run diff --git a/src/proto_alpha/lib_protocol/test/integration/operations/test_transfer_ticket.ml b/src/proto_alpha/lib_protocol/test/integration/operations/test_transfer_ticket.ml new file mode 100644 index 000000000000..c52d8df46dea --- /dev/null +++ b/src/proto_alpha/lib_protocol/test/integration/operations/test_transfer_ticket.ml @@ -0,0 +1,343 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Testing + ------- + Component: Transfer_ticket logic + Invocation: dune exec \ + src/proto_alpha/lib_protocol/test/integration/operations/main.exe \ + -- test "^transfer ticket$" + Subject: Test ticket transfers +*) + +open Protocol +open Alpha_context +open Tezos_micheline +open Lwt_result_syntax + +let wrap m = m >|= Environment.wrap_tzresult + +(* In this test, a ticketer contract mints and transfers a ticket to an implicit account, + who further transfers it to another implicit account. + The ticket balance is inspected for correctness. +*) +let test_mint_deposit_withdraw_implicit_transfer () = + let* block, (account, another_account) = + Context.init2 ~consensus_threshold:0 () + in + let baker = Context.Contract.pkh account in + let* ticketer, _, block = + Contract_helpers.originate_contract_from_string + ~script: + {| + parameter (pair nat nat address) ; + storage unit ; + code { CAR ; + UNPAIR 3 ; + DIG 2 ; + CONTRACT (ticket nat) ; + ASSERT_SOME ; + # contract : nat %ct : nat %qty + PUSH mutez 0 ; + # tez : contract : nat %ct : nat %qty + DIG 3 ; + # nat %qty : tez : contract : nat %ct + DIG 3 ; + # nat %ct : nat %qty : tez : contract + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + UNIT ; + SWAP ; + PAIR } + |} + ~storage:"Unit" + ~source_contract:account + ~baker + block + in + let contents = 42 in + let* block = + Op.transaction + (B block) + ~entrypoint:Entrypoint.default + ~parameters: + (Expr_common.( + pair_n [int (Z.of_int contents); int (Z.of_int 1); address account]) + |> Micheline.strip_locations |> Script.lazy_expr) + ~fee:Tez.one + account + ticketer + (Tez.of_mutez_exn 0L) + >>=? fun operation -> Block.bake ~operation block + in + let ty = Expr.from_string "nat" in + let* block = + Op.transfer_ticket + (B block) + ~entrypoint:Entrypoint.default + ~source:account + ~ty:(Script.lazy_expr ty) + ~contents:(Script.lazy_expr @@ Expr.from_string @@ string_of_int contents) + ~amount: + (WithExceptions.Option.get ~loc:__LOC__ + @@ Ticket_amount.of_zint @@ Z.of_int 1) + ~destination:another_account + ~ticketer + >>=? fun operation -> Block.bake ~operation block + in + let make_ex_token ctxt ~ticketer ~ty ~content = + let* Script_ir_translator.Ex_comparable_ty cty, ctxt = + wrap @@ Lwt.return + @@ Script_ir_translator.parse_comparable_ty ctxt + @@ Micheline.root ty + in + let* contents, ctxt = + wrap + @@ Script_ir_translator.parse_comparable_data ctxt cty + @@ Micheline.root content + in + return + (Ticket_token.Ex_token {contents_type = cty; ticketer; contents}, ctxt) + in + let* ctxt = + Incremental.begin_construction block >|=? Incremental.alpha_ctxt + in + let* token, ctxt = + make_ex_token + ctxt + ~ticketer + ~ty + ~content:(Expr.from_string @@ string_of_int contents) + in + let* key, ctxt = + wrap + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Contract another_account) + token + in + let* amount, _ = wrap @@ Ticket_balance.get_balance ctxt key in + match amount with + | Some amount -> Assert.equal_int ~loc:__LOC__ (Z.to_int amount) 1 + | _ -> return_unit + +(* In this test, a ticketer contract is called to mint and send a ticket + to an implicit account and a contract. Both destinations are given + in a `contract (ticket nat)` value. + Transfer should be possible since the target contract has the right + parameter type under the given entrypoint. +*) +let test_contract_as_ticket_transfer_destination () = + let* block, (account, another_account) = + Context.init2 ~consensus_threshold:0 () + in + let baker = Context.Contract.pkh account in + let* ticketer, _, block = + Contract_helpers.originate_contract_from_string + ~script: + {| + parameter (pair (contract (ticket nat)) nat nat) ; + storage unit ; + code { CAR ; + UNPAIR 3 ; + # contract (ticket nat) : nat %ct : nat %qty + PUSH mutez 0 ; + # tez : contract (ticket nat) : nat %ct : nat %qty + DIG 3 ; + # nat %qty : tez : contract (ticket nat) : nat %ct + DIG 3 ; + # nat %ct : nat %qty : tez : contract (ticket nat) + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + UNIT ; + SWAP ; + PAIR } + |} + ~storage:"Unit" + ~source_contract:account + ~baker + block + in + let* bag, _, block = + Contract_helpers.originate_contract_from_string + ~script: + {| + parameter (or (ticket %save nat) (address %send)); + storage (list (ticket nat)); + code { UNPAIR ; + IF_LEFT + { CONS ; NIL operation ; PAIR } + { SWAP ; + IF_CONS + { DIG 2 ; + CONTRACT %ticket (ticket nat) ; + ASSERT_SOME ; + PUSH mutez 0 ; + DIG 2 ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + PAIR } + { PUSH string "no ticket to send" ; FAILWITH }}} + |} + ~storage:"{}" + ~source_contract:account + ~baker + block + in + let contents = 42 in + let* block = + Op.transaction + (B block) + ~entrypoint:Entrypoint.default + ~parameters: + (Expr_common.( + pair_n + [ + string + (Destination.(to_b58check (Contract account)) + ^ Entrypoint.(to_address_suffix default)); + int (Z.of_int contents); + int (Z.of_int 1); + ]) + |> Micheline.strip_locations |> Script.lazy_expr) + ~fee:Tez.one + account + ticketer + (Tez.of_mutez_exn 0L) + >>=? fun operation -> Block.bake ~operation block + in + let ty = Expr.from_string "nat" in + let* block = + Op.transfer_ticket + (B block) + ~entrypoint:Entrypoint.default + ~source:account + ~ty:(Script.lazy_expr ty) + ~contents:(Script.lazy_expr @@ Expr.from_string @@ string_of_int contents) + ~amount: + (WithExceptions.Option.get ~loc:__LOC__ + @@ Ticket_amount.of_zint @@ Z.of_int 1) + ~destination:another_account + ~ticketer + >>=? fun operation -> Block.bake ~operation block + in + let make_ex_token ctxt ~ticketer ~ty ~content = + let* Script_ir_translator.Ex_comparable_ty cty, ctxt = + wrap @@ Lwt.return + @@ Script_ir_translator.parse_comparable_ty ctxt + @@ Micheline.root ty + in + let* contents, ctxt = + wrap + @@ Script_ir_translator.parse_comparable_data ctxt cty + @@ Micheline.root content + in + return + (Ticket_token.Ex_token {contents_type = cty; ticketer; contents}, ctxt) + in + let* ctxt = + Incremental.begin_construction block >|=? Incremental.alpha_ctxt + in + let* token, ctxt = + make_ex_token + ctxt + ~ticketer + ~ty + ~content:(Expr.from_string @@ string_of_int contents) + in + let* key, ctxt = + wrap + @@ Ticket_balance_key.of_ex_token + ctxt + ~owner:(Contract another_account) + token + in + let* amount, _ = wrap @@ Ticket_balance.get_balance ctxt key in + let* () = + match amount with + | Some amount -> Assert.equal_int ~loc:__LOC__ (Z.to_int amount) 1 + | _ -> return_unit + in + let* block = + Op.transaction + (B block) + ~entrypoint:Entrypoint.default + ~parameters: + (Expr_common.( + pair_n + [ + string + (Destination.(to_b58check (Contract bag)) + ^ Entrypoint.(to_address_suffix @@ of_string_strict_exn "save") + ); + int (Z.of_int contents); + int (Z.of_int 1); + ]) + |> Micheline.strip_locations |> Script.lazy_expr) + ~fee:Tez.one + account + ticketer + (Tez.of_mutez_exn 0L) + >>=? fun operation -> Block.bake ~operation block + in + let* ctxt = + Incremental.begin_construction block >|=? Incremental.alpha_ctxt + in + let* token, ctxt = + make_ex_token + ctxt + ~ticketer + ~ty + ~content:(Expr.from_string @@ string_of_int contents) + in + let* key, ctxt = + wrap @@ Ticket_balance_key.of_ex_token ctxt ~owner:(Contract bag) token + in + let* amount, _ = wrap @@ Ticket_balance.get_balance ctxt key in + match amount with + | Some amount -> Assert.equal_int ~loc:__LOC__ (Z.to_int amount) 1 + | _ -> return_unit + +let tests = + [ + Tztest.tztest + "Test ticket transfer operations" + `Quick + test_mint_deposit_withdraw_implicit_transfer; + Tztest.tztest + "Test 'contract (ticket cty)' as transfer destination" + `Quick + test_contract_as_ticket_transfer_destination; + ] -- GitLab From 6d3c3afb90d750b37169d0900c97c322e330305b Mon Sep 17 00:00:00 2001 From: Ding Xiang Fei Date: Sun, 27 Nov 2022 22:22:46 +0800 Subject: [PATCH 3/3] Test: add tezt tests on transfers --- tezt/lib_tezos/client.ml | 66 +- tezt/lib_tezos/client.mli | 29 +- .../contracts/proto_alpha/send_ticket_list.tz | 20 + .../contracts/proto_alpha/tickets_bag.tz | 21 + .../proto_alpha/tickets_bag_implicit.tz | 21 + .../proto_alpha/tickets_blackhole.tz | 4 + .../proto_alpha/tickets_list_blackhole.tz | 6 + .../contracts/proto_alpha/tickets_send.tz | 21 + .../proto_alpha/tickets_send_with_tez.tz | 20 + ...rom implicit accounts must be rejected.out | 210 ++++++ ...inated contracts and implicit accounts.out | 374 +++++++++ ... implicit accounts with some Tez along.out | 115 +++ ...icit accounts with the wrong type must.out | 195 +++++ ...ts from contracts to implicit accounts.out | 111 +++ ... contract storage to implicit accounts.out | 288 +++++++ ...rom implicit accounts must be rejected.out | 129 ++++ ...accounts or originated contracts accep.out | 197 +++++ ...rom implicit accounts must be rejected.out | 174 +++++ tezt/tests/tickets.ml | 713 +++++++++++++++++- tezt/tests/tx_rollup.ml | 2 +- tezt/tests/tx_rollup_l2_node.ml | 2 +- 21 files changed, 2667 insertions(+), 51 deletions(-) create mode 100644 tezt/tests/contracts/proto_alpha/send_ticket_list.tz create mode 100644 tezt/tests/contracts/proto_alpha/tickets_bag.tz create mode 100644 tezt/tests/contracts/proto_alpha/tickets_bag_implicit.tz create mode 100644 tezt/tests/contracts/proto_alpha/tickets_blackhole.tz create mode 100644 tezt/tests/contracts/proto_alpha/tickets_list_blackhole.tz create mode 100644 tezt/tests/contracts/proto_alpha/tickets_send.tz create mode 100644 tezt/tests/contracts/proto_alpha/tickets_send_with_tez.tz create mode 100644 tezt/tests/expected/tickets.ml/Alpha- Overdrafting ticket from implicit accounts must be rejected.out create mode 100644 tezt/tests/expected/tickets.ml/Alpha- Send tickets between originated contracts and implicit accounts.out create mode 100644 tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts with some Tez along.out create mode 100644 tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts with the wrong type must.out create mode 100644 tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts.out create mode 100644 tezt/tests/expected/tickets.ml/Alpha- Sending ticket from contract storage to implicit accounts.out create mode 100644 tezt/tests/expected/tickets.ml/Alpha- Sending ticket of wrong type from implicit accounts must be rejected.out create mode 100644 tezt/tests/expected/tickets.ml/Alpha- Sending tickets to either implicit accounts or originated contracts accep.out create mode 100644 tezt/tests/expected/tickets.ml/Alpha- Sending zero ticket from implicit accounts must be rejected.out diff --git a/tezt/lib_tezos/client.ml b/tezt/lib_tezos/client.ml index eb6a2d4c0838..c84058cc2ce7 100644 --- a/tezt/lib_tezos/client.ml +++ b/tezt/lib_tezos/client.ml @@ -1897,41 +1897,41 @@ module Tx_rollup = struct in let parse process = Process.check process in {value = process; run = parse} - - let transfer_tickets ?(wait = "none") ?burn_cap ?hooks ~qty ~src ~destination - ~entrypoint ~contents ~ty ~ticketer client = - let process = - spawn_command - ?hooks - client - (["--wait"; wait] - @ [ - "transfer"; - Int64.to_string qty; - "tickets"; - "from"; - src; - "to"; - destination; - "with"; - "entrypoint"; - entrypoint; - "and"; - "contents"; - contents; - "and"; - "type"; - ty; - "and"; - "ticketer"; - ticketer; - ] - @ optional_arg "burn-cap" Tez.to_string burn_cap) - in - let parse process = Process.check process in - {value = process; run = parse} end +let transfer_tickets ?(wait = "none") ?burn_cap ?hooks ?expect_failure ~qty ~src + ~destination ~entrypoint ~contents ~ty ~ticketer client = + let process = + spawn_command + ?hooks + client + (["--wait"; wait] + @ [ + "transfer"; + Int64.to_string qty; + "tickets"; + "from"; + src; + "to"; + destination; + "with"; + "entrypoint"; + entrypoint; + "and"; + "contents"; + contents; + "and"; + "type"; + ty; + "and"; + "ticketer"; + ticketer; + ] + @ optional_arg "burn-cap" Tez.to_string burn_cap) + in + let parse process = Process.check ?expect_failure process in + {value = process; run = parse} + let spawn_show_voting_period ?endpoint client = spawn_command ?endpoint client (mode_arg client @ ["show"; "voting"; "period"]) diff --git a/tezt/lib_tezos/client.mli b/tezt/lib_tezos/client.mli index aa493233f6eb..35447aba9c7c 100644 --- a/tezt/lib_tezos/client.mli +++ b/tezt/lib_tezos/client.mli @@ -1459,22 +1459,23 @@ module Tx_rollup : sig ticket_dispatch_info_data_list:string list -> t -> unit Runnable.process - - val transfer_tickets : - ?wait:string -> - ?burn_cap:Tez.t -> - ?hooks:Process.hooks -> - qty:int64 -> - src:string -> - destination:string -> - entrypoint:string -> - contents:string -> - ty:string -> - ticketer:string -> - t -> - unit Runnable.process end +val transfer_tickets : + ?wait:string -> + ?burn_cap:Tez.t -> + ?hooks:Process.hooks -> + ?expect_failure:bool -> + qty:int64 -> + src:string -> + destination:string -> + entrypoint:string -> + contents:string -> + ty:string -> + ticketer:string -> + t -> + unit Runnable.process + (** Run [octez-client show voting period] and return the period name. *) val show_voting_period : ?endpoint:endpoint -> t -> string Lwt.t diff --git a/tezt/tests/contracts/proto_alpha/send_ticket_list.tz b/tezt/tests/contracts/proto_alpha/send_ticket_list.tz new file mode 100644 index 000000000000..cb5cd649cca9 --- /dev/null +++ b/tezt/tests/contracts/proto_alpha/send_ticket_list.tz @@ -0,0 +1,20 @@ +# This contract mints tickets into a list and sends them to a contract specified in the parameter. +parameter address ; +storage unit; +code { CAR ; + CONTRACT (list (ticket string)) ; + ASSERT_SOME ; + PUSH mutez 0 ; + NIL (ticket string) ; + PUSH nat 1 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + CONS ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + UNIT ; + SWAP ; + PAIR } \ No newline at end of file diff --git a/tezt/tests/contracts/proto_alpha/tickets_bag.tz b/tezt/tests/contracts/proto_alpha/tickets_bag.tz new file mode 100644 index 000000000000..6449ed13140f --- /dev/null +++ b/tezt/tests/contracts/proto_alpha/tickets_bag.tz @@ -0,0 +1,21 @@ +# This contract is a bag of tickets with two entrypoints +# - "save" entrypoint: accept a string ticket and check it into the storage +# - "send" entrypoint: pop a ticket from the storage and send it to the target address at entrypoint ticket +parameter (or (ticket %save string) (address %send)); +storage (list (ticket string)); +code { UNPAIR ; + IF_LEFT + { CONS ; NIL operation ; PAIR } + { SWAP ; + IF_CONS + { DIG 2 ; + CONTRACT %ticket (ticket string) ; + ASSERT_SOME ; + PUSH mutez 0 ; + DIG 2 ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + PAIR } + { PUSH string "no ticket to send" ; FAILWITH }}} \ No newline at end of file diff --git a/tezt/tests/contracts/proto_alpha/tickets_bag_implicit.tz b/tezt/tests/contracts/proto_alpha/tickets_bag_implicit.tz new file mode 100644 index 000000000000..c2b0e04d7a18 --- /dev/null +++ b/tezt/tests/contracts/proto_alpha/tickets_bag_implicit.tz @@ -0,0 +1,21 @@ +# This contract is a bag of tickets with two entrypoints +# - "save" entrypoint: accept a string ticket and check it into the storage +# - "send" entrypoint: pop a ticket from the storage and send it to the target address at entrypoint default +parameter (or (ticket %save string) (address %send)); +storage (list (ticket string)); +code { UNPAIR ; + IF_LEFT + { CONS ; NIL operation ; PAIR } + { SWAP ; + IF_CONS + { DIG 2 ; + CONTRACT (ticket string) ; + ASSERT_SOME ; + PUSH mutez 0 ; + DIG 2 ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + PAIR } + { PUSH string "no ticket to send" ; FAILWITH }}} \ No newline at end of file diff --git a/tezt/tests/contracts/proto_alpha/tickets_blackhole.tz b/tezt/tests/contracts/proto_alpha/tickets_blackhole.tz new file mode 100644 index 000000000000..2b74a82a76e7 --- /dev/null +++ b/tezt/tests/contracts/proto_alpha/tickets_blackhole.tz @@ -0,0 +1,4 @@ +# This contract drops any inbound ticket +parameter (ticket %ticket string); +storage unit; +code { CDR ; NIL operation ; PAIR } \ No newline at end of file diff --git a/tezt/tests/contracts/proto_alpha/tickets_list_blackhole.tz b/tezt/tests/contracts/proto_alpha/tickets_list_blackhole.tz new file mode 100644 index 000000000000..6dca09ef3729 --- /dev/null +++ b/tezt/tests/contracts/proto_alpha/tickets_list_blackhole.tz @@ -0,0 +1,6 @@ +# This contract drops any inbound ticket list +parameter (list (ticket string)) ; +storage unit; +code { CDR ; + NIL operation ; + PAIR } diff --git a/tezt/tests/contracts/proto_alpha/tickets_send.tz b/tezt/tests/contracts/proto_alpha/tickets_send.tz new file mode 100644 index 000000000000..e7e79d0c501b --- /dev/null +++ b/tezt/tests/contracts/proto_alpha/tickets_send.tz @@ -0,0 +1,21 @@ +# This contract constructs one unit of a string ticket with content "Ticket" and send it to the input address +# which can be either a contract, which should have a default entrypoint to accept a ticket, or an implicit account +parameter (pair address nat); +storage unit; +code { CAR; + UNPAIR ; + CONTRACT (ticket string) ; + IF_NONE + { PUSH string "Contract not found" ; + FAILWITH } + { PUSH mutez 0 ; + DIG 2 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } \ No newline at end of file diff --git a/tezt/tests/contracts/proto_alpha/tickets_send_with_tez.tz b/tezt/tests/contracts/proto_alpha/tickets_send_with_tez.tz new file mode 100644 index 000000000000..5761810d1365 --- /dev/null +++ b/tezt/tests/contracts/proto_alpha/tickets_send_with_tez.tz @@ -0,0 +1,20 @@ +# This contract constructs one unit of a string ticket with content "Ticket" and sends it to the input address along with one mutez +# which can be either a contract, which should have a default entrypoint to accept a ticket, or an implicit account. +parameter address; +storage unit; +code { CAR; + CONTRACT (ticket string) ; + IF_NONE + { PUSH string "Contract not found" ; + FAILWITH } + { PUSH mutez 1 ; + PUSH nat 1 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } \ No newline at end of file diff --git a/tezt/tests/expected/tickets.ml/Alpha- Overdrafting ticket from implicit accounts must be rejected.out b/tezt/tests/expected/tickets.ml/Alpha- Overdrafting ticket from implicit accounts must be rejected.out new file mode 100644 index 000000000000..1df78bc24e04 --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Overdrafting ticket from implicit accounts must be rejected.out @@ -0,0 +1,210 @@ + +./octez-client --mode mockup --wait none originate contract ticketer transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_send.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1441.228 units (will add 100 for safety) +Estimated storage: 415 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.00054 + Expected counter: 1 + Gas limit: 1542 + Storage limit: 435 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.00054 + payload fees(the block proposer) ....... +ꜩ0.00054 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (pair address nat) ; + storage unit ; + code { CAR ; + UNPAIR ; + CONTRACT (ticket string) ; + IF_NONE + { PUSH string "Contract not found" ; FAILWITH } + { PUSH mutez 0 ; + DIG 2 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 158 bytes + Paid storage size diff: 158 bytes + Consumed gas: 1441.228 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0395 + storage fees ........................... +ꜩ0.0395 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as ticketer. + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg 'Pair "[PUBLIC_KEY_HASH]" 1' +Node is bootstrapped. +Estimated gas: 3588.163 units (will add 100 for safety) +Estimated storage: 66 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.000667 + Expected counter: 2 + Gas limit: 3689 + Storage limit: 86 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000667 + payload fees(the block proposer) ....... +ꜩ0.000667 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair "[PUBLIC_KEY_HASH]" 1) + This transaction was successfully applied + Updated storage: Unit + Storage size: 158 bytes + Paid storage size diff: 66 bytes + Consumed gas: 2588.410 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [PUBLIC_KEY_HASH] + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1)) + This transaction was successfully applied + Consumed gas: 1000.398 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [PUBLIC_KEY_HASH] ... +1 + + +./octez-client --mode mockup --wait none transfer 2 tickets from bootstrap1 to bootstrap2 with entrypoint default and contents '"Ticket"' and type string and ticketer '[CONTRACT_HASH]' --burn-cap 1 +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0 + Expected counter: 3 + Gas limit: 1040000 + Storage limit: 60000 bytes + Transfer tickets: + Ticket content: "Ticket" + Ticket content type: string + Ticket ticketer: [CONTRACT_HASH] + Ticket amount: 2 + Destination: [PUBLIC_KEY_HASH] + From: [PUBLIC_KEY_HASH] + This operation FAILED. + +Error: + Attempted to set negative ticket balance value '-1' for key expruK1GiQe8Hzv7WY6McsaUsUFqgPJGzmZGvGZQ5VG3NACdyPgVEM. + +./octez-client --mode mockup --wait none originate contract bag transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_bag.tz --init '{}' --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1446.306 units (will add 100 for safety) +Estimated storage: 451 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.000576 + Expected counter: 3 + Gas limit: 1547 + Storage limit: 471 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000576 + payload fees(the block proposer) ....... +ꜩ0.000576 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (or (ticket %save string) (address %send)) ; + storage (list (ticket string)) ; + code { UNPAIR ; + IF_LEFT + { CONS ; NIL operation ; PAIR } + { SWAP ; + IF_CONS + { DIG 2 ; + CONTRACT %ticket (ticket string) ; + ASSERT_SOME ; + PUSH mutez 0 ; + DIG 2 ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + PAIR } + { PUSH string "no ticket to send" ; FAILWITH } } } } + Initial storage: {} + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 194 bytes + Paid storage size diff: 194 bytes + Consumed gas: 1446.306 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0485 + storage fees ........................... +ꜩ0.0485 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as bag. + +./octez-client --mode mockup --wait none transfer 2 tickets from bootstrap1 to '[CONTRACT_HASH]' with entrypoint save and contents '"Ticket"' and type string and ticketer '[CONTRACT_HASH]' --burn-cap 1 +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0 + Expected counter: 4 + Gas limit: 1040000 + Storage limit: 60000 bytes + Transfer tickets: + Ticket content: "Ticket" + Ticket content type: string + Ticket ticketer: [CONTRACT_HASH] + Ticket amount: 2 + Destination: [CONTRACT_HASH] + Entrypoint: save + From: [PUBLIC_KEY_HASH] + This operation FAILED. + +Error: + Attempted to set negative ticket balance value '-1' for key expruK1GiQe8Hzv7WY6McsaUsUFqgPJGzmZGvGZQ5VG3NACdyPgVEM. diff --git a/tezt/tests/expected/tickets.ml/Alpha- Send tickets between originated contracts and implicit accounts.out b/tezt/tests/expected/tickets.ml/Alpha- Send tickets between originated contracts and implicit accounts.out new file mode 100644 index 000000000000..7203ff0a2068 --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Send tickets between originated contracts and implicit accounts.out @@ -0,0 +1,374 @@ + +./octez-client --mode mockup --wait none originate contract ticketer transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_send.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1441.228 units (will add 100 for safety) +Estimated storage: 415 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.00054 + Expected counter: 1 + Gas limit: 1542 + Storage limit: 435 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.00054 + payload fees(the block proposer) ....... +ꜩ0.00054 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (pair address nat) ; + storage unit ; + code { CAR ; + UNPAIR ; + CONTRACT (ticket string) ; + IF_NONE + { PUSH string "Contract not found" ; FAILWITH } + { PUSH mutez 0 ; + DIG 2 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 158 bytes + Paid storage size diff: 158 bytes + Consumed gas: 1441.228 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0395 + storage fees ........................... +ꜩ0.0395 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as ticketer. + +./octez-client --mode mockup --wait none originate contract bag transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_bag.tz --init '{}' --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1446.306 units (will add 100 for safety) +Estimated storage: 451 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.000576 + Expected counter: 2 + Gas limit: 1547 + Storage limit: 471 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000576 + payload fees(the block proposer) ....... +ꜩ0.000576 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (or (ticket %save string) (address %send)) ; + storage (list (ticket string)) ; + code { UNPAIR ; + IF_LEFT + { CONS ; NIL operation ; PAIR } + { SWAP ; + IF_CONS + { DIG 2 ; + CONTRACT %ticket (ticket string) ; + ASSERT_SOME ; + PUSH mutez 0 ; + DIG 2 ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + PAIR } + { PUSH string "no ticket to send" ; FAILWITH } } } } + Initial storage: {} + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 194 bytes + Paid storage size diff: 194 bytes + Consumed gas: 1446.306 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0485 + storage fees ........................... +ꜩ0.0485 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as bag. + +./octez-client --mode mockup --wait none originate contract blackhole transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_blackhole.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1410.196 units (will add 100 for safety) +Estimated storage: 308 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.00043 + Expected counter: 3 + Gas limit: 1511 + Storage limit: 328 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.00043 + payload fees(the block proposer) ....... +ꜩ0.00043 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (ticket %ticket string) ; + storage unit ; + code { CDR ; NIL operation ; PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 51 bytes + Paid storage size diff: 51 bytes + Consumed gas: 1410.196 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.01275 + storage fees ........................... +ꜩ0.01275 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as blackhole. + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg 'Pair "[PUBLIC_KEY_HASH]" 3' +Node is bootstrapped. +Estimated gas: 3588.163 units (will add 100 for safety) +Estimated storage: 66 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.000667 + Expected counter: 4 + Gas limit: 3689 + Storage limit: 86 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000667 + payload fees(the block proposer) ....... +ꜩ0.000667 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair "[PUBLIC_KEY_HASH]" 3) + This transaction was successfully applied + Updated storage: Unit + Storage size: 158 bytes + Paid storage size diff: 66 bytes + Consumed gas: 2588.410 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [PUBLIC_KEY_HASH] + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 3)) + This transaction was successfully applied + Consumed gas: 1000.398 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [PUBLIC_KEY_HASH] ... +3 + + +./octez-client --mode mockup get ticket balance for bootstrap1 with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +3 + +./octez-client --mode mockup --wait none transfer 2 tickets from bootstrap1 to bootstrap2 with entrypoint default and contents '"Ticket"' and type string and ticketer '[CONTRACT_HASH]' --burn-cap 1 +Node is bootstrapped. +Estimated gas: 2124.312 units (will add 100 for safety) +Estimated storage: 66 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.000524 + Expected counter: 5 + Gas limit: 2225 + Storage limit: 86 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000524 + payload fees(the block proposer) ....... +ꜩ0.000524 + Transfer tickets: + Ticket content: "Ticket" + Ticket content type: string + Ticket ticketer: [CONTRACT_HASH] + Ticket amount: 2 + Destination: [PUBLIC_KEY_HASH] + From: [PUBLIC_KEY_HASH] + This tickets transfer was successfully applied + Paid storage size diff: 66 bytes + Consumed gas: 2124.312 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + + +./octez-client --mode mockup get ticket balance for bootstrap1 with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +1 + +./octez-client --mode mockup get ticket balance for bootstrap2 with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +2 + +./octez-client --mode mockup --wait none transfer 1 tickets from bootstrap2 to '[CONTRACT_HASH]' with entrypoint save and contents '"Ticket"' and type string and ticketer '[CONTRACT_HASH]' --burn-cap 1 +Node is bootstrapped. +Estimated gas: 4936.532 units (will add 100 for safety) +Estimated storage: 110 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.000803 + Expected counter: 1 + Gas limit: 5037 + Storage limit: 130 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000803 + payload fees(the block proposer) ....... +ꜩ0.000803 + Transfer tickets: + Ticket content: "Ticket" + Ticket content type: string + Ticket ticketer: [CONTRACT_HASH] + Ticket amount: 1 + Destination: [CONTRACT_HASH] + Entrypoint: save + From: [PUBLIC_KEY_HASH] + This tickets transfer was successfully applied + Paid storage size diff: 66 bytes + Consumed gas: 2125.832 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Entrypoint: save + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1)) + This transaction was successfully applied + Updated storage: + { Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1) } + Storage size: 238 bytes + Paid storage size diff: 44 bytes + Consumed gas: 2811.345 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.011 + storage fees ........................... +ꜩ0.011 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [CONTRACT_HASH] ... +1 + + +./octez-client --mode mockup get ticket balance for bootstrap2 with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +1 + +./octez-client --mode mockup get ticket balance for '[CONTRACT_HASH]' with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +1 + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --entrypoint send --arg '"[CONTRACT_HASH]"' +Node is bootstrapped. +Estimated gas: 6446.754 units (will add 100 for safety) +Estimated storage: no bytes added +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.000954 + Expected counter: 6 + Gas limit: 6547 + Storage limit: 0 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000954 + payload fees(the block proposer) ....... +ꜩ0.000954 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Entrypoint: send + Parameter: "[CONTRACT_HASH]" + This transaction was successfully applied + Updated storage: {} + Storage size: 194 bytes + Consumed gas: 3694.167 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [CONTRACT_HASH] ... -1 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Entrypoint: ticket + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1)) + This transaction was successfully applied + Updated storage: Unit + Storage size: 51 bytes + Consumed gas: 2753.748 + + +./octez-client --mode mockup get ticket balance for '[CONTRACT_HASH]' with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +0 + +./octez-client --mode mockup get ticket balance for '[CONTRACT_HASH]' with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +0 diff --git a/tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts with some Tez along.out b/tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts with some Tez along.out new file mode 100644 index 000000000000..83e22954c600 --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts with some Tez along.out @@ -0,0 +1,115 @@ + +./octez-client --mode mockup --wait none originate contract ticketer transferring 1 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_send_with_tez.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1439.500 units (will add 100 for safety) +Estimated storage: 411 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.000537 + Expected counter: 1 + Gas limit: 1540 + Storage limit: 431 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000537 + payload fees(the block proposer) ....... +ꜩ0.000537 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ1 + Script: + { parameter address ; + storage unit ; + code { CAR ; + CONTRACT (ticket string) ; + IF_NONE + { PUSH string "Contract not found" ; FAILWITH } + { PUSH mutez 1 ; + PUSH nat 1 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 154 bytes + Paid storage size diff: 154 bytes + Consumed gas: 1439.500 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0385 + storage fees ........................... +ꜩ0.0385 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [PUBLIC_KEY_HASH] ... -ꜩ1 + [CONTRACT_HASH] ... +ꜩ1 + +New contract [CONTRACT_HASH] originated. +Contract memorized as ticketer. + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg '"[PUBLIC_KEY_HASH]"' +Node is bootstrapped. +Estimated gas: 3586.780 units (will add 100 for safety) +Estimated storage: 66 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.000663 + Expected counter: 2 + Gas limit: 3687 + Storage limit: 86 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000663 + payload fees(the block proposer) ....... +ꜩ0.000663 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: "[PUBLIC_KEY_HASH]" + This transaction was successfully applied + Updated storage: Unit + Storage size: 154 bytes + Paid storage size diff: 66 bytes + Consumed gas: 2587.027 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + Internal operations: + Internal Transaction: + Amount: ꜩ0.000001 + From: [CONTRACT_HASH] + To: [PUBLIC_KEY_HASH] + Parameter: (Pair 0x017dfc16eb4482b866500d1104e3e8822d43b67dd100 (Pair "Ticket" 1)) + This transaction was successfully applied + Consumed gas: 1000.398 + Balance updates: + [CONTRACT_HASH] ... -ꜩ0.000001 + [PUBLIC_KEY_HASH] ... +ꜩ0.000001 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [PUBLIC_KEY_HASH] ... +1 + + +./octez-client --mode mockup get ticket balance for bootstrap1 with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +1 diff --git a/tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts with the wrong type must.out b/tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts with the wrong type must.out new file mode 100644 index 000000000000..b3db2698b1f5 --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts with the wrong type must.out @@ -0,0 +1,195 @@ + +./octez-client --mode mockup --wait none originate contract ticketer transferring 1 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/send_ticket_list.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1441.840 units (will add 100 for safety) +Estimated storage: 402 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.000529 + Expected counter: 1 + Gas limit: 1542 + Storage limit: 422 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000529 + payload fees(the block proposer) ....... +ꜩ0.000529 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ1 + Script: + { parameter address ; + storage unit ; + code { CAR ; + CONTRACT (list (ticket string)) ; + ASSERT_SOME ; + PUSH mutez 0 ; + NIL (ticket string) ; + PUSH nat 1 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + CONS ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + UNIT ; + SWAP ; + PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 145 bytes + Paid storage size diff: 145 bytes + Consumed gas: 1441.840 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.03625 + storage fees ........................... +ꜩ0.03625 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [PUBLIC_KEY_HASH] ... -ꜩ1 + [CONTRACT_HASH] ... +ꜩ1 + +New contract [CONTRACT_HASH] originated. +Contract memorized as ticketer. + +./octez-client --mode mockup --wait none originate contract blackhole transferring 1 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_list_blackhole.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1410.157 units (will add 100 for safety) +Estimated storage: 299 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.000423 + Expected counter: 2 + Gas limit: 1511 + Storage limit: 319 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000423 + payload fees(the block proposer) ....... +ꜩ0.000423 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ1 + Script: + { parameter (list (ticket string)) ; + storage unit ; + code { CDR ; NIL operation ; PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 42 bytes + Paid storage size diff: 42 bytes + Consumed gas: 1410.157 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0105 + storage fees ........................... +ꜩ0.0105 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + [PUBLIC_KEY_HASH] ... -ꜩ1 + [CONTRACT_HASH] ... +ꜩ1 + +New contract [CONTRACT_HASH] originated. +Contract memorized as blackhole. + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg '"[CONTRACT_HASH]"' +Node is bootstrapped. +Estimated gas: 5793.984 units (will add 100 for safety) +Estimated storage: 66 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.000884 + Expected counter: 3 + Gas limit: 5894 + Storage limit: 86 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000884 + payload fees(the block proposer) ....... +ꜩ0.000884 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: "[CONTRACT_HASH]" + This transaction was successfully applied + Updated storage: Unit + Storage size: 145 bytes + Paid storage size diff: 66 bytes + Consumed gas: 3041.341 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: { Pair 0x01b90a0e40c09f8a1de565627e93370247fbfe637b00 (Pair "Ticket" 1) } + This transaction was successfully applied + Updated storage: Unit + Storage size: 42 bytes + Consumed gas: 2753.804 + + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg '"[PUBLIC_KEY_HASH]"' +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0 + Expected counter: 4 + Gas limit: 1040000 + Storage limit: 60000 bytes + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: "[PUBLIC_KEY_HASH]" + This operation FAILED. + +Runtime error in contract [CONTRACT_HASH]: + 01: { parameter address ; + 02: storage unit ; + 03: code { CAR ; + 04: CONTRACT (list (ticket string)) ; + 05: ASSERT_SOME ; + 06: PUSH mutez 0 ; + 07: NIL (ticket string) ; + 08: PUSH nat 1 ; + 09: PUSH string "Ticket" ; + 10: TICKET ; + 11: ASSERT_SOME ; + 12: CONS ; + 13: TRANSFER_TOKENS ; + 14: NIL operation ; + 15: SWAP ; + 16: CONS ; + 17: UNIT ; + 18: SWAP ; + 19: PAIR } } +At line 5 characters 9 to 20, +script reached FAILWITH instruction +with Unit +Fatal error: + transfer simulation failed diff --git a/tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts.out b/tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts.out new file mode 100644 index 000000000000..81a3a2453b49 --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Send tickets from contracts to implicit accounts.out @@ -0,0 +1,111 @@ + +./octez-client --mode mockup --wait none originate contract ticketer transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_send.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1441.228 units (will add 100 for safety) +Estimated storage: 415 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.00054 + Expected counter: 1 + Gas limit: 1542 + Storage limit: 435 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.00054 + payload fees(the block proposer) ....... +ꜩ0.00054 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (pair address nat) ; + storage unit ; + code { CAR ; + UNPAIR ; + CONTRACT (ticket string) ; + IF_NONE + { PUSH string "Contract not found" ; FAILWITH } + { PUSH mutez 0 ; + DIG 2 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 158 bytes + Paid storage size diff: 158 bytes + Consumed gas: 1441.228 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0395 + storage fees ........................... +ꜩ0.0395 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as ticketer. + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg 'Pair "[PUBLIC_KEY_HASH]" 1' +Node is bootstrapped. +Estimated gas: 3588.163 units (will add 100 for safety) +Estimated storage: 66 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.000667 + Expected counter: 2 + Gas limit: 3689 + Storage limit: 86 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000667 + payload fees(the block proposer) ....... +ꜩ0.000667 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair "[PUBLIC_KEY_HASH]" 1) + This transaction was successfully applied + Updated storage: Unit + Storage size: 158 bytes + Paid storage size diff: 66 bytes + Consumed gas: 2588.410 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [PUBLIC_KEY_HASH] + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1)) + This transaction was successfully applied + Consumed gas: 1000.398 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [PUBLIC_KEY_HASH] ... +1 + + +./octez-client --mode mockup get ticket balance for bootstrap1 with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +1 diff --git a/tezt/tests/expected/tickets.ml/Alpha- Sending ticket from contract storage to implicit accounts.out b/tezt/tests/expected/tickets.ml/Alpha- Sending ticket from contract storage to implicit accounts.out new file mode 100644 index 000000000000..2888761d6c00 --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Sending ticket from contract storage to implicit accounts.out @@ -0,0 +1,288 @@ + +./octez-client --mode mockup --wait none originate contract ticketer transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_send.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1441.228 units (will add 100 for safety) +Estimated storage: 415 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.00054 + Expected counter: 1 + Gas limit: 1542 + Storage limit: 435 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.00054 + payload fees(the block proposer) ....... +ꜩ0.00054 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (pair address nat) ; + storage unit ; + code { CAR ; + UNPAIR ; + CONTRACT (ticket string) ; + IF_NONE + { PUSH string "Contract not found" ; FAILWITH } + { PUSH mutez 0 ; + DIG 2 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 158 bytes + Paid storage size diff: 158 bytes + Consumed gas: 1441.228 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0395 + storage fees ........................... +ꜩ0.0395 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as ticketer. + +./octez-client --mode mockup --wait none originate contract bag transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_bag_implicit.tz --init '{}' --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1445.657 units (will add 100 for safety) +Estimated storage: 440 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.000565 + Expected counter: 2 + Gas limit: 1546 + Storage limit: 460 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000565 + payload fees(the block proposer) ....... +ꜩ0.000565 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (or (ticket %save string) (address %send)) ; + storage (list (ticket string)) ; + code { UNPAIR ; + IF_LEFT + { CONS ; NIL operation ; PAIR } + { SWAP ; + IF_CONS + { DIG 2 ; + CONTRACT (ticket string) ; + ASSERT_SOME ; + PUSH mutez 0 ; + DIG 2 ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + PAIR } + { PUSH string "no ticket to send" ; FAILWITH } } } } + Initial storage: {} + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 183 bytes + Paid storage size diff: 183 bytes + Consumed gas: 1445.657 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.04575 + storage fees ........................... +ꜩ0.04575 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as bag. + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg 'Pair "[PUBLIC_KEY_HASH]" 1' +Node is bootstrapped. +Estimated gas: 3588.163 units (will add 100 for safety) +Estimated storage: 66 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.000667 + Expected counter: 3 + Gas limit: 3689 + Storage limit: 86 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000667 + payload fees(the block proposer) ....... +ꜩ0.000667 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair "[PUBLIC_KEY_HASH]" 1) + This transaction was successfully applied + Updated storage: Unit + Storage size: 158 bytes + Paid storage size diff: 66 bytes + Consumed gas: 2588.410 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [PUBLIC_KEY_HASH] + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1)) + This transaction was successfully applied + Consumed gas: 1000.398 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [PUBLIC_KEY_HASH] ... +1 + + +./octez-client --mode mockup get ticket balance for bootstrap1 with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +1 + +./octez-client --mode mockup --wait none transfer 1 tickets from bootstrap1 to '[CONTRACT_HASH]' with entrypoint save and contents '"Ticket"' and type string and ticketer '[CONTRACT_HASH]' --burn-cap 1 +Node is bootstrapped. +Estimated gas: 4906.021 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.000799 + Expected counter: 4 + Gas limit: 5007 + Storage limit: 64 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000799 + payload fees(the block proposer) ....... +ꜩ0.000799 + Transfer tickets: + Ticket content: "Ticket" + Ticket content type: string + Ticket ticketer: [CONTRACT_HASH] + Ticket amount: 1 + Destination: [CONTRACT_HASH] + Entrypoint: save + From: [PUBLIC_KEY_HASH] + This tickets transfer was successfully applied + Consumed gas: 2095.828 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Entrypoint: save + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1)) + This transaction was successfully applied + Updated storage: + { Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1) } + Storage size: 227 bytes + Paid storage size diff: 44 bytes + Consumed gas: 2810.838 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.011 + storage fees ........................... +ꜩ0.011 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [CONTRACT_HASH] ... +1 + + +./octez-client --mode mockup get ticket balance for bootstrap1 with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +0 + +./octez-client --mode mockup get ticket balance for '[CONTRACT_HASH]' with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +1 + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --entrypoint send --arg '"[PUBLIC_KEY_HASH]"' +Node is bootstrapped. +Estimated gas: 4240.926 units (will add 100 for safety) +Estimated storage: no bytes added +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.000734 + Expected counter: 5 + Gas limit: 4341 + Storage limit: 0 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000734 + payload fees(the block proposer) ....... +ꜩ0.000734 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Entrypoint: send + Parameter: "[PUBLIC_KEY_HASH]" + This transaction was successfully applied + Updated storage: {} + Storage size: 183 bytes + Consumed gas: 3241.173 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [CONTRACT_HASH] ... -1 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [PUBLIC_KEY_HASH] + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1)) + This transaction was successfully applied + Consumed gas: 1000.398 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [PUBLIC_KEY_HASH] ... +1 + + +./octez-client --mode mockup get ticket balance for bootstrap2 with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +1 + +./octez-client --mode mockup get ticket balance for '[CONTRACT_HASH]' with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +0 diff --git a/tezt/tests/expected/tickets.ml/Alpha- Sending ticket of wrong type from implicit accounts must be rejected.out b/tezt/tests/expected/tickets.ml/Alpha- Sending ticket of wrong type from implicit accounts must be rejected.out new file mode 100644 index 000000000000..ae9c24146406 --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Sending ticket of wrong type from implicit accounts must be rejected.out @@ -0,0 +1,129 @@ + +./octez-client --mode mockup --wait none originate contract ticketer transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_send.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1441.228 units (will add 100 for safety) +Estimated storage: 415 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.00054 + Expected counter: 1 + Gas limit: 1542 + Storage limit: 435 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.00054 + payload fees(the block proposer) ....... +ꜩ0.00054 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (pair address nat) ; + storage unit ; + code { CAR ; + UNPAIR ; + CONTRACT (ticket string) ; + IF_NONE + { PUSH string "Contract not found" ; FAILWITH } + { PUSH mutez 0 ; + DIG 2 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 158 bytes + Paid storage size diff: 158 bytes + Consumed gas: 1441.228 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0395 + storage fees ........................... +ꜩ0.0395 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as ticketer. + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg 'Pair "[PUBLIC_KEY_HASH]" 1' +Node is bootstrapped. +Estimated gas: 3588.163 units (will add 100 for safety) +Estimated storage: 66 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.000667 + Expected counter: 2 + Gas limit: 3689 + Storage limit: 86 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000667 + payload fees(the block proposer) ....... +ꜩ0.000667 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair "[PUBLIC_KEY_HASH]" 1) + This transaction was successfully applied + Updated storage: Unit + Storage size: 158 bytes + Paid storage size diff: 66 bytes + Consumed gas: 2588.410 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [PUBLIC_KEY_HASH] + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1)) + This transaction was successfully applied + Consumed gas: 1000.398 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [PUBLIC_KEY_HASH] ... +1 + + +./octez-client --mode mockup --wait none transfer 2 tickets from bootstrap1 to bootstrap2 with entrypoint default and contents 0 and type nat and ticketer '[CONTRACT_HASH]' --burn-cap 1 +Node is bootstrapped. +This simulation failed: + Manager signed operations: + From: [PUBLIC_KEY_HASH] + Fee to the baker: ꜩ0 + Expected counter: 3 + Gas limit: 1040000 + Storage limit: 60000 bytes + Transfer tickets: + Ticket content: 0 + Ticket content type: nat + Ticket ticketer: [CONTRACT_HASH] + Ticket amount: 2 + Destination: [PUBLIC_KEY_HASH] + From: [PUBLIC_KEY_HASH] + This operation FAILED. + +Error: + Attempted to set negative ticket balance value '-2' for key exprugq4eqX58rVLseAJHVWVa8QNzQ4MTPUxdceBLT1zZHt2whCrLp. diff --git a/tezt/tests/expected/tickets.ml/Alpha- Sending tickets to either implicit accounts or originated contracts accep.out b/tezt/tests/expected/tickets.ml/Alpha- Sending tickets to either implicit accounts or originated contracts accep.out new file mode 100644 index 000000000000..013232a71ab7 --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Sending tickets to either implicit accounts or originated contracts accep.out @@ -0,0 +1,197 @@ + +./octez-client --mode mockup --wait none originate contract ticketer transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_send.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1441.228 units (will add 100 for safety) +Estimated storage: 415 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.00054 + Expected counter: 1 + Gas limit: 1542 + Storage limit: 435 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.00054 + payload fees(the block proposer) ....... +ꜩ0.00054 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (pair address nat) ; + storage unit ; + code { CAR ; + UNPAIR ; + CONTRACT (ticket string) ; + IF_NONE + { PUSH string "Contract not found" ; FAILWITH } + { PUSH mutez 0 ; + DIG 2 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 158 bytes + Paid storage size diff: 158 bytes + Consumed gas: 1441.228 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0395 + storage fees ........................... +ꜩ0.0395 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as ticketer. + +./octez-client --mode mockup --wait none originate contract blackhole transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_blackhole.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1410.196 units (will add 100 for safety) +Estimated storage: 308 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.00043 + Expected counter: 2 + Gas limit: 1511 + Storage limit: 328 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.00043 + payload fees(the block proposer) ....... +ꜩ0.00043 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (ticket %ticket string) ; + storage unit ; + code { CDR ; NIL operation ; PAIR } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 51 bytes + Paid storage size diff: 51 bytes + Consumed gas: 1410.196 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.01275 + storage fees ........................... +ꜩ0.01275 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as blackhole. + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg 'Pair "[PUBLIC_KEY_HASH]" 1' +Node is bootstrapped. +Estimated gas: 3588.163 units (will add 100 for safety) +Estimated storage: 66 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.000667 + Expected counter: 3 + Gas limit: 3689 + Storage limit: 86 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000667 + payload fees(the block proposer) ....... +ꜩ0.000667 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair "[PUBLIC_KEY_HASH]" 1) + This transaction was successfully applied + Updated storage: Unit + Storage size: 158 bytes + Paid storage size diff: 66 bytes + Consumed gas: 2588.410 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [PUBLIC_KEY_HASH] + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1)) + This transaction was successfully applied + Consumed gas: 1000.398 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [PUBLIC_KEY_HASH] ... +1 + + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg 'Pair "[CONTRACT_HASH]" 1' +Node is bootstrapped. +Estimated gas: 5793.484 units (will add 100 for safety) +Estimated storage: 66 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.000888 + Expected counter: 4 + Gas limit: 5894 + Storage limit: 86 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000888 + payload fees(the block proposer) ....... +ꜩ0.000888 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair "[CONTRACT_HASH]" 1) + This transaction was successfully applied + Updated storage: Unit + Storage size: 158 bytes + Paid storage size diff: 66 bytes + Consumed gas: 3040.897 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1)) + This transaction was successfully applied + Updated storage: Unit + Storage size: 51 bytes + Consumed gas: 2753.748 + diff --git a/tezt/tests/expected/tickets.ml/Alpha- Sending zero ticket from implicit accounts must be rejected.out b/tezt/tests/expected/tickets.ml/Alpha- Sending zero ticket from implicit accounts must be rejected.out new file mode 100644 index 000000000000..33c8bb056324 --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Sending zero ticket from implicit accounts must be rejected.out @@ -0,0 +1,174 @@ + +./octez-client --mode mockup --wait none originate contract ticketer transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_send.tz --init Unit --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1441.228 units (will add 100 for safety) +Estimated storage: 415 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.00054 + Expected counter: 1 + Gas limit: 1542 + Storage limit: 435 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.00054 + payload fees(the block proposer) ....... +ꜩ0.00054 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (pair address nat) ; + storage unit ; + code { CAR ; + UNPAIR ; + CONTRACT (ticket string) ; + IF_NONE + { PUSH string "Contract not found" ; FAILWITH } + { PUSH mutez 0 ; + DIG 2 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + TRANSFER_TOKENS ; + PUSH unit Unit ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } } + Initial storage: Unit + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 158 bytes + Paid storage size diff: 158 bytes + Consumed gas: 1441.228 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0395 + storage fees ........................... +ꜩ0.0395 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as ticketer. + +./octez-client --mode mockup --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg 'Pair "[PUBLIC_KEY_HASH]" 1' +Node is bootstrapped. +Estimated gas: 3588.163 units (will add 100 for safety) +Estimated storage: 66 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.000667 + Expected counter: 2 + Gas limit: 3689 + Storage limit: 86 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000667 + payload fees(the block proposer) ....... +ꜩ0.000667 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: (Pair "[PUBLIC_KEY_HASH]" 1) + This transaction was successfully applied + Updated storage: Unit + Storage size: 158 bytes + Paid storage size diff: 66 bytes + Consumed gas: 2588.410 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0165 + storage fees ........................... +ꜩ0.0165 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [PUBLIC_KEY_HASH] + Parameter: (Pair 0x013c68b1807d42e2e2cb5a4dddb457b75dbf4a4dce00 (Pair "Ticket" 1)) + This transaction was successfully applied + Consumed gas: 1000.398 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [PUBLIC_KEY_HASH] ... +1 + + +./octez-client --mode mockup get ticket balance for bootstrap1 with ticketer '[CONTRACT_HASH]' and type string and content '"Ticket"' +1 + +./octez-client --mode mockup --wait none originate contract bag transferring 0 from bootstrap1 running file:./tezt/tests/contracts/proto_alpha/tickets_bag.tz --init '{}' --burn-cap 1 +Node is bootstrapped. +Estimated gas: 1446.306 units (will add 100 for safety) +Estimated storage: 451 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.000576 + Expected counter: 3 + Gas limit: 1547 + Storage limit: 471 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000576 + payload fees(the block proposer) ....... +ꜩ0.000576 + Origination: + From: [PUBLIC_KEY_HASH] + Credit: ꜩ0 + Script: + { parameter (or (ticket %save string) (address %send)) ; + storage (list (ticket string)) ; + code { UNPAIR ; + IF_LEFT + { CONS ; NIL operation ; PAIR } + { SWAP ; + IF_CONS + { DIG 2 ; + CONTRACT %ticket (ticket string) ; + ASSERT_SOME ; + PUSH mutez 0 ; + DIG 2 ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + PAIR } + { PUSH string "no ticket to send" ; FAILWITH } } } } + Initial storage: {} + No delegate for this contract + This origination was successfully applied + Originated contracts: + [CONTRACT_HASH] + Storage size: 194 bytes + Paid storage size diff: 194 bytes + Consumed gas: 1446.306 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.0485 + storage fees ........................... +ꜩ0.0485 + [PUBLIC_KEY_HASH] ... -ꜩ0.06425 + storage fees ........................... +ꜩ0.06425 + +New contract [CONTRACT_HASH] originated. +Contract memorized as bag. + +./octez-client --mode mockup --wait none transfer 0 tickets from bootstrap1 to '[CONTRACT_HASH]' with entrypoint save and contents '"Ticket"' and type string and ticketer '[CONTRACT_HASH]' --burn-cap 1 +Fatal error: + ticket quantity should not be zero or negative diff --git a/tezt/tests/tickets.ml b/tezt/tests/tickets.ml index 7eea0a0bbbab..d1b52fe8e7ac 100644 --- a/tezt/tests/tickets.ml +++ b/tezt/tests/tickets.ml @@ -153,7 +153,707 @@ let test_send_tickets_in_big_map = ~amount:Tez.zero ~giver:"bootstrap2" ~receiver:send_contract_hash - ~arg:(sf {|"%s"|} receive_contract_hash) + ~arg:(sf "%S" receive_contract_hash) + ~hooks + client + in + unit + +let assert_ticket_balance ?hooks ~contract ~ticketer ~ty ~contents ~expected + client = + let* actual = + Client.ticket_balance + ?hooks + ~contract + ~ticketer + ~content_type:ty + ~content:contents + client + in + let expected = Int.to_string expected in + return + @@ Check.((String.trim actual = expected) ~__LOC__ string) + ~error_msg:"expected %R, got %L" + +(* 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. *) +let test_send_tickets_to_implicit_account = + Protocol.register_regression_test + ~__FILE__ + ~title:"Send tickets from contracts to implicit accounts" + ~tags:["client"; "michelson"] + ~supports:(Protocol.From_protocol 16) + @@ fun protocol -> + let* client = Client.init_mockup ~protocol () in + let* ticketer = + Client.originate_contract + ~alias:"ticketer" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_send.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "Pair %S 1" Constant.bootstrap1.public_key_hash) + ~hooks + client + in + let* () = + assert_ticket_balance + ~hooks + ~contract:Constant.bootstrap1.alias + ~ticketer + ~ty:"string" + ~contents:"\"Ticket\"" + ~expected:1 + client + in + unit + +(* 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 *) +let test_send_tickets_to_implicit_account_non_zero_amount = + Protocol.register_regression_test + ~__FILE__ + ~title: + "Send tickets from contracts to implicit accounts with some Tez along" + ~tags:["client"; "michelson"] + ~supports:(Protocol.From_protocol 16) + @@ fun protocol -> + let* client = Client.init_mockup ~protocol () in + let* ticketer = + Client.originate_contract + ~alias:"ticketer" + ~amount:Tez.one + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_send_with_tez.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + let* tez_before = Client.get_balance_for ~account:ticketer client in + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "%S" Constant.bootstrap1.public_key_hash) + ~hooks + client + in + let* () = + assert_ticket_balance + ~hooks + ~contract:Constant.bootstrap1.alias + ~ticketer + ~ty:"string" + ~contents:"\"Ticket\"" + ~expected:1 + client + in + let* tez_after = Client.get_balance_for ~account:ticketer client in + let balance_drop = Tez.(to_mutez @@ (tez_before - tez_after)) in + Check.((balance_drop = 1) int ~__LOC__) ~error_msg:"expected %R, got %L" ; + unit + +(* A contract handle accepting a list of ticket should reject implicit account destination *) +let test_send_tickets_to_implicit_with_wrong_type = + Protocol.register_regression_test + ~__FILE__ + ~title: + "Send tickets from contracts to implicit accounts with the wrong type \ + must fail" + ~tags:["client"; "michelson"] + ~supports:(Protocol.From_protocol 16) + @@ fun protocol -> + let* client = Client.init_mockup ~protocol () in + let* ticketer = + Client.originate_contract + ~alias:"ticketer" + ~amount:Tez.one + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "send_ticket_list.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + let* blackhole = + Client.originate_contract + ~alias:"blackhole" + ~amount:Tez.one + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_list_blackhole.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "%S" blackhole) + ~hooks + client + in + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "%S" Constant.bootstrap1.public_key_hash) + ~hooks + ~expect_failure:true + client + in + unit + +let test_ticket_transfer_commutative = + Protocol.register_regression_test + ~__FILE__ + ~title:"Send tickets between originated contracts and implicit accounts" + ~tags:["client"; "michelson"] + ~supports:(Protocol.From_protocol 16) + @@ fun protocol -> + let* client = Client.init_mockup ~protocol () in + let* ticketer = + Client.originate_contract + ~alias:"ticketer" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_send.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + let* bag = + Client.originate_contract + ~alias:"bag" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_bag.tz") + ~init:"{}" + ~burn_cap:Tez.one + ~hooks + client + in + let* blackhole = + Client.originate_contract + ~alias:"blackhole" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_blackhole.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + (* 1. ticket minter contract -> bootstrap1 (originated -> implicit) *) + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "Pair %S 3" Constant.bootstrap1.public_key_hash) + ~hooks + client + in + let ty = "string" in + let contents = {|"Ticket"|} in + let* () = + assert_ticket_balance + ~hooks + ~contract:Constant.bootstrap1.alias + ~ticketer + ~ty + ~contents + ~expected:3 + client + in + (* 2. bootstrap1 -> bootstrap2 (implicit -> implicit) *) + let*! () = + Client.transfer_tickets + ~burn_cap:Tez.one + ~qty:2L + ~src:Constant.bootstrap1.alias + ~destination:Constant.bootstrap2.alias + ~entrypoint:"default" + ~contents + ~ty + ~ticketer + ~hooks + client + in + let* () = + assert_ticket_balance + ~hooks + ~contract:Constant.bootstrap1.alias + ~ticketer + ~ty + ~contents + ~expected:1 + client + in + let* () = + assert_ticket_balance + ~hooks + ~contract:Constant.bootstrap2.alias + ~ticketer + ~ty + ~contents + ~expected:2 + client + in + (* 3. bootstrap2 -> bag (implicit -> originated) *) + let*! () = + Client.transfer_tickets + ~burn_cap:Tez.one + ~qty:1L + ~src:Constant.bootstrap2.alias + ~destination:bag + ~entrypoint:"save" + ~contents + ~ty + ~ticketer + ~hooks + client + in + let* () = + assert_ticket_balance + ~hooks + ~contract:Constant.bootstrap2.alias + ~ticketer + ~ty + ~contents + ~expected:1 + client + in + let* () = + assert_ticket_balance + ~hooks + ~contract:bag + ~ticketer + ~ty + ~contents + ~expected:1 + client + in + (* 4. bag -> blackhole (originated -> originated) *) + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:bag + ~entrypoint:"send" + ~arg:(sf "%S" blackhole) + ~hooks + client + in + let* () = + assert_ticket_balance + ~hooks + ~contract:bag + ~ticketer + ~ty + ~contents + ~expected:0 + client + in + assert_ticket_balance + ~hooks + ~contract:blackhole + ~ticketer + ~ty + ~contents + ~expected:0 + client + +let test_ticket_transfer_from_storage_to_implicit = + Protocol.register_regression_test + ~__FILE__ + ~title:"Sending ticket from contract storage to implicit accounts" + ~tags:["client"; "michelson"] + ~supports:(Protocol.From_protocol 16) + @@ fun protocol -> + let* client = Client.init_mockup ~protocol () in + let* ticketer = + Client.originate_contract + ~alias:"ticketer" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_send.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + let* bag = + Client.originate_contract + ~alias:"bag" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_bag_implicit.tz") + ~init:"{}" + ~burn_cap:Tez.one + ~hooks + client + in + (* ticketer -> bootstrap1 *) + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "Pair %S 1" Constant.bootstrap1.public_key_hash) + ~hooks + client + in + let ty = "string" in + let contents = {|"Ticket"|} in + let* () = + assert_ticket_balance + ~hooks + ~contract:Constant.bootstrap1.alias + ~ticketer + ~ty + ~contents + ~expected:1 + client + in + (* bootstrap1 -> bag *) + let*! () = + Client.transfer_tickets + ~burn_cap:Tez.one + ~qty:1L + ~src:Constant.bootstrap1.alias + ~destination:bag + ~entrypoint:"save" + ~contents + ~ty + ~ticketer + ~hooks + client + in + let* () = + assert_ticket_balance + ~hooks + ~contract:Constant.bootstrap1.alias + ~ticketer + ~ty + ~contents + ~expected:0 + client + in + let* () = + assert_ticket_balance + ~hooks + ~contract:bag + ~ticketer + ~ty + ~contents + ~expected:1 + client + in + (* bag -> bootstrap2 *) + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:bag + ~entrypoint:"send" + ~arg:(sf "%S" Constant.bootstrap2.public_key_hash) + ~hooks + client + in + let* () = + assert_ticket_balance + ~hooks + ~contract:Constant.bootstrap2.alias + ~ticketer + ~ty + ~contents + ~expected:1 + client + in + let* () = + assert_ticket_balance + ~hooks + ~contract:bag + ~ticketer + ~ty + ~contents + ~expected:0 + client + in + unit + +let test_zero_ticket_rejection = + Protocol.register_regression_test + ~__FILE__ + ~title:"Sending zero ticket from implicit accounts must be rejected" + ~tags:["client"; "michelson"] + ~supports:(Protocol.From_protocol 16) + @@ fun protocol -> + let* client = Client.init_mockup ~protocol () in + let* ticketer = + Client.originate_contract + ~alias:"ticketer" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_send.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "Pair %S 1" Constant.bootstrap1.public_key_hash) + ~hooks + client + in + let ty = "string" and contents = {|"Ticket"|} in + let* () = + assert_ticket_balance + ~hooks + ~contract:Constant.bootstrap1.alias + ~ticketer + ~ty + ~contents + ~expected:1 + client + in + let*! () = + Client.transfer_tickets + ~burn_cap:Tez.one + ~qty:0L + ~src:Constant.bootstrap1.alias + ~destination:Constant.bootstrap2.alias + ~entrypoint:"default" + ~contents + ~ty + ~ticketer + ~expect_failure:true + client + in + let* bag = + Client.originate_contract + ~alias:"bag" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_bag.tz") + ~init:"{}" + ~burn_cap:Tez.one + ~hooks + client + in + let*! () = + Client.transfer_tickets + ~burn_cap:Tez.one + ~qty:0L + ~src:Constant.bootstrap1.alias + ~destination:bag + ~entrypoint:"save" + ~contents + ~ty + ~ticketer + ~expect_failure:true + ~hooks + client + in + unit + +let test_ticket_overdraft_rejection = + Protocol.register_regression_test + ~__FILE__ + ~title:"Overdrafting ticket from implicit accounts must be rejected" + ~tags:["client"; "michelson"] + ~supports:(Protocol.From_protocol 16) + @@ fun protocol -> + let* client = Client.init_mockup ~protocol () in + let* ticketer = + Client.originate_contract + ~alias:"ticketer" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_send.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "Pair %S 1" Constant.bootstrap1.public_key_hash) + ~hooks + client + in + let ty = "string" and contents = {|"Ticket"|} in + let*! () = + Client.transfer_tickets + ~burn_cap:Tez.one + ~qty:2L + ~src:Constant.bootstrap1.alias + ~destination:Constant.bootstrap2.alias + ~entrypoint:"default" + ~contents + ~ty + ~ticketer + ~expect_failure:true + ~hooks + client + in + let* bag = + Client.originate_contract + ~alias:"bag" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_bag.tz") + ~init:"{}" + ~burn_cap:Tez.one + ~hooks + client + in + let*! () = + Client.transfer_tickets + ~burn_cap:Tez.one + ~qty:2L + ~src:Constant.bootstrap1.alias + ~destination:bag + ~entrypoint:"save" + ~contents + ~ty + ~ticketer + ~expect_failure:true + ~hooks + client + in + unit + +let test_ticket_of_wrong_type_rejection = + Protocol.register_regression_test + ~__FILE__ + ~title: + "Sending ticket of wrong type from implicit accounts must be rejected" + ~tags:["client"; "michelson"] + ~supports:(Protocol.From_protocol 16) + @@ fun protocol -> + let* client = Client.init_mockup ~protocol () in + let* ticketer = + Client.originate_contract + ~alias:"ticketer" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_send.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "Pair %S 1" Constant.bootstrap1.public_key_hash) + ~hooks + client + in + let*! () = + Client.transfer_tickets + ~burn_cap:Tez.one + ~qty:2L + ~src:Constant.bootstrap1.alias + ~destination:Constant.bootstrap2.alias + ~entrypoint:"default" + ~contents:"0" + ~ty:"nat" + ~ticketer + ~expect_failure:true + ~hooks + client + in + unit + +let test_originated_implicit_can_be_equipotent = + Protocol.register_regression_test + ~__FILE__ + ~title: + "Sending tickets to either implicit accounts or originated contracts \ + accepting tickets with default entrypoint should equally work" + ~tags:["client"; "michelson"] + ~supports:(Protocol.From_protocol 16) + @@ fun protocol -> + let* client = Client.init_mockup ~protocol () in + let* ticketer = + Client.originate_contract + ~alias:"ticketer" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_send.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + let* blackhole = + Client.originate_contract + ~alias:"blackhole" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "tickets_blackhole.tz") + ~init:"Unit" + ~burn_cap:Tez.one + ~hooks + client + in + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "Pair %S 1" Constant.bootstrap1.public_key_hash) + ~hooks + client + in + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "Pair %S 1" blackhole) ~hooks client in @@ -161,4 +861,13 @@ let test_send_tickets_in_big_map = let register ~protocols = test_create_and_remove_tickets protocols ; - test_send_tickets_in_big_map protocols + test_send_tickets_in_big_map protocols ; + test_send_tickets_to_implicit_account protocols ; + test_send_tickets_to_implicit_account_non_zero_amount protocols ; + test_send_tickets_to_implicit_with_wrong_type protocols ; + test_ticket_transfer_commutative protocols ; + test_ticket_transfer_from_storage_to_implicit protocols ; + test_zero_ticket_rejection protocols ; + test_ticket_overdraft_rejection protocols ; + test_ticket_of_wrong_type_rejection protocols ; + test_originated_implicit_can_be_equipotent protocols diff --git a/tezt/tests/tx_rollup.ml b/tezt/tests/tx_rollup.ml index 56bc912e195d..5f2f0e6c9150 100644 --- a/tezt/tests/tx_rollup.ml +++ b/tezt/tests/tx_rollup.ml @@ -1707,7 +1707,7 @@ let test_deposit_withdraw_max_big_tickets = let* () = repeat max_withdrawals_per_batch (fun () -> let*! () = - Client.Tx_rollup.transfer_tickets + Client.transfer_tickets ~qty:l2_amount ~src:account ~destination:withdraw_contract diff --git a/tezt/tests/tx_rollup_l2_node.ml b/tezt/tests/tx_rollup_l2_node.ml index 1c0b35ce3079..f435e997a82a 100644 --- a/tezt/tests/tx_rollup_l2_node.ml +++ b/tezt/tests/tx_rollup_l2_node.ml @@ -2404,7 +2404,7 @@ let test_round_trip ~title ?before_init ~originator ~operator ~batch_signer let* () = Client.bake_for_and_wait client in Log.info "Transfer the tickets to withdraw contract" ; let*! () = - Client.Tx_rollup.transfer_tickets + Client.transfer_tickets ~qty:15L ~src:Constant.bootstrap2.public_key_hash ~destination:withdraw_contract -- GitLab