From 81237c6490024b9786e21c64d90a9f2016d35861 Mon Sep 17 00:00:00 2001 From: lin Date: Mon, 24 Oct 2022 14:05:51 +0900 Subject: [PATCH 1/8] Proto: Factor out ticket token unparsing logic We will re-use this unparse function when representing tickets in the ticket balance RPC response. --- src/proto_alpha/lib_protocol/TEZOS_PROTOCOL | 1 + src/proto_alpha/lib_protocol/dune | 4 ++ .../lib_protocol/ticket_token_map.ml | 22 +------- .../lib_protocol/ticket_token_unparser.ml | 51 +++++++++++++++++++ .../lib_protocol/ticket_token_unparser.mli | 34 +++++++++++++ 5 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 src/proto_alpha/lib_protocol/ticket_token_unparser.ml create mode 100644 src/proto_alpha/lib_protocol/ticket_token_unparser.mli diff --git a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL index 938c2e763d8e..a8ae4f108e05 100644 --- a/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL +++ b/src/proto_alpha/lib_protocol/TEZOS_PROTOCOL @@ -221,6 +221,7 @@ "Script_big_map", "Script_cache", "Script_tc_errors_registration", + "Ticket_token_unparser", "Ticket_costs", "Ticket_scanner", "Ticket_balance_key", diff --git a/src/proto_alpha/lib_protocol/dune b/src/proto_alpha/lib_protocol/dune index e2ce10c4a8c1..5ea086515edc 100644 --- a/src/proto_alpha/lib_protocol/dune +++ b/src/proto_alpha/lib_protocol/dune @@ -231,6 +231,7 @@ Script_big_map Script_cache Script_tc_errors_registration + Ticket_token_unparser Ticket_costs Ticket_scanner Ticket_balance_key @@ -502,6 +503,7 @@ script_big_map.ml script_big_map.mli script_cache.ml script_cache.mli script_tc_errors_registration.ml script_tc_errors_registration.mli + ticket_token_unparser.ml ticket_token_unparser.mli ticket_costs.ml ticket_costs.mli ticket_scanner.ml ticket_scanner.mli ticket_balance_key.ml ticket_balance_key.mli @@ -753,6 +755,7 @@ script_big_map.ml script_big_map.mli script_cache.ml script_cache.mli script_tc_errors_registration.ml script_tc_errors_registration.mli + ticket_token_unparser.ml ticket_token_unparser.mli ticket_costs.ml ticket_costs.mli ticket_scanner.ml ticket_scanner.mli ticket_balance_key.ml ticket_balance_key.mli @@ -1009,6 +1012,7 @@ script_big_map.ml script_big_map.mli script_cache.ml script_cache.mli script_tc_errors_registration.ml script_tc_errors_registration.mli + ticket_token_unparser.ml ticket_token_unparser.mli ticket_costs.ml ticket_costs.mli ticket_scanner.ml ticket_scanner.mli ticket_balance_key.ml ticket_balance_key.mli diff --git a/src/proto_alpha/lib_protocol/ticket_token_map.ml b/src/proto_alpha/lib_protocol/ticket_token_map.ml index 9daab389c4f8..81310a54fdcc 100644 --- a/src/proto_alpha/lib_protocol/ticket_token_map.ml +++ b/src/proto_alpha/lib_protocol/ticket_token_map.ml @@ -120,27 +120,9 @@ let to_ticket_receipt ctxt ~owner ticket_token_map = (fun ctxt acc _ticket_hash (ex_ticket, amount) -> if Z.(equal amount zero) then return (acc, ctxt) else - let (Ticket_token.Ex_token {ticketer; contents_type; contents}) = - ex_ticket + let* ticket_token, ctxt = + Ticket_token_unparser.unparse ctxt ex_ticket in - let loc = Micheline.dummy_location in - let* contents, ctxt = - Script_ir_unparser.unparse_comparable_data - ctxt - Script_ir_unparser.Optimized_legacy - contents_type - contents - in - let*? ty_unstripped, ctxt = - Script_ir_unparser.unparse_ty ~loc ctxt contents_type - in - let*? ctxt = - Gas.consume ctxt (Script.strip_annotations_cost ty_unstripped) - in - let ty = Script.strip_annotations ty_unstripped in - let*? ctxt = Gas.consume ctxt (Script.strip_locations_cost ty) in - let contents_type = Micheline.strip_locations ty in - let ticket_token = Ticket_token.{ticketer; contents_type; contents} in let update = Ticket_receipt.{ticket_token; updates = [{account = owner; amount}]} in diff --git a/src/proto_alpha/lib_protocol/ticket_token_unparser.ml b/src/proto_alpha/lib_protocol/ticket_token_unparser.ml new file mode 100644 index 000000000000..0d0a5ab55f73 --- /dev/null +++ b/src/proto_alpha/lib_protocol/ticket_token_unparser.ml @@ -0,0 +1,51 @@ +(*****************************************************************************) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +(* TODO: https://gitlab.com/tezos/tezos/-/issues/4167 + + Disclaimer: + A more natural place to place [unparse] would be in [Ticket_token] module. + But unfortunantly, we could not put it there due to circular dependency. + The root cause of this circular dependency is the dependency + from [Script_ir_translator] to [Apply_internal_result], but removing this + dependency would require a relatively large refactor. *) + +let unparse ctxt (Ticket_token.Ex_token {ticketer; contents_type; contents}) = + let open Lwt_result_syntax in + let open Script_ir_unparser in + let* contents, ctxt = + unparse_comparable_data ctxt Optimized_legacy contents_type contents + in + let*? ty_unstripped, ctxt = + unparse_ty ~loc:Micheline.dummy_location ctxt contents_type + in + let*? ctxt = Gas.consume ctxt (Script.strip_annotations_cost ty_unstripped) in + let ty = Script.strip_annotations ty_unstripped in + let*? ctxt = Gas.consume ctxt (Script.strip_locations_cost ty) in + let contents_type = Micheline.strip_locations ty in + let ticket_token = Ticket_token.{ticketer; contents_type; contents} in + return (ticket_token, ctxt) diff --git a/src/proto_alpha/lib_protocol/ticket_token_unparser.mli b/src/proto_alpha/lib_protocol/ticket_token_unparser.mli new file mode 100644 index 000000000000..92a27fb35162 --- /dev/null +++ b/src/proto_alpha/lib_protocol/ticket_token_unparser.mli @@ -0,0 +1,34 @@ +(*****************************************************************************) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Alpha_context + +(** [unparse ctxt ex_token] returns the unparsed version of [ex_token] where + each ticket field is converted to a Micheline representation. The gas is + being consumed from [ctxt]. *) +val unparse : + context -> + Ticket_token.ex_token -> + (Ticket_token.unparsed_token * context) tzresult Lwt.t -- GitLab From 9a87d4227930ccf520239661ec347d6a2ce5e767 Mon Sep 17 00:00:00 2001 From: lin Date: Fri, 28 Oct 2022 16:53:57 +0900 Subject: [PATCH 2/8] Proto: Expose ticket_balances_of_value This function will be used to implement the all_ticket_balances RPC --- src/proto_alpha/lib_protocol/ticket_accounting.mli | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/proto_alpha/lib_protocol/ticket_accounting.mli b/src/proto_alpha/lib_protocol/ticket_accounting.mli index cc5ef763b987..621fb196a8ec 100644 --- a/src/proto_alpha/lib_protocol/ticket_accounting.mli +++ b/src/proto_alpha/lib_protocol/ticket_accounting.mli @@ -45,6 +45,16 @@ val ticket_diffs : lazy_storage_diff:Lazy_storage.diffs_item list -> (Z.t Ticket_token_map.t * Ticket_receipt.t * context) tzresult Lwt.t +(** [ticket_balances_of_value ctxt ~include_lazy has_tickets value] + scans all tickets in the given [value] using the type-witness [has_tickets] + and returns a map from ticket-tokens to the amount. *) +val ticket_balances_of_value : + context -> + include_lazy:bool -> + 'a Ticket_scanner.has_tickets -> + 'a -> + (Z.t Ticket_token_map.t * context) tzresult Lwt.t + (** [update_ticket_balances ctxt ~self_contract ~ticket_diffs operations] updates the ticket balances according to the [ticket_diffs] map and the set of operations. The function also returns the storage size diff resulting from -- GitLab From a0b590427605c219a421a53b3236aea6dfabb720 Mon Sep 17 00:00:00 2001 From: lin Date: Sat, 5 Nov 2022 02:36:11 +0900 Subject: [PATCH 3/8] Proto: Add Lwt-aware map/fold to Ticket_token_map --- .../lib_protocol/ticket_accounting.ml | 2 +- .../lib_protocol/ticket_operations_diff.ml | 2 +- .../lib_protocol/ticket_token_map.ml | 8 ++++++-- .../lib_protocol/ticket_token_map.mli | 20 +++++++++++++++---- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/proto_alpha/lib_protocol/ticket_accounting.ml b/src/proto_alpha/lib_protocol/ticket_accounting.ml index 3019d07dca03..5eaf1ea7de31 100644 --- a/src/proto_alpha/lib_protocol/ticket_accounting.ml +++ b/src/proto_alpha/lib_protocol/ticket_accounting.ml @@ -64,7 +64,7 @@ module Ticket_token_map = struct let add ctxt = Ticket_token_map.merge ctxt ~merge_overlap let sub ctxt m1 m2 = - map + map_e ctxt (fun ctxt _ amount -> Gas.consume ctxt (Ticket_costs.negate_cost amount) >|? fun ctxt -> diff --git a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml index e4fff65f597f..60c7f1fccf18 100644 --- a/src/proto_alpha/lib_protocol/ticket_operations_diff.ml +++ b/src/proto_alpha/lib_protocol/ticket_operations_diff.ml @@ -259,7 +259,7 @@ let ticket_token_map_of_operations ctxt ops = (** Traverses a list of operations and scans for tickets. *) let ticket_diffs_of_operations ctxt operations = ticket_token_map_of_operations ctxt operations >>=? fun (token_map, ctxt) -> - Ticket_token_map.fold + Ticket_token_map.fold_e ctxt (fun ctxt acc ticket_token destination_map -> (* Calculate the total amount of outgoing units for the current diff --git a/src/proto_alpha/lib_protocol/ticket_token_map.ml b/src/proto_alpha/lib_protocol/ticket_token_map.ml index 81310a54fdcc..655e007b3c3d 100644 --- a/src/proto_alpha/lib_protocol/ticket_token_map.ml +++ b/src/proto_alpha/lib_protocol/ticket_token_map.ml @@ -68,10 +68,14 @@ let update ctxt key f m = in Ticket_token_map.update ctxt key_hash f m |> Lwt.return -let fold ctxt f = +let fold_e ctxt f = Ticket_token_map.fold_e ctxt (fun ctxt acc _key_hash (tkn, value) -> f ctxt acc tkn value) +let fold_es ctxt f = + Ticket_token_map.fold_es ctxt (fun ctxt acc _key_hash (tkn, value) -> + f ctxt acc tkn value) + let find ctxt ticket_token map = key_of_ticket_token ctxt ticket_token >>=? fun (key_hash, ctxt) -> Ticket_token_map.find ctxt key_hash map >>?= fun (val_opt, ctxt) -> @@ -98,7 +102,7 @@ let of_list ctxt ~merge_overlap token_values = (Ticket_token_map.empty, ctxt) token_values -let map ctxt f = +let map_e ctxt f = Ticket_token_map.map_e ctxt (fun ctxt _key (tkn, value) -> f ctxt tkn value >|? fun (new_value, ctxt) -> ((tkn, new_value), ctxt)) diff --git a/src/proto_alpha/lib_protocol/ticket_token_map.mli b/src/proto_alpha/lib_protocol/ticket_token_map.mli index d4f39f6c2e8e..19fa9a260355 100644 --- a/src/proto_alpha/lib_protocol/ticket_token_map.mli +++ b/src/proto_alpha/lib_protocol/ticket_token_map.mli @@ -44,9 +44,9 @@ val update : 'a t -> ('a t * context) tzresult Lwt.t -(** [fold ctxt f z m] folds over the map [m] using the initial value [z] and +(** [fold_e ctxt f z m] folds over the map [m] using the initial value [z] and the accumulator function [f]. [f] must account for its own gas costs. *) -val fold : +val fold_e : context -> (context -> 'state -> @@ -57,6 +57,18 @@ val fold : 'a t -> ('state * context) tzresult +(** Lwt-aware variant of {!fold_e}. *) +val fold_es : + context -> + (context -> + 'state -> + Ticket_token.ex_token -> + 'a -> + ('state * context) tzresult Lwt.t) -> + 'state -> + 'a t -> + ('state * context) tzresult Lwt.t + (** [find ctxt k m] looks up the value with key [k] in the given map [m] and also accounts for the gas cost of finding the key. *) val find : @@ -81,10 +93,10 @@ val of_list : val to_list : context -> 'a t -> ((Ticket_token.ex_token * 'a) list * context) tzresult -(** [map ctxt f m] maps over all key-value pairs in the map [m] using the +(** [map_e ctxt f m] maps over all key-value pairs in the map [m] using the function [f]. It accounts for gas costs associated with traversing the elements. [f] must account for its own gas cost. *) -val map : +val map_e : context -> (context -> Ticket_token.ex_token -> 'a -> ('b * context) tzresult) -> 'a t -> -- GitLab From 6338a5dc7ddc1ef4c79d7f4a0eaa1827e6284dd4 Mon Sep 17 00:00:00 2001 From: lin Date: Mon, 24 Oct 2022 17:08:55 +0900 Subject: [PATCH 4/8] Proto/RPC: RPC for getting all ticket balances --- src/proto_alpha/lib_plugin/RPC.ml | 55 ++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index d88e154fd496..b72528e7698b 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -1709,6 +1709,20 @@ module Contract = struct ~input:Ticket_token.unparsed_token_encoding ~output:n RPC_path.(path /: Contract.rpc_arg / "ticket_balance") + + let all_ticket_balances = + let open Data_encoding in + let ticket_balance_encoding = + let open Data_encoding in + merge_objs Ticket_token.unparsed_token_encoding (obj1 (req "amount" n)) + in + RPC_service.get_service + ~description: + "Access the complete list of tickets owned by the given contract by \ + scanning the contract's storage." + ~query:RPC_query.empty + ~output:(list ticket_balance_encoding) + RPC_path.(path /: Contract.rpc_arg / "all_ticket_balances") end let get_contract contract f = @@ -1782,7 +1796,46 @@ module Contract = struct ~contents:(Micheline.root contents) in let* amount, _ctxt = Ticket_balance.get_balance ctxt ticket_hash in - return @@ Option.value amount ~default:Z.zero) + return @@ Option.value amount ~default:Z.zero) ; + Registration.opt_register1 + ~chunked:false + S.all_ticket_balances + (fun ctxt contract () () -> + get_contract contract @@ fun contract -> + let open Lwt_result_syntax in + let* ctxt, script = Contract.get_script ctxt contract in + match script with + | None -> return_none + | Some script -> + let* Ex_script (Script {storage; storage_type; _}), ctxt = + Script_ir_translator.parse_script + ctxt + ~elab_conf:(elab_conf ~legacy:true ()) + ~allow_forged_in_storage:true + script + in + let*? has_tickets, ctxt = + Ticket_scanner.type_has_tickets ctxt storage_type + in + let* ticket_token_map, ctxt = + Ticket_accounting.ticket_balances_of_value + ctxt + ~include_lazy:true + has_tickets + storage + in + let* ticket_balances, _ctxt = + Ticket_token_map.fold_es + ctxt + (fun ctxt acc ex_token amount -> + let* unparsed_token, ctxt = + Ticket_token_unparser.unparse ctxt ex_token + in + return ((unparsed_token, amount) :: acc, ctxt)) + [] + ticket_token_map + in + return_some ticket_balances) let get_storage_normalized ctxt block ~contract ~unparsing_mode = RPC_context.make_call1 -- GitLab From 9a6b4edf58de4e41bff78cfd8f2cfd91e90e6588 Mon Sep 17 00:00:00 2001 From: lin Date: Tue, 25 Oct 2022 20:08:48 +0900 Subject: [PATCH 5/8] Tezt/RPC: Add functions for all_ticket_balances --- tezt/lib_tezos/RPC.ml | 16 ++++++++++++++++ tezt/lib_tezos/RPC.mli | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/tezt/lib_tezos/RPC.ml b/tezt/lib_tezos/RPC.ml index ccf6983076a9..2a2d1ec77960 100644 --- a/tezt/lib_tezos/RPC.ml +++ b/tezt/lib_tezos/RPC.ml @@ -727,6 +727,22 @@ let post_chain_block_context_contract_ticket_balance ?(chain = "main") ~data JSON.as_int +let get_chain_block_context_contract_all_ticket_balances ?(chain = "main") + ?(block = "head") ~id () = + make + GET + [ + "chains"; + chain; + "blocks"; + block; + "context"; + "contracts"; + id; + "all_ticket_balances"; + ] + Fun.id + let get_chain_block_context_sc_rollups ?(chain = "main") ?(block = "head") () = make GET ["chains"; chain; "blocks"; block; "context"; "sc_rollups"] Fun.id diff --git a/tezt/lib_tezos/RPC.mli b/tezt/lib_tezos/RPC.mli index 49c5b86ae3d1..cb0c0100fd26 100644 --- a/tezt/lib_tezos/RPC.mli +++ b/tezt/lib_tezos/RPC.mli @@ -744,6 +744,14 @@ val get_chain_block_context_contract_storage : val post_chain_block_context_contract_ticket_balance : ?chain:string -> ?block:string -> id:string -> data:JSON.u -> unit -> int t +(** RPC [POST /chains//blocks//context/contracts//all_ticket_balances] + + [chain] defaults to ["main"]. + [block] defaults to ["head"]. +*) +val get_chain_block_context_contract_all_ticket_balances : + ?chain:string -> ?block:string -> id:string -> unit -> JSON.t t + (** {2 Smart contract rollup RPC module} *) (** RPC: [GET chains//blocks//context/sc_rollups] *) -- GitLab From 6895aa0eb3f52a896941ccb3a6085cd853bfc82d Mon Sep 17 00:00:00 2001 From: lin Date: Tue, 25 Oct 2022 20:15:02 +0900 Subject: [PATCH 6/8] Tezt: Test all_ticket_balances RPC --- .../Alpha- Ticket updates in receipt.out | 23 +++++ tezt/tests/ticket_receipt_and_rpc.ml | 95 +++++++++++++------ 2 files changed, 87 insertions(+), 31 deletions(-) diff --git a/tezt/tests/expected/ticket_receipt_and_rpc.ml/Alpha- Ticket updates in receipt.out b/tezt/tests/expected/ticket_receipt_and_rpc.ml/Alpha- Ticket updates in receipt.out index 25ecb11eb542..d7fe418b17f6 100644 --- a/tezt/tests/expected/ticket_receipt_and_rpc.ml/Alpha- Ticket updates in receipt.out +++ b/tezt/tests/expected/ticket_receipt_and_rpc.ml/Alpha- Ticket updates in receipt.out @@ -105,3 +105,26 @@ This sequence of operations was run: ./octez-client --mode mockup get ticket balance for '[CONTRACT_HASH]' with ticketer '[CONTRACT_HASH]' and type string and content '"blue"' 1 + +./octez-client --mode mockup rpc get '/chains/main/blocks/head/context/contracts/[CONTRACT_HASH]/all_ticket_balances' +[ { "ticketer": "[CONTRACT_HASH]", + "content_type": { "prim": "string" }, "content": { "string": "green" }, + "amount": "2" }, + { "ticketer": "[CONTRACT_HASH]", + "content_type": { "prim": "string" }, "content": { "string": "red" }, + "amount": "1" } ] + +./octez-client --mode mockup rpc get '/chains/main/blocks/head/context/contracts/[CONTRACT_HASH]/all_ticket_balances' +[ { "ticketer": "[CONTRACT_HASH]", + "content_type": { "prim": "string" }, "content": { "string": "blue" }, + "amount": "1" } ] + +./octez-client --mode mockup rpc get '/chains/main/blocks/head/context/contracts/[CONTRACT_HASH]/all_ticket_balances' +[ { "ticketer": "[CONTRACT_HASH]", + "content_type": { "prim": "string" }, "content": { "string": "blue" }, + "amount": "1" } ] + +./octez-client --mode mockup rpc get '/chains/main/blocks/head/context/contracts/[PUBLIC_KEY_HASH]/all_ticket_balances' +Fatal error: + No service found at this URL + diff --git a/tezt/tests/ticket_receipt_and_rpc.ml b/tezt/tests/ticket_receipt_and_rpc.ml index 1ab2bd7efc5d..8ac93ca3a616 100644 --- a/tezt/tests/ticket_receipt_and_rpc.ml +++ b/tezt/tests/ticket_receipt_and_rpc.ml @@ -132,45 +132,78 @@ let test_ticket_receipt_and_rpc = ~burn_cap:Tez.one client in + let tz_a = Constant.bootstrap2 in let* () = Client.transfer ~burn_cap:(Tez.of_int 2) ~amount:Tez.zero - ~giver:"bootstrap2" + ~giver:tz_a.alias ~receiver:kt_a ~arg:(Format.sprintf {|(Pair "%s" "%s")|} kt_b kt_c) ~hooks client in - (* Check that the ticket balance are expected via both RPC and CLI. *) - [ - (kt_a, kt_a, "string", "red", 1); - (kt_a, kt_a, "string", "green", 2); - (kt_a, kt_a, "string", "blue", 0); - (kt_b, kt_a, "string", "blue", 1); - (kt_c, kt_a, "string", "blue", 1); - ] - |> Lwt_list.iter_s - @@ fun (contract, ticketer, content_type, content, expected) -> - let* () = - rpc_check_ticket_balance - client - ~contract - ~ticketer - ~content_type - ~content - ~expected - in - let* () = - cli_check_ticket_balance - client - ~hooks - ~contract - ~ticketer - ~content_type - ~content - ~expected - in - unit + let* () = + (* Check that the ticket balance are expected via [ticket_balance] RPC and CLI. *) + [ + (kt_a, kt_a, "string", "red", 1); + (kt_a, kt_a, "string", "green", 2); + (kt_a, kt_a, "string", "blue", 0); + (kt_b, kt_a, "string", "blue", 1); + (kt_c, kt_a, "string", "blue", 1); + ] + |> Lwt_list.iter_s + @@ fun (contract, ticketer, content_type, content, expected) -> + let* () = + rpc_check_ticket_balance + client + ~contract + ~ticketer + ~content_type + ~content + ~expected + in + let* () = + cli_check_ticket_balance + client + ~hooks + ~contract + ~ticketer + ~content_type + ~content + ~expected + in + unit + in + let* () = + (* Check regressions for the [all_ticket_balances] RPC when called for + originated. *) + [kt_a; kt_b; kt_c] + |> Lwt_list.iter_s @@ fun contract -> + let* _ = + RPC.Client.call ~hooks client + @@ RPC.get_chain_block_context_contract_all_ticket_balances + ~id:contract + () + in + unit + in + let* () = + (* Check regressions for the [all_ticket_balances] RPC when called for + implicit. *) + let*? process = + RPC.Client.spawn ~hooks client + @@ RPC.get_chain_block_context_contract_all_ticket_balances + ~id:tz_a.public_key_hash + () + in + Process.check_error + ~msg: + (rex + "(No service found at this URL|Did not find service|Rpc request \ + failed)") + process + in + unit let register ~protocols = test_ticket_receipt_and_rpc protocols -- GitLab From b0b64eaaffd17da44381f3bb221f833e9d21d8aa Mon Sep 17 00:00:00 2001 From: lin Date: Tue, 25 Oct 2022 20:18:33 +0900 Subject: [PATCH 7/8] Tezt: Add comment for old test case --- tezt/tests/ticket_receipt_and_rpc.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/tezt/tests/ticket_receipt_and_rpc.ml b/tezt/tests/ticket_receipt_and_rpc.ml index 8ac93ca3a616..c79f51618bee 100644 --- a/tezt/tests/ticket_receipt_and_rpc.ml +++ b/tezt/tests/ticket_receipt_and_rpc.ml @@ -134,6 +134,7 @@ let test_ticket_receipt_and_rpc = in let tz_a = Constant.bootstrap2 in let* () = + (* Check regressions for ticket updates in the transaction receipt. *) Client.transfer ~burn_cap:(Tez.of_int 2) ~amount:Tez.zero -- GitLab From 3fe751745154f4f11c9183cb164e612743fa6ee9 Mon Sep 17 00:00:00 2001 From: lin Date: Thu, 27 Oct 2022 15:45:52 +0900 Subject: [PATCH 8/8] Doc: Add entry for all_ticket_balances RPC --- docs/protocols/alpha.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/protocols/alpha.rst b/docs/protocols/alpha.rst index c60e7237c764..9c2667a6a3bb 100644 --- a/docs/protocols/alpha.rst +++ b/docs/protocols/alpha.rst @@ -35,9 +35,12 @@ Breaking Changes RPC Changes ----------- -- Add RPC to get contract's balance of ticket with specified ticketer, content type, and content: +- Add RPC to get contract's balance of ticket with specified ticketer, content type, and content. Can be used for both implicit and originated contracts. ``POST /chains//blocks//context/contracts//ticket_balance``. (MR :gl:`!6488`) +- Add RPC to get the complete list of tickets owned by a given contract by scanning the contract's storage. Can only be used for originated contracts. + ``POST /chains//blocks//context/contracts//all_ticket_balances``. (MR :gl:`!6712`) + Operation receipts ------------------ -- GitLab