From 5c63b7a52a87f780b5f760cd30b1d099842bdf25 Mon Sep 17 00:00:00 2001 From: lin Date: Wed, 23 Nov 2022 21:09:14 +0000 Subject: [PATCH 1/2] Proto: Add ticket receipt to origininated->sc-rollup --- .../lib_client/operation_result.ml | 4 +- src/proto_alpha/lib_protocol/apply.ml | 38 +++++++++++++++++-- .../lib_protocol/apply_internal_results.ml | 14 ++++--- .../lib_protocol/apply_internal_results.mli | 1 + src/proto_alpha/lib_protocol/apply_results.ml | 13 ++++--- 5 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/proto_alpha/lib_client/operation_result.ml b/src/proto_alpha/lib_client/operation_result.ml index 16a01af980c4..2e20f35e1f06 100644 --- a/src/proto_alpha/lib_client/operation_result.ml +++ b/src/proto_alpha/lib_client/operation_result.ml @@ -647,8 +647,10 @@ let pp_transaction_result ppf = function pp_balance_updates ppf balance_updates ; Format.fprintf ppf "@,Ticket hash: %a" Ticket_hash.pp ticket_hash ; pp_paid_storage_size_diff ppf paid_storage_size_diff - | Transaction_to_sc_rollup_result {consumed_gas; inbox_after} -> + | Transaction_to_sc_rollup_result {consumed_gas; ticket_receipt; inbox_after} + -> pp_consumed_gas ppf consumed_gas ; + pp_ticket_receipt ppf ticket_receipt ; pp_inbox_after ppf inbox_after | Transaction_to_zk_rollup_result {balance_updates; consumed_gas; ticket_hash; paid_storage_size_diff} -> diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index b592439e2f85..ce879672ba11 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -676,8 +676,8 @@ let apply_internal_operation_contents : { destination; entrypoint = _; - parameters_ty = _; - parameters = _; + parameters_ty; + parameters; unparsed_parameters = payload; } -> assert_sc_rollup_feature_enabled ctxt >>?= fun () -> @@ -700,10 +700,40 @@ let apply_internal_operation_contents : ~payload ~sender ~source:payer - >|=? fun (inbox_after, _size, ctxt) -> + >>=? fun (inbox_after, _size, ctxt) -> + Ticket_scanner.type_has_tickets ctxt parameters_ty + >>?= fun (has_tickets, ctxt) -> + Ticket_accounting.ticket_balances_of_value + ctxt + ~include_lazy:true + has_tickets + parameters + >>=? fun (ticket_token_map, ctxt) -> + (* TODO: https://gitlab.com/tezos/tezos/-/issues/4354 + Factor out function for constructing a ticket receipt. + There are multiple places where we compute the receipt from a + ticket-token-map. We should factor out and reuse this logic. *) + Ticket_token_map.fold_es + ctxt + (fun ctxt acc ex_token amount -> + Ticket_token_unparser.unparse ctxt ex_token + >>=? fun (ticket_token, ctxt) -> + let item = + Ticket_receipt. + { + ticket_token; + updates = + [{account = Destination.Sc_rollup destination; amount}]; + } + in + return (item :: acc, ctxt)) + [] + ticket_token_map + >|=? fun (ticket_receipt, ctxt) -> let consumed_gas = Gas.consumed ~since:ctxt_before_op ~until:ctxt in let result = - Transaction_to_sc_rollup_result {consumed_gas; inbox_after} + Transaction_to_sc_rollup_result + {consumed_gas; ticket_receipt; inbox_after} in (ctxt, ITransaction_result result, []) | Event {ty = _; unparsed_data = _; tag = _} -> diff --git a/src/proto_alpha/lib_protocol/apply_internal_results.ml b/src/proto_alpha/lib_protocol/apply_internal_results.ml index 1f984ca1083f..0f5a93a137f1 100644 --- a/src/proto_alpha/lib_protocol/apply_internal_results.ml +++ b/src/proto_alpha/lib_protocol/apply_internal_results.ml @@ -160,6 +160,7 @@ type successful_transaction_result = } | Transaction_to_sc_rollup_result of { consumed_gas : Gas.Arith.fp; + ticket_receipt : Ticket_receipt.t; inbox_after : Sc_rollup.Inbox.t; } | Transaction_to_zk_rollup_result of { @@ -335,16 +336,19 @@ module Internal_operation = struct case ~title:"To_sc_rollup" (Tag 2) - (obj2 + (obj3 (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero) + (req "ticket_receipt" Ticket_receipt.encoding) (req "inbox_after" Sc_rollup.Inbox.encoding)) (function - | Transaction_to_sc_rollup_result {consumed_gas; inbox_after} -> - Some (consumed_gas, inbox_after) + | Transaction_to_sc_rollup_result + {consumed_gas; ticket_receipt; inbox_after} -> + Some (consumed_gas, ticket_receipt, inbox_after) | _ -> None) (function - | consumed_gas, inbox_after -> - Transaction_to_sc_rollup_result {consumed_gas; inbox_after}); + | consumed_gas, ticket_receipt, inbox_after -> + Transaction_to_sc_rollup_result + {consumed_gas; ticket_receipt; inbox_after}); ] let transaction_case = diff --git a/src/proto_alpha/lib_protocol/apply_internal_results.mli b/src/proto_alpha/lib_protocol/apply_internal_results.mli index 92754cceb50a..1f9e210d1a71 100644 --- a/src/proto_alpha/lib_protocol/apply_internal_results.mli +++ b/src/proto_alpha/lib_protocol/apply_internal_results.mli @@ -96,6 +96,7 @@ type successful_transaction_result = } | Transaction_to_sc_rollup_result of { consumed_gas : Gas.Arith.fp; + ticket_receipt : Ticket_receipt.t; inbox_after : Sc_rollup.Inbox.t; } | Transaction_to_zk_rollup_result of { diff --git a/src/proto_alpha/lib_protocol/apply_results.ml b/src/proto_alpha/lib_protocol/apply_results.ml index 1ddf35f9a8d1..a9e6e0b65712 100644 --- a/src/proto_alpha/lib_protocol/apply_results.ml +++ b/src/proto_alpha/lib_protocol/apply_results.ml @@ -410,16 +410,19 @@ module Manager_result = struct case ~title:"To_sc_rollup" (Tag 2) - (obj2 + (obj3 (dft "consumed_milligas" Gas.Arith.n_fp_encoding Gas.Arith.zero) + (req "ticket_updates" Ticket_receipt.encoding) (req "inbox_after" Sc_rollup.Inbox.encoding)) (function - | Transaction_to_sc_rollup_result {consumed_gas; inbox_after} -> - Some (consumed_gas, inbox_after) + | Transaction_to_sc_rollup_result + {consumed_gas; ticket_receipt; inbox_after} -> + Some (consumed_gas, ticket_receipt, inbox_after) | _ -> None) (function - | consumed_gas, inbox_after -> - Transaction_to_sc_rollup_result {consumed_gas; inbox_after}); + | consumed_gas, ticket_receipt, inbox_after -> + Transaction_to_sc_rollup_result + {consumed_gas; ticket_receipt; inbox_after}); ] let transaction_case = -- GitLab From bf3f2ad0bfcd17c947f8f4bce36fdb65c5f933ba Mon Sep 17 00:00:00 2001 From: lin Date: Mon, 28 Nov 2022 12:08:34 +0000 Subject: [PATCH 2/2] Tezt: Test ticket receipt for originated->sc-rollup --- .../proto_alpha/send_ticket_list_multiple.tz | 25 ++++ .../proto_alpha/send_tickets_from_storage.tz | 28 ++++ ...rt-contract rollup should succeed with.out | 67 ++++++++++ ...rt-contract rollup should succeed with.out | 124 ++++++++++++++++++ tezt/tests/tickets.ml | 113 +++++++++++++++- 5 files changed, 356 insertions(+), 1 deletion(-) create mode 100644 tezt/tests/contracts/proto_alpha/send_ticket_list_multiple.tz create mode 100644 tezt/tests/contracts/proto_alpha/send_tickets_from_storage.tz create mode 100644 tezt/tests/expected/tickets.ml/Alpha- Minting then sending tickets to smart-contract rollup should succeed with.out create mode 100644 tezt/tests/expected/tickets.ml/Alpha- Sending tickets from storage to smart-contract rollup should succeed with.out diff --git a/tezt/tests/contracts/proto_alpha/send_ticket_list_multiple.tz b/tezt/tests/contracts/proto_alpha/send_ticket_list_multiple.tz new file mode 100644 index 000000000000..a0049fd82c78 --- /dev/null +++ b/tezt/tests/contracts/proto_alpha/send_ticket_list_multiple.tz @@ -0,0 +1,25 @@ +# This contract mints tickets into a list with multiple elements 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 ; + PUSH nat 1 ; + PUSH string "Ticket2" ; + TICKET ; + ASSERT_SOME ; + CONS ; + TRANSFER_TOKENS ; + NIL operation ; + SWAP ; + CONS ; + UNIT ; + SWAP ; + PAIR } diff --git a/tezt/tests/contracts/proto_alpha/send_tickets_from_storage.tz b/tezt/tests/contracts/proto_alpha/send_tickets_from_storage.tz new file mode 100644 index 000000000000..bdaf51bb1352 --- /dev/null +++ b/tezt/tests/contracts/proto_alpha/send_tickets_from_storage.tz @@ -0,0 +1,28 @@ +# Contract for sending tickets from storage. Has two entrypoints: +# - Mint: creates two new tickets and saves them in the storage +# - Send: takes a contract and sends all stored tickets to it +{ parameter (or (unit %mint) (contract %send (list (ticket string)))) ; + storage (list (ticket string)) ; + code { UNPAIR ; + IF_LEFT + { DROP ; + PUSH nat 1 ; + PUSH string "Ticket" ; + TICKET ; + ASSERT_SOME ; + CONS ; + PUSH nat 1 ; + PUSH string "Ticket2" ; + TICKET ; + ASSERT_SOME ; + CONS ; + NIL operation ; + PAIR } + { PUSH mutez 0 ; + DIG 2 ; + TRANSFER_TOKENS ; + NIL (ticket string) ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } } } diff --git a/tezt/tests/expected/tickets.ml/Alpha- Minting then sending tickets to smart-contract rollup should succeed with.out b/tezt/tests/expected/tickets.ml/Alpha- Minting then sending tickets to smart-contract rollup should succeed with.out new file mode 100644 index 000000000000..8a3669e0169d --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Minting then sending tickets to smart-contract rollup should succeed with.out @@ -0,0 +1,67 @@ + +./octez-client --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --arg '"[SC_ROLLUP_HASH]"' +Node is bootstrapped. +Estimated gas: 4514.574 units (will add 100 for safety) +Estimated storage: 132 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.000758 + Expected counter: 3 + Gas limit: 4615 + Storage limit: 152 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000758 + payload fees(the block proposer) ....... +ꜩ0.000758 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Parameter: "[SC_ROLLUP_HASH]" + This transaction was successfully applied + Updated storage: Unit + Storage size: 197 bytes + Paid storage size diff: 132 bytes + Consumed gas: 3504.135 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.033 + storage fees ........................... +ꜩ0.033 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [SC_ROLLUP_HASH] + Parameter: { Pair 0x01fd32c99a7029e62387c85d6e9394626ecbcaa97700 (Pair "Ticket2" 1) ; + Pair 0x01fd32c99a7029e62387c85d6e9394626ecbcaa97700 (Pair "Ticket" 1) } + This transaction was successfully applied + Consumed gas: 1010.439 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [SC_ROLLUP_HASH] ... +1 + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket2" + Account updates: + [SC_ROLLUP_HASH] ... +1 + Resulting inbox state: { level = 4 + current messages hash = hash: [SC_ROLLUP_INBOX_LEVEL_TREE_HASH] + level: 4 + nb_messages_in_commitment_period = 12 + old_levels_messages = + content = hash: [SC_ROLLUP_INBOX_LEVEL_TREE_HASH] + level: 3 + index = 3 + back_pointers = [SC_ROLLUP_INBOX_HASH] + [SC_ROLLUP_INBOX_HASH] + + } + diff --git a/tezt/tests/expected/tickets.ml/Alpha- Sending tickets from storage to smart-contract rollup should succeed with.out b/tezt/tests/expected/tickets.ml/Alpha- Sending tickets from storage to smart-contract rollup should succeed with.out new file mode 100644 index 000000000000..b599c255cdf9 --- /dev/null +++ b/tezt/tests/expected/tickets.ml/Alpha- Sending tickets from storage to smart-contract rollup should succeed with.out @@ -0,0 +1,124 @@ + +./octez-client --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --entrypoint mint +Node is bootstrapped. +Estimated gas: 3053.548 units (will add 100 for safety) +Estimated storage: 221 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.000577 + Expected counter: 3 + Gas limit: 3154 + Storage limit: 241 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000577 + payload fees(the block proposer) ....... +ꜩ0.000577 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Entrypoint: mint + This transaction was successfully applied + Updated storage: + { Pair 0x017a1d05251a570ed6e6e5af81f60883b857f8664500 (Pair "Ticket2" 1) ; + Pair 0x017a1d05251a570ed6e6e5af81f60883b857f8664500 (Pair "Ticket" 1) } + Storage size: 309 bytes + Paid storage size diff: 221 bytes + Consumed gas: 3053.548 + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.05525 + storage fees ........................... +ꜩ0.05525 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [CONTRACT_HASH] ... +1 + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket2" + Account updates: + [CONTRACT_HASH] ... +1 + + +./octez-client --wait none transfer 0 from bootstrap1 to '[CONTRACT_HASH]' --burn-cap 1 --entrypoint send --arg '"[SC_ROLLUP_HASH]"' +Node is bootstrapped. +Estimated gas: 4871.741 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.000798 + Expected counter: 4 + Gas limit: 4972 + Storage limit: 0 bytes + Balance updates: + [PUBLIC_KEY_HASH] ... -ꜩ0.000798 + payload fees(the block proposer) ....... +ꜩ0.000798 + Transaction: + Amount: ꜩ0 + From: [PUBLIC_KEY_HASH] + To: [CONTRACT_HASH] + Entrypoint: send + Parameter: "[SC_ROLLUP_HASH]" + This transaction was successfully applied + Updated storage: {} + Storage size: 220 bytes + Consumed gas: 3861.302 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [CONTRACT_HASH] ... -1 + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket2" + Account updates: + [CONTRACT_HASH] ... -1 + Internal operations: + Internal Transaction: + Amount: ꜩ0 + From: [CONTRACT_HASH] + To: [SC_ROLLUP_HASH] + Parameter: { Pair 0x017a1d05251a570ed6e6e5af81f60883b857f8664500 (Pair "Ticket2" 1) ; + Pair 0x017a1d05251a570ed6e6e5af81f60883b857f8664500 (Pair "Ticket" 1) } + This transaction was successfully applied + Consumed gas: 1010.439 + Ticket updates: + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket" + Account updates: + [SC_ROLLUP_HASH] ... +1 + Ticketer: [CONTRACT_HASH] + Content type: string + Content: "Ticket2" + Account updates: + [SC_ROLLUP_HASH] ... +1 + Resulting inbox state: { level = 5 + current messages hash = hash: [SC_ROLLUP_INBOX_LEVEL_TREE_HASH] + level: 5 + nb_messages_in_commitment_period = 15 + old_levels_messages = + content = hash: [SC_ROLLUP_INBOX_LEVEL_TREE_HASH] + level: 4 + index = 4 + back_pointers = [SC_ROLLUP_INBOX_HASH] + [SC_ROLLUP_INBOX_HASH] + [SC_ROLLUP_INBOX_HASH] + + } + diff --git a/tezt/tests/tickets.ml b/tezt/tests/tickets.ml index d1b52fe8e7ac..6d146bbad46b 100644 --- a/tezt/tests/tickets.ml +++ b/tezt/tests/tickets.ml @@ -859,6 +859,115 @@ let test_originated_implicit_can_be_equipotent = in unit +let setup_sc_enabled_node protocol ~parameters_ty = + let parameters = [(["sc_rollup_enable"], `Bool true)] in + let base = Either.right (protocol, None) in + let* parameter_file = Protocol.write_parameter_file ~base parameters in + let nodes_args = + Node.[Synchronisation_threshold 0; History_mode Archive; No_bootstrap_peers] + in + let* tezos_node, tezos_client = + Client.init_with_protocol ~parameter_file `Client ~protocol ~nodes_args () + in + let* sc_rollup = + Client.Sc_rollup.( + originate + ~burn_cap:(Tez.of_int 2) + ~src:Constant.bootstrap1.alias + ~kind:"wasm_2_0_0" + ~parameters_ty + ~boot_sector:Constant.wasm_echo_kernel_boot_sector + tezos_client) + in + let* () = Client.bake_for_and_wait tezos_client in + return (tezos_node, tezos_client, sc_rollup) + +let test_send_tickets_to_sc_rollup = + Protocol.register_regression_test + ~__FILE__ + ~title: + "Minting then sending tickets to smart-contract rollup should succeed \ + with appropriate ticket updates field in receipt." + ~tags:["client"; "michelson"] + ~supports:(Protocol.From_protocol 16) + @@ fun protocol -> + let* _node, client, sc_rollup = + setup_sc_enabled_node protocol ~parameters_ty:"list (ticket string)" + in + let* ticketer = + Client.originate_contract + ~alias:"ticketer" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "send_ticket_list_multiple.tz") + ~init:"Unit" + ~burn_cap:Tez.one + client + in + let* () = Client.bake_for_and_wait client in + let* () = + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "%S" sc_rollup) + ~hooks + client + in + let* () = Client.bake_for_and_wait client in + unit + +let test_send_tickets_from_storage_to_sc_rollup = + Protocol.register_regression_test + ~__FILE__ + ~title: + "Sending tickets from storage to smart-contract rollup should succeed \ + with appropriate ticket updates field in receipt." + ~tags:["client"; "michelson"] + ~supports:(Protocol.From_protocol 16) + @@ fun protocol -> + let* _node, client, sc_rollup = + setup_sc_enabled_node protocol ~parameters_ty:"list (ticket string)" + in + let* ticketer = + Client.originate_contract + ~alias:"ticketer" + ~amount:Tez.zero + ~src:Constant.bootstrap1.alias + ~prg:(protocol_dependent_path protocol "send_tickets_from_storage.tz") + ~init:"{}" + ~burn_cap:Tez.one + client + in + let* () = Client.bake_for_and_wait client in + let* () = + (* Call "mint" entrypoint to mint tickets and store them in storage. *) + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~entrypoint:"mint" + ~hooks + client + in + let* () = Client.bake_for_and_wait client in + let* () = + (* Call "send" entrypoint to send tickets to sc-rollup from storage. *) + Client.transfer + ~burn_cap:Tez.one + ~amount:Tez.zero + ~giver:Constant.bootstrap1.alias + ~receiver:ticketer + ~arg:(sf "%S" sc_rollup) + ~entrypoint:"send" + ~hooks + client + in + let* () = Client.bake_for_and_wait client in + unit + let register ~protocols = test_create_and_remove_tickets protocols ; test_send_tickets_in_big_map protocols ; @@ -870,4 +979,6 @@ let register ~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 + test_originated_implicit_can_be_equipotent protocols ; + test_send_tickets_to_sc_rollup protocols ; + test_send_tickets_from_storage_to_sc_rollup protocols -- GitLab