From 668d0aa51d519ae50c009ba6cade22ea5f8a665e Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Wed, 26 Jul 2023 18:52:36 +0200 Subject: [PATCH 1/3] SCORU/Node: associate level to block even if already processed --- src/lib_smart_rollup_node/rollup_node_daemon.ml | 11 ++++++----- src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml | 11 ++++++----- src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml | 11 ++++++----- src/proto_alpha/lib_sc_rollup_node/daemon.ml | 11 ++++++----- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/lib_smart_rollup_node/rollup_node_daemon.ml b/src/lib_smart_rollup_node/rollup_node_daemon.ml index e041040fedc4..d4039fb65a76 100644 --- a/src/lib_smart_rollup_node/rollup_node_daemon.ml +++ b/src/lib_smart_rollup_node/rollup_node_daemon.ml @@ -105,11 +105,7 @@ let handle_protocol_migration ~catching_up state (head : Layer1.header) = let process_new_head ({node_ctxt; _} as state) ~catching_up ~predecessor (head : Layer1.header) = let open Lwt_result_syntax in - let* () = - Node_context.save_level - node_ctxt - {Layer1.hash = head.hash; level = head.level} - and* () = Node_context.save_protocol_info node_ctxt head ~predecessor in + let* () = Node_context.save_protocol_info node_ctxt head ~predecessor in let* () = handle_protocol_migration ~catching_up state head in let* rollup_ctxt = previous_context node_ctxt ~predecessor in let module Plugin = (val state.plugin) in @@ -183,6 +179,11 @@ let rec process_head ({node_ctxt; _} as state) ~catching_up (head : Layer1.header) = let open Lwt_result_syntax in let start_timestamp = Time.System.now () in + let* () = + Node_context.save_level + node_ctxt + {Layer1.hash = head.hash; level = head.level} + in let* already_processed = Node_context.is_processed node_ctxt head.hash in unless (already_processed || is_before_origination node_ctxt head) @@ fun () -> 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 4b995b121b8b..ccdcafb98e37 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/daemon.ml @@ -84,6 +84,11 @@ let rec process_head (daemon_components : (module Daemon_components.S)) (node_ctxt : _ Node_context.t) ~catching_up (head : Layer1.header) = let open Lwt_result_syntax in let start_timestamp = Time.System.now () in + let* () = + Node_context.save_level + node_ctxt + {Layer1.hash = head.hash; level = head.level} + 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 in @@ -99,11 +104,7 @@ let rec process_head (daemon_components : (module Daemon_components.S)) process_head daemon_components node_ctxt ~catching_up:true predecessor in let* ctxt = previous_context node_ctxt ~predecessor in - let* () = - Node_context.save_level - node_ctxt - {Layer1.hash = head.hash; level = head.level} - and* () = Node_context.save_protocol_info node_ctxt head ~predecessor in + let* () = Node_context.save_protocol_info node_ctxt head ~predecessor in let* inbox_hash, inbox, inbox_witness, messages = Inbox.process_head node_ctxt ~predecessor head in diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml b/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml index fa8855e10096..062fe74f0c06 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml @@ -84,6 +84,11 @@ let rec process_head (daemon_components : (module Daemon_components.S)) (node_ctxt : _ Node_context.t) ~catching_up (head : Layer1.header) = let open Lwt_result_syntax in let start_timestamp = Time.System.now () in + let* () = + Node_context.save_level + node_ctxt + {Layer1.hash = head.hash; level = head.level} + 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 in @@ -99,11 +104,7 @@ let rec process_head (daemon_components : (module Daemon_components.S)) process_head daemon_components node_ctxt ~catching_up:true predecessor in let* ctxt = previous_context node_ctxt ~predecessor in - let* () = - Node_context.save_level - node_ctxt - {Layer1.hash = head.hash; level = head.level} - and* () = Node_context.save_protocol_info node_ctxt head ~predecessor in + let* () = Node_context.save_protocol_info node_ctxt head ~predecessor in let* inbox_hash, inbox, inbox_witness, messages = Inbox.process_head node_ctxt ~predecessor head in diff --git a/src/proto_alpha/lib_sc_rollup_node/daemon.ml b/src/proto_alpha/lib_sc_rollup_node/daemon.ml index fa8855e10096..062fe74f0c06 100644 --- a/src/proto_alpha/lib_sc_rollup_node/daemon.ml +++ b/src/proto_alpha/lib_sc_rollup_node/daemon.ml @@ -84,6 +84,11 @@ let rec process_head (daemon_components : (module Daemon_components.S)) (node_ctxt : _ Node_context.t) ~catching_up (head : Layer1.header) = let open Lwt_result_syntax in let start_timestamp = Time.System.now () in + let* () = + Node_context.save_level + node_ctxt + {Layer1.hash = head.hash; level = head.level} + 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 in @@ -99,11 +104,7 @@ let rec process_head (daemon_components : (module Daemon_components.S)) process_head daemon_components node_ctxt ~catching_up:true predecessor in let* ctxt = previous_context node_ctxt ~predecessor in - let* () = - Node_context.save_level - node_ctxt - {Layer1.hash = head.hash; level = head.level} - and* () = Node_context.save_protocol_info node_ctxt head ~predecessor in + let* () = Node_context.save_protocol_info node_ctxt head ~predecessor in let* inbox_hash, inbox, inbox_witness, messages = Inbox.process_head node_ctxt ~predecessor head in -- GitLab From 16540bd9f20b94310709dbf129d55af3eee20fe8 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Wed, 26 Jul 2023 19:02:42 +0200 Subject: [PATCH 2/3] SCORU/Node/Store: recompute correct level associations --- src/lib_smart_rollup_node/store.ml | 2 +- src/lib_smart_rollup_node/store_migration.ml | 32 ++++++++++++++++++++ src/lib_smart_rollup_node/store_v3.ml | 31 +++++++++++++++++++ src/lib_smart_rollup_node/store_v3.mli | 29 ++++++++++++++++++ src/lib_smart_rollup_node/store_version.ml | 7 +++-- src/lib_smart_rollup_node/store_version.mli | 2 +- 6 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 src/lib_smart_rollup_node/store_v3.ml create mode 100644 src/lib_smart_rollup_node/store_v3.mli diff --git a/src/lib_smart_rollup_node/store.ml b/src/lib_smart_rollup_node/store.ml index f89bd6e8cfb5..98b5204e32e8 100644 --- a/src/lib_smart_rollup_node/store.ml +++ b/src/lib_smart_rollup_node/store.ml @@ -24,4 +24,4 @@ (* *) (*****************************************************************************) -include Store_v2 +include Store_v3 diff --git a/src/lib_smart_rollup_node/store_migration.ml b/src/lib_smart_rollup_node/store_migration.ml index a10d8043c46d..fa753d248478 100644 --- a/src/lib_smart_rollup_node/store_migration.ml +++ b/src/lib_smart_rollup_node/store_migration.ml @@ -436,3 +436,35 @@ module V2_migrations = struct let final_actions = final_actions end) end + +module V3_migrations = struct + let levels_store_location ~storage_dir = + let open Filename.Infix in + storage_dir // "levels_to_hashes" + + let recompute_level (v3_store : _ Store_v3.t) (l2_block : Sc_rollup_block.t) = + Store.Levels_to_hashes.add + ~flush:true + v3_store.levels_to_hashes + l2_block.header.level + l2_block.header.block_hash + + let final_actions ~storage_dir ~tmp_dir _ _ = + let open Lwt_result_syntax in + let*! () = Lwt_utils_unix.remove_dir (levels_store_location ~storage_dir) in + let*! () = + Lwt_unix.rename + (levels_store_location ~storage_dir:tmp_dir) + (levels_store_location ~storage_dir) + in + return_unit + + module From_v2 = + Make (Store_v2) (Store_v3) + (struct + let migrate_block_action _v2_store v3_store l2_block = + recompute_level v3_store l2_block + + let final_actions = final_actions + end) +end diff --git a/src/lib_smart_rollup_node/store_v3.ml b/src/lib_smart_rollup_node/store_v3.ml new file mode 100644 index 000000000000..b08efcd0cabb --- /dev/null +++ b/src/lib_smart_rollup_node/store_v3.ml @@ -0,0 +1,31 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* Copyright (c) 2023 Functori, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include Store_sigs +include Store_utils +include Store_v2 + +let version = Store_version.V3 diff --git a/src/lib_smart_rollup_node/store_v3.mli b/src/lib_smart_rollup_node/store_v3.mli new file mode 100644 index 000000000000..8b35ac2ebfaa --- /dev/null +++ b/src/lib_smart_rollup_node/store_v3.mli @@ -0,0 +1,29 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs, *) +(* Copyright (c) 2023 Functori, *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include module type of struct + include Store_v2 +end diff --git a/src/lib_smart_rollup_node/store_version.ml b/src/lib_smart_rollup_node/store_version.ml index db71f6289113..2965415bafa1 100644 --- a/src/lib_smart_rollup_node/store_version.ml +++ b/src/lib_smart_rollup_node/store_version.ml @@ -23,20 +23,21 @@ (* *) (*****************************************************************************) -type t = V0 | V1 | V2 +type t = V0 | V1 | V2 | V3 let pp ppf v = Format.pp_print_string ppf - @@ match v with V0 -> "v0" | V1 -> "v1" | V2 -> "v2" + @@ match v with V0 -> "v0" | V1 -> "v1" | V2 -> "v2" | V3 -> "v3" let encoding = let open Data_encoding in conv - (function V0 -> 0 | V1 -> 1 | V2 -> 2) + (function V0 -> 0 | V1 -> 1 | V2 -> 2 | V3 -> 3) (function | 0 -> V0 | 1 -> V1 | 2 -> V2 + | 3 -> V3 | v -> Format.ksprintf Stdlib.failwith "Unsupported store version %d" v) (obj1 (req "store_version" int31)) diff --git a/src/lib_smart_rollup_node/store_version.mli b/src/lib_smart_rollup_node/store_version.mli index 1f2f8b4a26cc..2f6e106a2fea 100644 --- a/src/lib_smart_rollup_node/store_version.mli +++ b/src/lib_smart_rollup_node/store_version.mli @@ -23,7 +23,7 @@ (* *) (*****************************************************************************) -type t = V0 | V1 | V2 +type t = V0 | V1 | V2 | V3 (** Pretty-printer for store versions *) val pp : Format.formatter -> t -> unit -- GitLab From 73e9763b83657222f80d0263d4875d47619e2ef0 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 28 Jul 2023 17:35:09 +0200 Subject: [PATCH 3/3] SCORU/Node: don't depend on level hash association to publish This additional safety measure prevents from publishing an incorrect commitment in case the level -> hash association is not correct. --- src/lib_smart_rollup_node/publisher.ml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/lib_smart_rollup_node/publisher.ml b/src/lib_smart_rollup_node/publisher.ml index 19b8a40d476a..2e49f7f73c4a 100644 --- a/src/lib_smart_rollup_node/publisher.ml +++ b/src/lib_smart_rollup_node/publisher.ml @@ -219,7 +219,8 @@ let missing_commitments (node_ctxt : _ Node_context.t) = | None -> node_ctxt.genesis_info.level | Some lpc -> lpc.inbox_level in - let* head = Node_context.last_processed_head_opt node_ctxt in + let* head = Node_context.last_processed_head_opt node_ctxt + and* finalized_level = Node_context.get_finalized_level node_ctxt in let next_head_level = Option.map (fun (b : Sc_rollup_block.t) -> Int32.succ b.header.level) head in @@ -250,7 +251,11 @@ let missing_commitments (node_ctxt : _ Node_context.t) = Int32.sub next_head_level first_published_at_level > sc_rollup_challenge_window_int32 in - let acc = if past_curfew then acc else commitment :: acc in + let is_finalized = commitment.inbox_level <= finalized_level in + (* Only publish commitments that are finalized and not past the curfew *) + let acc = + if is_finalized && not past_curfew then commitment :: acc else acc + in (* We keep the commitment and go back to the previous one. *) gather acc commitment.predecessor in -- GitLab