From 46b55ee0de3d05b503ce8f8b6d3525515cc9e684 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 18 Feb 2025 17:16:23 +0100 Subject: [PATCH 1/3] Rollup node: add query parameter outbox_level to pending outbox RPCs --- src/lib_smart_rollup/rollup_node_services.ml | 10 +++++-- src/lib_smart_rollup_node/node_context.ml | 31 ++++++++++++++++---- src/lib_smart_rollup_node/node_context.mli | 4 +-- src/lib_smart_rollup_node/rpc_directory.ml | 10 ++++--- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/lib_smart_rollup/rollup_node_services.ml b/src/lib_smart_rollup/rollup_node_services.ml index 93d51062dc3e..31b2c628dd67 100644 --- a/src/lib_smart_rollup/rollup_node_services.ml +++ b/src/lib_smart_rollup/rollup_node_services.ml @@ -914,6 +914,12 @@ module Query = struct q#drop_duplicate) |> seal + let outbox_level_query = + let open Tezos_rpc.Query in + query (fun l -> l) + |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun k -> k) + |> seal + let outbox_query : bool Tezos_rpc.Query.t = let open Tezos_rpc.Query in query (fun b -> b) @@ -1131,14 +1137,14 @@ module Local = struct let outbox_pending_executable = Tezos_rpc.Service.get_service ~description:"Pending outbox messages which can be executed" - ~query:Tezos_rpc.Query.empty + ~query:Query.outbox_level_query ~output:(Data_encoding.list Encodings.outbox) (path / "outbox" / "pending" / "executable") let outbox_pending_unexecutable = Tezos_rpc.Service.get_service ~description:"Pending outbox messages which cannot yet be executed" - ~query:Tezos_rpc.Query.empty + ~query:Query.outbox_level_query ~output:(Data_encoding.list Encodings.outbox) (path / "outbox" / "pending" / "unexecutable") diff --git a/src/lib_smart_rollup_node/node_context.ml b/src/lib_smart_rollup_node/node_context.ml index 43386829bac5..514f6f2bc66b 100644 --- a/src/lib_smart_rollup_node/node_context.ml +++ b/src/lib_smart_rollup_node/node_context.ml @@ -668,7 +668,9 @@ let register_outbox_messages {store; _} ~outbox_level ~indexes = let*? indexes = Bitset.from_list indexes in Store.Outbox_messages.register_outbox_messages store ~outbox_level ~indexes -let get_executable_pending_outbox_messages {store; lcc; current_protocol; _} = +let get_executable_pending_outbox_messages ?outbox_level + {store; lcc; current_protocol; _} = + let open Lwt_result_syntax in let max_level = (Reference.get lcc).level in let constants = (Reference.get current_protocol).constants.sc_rollup in let min_level = @@ -678,9 +680,19 @@ let get_executable_pending_outbox_messages {store; lcc; current_protocol; _} = (constants.max_number_of_stored_cemented_commitments * constants.commitment_period_in_blocks)) in - Store.Outbox_messages.pending store ~min_level ~max_level - -let get_unexecutable_pending_outbox_messages ({store; lcc; _} as node_ctxt) = + match outbox_level with + | None -> Store.Outbox_messages.pending store ~min_level ~max_level + | Some outbox_level when outbox_level > max_level || outbox_level < min_level + -> + return_nil + | Some outbox_level -> + Store.Outbox_messages.pending + store + ~min_level:outbox_level + ~max_level:outbox_level + +let get_unexecutable_pending_outbox_messages ?outbox_level + ({store; lcc; _} as node_ctxt) = let open Lwt_result_syntax in let* head = last_processed_head_opt node_ctxt in let*? max_level = @@ -689,7 +701,16 @@ let get_unexecutable_pending_outbox_messages ({store; lcc; _} as node_ctxt) = | Some h -> Ok h.header.level in let min_level = Int32.succ (Reference.get lcc).level in - Store.Outbox_messages.pending store ~min_level ~max_level + match outbox_level with + | None -> Store.Outbox_messages.pending store ~min_level ~max_level + | Some outbox_level when outbox_level > max_level || outbox_level < min_level + -> + return_nil + | Some outbox_level -> + Store.Outbox_messages.pending + store + ~min_level:outbox_level + ~max_level:outbox_level let get_full_l2_block ?get_outbox_messages node_ctxt block_hash = let open Lwt_result_syntax in diff --git a/src/lib_smart_rollup_node/node_context.mli b/src/lib_smart_rollup_node/node_context.mli index b22b510f54af..97f300eb6ff0 100644 --- a/src/lib_smart_rollup_node/node_context.mli +++ b/src/lib_smart_rollup_node/node_context.mli @@ -473,13 +473,13 @@ val register_outbox_messages : The returned list contains outbox levels and indexes for each level (in order). *) val get_executable_pending_outbox_messages : - _ t -> (int32 * int list) list tzresult Lwt.t + ?outbox_level:int32 -> _ t -> (int32 * int list) list tzresult Lwt.t (** Returns the pending messages (i.e. unexecuted) that cannot be executed yet. The returned list contains outbox levels and indexes for each level (in order). *) val get_unexecutable_pending_outbox_messages : - _ t -> (int32 * int list) list tzresult Lwt.t + ?outbox_level:int32 -> _ t -> (int32 * int list) list tzresult Lwt.t (** {3 Protocol} *) diff --git a/src/lib_smart_rollup_node/rpc_directory.ml b/src/lib_smart_rollup_node/rpc_directory.ml index 7c89ffff4737..2032bef6a1a5 100644 --- a/src/lib_smart_rollup_node/rpc_directory.ml +++ b/src/lib_smart_rollup_node/rpc_directory.ml @@ -522,20 +522,22 @@ let get_outbox_content (node_ctxt : _ Node_context.t) let () = Local_directory.register0 Rollup_node_services.Local.outbox_pending_executable - @@ fun node_ctxt () () -> + @@ fun node_ctxt outbox_level () -> let open Lwt_result_syntax in let* outbox_messages = - Node_context.get_executable_pending_outbox_messages node_ctxt + Node_context.get_executable_pending_outbox_messages ?outbox_level node_ctxt in List.map_ep (get_outbox_content node_ctxt) outbox_messages let () = Local_directory.register0 Rollup_node_services.Local.outbox_pending_unexecutable - @@ fun node_ctxt () () -> + @@ fun node_ctxt outbox_level () -> let open Lwt_result_syntax in let* outbox_messages = - Node_context.get_unexecutable_pending_outbox_messages node_ctxt + Node_context.get_unexecutable_pending_outbox_messages + ?outbox_level + node_ctxt in List.map_ep (get_outbox_content node_ctxt) outbox_messages -- GitLab From 26037c1d2fab791077ec55cd8031c4d6fe39600d Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 18 Feb 2025 17:38:05 +0100 Subject: [PATCH 2/3] Rollup node: add RPC /local/outbox/pending to fetch all outbox messages Each message is accompanied by its status. --- src/lib_smart_rollup/rollup_node_services.ml | 18 +++++++++ src/lib_smart_rollup_node/node_context.ml | 39 ++++++++++++++++++++ src/lib_smart_rollup_node/node_context.mli | 6 +++ src/lib_smart_rollup_node/rpc_directory.ml | 13 +++++++ 4 files changed, 76 insertions(+) diff --git a/src/lib_smart_rollup/rollup_node_services.ml b/src/lib_smart_rollup/rollup_node_services.ml index 31b2c628dd67..ec28f552d0ee 100644 --- a/src/lib_smart_rollup/rollup_node_services.ml +++ b/src/lib_smart_rollup/rollup_node_services.ml @@ -254,6 +254,10 @@ module Encodings = struct (req "message_index" int31) (opt "message" Outbox_message.summary_encoding)))) + let outbox_msg_status : [`Executable | `Lost | `Pending] t = + string_enum + [("executable", `Executable); ("pending", `Pending); ("lost", `Lost)] + let queued_message = L2_message.encoding let batcher_queue = list queued_message @@ -1134,6 +1138,20 @@ module Local = struct (Data_encoding.option Encodings.commitment_with_hash_and_level_infos) (path / "commitments" /: Arg.commitment_hash) + let outbox_pending = + Tezos_rpc.Service.get_service + ~description: + "Pending outbox messages with their status (executable, pending, or \ + lost)" + ~query:Query.outbox_level_query + ~output: + Data_encoding.( + list + (merge_objs + Encodings.outbox + (obj1 (req "status" Encodings.outbox_msg_status)))) + (path / "outbox" / "pending") + let outbox_pending_executable = Tezos_rpc.Service.get_service ~description:"Pending outbox messages which can be executed" diff --git a/src/lib_smart_rollup_node/node_context.ml b/src/lib_smart_rollup_node/node_context.ml index 514f6f2bc66b..8c3aa2971c33 100644 --- a/src/lib_smart_rollup_node/node_context.ml +++ b/src/lib_smart_rollup_node/node_context.ml @@ -712,6 +712,45 @@ let get_unexecutable_pending_outbox_messages ?outbox_level ~min_level:outbox_level ~max_level:outbox_level +let get_pending_outbox_messages ?outbox_level + ({store; lcc; current_protocol; _} as node_ctxt) = + let open Lwt_result_syntax in + let* head = last_processed_head_opt node_ctxt in + let*? max_level = + match head with + | None -> error_with "No L2 head" + | Some h -> Ok h.header.level + in + let lcc = (Reference.get lcc).level in + let constants = (Reference.get current_protocol).constants.sc_rollup in + let lost_level = + Int32.sub + lcc + (Int32.of_int + (constants.max_number_of_stored_cemented_commitments + * constants.commitment_period_in_blocks)) + in + let+ messages = + match outbox_level with + | None -> Store.Outbox_messages.pending store ~min_level:0l ~max_level + | Some outbox_level when outbox_level > max_level -> return_nil + | Some outbox_level -> + Store.Outbox_messages.pending + store + ~min_level:outbox_level + ~max_level:outbox_level + in + List.rev_map + (fun ((outbox_level, _) as msg) -> + let status = + if outbox_level < lost_level then `Lost + else if outbox_level <= lcc then `Executable + else `Pending + in + (msg, status)) + messages + |> List.rev + let get_full_l2_block ?get_outbox_messages node_ctxt block_hash = let open Lwt_result_syntax in let* block = Store.L2_blocks.find_full node_ctxt.store block_hash in diff --git a/src/lib_smart_rollup_node/node_context.mli b/src/lib_smart_rollup_node/node_context.mli index 97f300eb6ff0..25da4cf76316 100644 --- a/src/lib_smart_rollup_node/node_context.mli +++ b/src/lib_smart_rollup_node/node_context.mli @@ -481,6 +481,12 @@ val get_executable_pending_outbox_messages : val get_unexecutable_pending_outbox_messages : ?outbox_level:int32 -> _ t -> (int32 * int list) list tzresult Lwt.t +(** Returns all pending messages with their status. *) +val get_pending_outbox_messages : + ?outbox_level:int32 -> + _ t -> + ((int32 * int list) * [`Executable | `Lost | `Pending]) list tzresult Lwt.t + (** {3 Protocol} *) (** [protocol_of_level_with_store store level] returns the protocol of block level [level]. *) diff --git a/src/lib_smart_rollup_node/rpc_directory.ml b/src/lib_smart_rollup_node/rpc_directory.ml index 2032bef6a1a5..0adf1e5356c8 100644 --- a/src/lib_smart_rollup_node/rpc_directory.ml +++ b/src/lib_smart_rollup_node/rpc_directory.ml @@ -541,6 +541,19 @@ let () = in List.map_ep (get_outbox_content node_ctxt) outbox_messages +let () = + Local_directory.register0 Rollup_node_services.Local.outbox_pending + @@ fun node_ctxt outbox_level () -> + let open Lwt_result_syntax in + let* outbox_messages = + Node_context.get_pending_outbox_messages ?outbox_level node_ctxt + in + List.map_ep + (fun (outbox_msg, status) -> + let+ outbos_msg = get_outbox_content node_ctxt outbox_msg in + (outbos_msg, status)) + outbox_messages + let () = Local_directory.register0 Rollup_node_services.Local.gc_info @@ fun node_ctxt () () -> -- GitLab From b52ba4047b879ef08f19ce6169d818ef3692def3 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Tue, 18 Feb 2025 17:40:32 +0100 Subject: [PATCH 3/3] Doc: changelog --- CHANGES.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 6ebf7c9da342..4399dd64e4e3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -249,6 +249,13 @@ Smart Rollup node - Support ``remote`` signer scheme and check remote signer available on startup. (MR :gl:`!16651`) +- Add query parameter ``outbox_level`` for RPCs + ``/local/outbox/pending/executable`` and + ``/local/outbox/pending/unexecutable``. (MR :gl:`!16831`) + +- Add a new RPC RPC ``/local/outbox/pending`` to fetch all known outbox messages + with their status. (MR :gl:`!16831`) + Smart Rollup WASM Debugger -------------------------- -- GitLab