From 8da2d9bd90420da9c5d4519235d07d0af43eae9c Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 21 Apr 2023 11:32:05 +0200 Subject: [PATCH 1/5] SCORU/Node: only store finalized level instead of L2 block --- src/proto_alpha/lib_sc_rollup_node/daemon.ml | 2 +- .../lib_sc_rollup_node/node_context.ml | 25 +++++++++++-------- .../lib_sc_rollup_node/node_context.mli | 7 ++++-- src/proto_alpha/lib_sc_rollup_node/store.ml | 22 ++++++++-------- src/proto_alpha/lib_sc_rollup_node/store.mli | 5 ++-- 5 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index d795b32847e7..65d80a10be23 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -316,7 +316,7 @@ module Make (PVM : Pvm.S) = struct Daemon_event.head_processing block.hash block.level ~finalized:true in let* () = process_l1_block_operations ~finalized:true node_ctxt block in - let* () = Node_context.mark_finalized_head node_ctxt block.hash in + let* () = Node_context.mark_finalized_level node_ctxt block.level in return_unit let previous_context (node_ctxt : _ Node_context.t) diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.ml b/src/proto_alpha/lib_sc_rollup_node/node_context.ml index a1e10aee4659..f760fe58d3c6 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.ml @@ -396,17 +396,13 @@ let is_processed {store; _} head = Store.L2_blocks.mem store.l2_blocks head let last_processed_head_opt {store; _} = Store.L2_head.read store.l2_head -let mark_finalized_head {store; _} head_hash = - let open Lwt_result_syntax in - let* block = Store.L2_blocks.read store.l2_blocks head_hash in - match block with - | None -> return_unit - | Some (block_info, header) -> - let block = {block_info with header} in - Store.Last_finalized_head.write store.last_finalized_head block +let mark_finalized_level {store; _} level = + Store.Last_finalized_level.write store.last_finalized_level level -let get_finalized_head_opt {store; _} = - Store.Last_finalized_head.read store.last_finalized_head +let get_finalized_level {store; _} = + let open Lwt_result_syntax in + let+ level = Store.Last_finalized_level.read store.last_finalized_level in + Option.value level ~default:0l let get_l2_block {store; _} block_hash = let open Lwt_result_syntax in @@ -434,6 +430,15 @@ let find_l2_block_by_level node_ctxt level = | None -> return_none | Some block_hash -> find_l2_block node_ctxt block_hash +let get_finalized_head_opt node_ctxt = + let open Lwt_result_syntax in + let* level = + Store.Last_finalized_level.read node_ctxt.store.last_finalized_level + in + match level with + | None -> return_none + | Some level -> find_l2_block_by_level node_ctxt level + let head_of_block_level (hash, level) = {Layer1.hash; level} let block_level_of_head Layer1.{hash; level} = (hash, level) diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.mli b/src/proto_alpha/lib_sc_rollup_node/node_context.mli index 33100b289a92..387be7e4c48f 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.mli +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.mli @@ -196,9 +196,12 @@ val last_processed_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t (** [mark_finalized_head store head] remembers that the [head] is finalized. By construction, every block whose level is smaller than [head]'s is also finalized. *) -val mark_finalized_head : rw -> Block_hash.t -> unit tzresult Lwt.t +val mark_finalized_level : rw -> int32 -> unit tzresult Lwt.t -(** [last_finalized_head_opt store] returns the last finalized head if it exists. *) +(** [get_finalized_level t] returns the last finalized level. *) +val get_finalized_level : _ t -> int32 tzresult Lwt.t + +(** [get_finalized_head_opt store] returns the last finalized head if it exists. *) val get_finalized_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t (** [hash_of_level node_ctxt level] returns the current block hash for a given diff --git a/src/proto_alpha/lib_sc_rollup_node/store.ml b/src/proto_alpha/lib_sc_rollup_node/store.ml index dd1a6b70ae1c..17fb35d80197 100644 --- a/src/proto_alpha/lib_sc_rollup_node/store.ml +++ b/src/proto_alpha/lib_sc_rollup_node/store.ml @@ -197,12 +197,12 @@ module L2_head = Indexed_store.Make_singleton (struct let encoding = Sc_rollup_block.encoding end) -module Last_finalized_head = Indexed_store.Make_singleton (struct - type t = Sc_rollup_block.t +module Last_finalized_level = Indexed_store.Make_singleton (struct + type t = int32 - let name = "finalized_head" + let name = "finalized_level" - let encoding = Sc_rollup_block.encoding + let encoding = Data_encoding.int32 end) (** Table from L1 levels to blocks hashes. *) @@ -357,7 +357,7 @@ type 'a store = { commitments : 'a Commitments.t; commitments_published_at_level : 'a Commitments_published_at_level.t; l2_head : 'a L2_head.t; - last_finalized_head : 'a Last_finalized_head.t; + last_finalized_level : 'a Last_finalized_level.t; levels_to_hashes : 'a Levels_to_hashes.t; irmin_store : 'a Irmin_store.t; } @@ -376,7 +376,7 @@ let readonly commitments; commitments_published_at_level; l2_head; - last_finalized_head; + last_finalized_level; levels_to_hashes; irmin_store; } : @@ -389,7 +389,7 @@ let readonly commitments_published_at_level = Commitments_published_at_level.readonly commitments_published_at_level; l2_head = L2_head.readonly l2_head; - last_finalized_head = Last_finalized_head.readonly last_finalized_head; + last_finalized_level = Last_finalized_level.readonly last_finalized_level; levels_to_hashes = Levels_to_hashes.readonly levels_to_hashes; irmin_store = Irmin_store.readonly irmin_store; } @@ -402,7 +402,7 @@ let close commitments; commitments_published_at_level; l2_head = _; - last_finalized_head = _; + last_finalized_level = _; levels_to_hashes; irmin_store; } : @@ -432,8 +432,8 @@ let load (type a) (mode : a mode) ~l2_blocks_cache_size data_dir : ~path:(path "commitments_published_at_level") in let* l2_head = L2_head.load mode ~path:(path "l2_head") in - let* last_finalized_head = - Last_finalized_head.load mode ~path:(path "last_finalized_head") + let* last_finalized_level = + Last_finalized_level.load mode ~path:(path "last_finalized_level") in let* levels_to_hashes = Levels_to_hashes.load mode ~path:(path "levels_to_hashes") @@ -446,7 +446,7 @@ let load (type a) (mode : a mode) ~l2_blocks_cache_size data_dir : commitments; commitments_published_at_level; l2_head; - last_finalized_head; + last_finalized_level; levels_to_hashes; irmin_store; } diff --git a/src/proto_alpha/lib_sc_rollup_node/store.mli b/src/proto_alpha/lib_sc_rollup_node/store.mli index 974f5241c44c..2bf1bd361a0f 100644 --- a/src/proto_alpha/lib_sc_rollup_node/store.mli +++ b/src/proto_alpha/lib_sc_rollup_node/store.mli @@ -77,8 +77,7 @@ end module L2_head : SINGLETON_STORE with type value := Sc_rollup_block.t -module Last_finalized_head : - SINGLETON_STORE with type value := Sc_rollup_block.t +module Last_finalized_level : SINGLETON_STORE with type value := int32 module Levels_to_hashes : INDEXABLE_STORE with type key := int32 and type value := Block_hash.t @@ -129,7 +128,7 @@ type +'a store = { commitments : 'a Commitments.t; commitments_published_at_level : 'a Commitments_published_at_level.t; l2_head : 'a L2_head.t; - last_finalized_head : 'a Last_finalized_head.t; + last_finalized_level : 'a Last_finalized_level.t; levels_to_hashes : 'a Levels_to_hashes.t; irmin_store : 'a Irmin_store.t; } -- GitLab From 4e4fa8282efeabc7cc1cce100af6bea9a1e633e9 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 21 Apr 2023 11:35:20 +0200 Subject: [PATCH 2/5] SCORU/Node: use finalized level where possible --- .../lib_sc_rollup_node/RPC_directory_helpers.ml | 6 ++---- src/proto_alpha/lib_sc_rollup_node/RPC_server.ml | 9 ++------- src/proto_alpha/lib_sc_rollup_node/daemon.ml | 9 ++------- 3 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/RPC_directory_helpers.ml b/src/proto_alpha/lib_sc_rollup_node/RPC_directory_helpers.ml index ca7cf1e405fa..b729005cdb98 100644 --- a/src/proto_alpha/lib_sc_rollup_node/RPC_directory_helpers.ml +++ b/src/proto_alpha/lib_sc_rollup_node/RPC_directory_helpers.ml @@ -75,10 +75,8 @@ module Block_directory_helpers = struct let get_finalized node_ctxt = let open Lwt_result_syntax in - let* head = Node_context.get_finalized_head_opt node_ctxt in - match head with - | None -> failwith "No finalized head" - | Some {header = {block_hash; _}; _} -> return block_hash + let* level = Node_context.get_finalized_level node_ctxt in + Node_context.hash_of_level node_ctxt level let get_last_cemented (node_ctxt : _ Node_context.t) = protect @@ fun () -> diff --git a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml index bc9bcbf82b63..993c887ba690 100644 --- a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml @@ -375,13 +375,8 @@ module Make (Simulation : Simulation.S) (Batcher : Batcher.S) = struct let inbox_info_of_level (node_ctxt : _ Node_context.t) inbox_level = let open Alpha_context in let open Lwt_result_syntax in - let+ finalized_head = Node_context.get_finalized_head_opt node_ctxt in - let finalized = - match finalized_head with - | None -> false - | Some {header = {level = finalized_level; _}; _} -> - Compare.Int32.(inbox_level <= Raw_level.to_int32 finalized_level) - in + let+ finalized_level = Node_context.get_finalized_level node_ctxt in + let finalized = Compare.Int32.(inbox_level <= finalized_level) in let lcc = Reference.get node_ctxt.lcc in let cemented = Compare.Int32.(inbox_level <= Raw_level.to_int32 lcc.level) diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index 65d80a10be23..4ea43f096200 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -297,13 +297,8 @@ module Make (PVM : Pvm.S) = struct let rec processed_finalized_block (node_ctxt : _ Node_context.t) (block : Layer1.header) = let open Lwt_result_syntax in - let* last_finalized = Node_context.get_finalized_head_opt node_ctxt in - let already_finalized = - match last_finalized with - | Some finalized -> - block.level <= Raw_level.to_int32 finalized.header.level - | None -> false - in + let* finalized_level = Node_context.get_finalized_level node_ctxt in + let already_finalized = block.level <= finalized_level in unless (already_finalized || before_origination node_ctxt block) @@ fun () -> let* predecessor = -- GitLab From b9c736b959966b449636ad687ee953e41af81347 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 21 Apr 2023 13:50:57 +0200 Subject: [PATCH 3/5] SCORU/Node: remove useless handling of finalized block This also prevents accidentally fetching a block from a previous protocol. --- src/proto_alpha/lib_sc_rollup_node/daemon.ml | 70 +++++-------------- .../lib_sc_rollup_node/daemon_event.ml | 26 ++----- .../lib_sc_rollup_node/daemon_event.mli | 12 ++-- .../lib_sc_rollup_node/node_context.ml | 17 ----- .../lib_sc_rollup_node/node_context.mli | 13 ---- 5 files changed, 27 insertions(+), 111 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index 4ea43f096200..c938332a6b64 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -222,15 +222,8 @@ module Make (PVM : Pvm.S) = struct (* Other manager operations *) return_unit - (** Process an L1 SCORU operation (for the node's rollup) which is finalized - for the first time. *) - let process_finalized_l1_operation (type kind) _node_ctxt _head ~source:_ - (_operation : kind manager_operation) - (_result : kind successful_manager_operation_result) = - return_unit - - let process_l1_operation (type kind) ~finalized node_ctxt - (head : Layer1.header) ~source (operation : kind manager_operation) + let process_l1_operation (type kind) node_ctxt (head : Layer1.header) ~source + (operation : kind manager_operation) (result : kind Apply_results.manager_operation_result) = let open Lwt_result_syntax in let is_for_my_rollup : type kind. kind manager_operation -> bool = function @@ -253,19 +246,20 @@ module Make (PVM : Pvm.S) = struct if not (is_for_my_rollup operation) then return_unit else (* Only look at operations that are for the node's rollup *) - let*! () = Daemon_event.included_operation ~finalized operation result in + let*! () = Daemon_event.included_operation operation result in match result with | Applied success_result -> - let process = - if finalized then process_finalized_l1_operation - else process_included_l1_operation - in - process node_ctxt head ~source operation success_result + process_included_l1_operation + node_ctxt + head + ~source + operation + success_result | _ -> (* No action for non successful operations *) return_unit - let process_l1_block_operations ~finalized node_ctxt (head : Layer1.header) = + let process_l1_block_operations node_ctxt (head : Layer1.header) = let open Lwt_result_syntax in let* block = Layer1.fetch_tezos_block node_ctxt.Node_context.cctxt head.hash @@ -274,7 +268,7 @@ module Make (PVM : Pvm.S) = struct result = let open Lwt_result_syntax in let* () = accu in - process_l1_operation ~finalized node_ctxt head ~source operation result + process_l1_operation node_ctxt head ~source operation result in let apply_internal (type kind) accu ~source:_ (_operation : kind Apply_internal_results.internal_operation) @@ -294,26 +288,6 @@ module Make (PVM : Pvm.S) = struct let origination_level = Raw_level.to_int32 node_ctxt.genesis_info.level in header.level < origination_level - let rec processed_finalized_block (node_ctxt : _ Node_context.t) - (block : Layer1.header) = - let open Lwt_result_syntax in - let* finalized_level = Node_context.get_finalized_level node_ctxt in - let already_finalized = block.level <= finalized_level in - unless (already_finalized || before_origination node_ctxt block) - @@ fun () -> - let* predecessor = - Node_context.get_predecessor_header_opt node_ctxt block - in - let* () = - Option.iter_es (processed_finalized_block node_ctxt) predecessor - in - let*! () = - Daemon_event.head_processing block.hash block.level ~finalized:true - in - let* () = process_l1_block_operations ~finalized:true node_ctxt block in - let* () = Node_context.mark_finalized_level node_ctxt block.level in - return_unit - let previous_context (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) = let open Lwt_result_syntax in @@ -327,9 +301,7 @@ module Make (PVM : Pvm.S) = struct let open Lwt_result_syntax in let* already_processed = Node_context.is_processed node_ctxt head.hash in unless (already_processed || before_origination node_ctxt head) @@ fun () -> - let*! () = - Daemon_event.head_processing head.hash head.level ~finalized:false - in + let*! () = Daemon_event.head_processing head.hash head.level in let* predecessor = Node_context.get_predecessor_header_opt node_ctxt head in match predecessor with | None -> @@ -351,7 +323,7 @@ module Make (PVM : Pvm.S) = struct when_ (Node_context.dal_supported node_ctxt) @@ fun () -> Dal_slots_tracker.process_head node_ctxt (Layer1.head_of_header head) in - let* () = process_l1_block_operations ~finalized:false node_ctxt head in + let* () = process_l1_block_operations node_ctxt head in (* Avoid storing and publishing commitments if the head is not final. *) (* Avoid triggering the pvm execution if this has been done before for this head. *) @@ -396,23 +368,17 @@ module Make (PVM : Pvm.S) = struct let l2_block = Sc_rollup_block.{header; content = (); num_ticks; initial_tick} in - let* finalized_block, _ = - Node_context.nth_predecessor_header + let* () = + Node_context.mark_finalized_level node_ctxt - node_ctxt.block_finality_time - head + Int32.(sub head.level (of_int node_ctxt.block_finality_time)) in - let* () = processed_finalized_block node_ctxt finalized_block in let* () = Node_context.save_l2_head node_ctxt l2_block in - let*! () = - Daemon_event.new_head_processed head.hash (Raw_level.to_int32 level) - in + let*! () = Daemon_event.new_head_processed head.hash head.level in return_unit (* [on_layer_1_head node_ctxt head] processes a new head from the L1. It - also processes any missing blocks that were not processed. Every time a - head is processed we also process head~2 as finalized (which may recursively - imply the processing of head~3, etc). *) + also processes any missing blocks that were not processed. *) let on_layer_1_head node_ctxt (head : Layer1.header) = let open Lwt_result_syntax in let* old_head = Node_context.last_processed_head_opt node_ctxt in diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon_event.ml b/src/proto_alpha/lib_sc_rollup_node/daemon_event.ml index 7a4cb11f17c3..aee7081067df 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon_event.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon_event.ml @@ -29,16 +29,13 @@ module Simple = struct let section = [Protocol.name; "sc_rollup_node"; "daemon"] let head_processing = - declare_3 + declare_2 ~section ~name:"sc_rollup_daemon_process_head" - ~msg:"Processing {finalized} head {hash} at level {level}" + ~msg:"Processing head {hash} at level {level}" ~level:Notice ("hash", Block_hash.encoding) ("level", Data_encoding.int32) - ("finalized", Data_encoding.bool) - ~pp3:(fun fmt finalized -> - Format.pp_print_string fmt @@ if finalized then "finalized" else "new") let new_head_processed = declare_2 @@ -103,15 +100,6 @@ module Simple = struct | None -> Format.pp_print_string ppf "none" | Some e -> Environment.Error_monad.pp_trace ppf e) - let finalized_successful_operation = - declare_1 - ~section - ~name:"sc_rollup_daemon_finalized_successful_operation" - ~msg:"Operation {operation} was finalized" - ~level:Debug - ("operation", L1_operation.encoding) - ~pp1:L1_operation.pp - let error = declare_1 ~section @@ -132,8 +120,7 @@ module Simple = struct () end -let head_processing hash level ~finalized = - Simple.(emit head_processing (hash, level, finalized)) +let head_processing hash level = Simple.(emit head_processing (hash, level)) let new_head_processed hash level = Simple.(emit new_head_processed (hash, level)) @@ -155,18 +142,13 @@ let processing_heads_iteration = let new_heads_processed = new_heads_iteration Simple.new_heads_processed -let included_operation (type kind) ~finalized +let included_operation (type kind) (operation : kind Protocol.Alpha_context.manager_operation) (result : kind Protocol.Apply_results.manager_operation_result) = match L1_operation.of_manager_operation operation with | None -> Lwt.return_unit | Some operation -> ( match result with - | Applied _ when finalized -> - Simple.(emit finalized_successful_operation) operation - | _ when finalized -> - (* No events for finalized non successful operations *) - Lwt.return_unit | Applied _ -> Simple.(emit included_successful_operation) operation | result -> let status, errors = diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon_event.mli b/src/proto_alpha/lib_sc_rollup_node/daemon_event.mli index 7ae454d6a628..2456fe946b41 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon_event.mli +++ b/src/proto_alpha/lib_sc_rollup_node/daemon_event.mli @@ -26,10 +26,9 @@ (** This module defines functions that emit the events used by the smart rollup node daemon (see {!Daemon}). *) -(** [head_processing hash level ~finalized] emits the event that the - block of the given [hash] and at the given [level] is being processed, and - whether it is [finalized]. *) -val head_processing : Block_hash.t -> int32 -> finalized:bool -> unit Lwt.t +(** [head_processing hash level] emits the event that the + block of the given [hash] and at the given [level] is being processed. *) +val head_processing : Block_hash.t -> int32 -> unit Lwt.t (** [new_head_processed hash level] emits the event that the daemon has finished processing the head of the given [hash] and at the given [level]. *) @@ -43,10 +42,9 @@ val processing_heads_iteration : Layer1.head list -> unit Lwt.t processed. *) val new_heads_processed : Layer1.head list -> unit Lwt.t -(** [included_operation ~finalized op result] emits an event that an operation - for the rollup was included in a block (or finalized). *) +(** [included_operation op result] emits an event that an operation + for the rollup was included in a block. *) val included_operation : - finalized:bool -> 'kind Protocol.Alpha_context.manager_operation -> 'kind Protocol.Apply_results.manager_operation_result -> unit Lwt.t diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.ml b/src/proto_alpha/lib_sc_rollup_node/node_context.ml index f760fe58d3c6..9d151d780dfc 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.ml @@ -469,28 +469,11 @@ let get_predecessor node_ctxt (hash, level) = (* [head] is not already known in the L2 chain *) Layer1.get_predecessor node_ctxt.l1_ctxt (hash, level) -let nth_predecessor node_ctxt n block = - let open Lwt_result_syntax in - let+ res, preds = - Layer1.nth_predecessor - ~get_predecessor:(get_predecessor node_ctxt) - n - (block_level_of_head block) - in - (head_of_block_level res, List.map head_of_block_level preds) - let header_of_head node_ctxt Layer1.{hash; level} = let open Lwt_result_syntax in let+ header = Layer1.fetch_tezos_shell_header node_ctxt.cctxt hash in {Layer1.hash; level; header} -let nth_predecessor_header node_ctxt n block = - let open Lwt_result_syntax in - let* res, preds = nth_predecessor node_ctxt n (Layer1.head_of_header block) in - let* res = header_of_head node_ctxt res - and* preds = List.map_ep (header_of_head node_ctxt) preds in - return (res, preds) - let get_tezos_reorg_for_new_head node_ctxt old_head new_head = let open Lwt_result_syntax in let old_head = diff --git a/src/proto_alpha/lib_sc_rollup_node/node_context.mli b/src/proto_alpha/lib_sc_rollup_node/node_context.mli index 387be7e4c48f..a1f89c7a1575 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.mli +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.mli @@ -224,12 +224,6 @@ val get_predecessor_opt : (** [get_predecessor state head] returns the predecessor block of [head]. *) val get_predecessor : _ t -> Layer1.head -> Layer1.head tzresult Lwt.t -(** [nth_predecessor n head] return [block, history] where [block] is the nth - predecessor of [head] and [history] is the list of blocks between [block] - (excluded) and [head] (included) on the chain. *) -val nth_predecessor : - _ t -> int -> Layer1.head -> (Layer1.head * Layer1.head list) tzresult Lwt.t - (** Same as {!get_predecessor_opt} with headers. *) val get_predecessor_header_opt : _ t -> Layer1.header -> Layer1.header option tzresult Lwt.t @@ -238,13 +232,6 @@ val get_predecessor_header_opt : val get_predecessor_header : _ t -> Layer1.header -> Layer1.header tzresult Lwt.t -(** Same as {!nth_predecessor} with headers. *) -val nth_predecessor_header : - _ t -> - int -> - Layer1.header -> - (Layer1.header * Layer1.header list) tzresult Lwt.t - (** [get_tezos_reorg_for_new_head node_ctxt old_head new_head] returns the L1 reorganization between [old_head] and [new_head]. *) val get_tezos_reorg_for_new_head : -- GitLab From 0b547f8bcf4bb029427fdc67a92fc35c9ed120f7 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 21 Apr 2023 11:32:05 +0200 Subject: [PATCH 4/5] SCORU/Node: backport !8524 to Mumbai rollup node - SCORU/Node: only store finalized level instead of L2 block - SCORU/Node: use finalized level where possible - SCORU/Node: remove useless handling of finalized block --- .../RPC_directory_helpers.ml | 6 +- .../lib_sc_rollup_node/RPC_server.ml | 9 +-- .../lib_sc_rollup_node/daemon.ml | 75 +++++-------------- .../lib_sc_rollup_node/daemon_event.ml | 26 +------ .../lib_sc_rollup_node/daemon_event.mli | 12 ++- .../lib_sc_rollup_node/node_context.ml | 42 ++++------- .../lib_sc_rollup_node/node_context.mli | 20 ++--- .../lib_sc_rollup_node/store.ml | 22 +++--- .../lib_sc_rollup_node/store.mli | 5 +- 9 files changed, 64 insertions(+), 153 deletions(-) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.ml index ca7cf1e405fa..b729005cdb98 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.ml @@ -75,10 +75,8 @@ module Block_directory_helpers = struct let get_finalized node_ctxt = let open Lwt_result_syntax in - let* head = Node_context.get_finalized_head_opt node_ctxt in - match head with - | None -> failwith "No finalized head" - | Some {header = {block_hash; _}; _} -> return block_hash + let* level = Node_context.get_finalized_level node_ctxt in + Node_context.hash_of_level node_ctxt level let get_last_cemented (node_ctxt : _ Node_context.t) = protect @@ fun () -> diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml index a72a534334a1..ba98cacfc640 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml @@ -423,13 +423,8 @@ module Make (Simulation : Simulation.S) (Batcher : Batcher.S) = struct let inbox_info_of_level (node_ctxt : _ Node_context.t) inbox_level = let open Alpha_context in let open Lwt_result_syntax in - let+ finalized_head = Node_context.get_finalized_head_opt node_ctxt in - let finalized = - match finalized_head with - | None -> false - | Some {header = {level = finalized_level; _}; _} -> - Compare.Int32.(inbox_level <= Raw_level.to_int32 finalized_level) - in + let+ finalized_level = Node_context.get_finalized_level node_ctxt in + let finalized = Compare.Int32.(inbox_level <= finalized_level) in let lcc = Reference.get node_ctxt.lcc in let cemented = Compare.Int32.(inbox_level <= Raw_level.to_int32 lcc.level) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml index e637f2249de6..ef8f20fe450f 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon.ml @@ -220,15 +220,8 @@ module Make (PVM : Pvm.S) = struct (* Other manager operations *) return_unit - (** Process an L1 SCORU operation (for the node's rollup) which is finalized - for the first time. *) - let process_finalized_l1_operation (type kind) _node_ctxt _head ~source:_ - (_operation : kind manager_operation) - (_result : kind successful_manager_operation_result) = - return_unit - - let process_l1_operation (type kind) ~finalized node_ctxt - (head : Layer1.header) ~source (operation : kind manager_operation) + let process_l1_operation (type kind) node_ctxt (head : Layer1.header) ~source + (operation : kind manager_operation) (result : kind Apply_results.manager_operation_result) = let open Lwt_result_syntax in let is_for_my_rollup : type kind. kind manager_operation -> bool = function @@ -254,19 +247,20 @@ module Make (PVM : Pvm.S) = struct if not (is_for_my_rollup operation) then return_unit else (* Only look at operations that are for the node's rollup *) - let*! () = Daemon_event.included_operation ~finalized operation result in + let*! () = Daemon_event.included_operation operation result in match result with | Applied success_result -> - let process = - if finalized then process_finalized_l1_operation - else process_included_l1_operation - in - process node_ctxt head ~source operation success_result + process_included_l1_operation + node_ctxt + head + ~source + operation + success_result | _ -> (* No action for non successful operations *) return_unit - let process_l1_block_operations ~finalized node_ctxt (head : Layer1.header) = + let process_l1_block_operations node_ctxt (head : Layer1.header) = let open Lwt_result_syntax in let* block = Layer1.fetch_tezos_block node_ctxt.Node_context.cctxt head.hash @@ -275,7 +269,7 @@ module Make (PVM : Pvm.S) = struct result = let open Lwt_result_syntax in let* () = accu in - process_l1_operation ~finalized node_ctxt head ~source operation result + process_l1_operation node_ctxt head ~source operation result in let apply_internal (type kind) accu ~source:_ (_operation : kind Apply_internal_results.internal_operation) @@ -295,31 +289,6 @@ module Make (PVM : Pvm.S) = struct let origination_level = Raw_level.to_int32 node_ctxt.genesis_info.level in header.level < origination_level - let rec processed_finalized_block (node_ctxt : _ Node_context.t) - (block : Layer1.header) = - let open Lwt_result_syntax in - let* last_finalized = Node_context.get_finalized_head_opt node_ctxt in - let already_finalized = - match last_finalized with - | Some finalized -> - block.level <= Raw_level.to_int32 finalized.header.level - | None -> false - in - unless (already_finalized || before_origination node_ctxt block) - @@ fun () -> - let* predecessor = - Node_context.get_predecessor_header_opt node_ctxt block - in - let* () = - Option.iter_es (processed_finalized_block node_ctxt) predecessor - in - let*! () = - Daemon_event.head_processing block.hash block.level ~finalized:true - in - let* () = process_l1_block_operations ~finalized:true node_ctxt block in - let* () = Node_context.mark_finalized_head node_ctxt block.hash in - return_unit - let previous_context (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) = let open Lwt_result_syntax in @@ -333,9 +302,7 @@ module Make (PVM : Pvm.S) = struct let open Lwt_result_syntax in let* already_processed = Node_context.is_processed node_ctxt head.hash in unless (already_processed || before_origination node_ctxt head) @@ fun () -> - let*! () = - Daemon_event.head_processing head.hash head.level ~finalized:false - in + let*! () = Daemon_event.head_processing head.hash head.level in let* predecessor = Node_context.get_predecessor_header_opt node_ctxt head in match predecessor with | None -> @@ -357,7 +324,7 @@ module Make (PVM : Pvm.S) = struct when_ (Node_context.dal_supported node_ctxt) @@ fun () -> Dal_slots_tracker.process_head node_ctxt (Layer1.head_of_header head) in - let* () = process_l1_block_operations ~finalized:false node_ctxt head in + let* () = process_l1_block_operations node_ctxt head in (* Avoid storing and publishing commitments if the head is not final. *) (* Avoid triggering the pvm execution if this has been done before for this head. *) @@ -402,23 +369,17 @@ module Make (PVM : Pvm.S) = struct let l2_block = Sc_rollup_block.{header; content = (); num_ticks; initial_tick} in - let* finalized_block, _ = - Node_context.nth_predecessor_header + let* () = + Node_context.mark_finalized_level node_ctxt - node_ctxt.block_finality_time - head + Int32.(sub head.level (of_int node_ctxt.block_finality_time)) in - let* () = processed_finalized_block node_ctxt finalized_block in let* () = Node_context.save_l2_head node_ctxt l2_block in - let*! () = - Daemon_event.new_head_processed head.hash (Raw_level.to_int32 level) - in + let*! () = Daemon_event.new_head_processed head.hash head.level in return_unit (* [on_layer_1_head node_ctxt head] processes a new head from the L1. It - also processes any missing blocks that were not processed. Every time a - head is processed we also process head~2 as finalized (which may recursively - imply the processing of head~3, etc). *) + also processes any missing blocks that were not processed. *) let on_layer_1_head node_ctxt (head : Layer1.header) = let open Lwt_result_syntax in let* old_head = Node_context.last_processed_head_opt node_ctxt in diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon_event.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon_event.ml index 7a4cb11f17c3..aee7081067df 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon_event.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon_event.ml @@ -29,16 +29,13 @@ module Simple = struct let section = [Protocol.name; "sc_rollup_node"; "daemon"] let head_processing = - declare_3 + declare_2 ~section ~name:"sc_rollup_daemon_process_head" - ~msg:"Processing {finalized} head {hash} at level {level}" + ~msg:"Processing head {hash} at level {level}" ~level:Notice ("hash", Block_hash.encoding) ("level", Data_encoding.int32) - ("finalized", Data_encoding.bool) - ~pp3:(fun fmt finalized -> - Format.pp_print_string fmt @@ if finalized then "finalized" else "new") let new_head_processed = declare_2 @@ -103,15 +100,6 @@ module Simple = struct | None -> Format.pp_print_string ppf "none" | Some e -> Environment.Error_monad.pp_trace ppf e) - let finalized_successful_operation = - declare_1 - ~section - ~name:"sc_rollup_daemon_finalized_successful_operation" - ~msg:"Operation {operation} was finalized" - ~level:Debug - ("operation", L1_operation.encoding) - ~pp1:L1_operation.pp - let error = declare_1 ~section @@ -132,8 +120,7 @@ module Simple = struct () end -let head_processing hash level ~finalized = - Simple.(emit head_processing (hash, level, finalized)) +let head_processing hash level = Simple.(emit head_processing (hash, level)) let new_head_processed hash level = Simple.(emit new_head_processed (hash, level)) @@ -155,18 +142,13 @@ let processing_heads_iteration = let new_heads_processed = new_heads_iteration Simple.new_heads_processed -let included_operation (type kind) ~finalized +let included_operation (type kind) (operation : kind Protocol.Alpha_context.manager_operation) (result : kind Protocol.Apply_results.manager_operation_result) = match L1_operation.of_manager_operation operation with | None -> Lwt.return_unit | Some operation -> ( match result with - | Applied _ when finalized -> - Simple.(emit finalized_successful_operation) operation - | _ when finalized -> - (* No events for finalized non successful operations *) - Lwt.return_unit | Applied _ -> Simple.(emit included_successful_operation) operation | result -> let status, errors = diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon_event.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon_event.mli index 7ae454d6a628..2456fe946b41 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon_event.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/daemon_event.mli @@ -26,10 +26,9 @@ (** This module defines functions that emit the events used by the smart rollup node daemon (see {!Daemon}). *) -(** [head_processing hash level ~finalized] emits the event that the - block of the given [hash] and at the given [level] is being processed, and - whether it is [finalized]. *) -val head_processing : Block_hash.t -> int32 -> finalized:bool -> unit Lwt.t +(** [head_processing hash level] emits the event that the + block of the given [hash] and at the given [level] is being processed. *) +val head_processing : Block_hash.t -> int32 -> unit Lwt.t (** [new_head_processed hash level] emits the event that the daemon has finished processing the head of the given [hash] and at the given [level]. *) @@ -43,10 +42,9 @@ val processing_heads_iteration : Layer1.head list -> unit Lwt.t processed. *) val new_heads_processed : Layer1.head list -> unit Lwt.t -(** [included_operation ~finalized op result] emits an event that an operation - for the rollup was included in a block (or finalized). *) +(** [included_operation op result] emits an event that an operation + for the rollup was included in a block. *) val included_operation : - finalized:bool -> 'kind Protocol.Alpha_context.manager_operation -> 'kind Protocol.Apply_results.manager_operation_result -> unit Lwt.t diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml index fd241d16ee47..f740ed4fe79c 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.ml @@ -379,17 +379,13 @@ let is_processed {store; _} head = Store.L2_blocks.mem store.l2_blocks head let last_processed_head_opt {store; _} = Store.L2_head.read store.l2_head -let mark_finalized_head {store; _} head_hash = - let open Lwt_result_syntax in - let* block = Store.L2_blocks.read store.l2_blocks head_hash in - match block with - | None -> return_unit - | Some (block_info, header) -> - let block = {block_info with header} in - Store.Last_finalized_head.write store.last_finalized_head block +let mark_finalized_level {store; _} level = + Store.Last_finalized_level.write store.last_finalized_level level -let get_finalized_head_opt {store; _} = - Store.Last_finalized_head.read store.last_finalized_head +let get_finalized_level {store; _} = + let open Lwt_result_syntax in + let+ level = Store.Last_finalized_level.read store.last_finalized_level in + Option.value level ~default:0l let get_l2_block {store; _} block_hash = let open Lwt_result_syntax in @@ -417,6 +413,15 @@ let find_l2_block_by_level node_ctxt level = | None -> return_none | Some block_hash -> find_l2_block node_ctxt block_hash +let get_finalized_head_opt node_ctxt = + let open Lwt_result_syntax in + let* level = + Store.Last_finalized_level.read node_ctxt.store.last_finalized_level + in + match level with + | None -> return_none + | Some level -> find_l2_block_by_level node_ctxt level + let head_of_block_level (hash, level) = {Layer1.hash; level} let block_level_of_head Layer1.{hash; level} = (hash, level) @@ -447,28 +452,11 @@ let get_predecessor node_ctxt (hash, level) = (* [head] is not already known in the L2 chain *) Layer1.get_predecessor node_ctxt.l1_ctxt (hash, level) -let nth_predecessor node_ctxt n block = - let open Lwt_result_syntax in - let+ res, preds = - Layer1.nth_predecessor - ~get_predecessor:(get_predecessor node_ctxt) - n - (block_level_of_head block) - in - (head_of_block_level res, List.map head_of_block_level preds) - let header_of_head node_ctxt Layer1.{hash; level} = let open Lwt_result_syntax in let+ header = Layer1.fetch_tezos_shell_header node_ctxt.cctxt hash in {Layer1.hash; level; header} -let nth_predecessor_header node_ctxt n block = - let open Lwt_result_syntax in - let* res, preds = nth_predecessor node_ctxt n (Layer1.head_of_header block) in - let* res = header_of_head node_ctxt res - and* preds = List.map_ep (header_of_head node_ctxt) preds in - return (res, preds) - let get_tezos_reorg_for_new_head node_ctxt old_head new_head = let open Lwt_result_syntax in let old_head = diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli index eead4d447f69..53ab58a46c99 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/node_context.mli @@ -193,9 +193,12 @@ val last_processed_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t (** [mark_finalized_head store head] remembers that the [head] is finalized. By construction, every block whose level is smaller than [head]'s is also finalized. *) -val mark_finalized_head : rw -> Block_hash.t -> unit tzresult Lwt.t +val mark_finalized_level : rw -> int32 -> unit tzresult Lwt.t -(** [last_finalized_head_opt store] returns the last finalized head if it exists. *) +(** [get_finalized_level t] returns the last finalized level. *) +val get_finalized_level : _ t -> int32 tzresult Lwt.t + +(** [get_finalized_head_opt store] returns the last finalized head if it exists. *) val get_finalized_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t (** [hash_of_level node_ctxt level] returns the current block hash for a given @@ -218,12 +221,6 @@ val get_predecessor_opt : (** [get_predecessor state head] returns the predecessor block of [head]. *) val get_predecessor : _ t -> Layer1.head -> Layer1.head tzresult Lwt.t -(** [nth_predecessor n head] return [block, history] where [block] is the nth - predecessor of [head] and [history] is the list of blocks between [block] - (excluded) and [head] (included) on the chain. *) -val nth_predecessor : - _ t -> int -> Layer1.head -> (Layer1.head * Layer1.head list) tzresult Lwt.t - (** Same as {!get_predecessor_opt} with headers. *) val get_predecessor_header_opt : _ t -> Layer1.header -> Layer1.header option tzresult Lwt.t @@ -232,13 +229,6 @@ val get_predecessor_header_opt : val get_predecessor_header : _ t -> Layer1.header -> Layer1.header tzresult Lwt.t -(** Same as {!nth_predecessor} with headers. *) -val nth_predecessor_header : - _ t -> - int -> - Layer1.header -> - (Layer1.header * Layer1.header list) tzresult Lwt.t - (** [get_tezos_reorg_for_new_head node_ctxt old_head new_head] returns the L1 reorganization between [old_head] and [new_head]. *) val get_tezos_reorg_for_new_head : diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/store.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/store.ml index a0baa5160526..38e4c30c0772 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/store.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/store.ml @@ -196,12 +196,12 @@ module L2_head = Indexed_store.Make_singleton (struct let encoding = Sc_rollup_block.encoding end) -module Last_finalized_head = Indexed_store.Make_singleton (struct - type t = Sc_rollup_block.t +module Last_finalized_level = Indexed_store.Make_singleton (struct + type t = int32 - let name = "finalized_head" + let name = "finalized_level" - let encoding = Sc_rollup_block.encoding + let encoding = Data_encoding.int32 end) (** Table from L1 levels to blocks hashes. *) @@ -384,7 +384,7 @@ type 'a store = { commitments : 'a Commitments.t; commitments_published_at_level : 'a Commitments_published_at_level.t; l2_head : 'a L2_head.t; - last_finalized_head : 'a Last_finalized_head.t; + last_finalized_level : 'a Last_finalized_level.t; levels_to_hashes : 'a Levels_to_hashes.t; irmin_store : 'a Irmin_store.t; } @@ -403,7 +403,7 @@ let readonly commitments; commitments_published_at_level; l2_head; - last_finalized_head; + last_finalized_level; levels_to_hashes; irmin_store; } : @@ -416,7 +416,7 @@ let readonly commitments_published_at_level = Commitments_published_at_level.readonly commitments_published_at_level; l2_head = L2_head.readonly l2_head; - last_finalized_head = Last_finalized_head.readonly last_finalized_head; + last_finalized_level = Last_finalized_level.readonly last_finalized_level; levels_to_hashes = Levels_to_hashes.readonly levels_to_hashes; irmin_store = Irmin_store.readonly irmin_store; } @@ -429,7 +429,7 @@ let close commitments; commitments_published_at_level; l2_head = _; - last_finalized_head = _; + last_finalized_level = _; levels_to_hashes; irmin_store; } : @@ -459,8 +459,8 @@ let load (type a) (mode : a mode) ~l2_blocks_cache_size data_dir : ~path:(path "commitments_published_at_level") in let* l2_head = L2_head.load mode ~path:(path "l2_head") in - let* last_finalized_head = - Last_finalized_head.load mode ~path:(path "last_finalized_head") + let* last_finalized_level = + Last_finalized_level.load mode ~path:(path "last_finalized_level") in let* levels_to_hashes = Levels_to_hashes.load mode ~path:(path "levels_to_hashes") @@ -473,7 +473,7 @@ let load (type a) (mode : a mode) ~l2_blocks_cache_size data_dir : commitments; commitments_published_at_level; l2_head; - last_finalized_head; + last_finalized_level; levels_to_hashes; irmin_store; } diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/store.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/store.mli index 252c0f25c100..598836d8f1b0 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/store.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/store.mli @@ -77,8 +77,7 @@ end module L2_head : SINGLETON_STORE with type value := Sc_rollup_block.t -module Last_finalized_head : - SINGLETON_STORE with type value := Sc_rollup_block.t +module Last_finalized_level : SINGLETON_STORE with type value := int32 module Levels_to_hashes : INDEXABLE_STORE with type key := int32 and type value := Block_hash.t @@ -142,7 +141,7 @@ type +'a store = { commitments : 'a Commitments.t; commitments_published_at_level : 'a Commitments_published_at_level.t; l2_head : 'a L2_head.t; - last_finalized_head : 'a Last_finalized_head.t; + last_finalized_level : 'a Last_finalized_level.t; levels_to_hashes : 'a Levels_to_hashes.t; irmin_store : 'a Irmin_store.t; } -- GitLab From bd4db67d0e8496b78d55861a2946be2d982f2b5e Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 21 Apr 2023 11:32:05 +0200 Subject: [PATCH 5/5] SCORU/Node: backport !8524 to Nairobi rollup node - SCORU/Node: only store finalized level instead of L2 block - SCORU/Node: use finalized level where possible - SCORU/Node: remove useless handling of finalized block --- .../RPC_directory_helpers.ml | 6 +- .../lib_sc_rollup_node/RPC_server.ml | 9 +-- .../lib_sc_rollup_node/daemon.ml | 75 +++++-------------- .../lib_sc_rollup_node/daemon_event.ml | 26 +------ .../lib_sc_rollup_node/daemon_event.mli | 12 ++- .../lib_sc_rollup_node/node_context.ml | 42 ++++------- .../lib_sc_rollup_node/node_context.mli | 20 ++--- .../lib_sc_rollup_node/store.ml | 22 +++--- .../lib_sc_rollup_node/store.mli | 5 +- 9 files changed, 64 insertions(+), 153 deletions(-) diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory_helpers.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory_helpers.ml index ca7cf1e405fa..b729005cdb98 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory_helpers.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory_helpers.ml @@ -75,10 +75,8 @@ module Block_directory_helpers = struct let get_finalized node_ctxt = let open Lwt_result_syntax in - let* head = Node_context.get_finalized_head_opt node_ctxt in - match head with - | None -> failwith "No finalized head" - | Some {header = {block_hash; _}; _} -> return block_hash + let* level = Node_context.get_finalized_level node_ctxt in + Node_context.hash_of_level node_ctxt level let get_last_cemented (node_ctxt : _ Node_context.t) = protect @@ fun () -> diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml index bc9bcbf82b63..993c887ba690 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml @@ -375,13 +375,8 @@ module Make (Simulation : Simulation.S) (Batcher : Batcher.S) = struct let inbox_info_of_level (node_ctxt : _ Node_context.t) inbox_level = let open Alpha_context in let open Lwt_result_syntax in - let+ finalized_head = Node_context.get_finalized_head_opt node_ctxt in - let finalized = - match finalized_head with - | None -> false - | Some {header = {level = finalized_level; _}; _} -> - Compare.Int32.(inbox_level <= Raw_level.to_int32 finalized_level) - in + let+ finalized_level = Node_context.get_finalized_level node_ctxt in + let finalized = Compare.Int32.(inbox_level <= finalized_level) in let lcc = Reference.get node_ctxt.lcc in let cemented = Compare.Int32.(inbox_level <= Raw_level.to_int32 lcc.level) diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml index 5dfc35cbff02..f4cd8a88762a 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml @@ -222,15 +222,8 @@ module Make (PVM : Pvm.S) = struct (* Other manager operations *) return_unit - (** Process an L1 SCORU operation (for the node's rollup) which is finalized - for the first time. *) - let process_finalized_l1_operation (type kind) _node_ctxt _head ~source:_ - (_operation : kind manager_operation) - (_result : kind successful_manager_operation_result) = - return_unit - - let process_l1_operation (type kind) ~finalized node_ctxt - (head : Layer1.header) ~source (operation : kind manager_operation) + let process_l1_operation (type kind) node_ctxt (head : Layer1.header) ~source + (operation : kind manager_operation) (result : kind Apply_results.manager_operation_result) = let open Lwt_result_syntax in let is_for_my_rollup : type kind. kind manager_operation -> bool = function @@ -253,19 +246,20 @@ module Make (PVM : Pvm.S) = struct if not (is_for_my_rollup operation) then return_unit else (* Only look at operations that are for the node's rollup *) - let*! () = Daemon_event.included_operation ~finalized operation result in + let*! () = Daemon_event.included_operation operation result in match result with | Applied success_result -> - let process = - if finalized then process_finalized_l1_operation - else process_included_l1_operation - in - process node_ctxt head ~source operation success_result + process_included_l1_operation + node_ctxt + head + ~source + operation + success_result | _ -> (* No action for non successful operations *) return_unit - let process_l1_block_operations ~finalized node_ctxt (head : Layer1.header) = + let process_l1_block_operations node_ctxt (head : Layer1.header) = let open Lwt_result_syntax in let* block = Layer1.fetch_tezos_block node_ctxt.Node_context.cctxt head.hash @@ -274,7 +268,7 @@ module Make (PVM : Pvm.S) = struct result = let open Lwt_result_syntax in let* () = accu in - process_l1_operation ~finalized node_ctxt head ~source operation result + process_l1_operation node_ctxt head ~source operation result in let apply_internal (type kind) accu ~source:_ (_operation : kind Apply_internal_results.internal_operation) @@ -294,31 +288,6 @@ module Make (PVM : Pvm.S) = struct let origination_level = Raw_level.to_int32 node_ctxt.genesis_info.level in header.level < origination_level - let rec processed_finalized_block (node_ctxt : _ Node_context.t) - (block : Layer1.header) = - let open Lwt_result_syntax in - let* last_finalized = Node_context.get_finalized_head_opt node_ctxt in - let already_finalized = - match last_finalized with - | Some finalized -> - block.level <= Raw_level.to_int32 finalized.header.level - | None -> false - in - unless (already_finalized || before_origination node_ctxt block) - @@ fun () -> - let* predecessor = - Node_context.get_predecessor_header_opt node_ctxt block - in - let* () = - Option.iter_es (processed_finalized_block node_ctxt) predecessor - in - let*! () = - Daemon_event.head_processing block.hash block.level ~finalized:true - in - let* () = process_l1_block_operations ~finalized:true node_ctxt block in - let* () = Node_context.mark_finalized_head node_ctxt block.hash in - return_unit - let previous_context (node_ctxt : _ Node_context.t) ~(predecessor : Layer1.header) = let open Lwt_result_syntax in @@ -332,9 +301,7 @@ module Make (PVM : Pvm.S) = struct let open Lwt_result_syntax in let* already_processed = Node_context.is_processed node_ctxt head.hash in unless (already_processed || before_origination node_ctxt head) @@ fun () -> - let*! () = - Daemon_event.head_processing head.hash head.level ~finalized:false - in + let*! () = Daemon_event.head_processing head.hash head.level in let* predecessor = Node_context.get_predecessor_header_opt node_ctxt head in match predecessor with | None -> @@ -356,7 +323,7 @@ module Make (PVM : Pvm.S) = struct when_ (Node_context.dal_supported node_ctxt) @@ fun () -> Dal_slots_tracker.process_head node_ctxt (Layer1.head_of_header head) in - let* () = process_l1_block_operations ~finalized:false node_ctxt head in + let* () = process_l1_block_operations node_ctxt head in (* Avoid storing and publishing commitments if the head is not final. *) (* Avoid triggering the pvm execution if this has been done before for this head. *) @@ -401,23 +368,17 @@ module Make (PVM : Pvm.S) = struct let l2_block = Sc_rollup_block.{header; content = (); num_ticks; initial_tick} in - let* finalized_block, _ = - Node_context.nth_predecessor_header + let* () = + Node_context.mark_finalized_level node_ctxt - node_ctxt.block_finality_time - head + Int32.(sub head.level (of_int node_ctxt.block_finality_time)) in - let* () = processed_finalized_block node_ctxt finalized_block in let* () = Node_context.save_l2_head node_ctxt l2_block in - let*! () = - Daemon_event.new_head_processed head.hash (Raw_level.to_int32 level) - in + let*! () = Daemon_event.new_head_processed head.hash head.level in return_unit (* [on_layer_1_head node_ctxt head] processes a new head from the L1. It - also processes any missing blocks that were not processed. Every time a - head is processed we also process head~2 as finalized (which may recursively - imply the processing of head~3, etc). *) + also processes any missing blocks that were not processed. *) let on_layer_1_head node_ctxt (head : Layer1.header) = let open Lwt_result_syntax in let* old_head = Node_context.last_processed_head_opt node_ctxt in diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon_event.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon_event.ml index 7a4cb11f17c3..aee7081067df 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon_event.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon_event.ml @@ -29,16 +29,13 @@ module Simple = struct let section = [Protocol.name; "sc_rollup_node"; "daemon"] let head_processing = - declare_3 + declare_2 ~section ~name:"sc_rollup_daemon_process_head" - ~msg:"Processing {finalized} head {hash} at level {level}" + ~msg:"Processing head {hash} at level {level}" ~level:Notice ("hash", Block_hash.encoding) ("level", Data_encoding.int32) - ("finalized", Data_encoding.bool) - ~pp3:(fun fmt finalized -> - Format.pp_print_string fmt @@ if finalized then "finalized" else "new") let new_head_processed = declare_2 @@ -103,15 +100,6 @@ module Simple = struct | None -> Format.pp_print_string ppf "none" | Some e -> Environment.Error_monad.pp_trace ppf e) - let finalized_successful_operation = - declare_1 - ~section - ~name:"sc_rollup_daemon_finalized_successful_operation" - ~msg:"Operation {operation} was finalized" - ~level:Debug - ("operation", L1_operation.encoding) - ~pp1:L1_operation.pp - let error = declare_1 ~section @@ -132,8 +120,7 @@ module Simple = struct () end -let head_processing hash level ~finalized = - Simple.(emit head_processing (hash, level, finalized)) +let head_processing hash level = Simple.(emit head_processing (hash, level)) let new_head_processed hash level = Simple.(emit new_head_processed (hash, level)) @@ -155,18 +142,13 @@ let processing_heads_iteration = let new_heads_processed = new_heads_iteration Simple.new_heads_processed -let included_operation (type kind) ~finalized +let included_operation (type kind) (operation : kind Protocol.Alpha_context.manager_operation) (result : kind Protocol.Apply_results.manager_operation_result) = match L1_operation.of_manager_operation operation with | None -> Lwt.return_unit | Some operation -> ( match result with - | Applied _ when finalized -> - Simple.(emit finalized_successful_operation) operation - | _ when finalized -> - (* No events for finalized non successful operations *) - Lwt.return_unit | Applied _ -> Simple.(emit included_successful_operation) operation | result -> let status, errors = diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon_event.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon_event.mli index 7ae454d6a628..2456fe946b41 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon_event.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon_event.mli @@ -26,10 +26,9 @@ (** This module defines functions that emit the events used by the smart rollup node daemon (see {!Daemon}). *) -(** [head_processing hash level ~finalized] emits the event that the - block of the given [hash] and at the given [level] is being processed, and - whether it is [finalized]. *) -val head_processing : Block_hash.t -> int32 -> finalized:bool -> unit Lwt.t +(** [head_processing hash level] emits the event that the + block of the given [hash] and at the given [level] is being processed. *) +val head_processing : Block_hash.t -> int32 -> unit Lwt.t (** [new_head_processed hash level] emits the event that the daemon has finished processing the head of the given [hash] and at the given [level]. *) @@ -43,10 +42,9 @@ val processing_heads_iteration : Layer1.head list -> unit Lwt.t processed. *) val new_heads_processed : Layer1.head list -> unit Lwt.t -(** [included_operation ~finalized op result] emits an event that an operation - for the rollup was included in a block (or finalized). *) +(** [included_operation op result] emits an event that an operation + for the rollup was included in a block. *) val included_operation : - finalized:bool -> 'kind Protocol.Alpha_context.manager_operation -> 'kind Protocol.Apply_results.manager_operation_result -> unit Lwt.t diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.ml index d7909111fed8..15e2f5875567 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.ml @@ -377,17 +377,13 @@ let is_processed {store; _} head = Store.L2_blocks.mem store.l2_blocks head let last_processed_head_opt {store; _} = Store.L2_head.read store.l2_head -let mark_finalized_head {store; _} head_hash = - let open Lwt_result_syntax in - let* block = Store.L2_blocks.read store.l2_blocks head_hash in - match block with - | None -> return_unit - | Some (block_info, header) -> - let block = {block_info with header} in - Store.Last_finalized_head.write store.last_finalized_head block +let mark_finalized_level {store; _} level = + Store.Last_finalized_level.write store.last_finalized_level level -let get_finalized_head_opt {store; _} = - Store.Last_finalized_head.read store.last_finalized_head +let get_finalized_level {store; _} = + let open Lwt_result_syntax in + let+ level = Store.Last_finalized_level.read store.last_finalized_level in + Option.value level ~default:0l let get_l2_block {store; _} block_hash = let open Lwt_result_syntax in @@ -415,6 +411,15 @@ let find_l2_block_by_level node_ctxt level = | None -> return_none | Some block_hash -> find_l2_block node_ctxt block_hash +let get_finalized_head_opt node_ctxt = + let open Lwt_result_syntax in + let* level = + Store.Last_finalized_level.read node_ctxt.store.last_finalized_level + in + match level with + | None -> return_none + | Some level -> find_l2_block_by_level node_ctxt level + let head_of_block_level (hash, level) = {Layer1.hash; level} let block_level_of_head Layer1.{hash; level} = (hash, level) @@ -445,28 +450,11 @@ let get_predecessor node_ctxt (hash, level) = (* [head] is not already known in the L2 chain *) Layer1.get_predecessor node_ctxt.l1_ctxt (hash, level) -let nth_predecessor node_ctxt n block = - let open Lwt_result_syntax in - let+ res, preds = - Layer1.nth_predecessor - ~get_predecessor:(get_predecessor node_ctxt) - n - (block_level_of_head block) - in - (head_of_block_level res, List.map head_of_block_level preds) - let header_of_head node_ctxt Layer1.{hash; level} = let open Lwt_result_syntax in let+ header = Layer1.fetch_tezos_shell_header node_ctxt.cctxt hash in {Layer1.hash; level; header} -let nth_predecessor_header node_ctxt n block = - let open Lwt_result_syntax in - let* res, preds = nth_predecessor node_ctxt n (Layer1.head_of_header block) in - let* res = header_of_head node_ctxt res - and* preds = List.map_ep (header_of_head node_ctxt) preds in - return (res, preds) - let get_tezos_reorg_for_new_head node_ctxt old_head new_head = let open Lwt_result_syntax in let old_head = diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli index 2bbf577df8fe..37cdd1cd9aac 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/node_context.mli @@ -191,9 +191,12 @@ val last_processed_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t (** [mark_finalized_head store head] remembers that the [head] is finalized. By construction, every block whose level is smaller than [head]'s is also finalized. *) -val mark_finalized_head : rw -> Block_hash.t -> unit tzresult Lwt.t +val mark_finalized_level : rw -> int32 -> unit tzresult Lwt.t -(** [last_finalized_head_opt store] returns the last finalized head if it exists. *) +(** [get_finalized_level t] returns the last finalized level. *) +val get_finalized_level : _ t -> int32 tzresult Lwt.t + +(** [get_finalized_head_opt store] returns the last finalized head if it exists. *) val get_finalized_head_opt : _ t -> Sc_rollup_block.t option tzresult Lwt.t (** [hash_of_level node_ctxt level] returns the current block hash for a given @@ -216,12 +219,6 @@ val get_predecessor_opt : (** [get_predecessor state head] returns the predecessor block of [head]. *) val get_predecessor : _ t -> Layer1.head -> Layer1.head tzresult Lwt.t -(** [nth_predecessor n head] return [block, history] where [block] is the nth - predecessor of [head] and [history] is the list of blocks between [block] - (excluded) and [head] (included) on the chain. *) -val nth_predecessor : - _ t -> int -> Layer1.head -> (Layer1.head * Layer1.head list) tzresult Lwt.t - (** Same as {!get_predecessor_opt} with headers. *) val get_predecessor_header_opt : _ t -> Layer1.header -> Layer1.header option tzresult Lwt.t @@ -230,13 +227,6 @@ val get_predecessor_header_opt : val get_predecessor_header : _ t -> Layer1.header -> Layer1.header tzresult Lwt.t -(** Same as {!nth_predecessor} with headers. *) -val nth_predecessor_header : - _ t -> - int -> - Layer1.header -> - (Layer1.header * Layer1.header list) tzresult Lwt.t - (** [get_tezos_reorg_for_new_head node_ctxt old_head new_head] returns the L1 reorganization between [old_head] and [new_head]. *) val get_tezos_reorg_for_new_head : diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/store.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/store.ml index dd1a6b70ae1c..17fb35d80197 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/store.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/store.ml @@ -197,12 +197,12 @@ module L2_head = Indexed_store.Make_singleton (struct let encoding = Sc_rollup_block.encoding end) -module Last_finalized_head = Indexed_store.Make_singleton (struct - type t = Sc_rollup_block.t +module Last_finalized_level = Indexed_store.Make_singleton (struct + type t = int32 - let name = "finalized_head" + let name = "finalized_level" - let encoding = Sc_rollup_block.encoding + let encoding = Data_encoding.int32 end) (** Table from L1 levels to blocks hashes. *) @@ -357,7 +357,7 @@ type 'a store = { commitments : 'a Commitments.t; commitments_published_at_level : 'a Commitments_published_at_level.t; l2_head : 'a L2_head.t; - last_finalized_head : 'a Last_finalized_head.t; + last_finalized_level : 'a Last_finalized_level.t; levels_to_hashes : 'a Levels_to_hashes.t; irmin_store : 'a Irmin_store.t; } @@ -376,7 +376,7 @@ let readonly commitments; commitments_published_at_level; l2_head; - last_finalized_head; + last_finalized_level; levels_to_hashes; irmin_store; } : @@ -389,7 +389,7 @@ let readonly commitments_published_at_level = Commitments_published_at_level.readonly commitments_published_at_level; l2_head = L2_head.readonly l2_head; - last_finalized_head = Last_finalized_head.readonly last_finalized_head; + last_finalized_level = Last_finalized_level.readonly last_finalized_level; levels_to_hashes = Levels_to_hashes.readonly levels_to_hashes; irmin_store = Irmin_store.readonly irmin_store; } @@ -402,7 +402,7 @@ let close commitments; commitments_published_at_level; l2_head = _; - last_finalized_head = _; + last_finalized_level = _; levels_to_hashes; irmin_store; } : @@ -432,8 +432,8 @@ let load (type a) (mode : a mode) ~l2_blocks_cache_size data_dir : ~path:(path "commitments_published_at_level") in let* l2_head = L2_head.load mode ~path:(path "l2_head") in - let* last_finalized_head = - Last_finalized_head.load mode ~path:(path "last_finalized_head") + let* last_finalized_level = + Last_finalized_level.load mode ~path:(path "last_finalized_level") in let* levels_to_hashes = Levels_to_hashes.load mode ~path:(path "levels_to_hashes") @@ -446,7 +446,7 @@ let load (type a) (mode : a mode) ~l2_blocks_cache_size data_dir : commitments; commitments_published_at_level; l2_head; - last_finalized_head; + last_finalized_level; levels_to_hashes; irmin_store; } diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/store.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/store.mli index 974f5241c44c..2bf1bd361a0f 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/store.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/store.mli @@ -77,8 +77,7 @@ end module L2_head : SINGLETON_STORE with type value := Sc_rollup_block.t -module Last_finalized_head : - SINGLETON_STORE with type value := Sc_rollup_block.t +module Last_finalized_level : SINGLETON_STORE with type value := int32 module Levels_to_hashes : INDEXABLE_STORE with type key := int32 and type value := Block_hash.t @@ -129,7 +128,7 @@ type +'a store = { commitments : 'a Commitments.t; commitments_published_at_level : 'a Commitments_published_at_level.t; l2_head : 'a L2_head.t; - last_finalized_head : 'a Last_finalized_head.t; + last_finalized_level : 'a Last_finalized_level.t; levels_to_hashes : 'a Levels_to_hashes.t; irmin_store : 'a Irmin_store.t; } -- GitLab