From 473f58d0ab18e9d907dd1093bc60dc3ed5f693ca Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Thu, 28 Mar 2024 17:28:06 +0100 Subject: [PATCH 1/8] Rollup node/RPC: add /health heartbeat endpoint --- src/lib_smart_rollup/rollup_node_services.ml | 8 ++++++++ src/lib_smart_rollup_node/rpc_directory.ml | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/lib_smart_rollup/rollup_node_services.ml b/src/lib_smart_rollup/rollup_node_services.ml index 827f6fbc93ff..2013b5832dad 100644 --- a/src/lib_smart_rollup/rollup_node_services.ml +++ b/src/lib_smart_rollup/rollup_node_services.ml @@ -528,6 +528,14 @@ module Root = struct let prefix = root end) + let health = + Tezos_rpc.Service.get_service + ~description: + "Returns an empty response if the rollup node can answer requests" + ~query:Tezos_rpc.Query.empty + ~output:Data_encoding.unit + (path / "health") + let openapi = Tezos_rpc.Service.get_service ~description:"OpenAPI specification of RPCs for rollup node" diff --git a/src/lib_smart_rollup_node/rpc_directory.ml b/src/lib_smart_rollup_node/rpc_directory.ml index 9de9402db18e..bbb0f36fdb51 100644 --- a/src/lib_smart_rollup_node/rpc_directory.ml +++ b/src/lib_smart_rollup_node/rpc_directory.ml @@ -72,6 +72,10 @@ module Local_directory = Make_directory (struct Lwt_result.return (Node_context.readonly node_ctxt) end) +let () = + Root_directory.register0 Rollup_node_services.Root.health + @@ fun _node_ctxt () () -> Lwt_result_syntax.return_unit + let () = Global_directory.register0 Rollup_node_services.Global.sc_rollup_address @@ fun node_ctxt () () -> Lwt_result.return node_ctxt.config.sc_rollup_address -- GitLab From 06c7c4a06ffe1d556f0a05e75031ab26b30e2f4e Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 29 Mar 2024 10:26:48 +0100 Subject: [PATCH 2/8] Rollup node/RPC: retrieve version information with /version --- src/lib_layer2_store/context.ml | 2 ++ src/lib_layer2_store/context.mli | 3 +++ src/lib_smart_rollup/rollup_node_services.ml | 24 ++++++++++++++++++++ src/lib_smart_rollup_node/rpc_directory.ml | 12 ++++++++++ 4 files changed, 41 insertions(+) diff --git a/src/lib_layer2_store/context.ml b/src/lib_layer2_store/context.ml index 6afdc8fee4a6..c4cc4e99b32a 100644 --- a/src/lib_layer2_store/context.ml +++ b/src/lib_layer2_store/context.ml @@ -227,4 +227,6 @@ module Version = struct int31 let check = function V0 -> Result.return_unit + + let to_string = function V0 -> "0" end diff --git a/src/lib_layer2_store/context.mli b/src/lib_layer2_store/context.mli index 396f1c53a008..f945fab9afec 100644 --- a/src/lib_layer2_store/context.mli +++ b/src/lib_layer2_store/context.mli @@ -175,6 +175,9 @@ module Version : sig (** [check v] fails if [v] is different from the expected version of the context. *) val check : t -> unit tzresult + + (** String representation of context version. *) + val to_string : t -> string end module Internal_for_tests : sig diff --git a/src/lib_smart_rollup/rollup_node_services.ml b/src/lib_smart_rollup/rollup_node_services.ml index 2013b5832dad..c55f7d3cd128 100644 --- a/src/lib_smart_rollup/rollup_node_services.ml +++ b/src/lib_smart_rollup/rollup_node_services.ml @@ -99,9 +99,26 @@ type sync_result = percentage_done : float; } +type version = { + version : string; + store_version : string; + context_version : string; +} + module Encodings = struct open Data_encoding + let version = + conv + (fun {version; store_version; context_version} -> + (version, store_version, context_version)) + (fun (version, store_version, context_version) -> + {version; store_version; context_version}) + @@ obj3 + (req "version" string) + (req "store_version" string) + (req "context_version" string) + let commitment_with_hash = obj2 (req "commitment" Commitment.encoding) @@ -536,6 +553,13 @@ module Root = struct ~output:Data_encoding.unit (path / "health") + let version = + Tezos_rpc.Service.get_service + ~description:"Returns the version information of the rollup node" + ~query:Tezos_rpc.Query.empty + ~output:Encodings.version + (path / "version") + let openapi = Tezos_rpc.Service.get_service ~description:"OpenAPI specification of RPCs for rollup node" diff --git a/src/lib_smart_rollup_node/rpc_directory.ml b/src/lib_smart_rollup_node/rpc_directory.ml index bbb0f36fdb51..bf03183a4973 100644 --- a/src/lib_smart_rollup_node/rpc_directory.ml +++ b/src/lib_smart_rollup_node/rpc_directory.ml @@ -76,6 +76,18 @@ let () = Root_directory.register0 Rollup_node_services.Root.health @@ fun _node_ctxt () () -> Lwt_result_syntax.return_unit +let () = + Root_directory.register0 Rollup_node_services.Root.version + @@ fun _node_ctxt () () -> + let open Lwt_result_syntax in + let version = + Tezos_version.Version.to_string + Tezos_version_value.Current_git_info.octez_version + in + let store_version = Format.asprintf "%a" Store_version.pp Store.version in + let context_version = Context.Version.(to_string version) in + return Rollup_node_services.{version; store_version; context_version} + let () = Global_directory.register0 Rollup_node_services.Global.sc_rollup_address @@ fun node_ctxt () () -> Lwt_result.return node_ctxt.config.sc_rollup_address -- GitLab From e6c92534415e7cb94e85e4d2c792e25ebb465008 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 29 Mar 2024 10:31:11 +0100 Subject: [PATCH 3/8] Rollup node/RPC: add GC stats RPC --- src/lib_smart_rollup/rollup_node_services.ml | 97 ++++++++++++++++++++ src/lib_smart_rollup_node/rpc_directory.ml | 4 + 2 files changed, 101 insertions(+) diff --git a/src/lib_smart_rollup/rollup_node_services.ml b/src/lib_smart_rollup/rollup_node_services.ml index c55f7d3cd128..be4ef47d20f2 100644 --- a/src/lib_smart_rollup/rollup_node_services.ml +++ b/src/lib_smart_rollup/rollup_node_services.ml @@ -295,6 +295,96 @@ module Encodings = struct (req "first_available_level" int32) (opt "last_context_split_level" int32) + let ocaml_gc_stat_encoding = + let open Gc in + conv + (fun { + minor_words; + promoted_words; + major_words; + minor_collections; + major_collections; + forced_major_collections; + heap_words; + heap_chunks; + live_words; + live_blocks; + free_words; + free_blocks; + largest_free; + fragments; + compactions; + top_heap_words; + stack_size; + } -> + ( ( minor_words, + promoted_words, + major_words, + minor_collections, + major_collections, + forced_major_collections ), + ( (heap_words, heap_chunks, live_words, live_blocks, free_words), + ( free_blocks, + largest_free, + fragments, + compactions, + top_heap_words, + stack_size ) ) )) + (fun ( ( minor_words, + promoted_words, + major_words, + minor_collections, + major_collections, + forced_major_collections ), + ( (heap_words, heap_chunks, live_words, live_blocks, free_words), + ( free_blocks, + largest_free, + fragments, + compactions, + top_heap_words, + stack_size ) ) ) -> + { + minor_words; + promoted_words; + major_words; + minor_collections; + major_collections; + forced_major_collections; + heap_words; + heap_chunks; + live_words; + live_blocks; + free_words; + free_blocks; + largest_free; + fragments; + compactions; + top_heap_words; + stack_size; + }) + (merge_objs + (obj6 + (req "minor_words" float) + (req "promoted_words" float) + (req "major_words" float) + (req "minor_collections" int31) + (req "major_collections" int31) + (req "forced_major_collections" int31)) + (merge_objs + (obj5 + (req "heap_words" int31) + (req "heap_chunks" int31) + (req "live_words" int31) + (req "live_blocks" int31) + (req "free_words" int31)) + (obj6 + (req "free_blocks" int31) + (req "largest_free" int31) + (req "fragments" int31) + (req "compactions" int31) + (req "top_heap_words" int31) + (req "stack_size" int31)))) + let synchronization_result = union [ @@ -560,6 +650,13 @@ module Root = struct ~output:Encodings.version (path / "version") + let ocaml_gc = + Tezos_rpc.Service.get_service + ~description:"Gets stats from the OCaml Garbage Collector" + ~query:Tezos_rpc.Query.empty + ~output:Encodings.ocaml_gc_stat_encoding + (path / "stats" / "ocaml_gc") + let openapi = Tezos_rpc.Service.get_service ~description:"OpenAPI specification of RPCs for rollup node" diff --git a/src/lib_smart_rollup_node/rpc_directory.ml b/src/lib_smart_rollup_node/rpc_directory.ml index bf03183a4973..eee9d70df866 100644 --- a/src/lib_smart_rollup_node/rpc_directory.ml +++ b/src/lib_smart_rollup_node/rpc_directory.ml @@ -88,6 +88,10 @@ let () = let context_version = Context.Version.(to_string version) in return Rollup_node_services.{version; store_version; context_version} +let () = + Root_directory.register0 Rollup_node_services.Root.ocaml_gc + @@ fun _node_ctxt () () -> Lwt_result_syntax.return @@ Gc.stat () + let () = Global_directory.register0 Rollup_node_services.Global.sc_rollup_address @@ fun node_ctxt () () -> Lwt_result.return node_ctxt.config.sc_rollup_address -- GitLab From b2caab8f3853762d68ff59d7b7fe3aad2d5943c4 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 29 Mar 2024 10:31:27 +0100 Subject: [PATCH 4/8] Rollup node/RPC: add memory stats RPC --- src/lib_smart_rollup/rollup_node_services.ml | 45 ++++++++++++++++++++ src/lib_smart_rollup_node/rpc_directory.ml | 6 +++ 2 files changed, 51 insertions(+) diff --git a/src/lib_smart_rollup/rollup_node_services.ml b/src/lib_smart_rollup/rollup_node_services.ml index be4ef47d20f2..4af24aeecc22 100644 --- a/src/lib_smart_rollup/rollup_node_services.ml +++ b/src/lib_smart_rollup/rollup_node_services.ml @@ -385,6 +385,44 @@ module Encodings = struct (req "top_heap_words" int31) (req "stack_size" int31)))) + let mem_stat_encoding = + let open Memory in + union + ~tag_size:`Uint8 + [ + case + (Tag 0) + (conv + (fun {page_size; size; resident; shared; text; lib; data; dt} -> + (page_size, size, resident, shared, text, lib, data, dt)) + (fun (page_size, size, resident, shared, text, lib, data, dt) -> + {page_size; size; resident; shared; text; lib; data; dt}) + (obj8 + (req "page_size" int31) + (req "size" int64) + (req "resident" int64) + (req "shared" int64) + (req "text" int64) + (req "lib" int64) + (req "data" int64) + (req "dt" int64))) + ~title:"Linux_proc_statm" + (function Statm x -> Some x | _ -> None) + (function res -> Statm res); + case + (Tag 1) + (conv + (fun {page_size; mem; resident} -> (page_size, mem, resident)) + (fun (page_size, mem, resident) -> {page_size; mem; resident}) + (obj3 + (req "page_size" int31) + (req "mem" float) + (req "resident" int64))) + ~title:"Darwin_ps" + (function Ps x -> Some x | _ -> None) + (function res -> Ps res); + ] + let synchronization_result = union [ @@ -657,6 +695,13 @@ module Root = struct ~output:Encodings.ocaml_gc_stat_encoding (path / "stats" / "ocaml_gc") + let memory = + Tezos_rpc.Service.get_service + ~description:"Gets memory usage stats" + ~query:Tezos_rpc.Query.empty + ~output:Encodings.mem_stat_encoding + (path / "stats" / "memory") + let openapi = Tezos_rpc.Service.get_service ~description:"OpenAPI specification of RPCs for rollup node" diff --git a/src/lib_smart_rollup_node/rpc_directory.ml b/src/lib_smart_rollup_node/rpc_directory.ml index eee9d70df866..25060802d93b 100644 --- a/src/lib_smart_rollup_node/rpc_directory.ml +++ b/src/lib_smart_rollup_node/rpc_directory.ml @@ -92,6 +92,12 @@ let () = Root_directory.register0 Rollup_node_services.Root.ocaml_gc @@ fun _node_ctxt () () -> Lwt_result_syntax.return @@ Gc.stat () +let () = + Root_directory.register0 Rollup_node_services.Root.memory + @@ fun _node_ctxt () () -> + let open Lwt_result_syntax in + Sys_info.memory_stats () |> lwt_map_error TzTrace.make + let () = Global_directory.register0 Rollup_node_services.Global.sc_rollup_address @@ fun node_ctxt () () -> Lwt_result.return node_ctxt.config.sc_rollup_address -- GitLab From 30bab513bed1e7aa91dfa715e1fa00de21400e9f Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 29 Mar 2024 10:32:37 +0100 Subject: [PATCH 5/8] Rollup node/RPC: /stats is not available in secure ACL --- src/lib_smart_rollup_node/rpc_server.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib_smart_rollup_node/rpc_server.ml b/src/lib_smart_rollup_node/rpc_server.ml index e1ada6feb3a0..983d6e1ab6d2 100644 --- a/src/lib_smart_rollup_node/rpc_server.ml +++ b/src/lib_smart_rollup_node/rpc_server.ml @@ -50,6 +50,7 @@ module Acl = struct "GET /global/block/*/durable/wasm_2_0_0/subkeys"; "/local/batcher/**"; "/admin/**"; + "/stats/**"; ]; } -- GitLab From 0024753366566b89be86d1c44c2e878b71c162c3 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 29 Mar 2024 10:40:44 +0100 Subject: [PATCH 6/8] Rollup node/RPC: add /config RPC --- src/lib_smart_rollup_node/configuration.ml | 15 ++++++++++++-- src/lib_smart_rollup_node/configuration.mli | 6 ++++++ src/lib_smart_rollup_node/rpc_directory.ml | 23 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/lib_smart_rollup_node/configuration.ml b/src/lib_smart_rollup_node/configuration.ml index 4df9a0770029..5db6d022881b 100644 --- a/src/lib_smart_rollup_node/configuration.ml +++ b/src/lib_smart_rollup_node/configuration.ml @@ -197,7 +197,7 @@ let default_batcher_min_batch_elements = 10 let default_batcher_min_batch_size = 10 -let default_batcher_max_batch_elements = max_int +let default_batcher_max_batch_elements = (1 lsl 30) - 1 let default_batcher = { @@ -407,8 +407,15 @@ let cors_encoding : Resto_cohttp.Cors.t Data_encoding.t = (req "allowed_headers" (list string)) (req "allowed_origins" (list string)) -let encoding : t Data_encoding.t = +let encoding default_display : t Data_encoding.t = let open Data_encoding in + let dft = + match default_display with + | `Hide -> dft + | `Show -> + fun ?title ?description name enc _default -> + req ?title ?description name enc + in conv (fun { sc_rollup_address; @@ -596,6 +603,10 @@ let encoding : t Data_encoding.t = (opt "history-mode" history_mode_encoding) (dft "cors" cors_encoding Resto_cohttp.Cors.default)))) +let encoding_no_default = encoding `Show + +let encoding = encoding `Hide + (** Maps a mode to their corresponding purposes. The Custom mode returns each purposes where it has at least one operation kind from (i.e. {!purposes_of_operation_kinds}). *) diff --git a/src/lib_smart_rollup_node/configuration.mli b/src/lib_smart_rollup_node/configuration.mli index e10c034e4d2d..00985720ed68 100644 --- a/src/lib_smart_rollup_node/configuration.mli +++ b/src/lib_smart_rollup_node/configuration.mli @@ -241,6 +241,12 @@ val default_irmin_cache_size : int details such as a timestamp, message content, severity level, etc. *) val default_index_buffer_size : int +(** Encoding for configuration. *) +val encoding : t Data_encoding.t + +(** Encoding for configuration without any default value. *) +val encoding_no_default : t Data_encoding.t + (** [save ~force ~data_dir configuration] writes the [configuration] file in [data_dir]. If [force] is [true], existing configurations are overwritten. *) diff --git a/src/lib_smart_rollup_node/rpc_directory.ml b/src/lib_smart_rollup_node/rpc_directory.ml index 25060802d93b..2834d3899a0b 100644 --- a/src/lib_smart_rollup_node/rpc_directory.ml +++ b/src/lib_smart_rollup_node/rpc_directory.ml @@ -27,6 +27,22 @@ open Rpc_directory_helpers +(* Add extra services which must live in the rollup node library *) +module Rollup_node_services = struct + include Rollup_node_services + + module Root = struct + include Root + + let config = + Tezos_rpc.Service.get_service + ~description:"Returns the rollup node configuration" + ~query:Tezos_rpc.Query.empty + ~output:Configuration.encoding_no_default + Tezos_rpc.Path.(root / "config") + end +end + let get_head_hash_opt node_ctxt = let open Lwt_result_syntax in let+ res = Node_context.last_processed_head_opt node_ctxt in @@ -88,6 +104,13 @@ let () = let context_version = Context.Version.(to_string version) in return Rollup_node_services.{version; store_version; context_version} +let () = + Root_directory.register0 Rollup_node_services.Root.config + @@ fun node_ctxt () () -> + let open Lwt_result_syntax in + let+ history_mode = Node_context.get_history_mode node_ctxt in + {node_ctxt.config with history_mode = Some history_mode} + let () = Root_directory.register0 Rollup_node_services.Root.ocaml_gc @@ fun _node_ctxt () () -> Lwt_result_syntax.return @@ Gc.stat () -- GitLab From 1d96ffd013269396d9368c42dfc499d4e4edbcd4 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 29 Mar 2024 10:41:02 +0100 Subject: [PATCH 7/8] Rollup node/RPC: /config RPC not available in secure ACL --- src/lib_smart_rollup_node/rpc_server.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib_smart_rollup_node/rpc_server.ml b/src/lib_smart_rollup_node/rpc_server.ml index 983d6e1ab6d2..910bb84d4999 100644 --- a/src/lib_smart_rollup_node/rpc_server.ml +++ b/src/lib_smart_rollup_node/rpc_server.ml @@ -51,6 +51,7 @@ module Acl = struct "/local/batcher/**"; "/admin/**"; "/stats/**"; + "/config"; ]; } -- GitLab From 249b8a4e0d8a1fa9eb72f928d23807871d833a57 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 29 Mar 2024 11:58:34 +0100 Subject: [PATCH 8/8] Doc: changelog --- CHANGES.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 1522aa7dae3c..efef9c327cf4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -203,6 +203,9 @@ Smart Rollup node - Fix issue with catching up on rollup originated in previous protocol with an empty rollup node. (MR :gl:`!12565`) +- Added new administrative RPCs ``/health``, ``/version``, ``/stats/ocaml_gc``, + ``/stats/memory``, and ``/config``. (MR :gl:`!12718`) + Smart Rollup WASM Debugger -------------------------- -- GitLab