diff --git a/CHANGES.rst b/CHANGES.rst index 5c8ce5abacc500acdd5ea0029e67643cbb4aaad1..41a3f2f65d61a25cd30a80d231402d0653155b98 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -67,6 +67,14 @@ Client guaranteed to be included in the order they are received from the operations source. +- Added commands to get the used and paid storage spaces of contracts: + ``tezos-client get used storage space for `` and + ``tezos-client get paid storage space for ``. + +- Added RPCs to get the used and paid storage spaces of contracts: + ``GET /chains//blocks//context/contracts//storage/used_space`` + and ``GET /chains//blocks//context/contracts//storage/paid_space``. + Baker ----- diff --git a/src/proto_alpha/lib_client/client_proto_context.ml b/src/proto_alpha/lib_client/client_proto_context.ml index 5c3d6e0a74d3a9d76a98cdd6242b4d57d963a64f..1ea268a0455126c69656c4ae72677f266355498d 100644 --- a/src/proto_alpha/lib_client/client_proto_context.ml +++ b/src/proto_alpha/lib_client/client_proto_context.ml @@ -40,6 +40,12 @@ let get_storage (rpc : #rpc_context) ~chain ~block ~unparsing_mode contract = ~unparsing_mode ~contract +let get_used_storage_space (rpc : #rpc_context) ~chain ~block contract = + Plugin.RPC.Contract.get_used_storage_space rpc (chain, block) ~contract + +let get_paid_storage_space (rpc : #rpc_context) ~chain ~block contract = + Plugin.RPC.Contract.get_paid_storage_space rpc (chain, block) ~contract + let get_big_map_value (rpc : #rpc_context) ~chain ~block ~unparsing_mode id key = Plugin.RPC.Big_map.big_map_get_normalized diff --git a/src/proto_alpha/lib_client/client_proto_context.mli b/src/proto_alpha/lib_client/client_proto_context.mli index 2b5f73c969f4b7ad05348c4dcca0bfbbda89d21d..8176311498d741d72b019120b1f7fab732faa991 100644 --- a/src/proto_alpha/lib_client/client_proto_context.mli +++ b/src/proto_alpha/lib_client/client_proto_context.mli @@ -42,6 +42,22 @@ val get_storage : Contract_hash.t -> Script.expr option tzresult Lwt.t +(** Calls {!Tezos_protocol_plugin_alpha.Plugin.RPC.Contract.get_used_storage_space}. *) +val get_used_storage_space : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Contract_hash.t -> + Z.t option tzresult Lwt.t + +(** Calls {!Tezos_protocol_plugin_alpha.Plugin.RPC.Contract.get_paid_storage_space}. *) +val get_paid_storage_space : + #Protocol_client_context.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Contract_hash.t -> + Z.t option tzresult Lwt.t + (** Calls {!Tezos_protocol_alpha.Protocol.Contract_services.contract_big_map_get_opt}. *) val get_contract_big_map_value : #Protocol_client_context.rpc_context -> diff --git a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml index 4e0ffd003e0efd4ddcf47d7694b08f19316509e9..bdec8cb1db2ff11ec77100dbdc938a236602f364 100644 --- a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml +++ b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml @@ -245,6 +245,48 @@ let commands_ro () = cctxt#answer "%a" Michelson_v1_printer.print_expr_unwrapped storage in return_unit); + command + ~group + ~desc:"Get the used storage space of a contract." + no_options + (prefixes ["get"; "contract"; "used"; "storage"; "space"; "for"] + @@ OriginatedContractAlias.destination_param + ~name:"src" + ~desc:"source contract" + @@ stop) + (fun () contract (cctxt : Protocol_client_context.full) -> + let open Lwt_result_syntax in + let* used_space = + get_used_storage_space + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + contract + in + check_smart_contract cctxt used_space @@ fun used_space -> + let*! () = cctxt#answer "%a" Z.pp_print used_space in + return_unit); + command + ~group + ~desc:"Get the paid storage space of a contract." + no_options + (prefixes ["get"; "contract"; "paid"; "storage"; "space"; "for"] + @@ OriginatedContractAlias.destination_param + ~name:"src" + ~desc:"source contract" + @@ stop) + (fun () contract (cctxt : Protocol_client_context.full) -> + let open Lwt_result_syntax in + let* paid_space = + get_paid_storage_space + cctxt + ~chain:cctxt#chain + ~block:cctxt#block + contract + in + check_smart_contract cctxt paid_space @@ fun paid_space -> + let*! () = cctxt#answer "%a" Z.pp_print paid_space in + return_unit); command ~group ~desc: diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index b748185caee0f2ea4e53f7e84e66bef7bf0f6556..bf0c8e836267627b38c811241c1ac8b06ef8832e 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -1666,54 +1666,82 @@ module Contract = struct ~query:RPC_query.empty ~output:(option Script.encoding) RPC_path.(path /: Contract.rpc_arg / "script" / "normalized") + + let get_used_storage_space = + let open Data_encoding in + RPC_service.get_service + ~description:"Access the used storage space of the contract." + ~query:RPC_query.empty + ~output:(option z) + RPC_path.(path /: Contract.rpc_arg / "storage" / "used_space") + + let get_paid_storage_space = + let open Data_encoding in + RPC_service.get_service + ~description:"Access the paid storage space of the contract." + ~query:RPC_query.empty + ~output:(option z) + RPC_path.(path /: Contract.rpc_arg / "storage" / "paid_space") end + let get_contract contract f = + match contract with + | Contract.Implicit _ -> return_none + | Contract.Originated contract -> f contract + let register () = (* Patched RPC: get_storage *) Registration.register1 ~chunked:true S.get_storage_normalized (fun ctxt contract () unparsing_mode -> - match contract with - | Implicit _ -> return_none - | Originated contract -> ( - Contract.get_script ctxt contract >>=? fun (ctxt, script) -> - match script with - | None -> return_none - | Some script -> - let ctxt = Gas.set_unlimited ctxt in - let open Script_ir_translator in - parse_script - ctxt - ~elab_conf:(elab_conf ~legacy:true ()) - ~allow_forged_in_storage:true - script - >>=? fun (Ex_script (Script {storage; storage_type; _}), ctxt) - -> - unparse_data ctxt unparsing_mode storage_type storage - >|=? fun (storage, _ctxt) -> - Some (Micheline.strip_locations storage))) ; + get_contract contract @@ fun contract -> + Contract.get_script ctxt contract >>=? fun (ctxt, script) -> + match script with + | None -> return_none + | Some script -> + let ctxt = Gas.set_unlimited ctxt in + let open Script_ir_translator in + parse_script + ctxt + ~elab_conf:(elab_conf ~legacy:true ()) + ~allow_forged_in_storage:true + script + >>=? fun (Ex_script (Script {storage; storage_type; _}), ctxt) -> + unparse_data ctxt unparsing_mode storage_type storage + >|=? fun (storage, _ctxt) -> + Some (Micheline.strip_locations storage)) ; (* Patched RPC: get_script *) Registration.register1 ~chunked:true S.get_script_normalized (fun ctxt contract () (unparsing_mode, normalize_types) -> - match contract with - | Implicit _ -> return_none - | Originated contract -> ( - Contract.get_script ctxt contract >>=? fun (ctxt, script) -> - match script with - | None -> return_none - | Some script -> - let ctxt = Gas.set_unlimited ctxt in - Script_ir_translator.parse_and_unparse_script_unaccounted - ctxt - ~legacy:true - ~allow_forged_in_storage:true - unparsing_mode - ~normalize_types - script - >>=? fun (script, _ctxt) -> return_some script)) + get_contract contract @@ fun contract -> + Contract.get_script ctxt contract >>=? fun (ctxt, script) -> + match script with + | None -> return_none + | Some script -> + let ctxt = Gas.set_unlimited ctxt in + Script_ir_translator.parse_and_unparse_script_unaccounted + ctxt + ~legacy:true + ~allow_forged_in_storage:true + unparsing_mode + ~normalize_types + script + >>=? fun (script, _ctxt) -> return_some script) ; + Registration.register1 + ~chunked:false + S.get_used_storage_space + (fun ctxt contract () () -> + get_contract contract @@ fun _ -> + Contract.used_storage_space ctxt contract >>=? return_some) ; + Registration.register1 + ~chunked:false + S.get_paid_storage_space + (fun ctxt contract () () -> + get_contract contract @@ fun _ -> + Contract.paid_storage_space ctxt contract >>=? return_some) let get_storage_normalized ctxt block ~contract ~unparsing_mode = RPC_context.make_call1 @@ -1733,6 +1761,24 @@ module Contract = struct (Contract.Originated contract) () (unparsing_mode, normalize_types) + + let get_used_storage_space ctxt block ~contract = + RPC_context.make_call1 + S.get_used_storage_space + ctxt + block + (Contract.Originated contract) + () + () + + let get_paid_storage_space ctxt block ~contract = + RPC_context.make_call1 + S.get_paid_storage_space + ctxt + block + (Contract.Originated contract) + () + () end module Big_map = struct diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 2816cf47d67bb3e8feafeefe1bbaf2877db34d28..9dcf7e00be345e6c0976c472b6b2fbcb49b0ef1b 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -1763,6 +1763,8 @@ module Contract : sig val used_storage_space : context -> t -> Z.t tzresult Lwt.t + val paid_storage_space : context -> t -> Z.t tzresult Lwt.t + val increment_counter : context -> public_key_hash -> context tzresult Lwt.t val check_counter_increment :