From d77aad52b107f1e217959125e04dd87e9efd85a5 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 12 May 2023 00:31:05 +0200 Subject: [PATCH 1/5] SCORU/Node: version information for store --- .../lib_sc_rollup_node/store_migration.ml | 34 ++++++++++++------- .../lib_sc_rollup_node/store_version.ml | 30 ++++++++++++++++ .../lib_sc_rollup_node/store_version.mli | 6 ++++ 3 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/store_migration.ml b/src/proto_alpha/lib_sc_rollup_node/store_migration.ml index 5e3c45dc772b..2c3fd7901eca 100644 --- a/src/proto_alpha/lib_sc_rollup_node/store_migration.ml +++ b/src/proto_alpha/lib_sc_rollup_node/store_migration.ml @@ -25,11 +25,13 @@ open Store_version +type version_result = Version_known | Unintialized_version + let messages_store_location ~storage_dir = let open Filename.Infix in storage_dir // "messages" -let version_of_unversionned_store ~storage_dir = +let version_of_unversioned_store ~storage_dir = let open Lwt_syntax in let path = messages_store_location ~storage_dir in let* messages_store_v0 = Store_v0.Messages.load ~path ~cache_size:1 Read_only @@ -59,14 +61,18 @@ let version_of_unversionned_store ~storage_dir = return_none | Error _, Error _ -> failwith - "Cannot determine unversionned store version (no messages decodable)" + "Cannot determine unversioned store version (no messages decodable)" in Lwt.finalize guess_version cleanup let version_of_store ~storage_dir = - (* TODO: https://gitlab.com/tezos/tezos/-/issues/5554 - Use store version information when available. *) - version_of_unversionned_store ~storage_dir + let open Lwt_result_syntax in + let* version = Store_version.read_version_file ~dir:storage_dir in + match version with + | Some v -> return_some (v, Version_known) + | None -> + let+ v = version_of_unversioned_store ~storage_dir in + Option.map (fun v -> (v, Unintialized_version)) v module type MIGRATION_ACTIONS = sig type from_store @@ -143,7 +149,7 @@ module Make Actions.final_actions ~storage_dir ~tmp_dir source_store dest_store in let*! () = Lwt_utils_unix.remove_dir tmp_dir in - return_unit + Store_version.write_version_file ~dir:storage_dir S_dest.version in Lwt.finalize run_migration cleanup @@ -182,12 +188,16 @@ let maybe_run_migration ~storage_dir = let last_version = Store.version in match (current_version, last_version) with | None, _ -> - (* Store not initialized, nothing to do *) - return_unit - | Some current, last when last = current -> - (* Up to date, nothing to do *) - return_unit - | Some current, last -> ( + (* Store not initialized, write last version *) + Store_version.write_version_file ~dir:storage_dir last_version + | Some (current, versioned), last when last = current -> ( + match versioned with + | Unintialized_version -> + Store_version.write_version_file ~dir:storage_dir last_version + | Version_known -> + (* Up to date, nothing to do *) + return_unit) + | Some (current, _), last -> ( let migrations = migration_path ~from:current ~dest:last in match migrations with | None -> diff --git a/src/proto_alpha/lib_sc_rollup_node/store_version.ml b/src/proto_alpha/lib_sc_rollup_node/store_version.ml index ec294eb1a23f..cdb8252b3bae 100644 --- a/src/proto_alpha/lib_sc_rollup_node/store_version.ml +++ b/src/proto_alpha/lib_sc_rollup_node/store_version.ml @@ -27,3 +27,33 @@ type t = V0 | V1 let pp ppf v = Format.pp_print_string ppf @@ match v with V0 -> "v0" | V1 -> "v1" + +let encoding = + let open Data_encoding in + conv + (function V0 -> 0 | V1 -> 1) + (function + | 0 -> V0 + | 1 -> V1 + | v -> Format.ksprintf Stdlib.failwith "Unsupported store version %d" v) + (obj1 (req "store_version" int31)) + +let path ~dir = Filename.concat dir "version" + +let read_version_file ~dir = + let open Lwt_result_syntax in + protect @@ fun () -> + let filename = path ~dir in + let*! exists = Lwt_unix.file_exists filename in + if not exists then return_none + else + let* json = Lwt_utils_unix.Json.read_file filename in + return_some (Data_encoding.Json.destruct encoding json) + +let write_version_file ~dir version = + let open Lwt_result_syntax in + protect @@ fun () -> + let filename = path ~dir in + let*! () = Lwt_utils_unix.create_dir dir in + let json = Data_encoding.Json.construct encoding version in + Lwt_utils_unix.Json.write_file filename json diff --git a/src/proto_alpha/lib_sc_rollup_node/store_version.mli b/src/proto_alpha/lib_sc_rollup_node/store_version.mli index 86b8485e19c1..870c76d05ba2 100644 --- a/src/proto_alpha/lib_sc_rollup_node/store_version.mli +++ b/src/proto_alpha/lib_sc_rollup_node/store_version.mli @@ -27,3 +27,9 @@ type t = V0 | V1 (** Pretty-printer for store versions *) val pp : Format.formatter -> t -> unit + +(** Read the version file from [dir]. *) +val read_version_file : dir:string -> t option tzresult Lwt.t + +(** Write a version to the version file in [dir]. *) +val write_version_file : dir:string -> t -> unit tzresult Lwt.t -- GitLab From 3d26297070162ca8a9ef2ce5e72a90f4fd28a987 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 12 May 2023 09:20:35 +0200 Subject: [PATCH 2/5] SCORU/Node: correct r/w typing constraint on context rollup address --- src/proto_alpha/lib_sc_rollup_node/context.ml | 20 +++++++++++++++++-- .../lib_sc_rollup_node/context.mli | 9 ++++++--- .../lib_sc_rollup_node/node_context.ml | 13 +----------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/context.ml b/src/proto_alpha/lib_sc_rollup_node/context.ml index cb60df692018..ec144bf3dcac 100644 --- a/src/proto_alpha/lib_sc_rollup_node/context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/context.ml @@ -204,7 +204,7 @@ end module Rollup = struct let path = ["rollup_address"] - let set_address (index : _ index) addr = + let set_address (index : rw_index) addr = let open Lwt_result_syntax in protect @@ fun () -> let info () = @@ -220,7 +220,7 @@ module Rollup = struct let*! () = IStore.set_exn ~info store path value in return_unit - let get_address (index : _ index) = + let get_address (index : _ raw_index) = let open Lwt_result_syntax in protect @@ fun () -> let*! store = IStore.main index.repo in @@ -229,4 +229,20 @@ module Rollup = struct @@ Option.map (Data_encoding.Binary.of_bytes_exn Sc_rollup.Address.encoding) value + + let check_or_set_address (type a) (mode : a mode) (index : a raw_index) + rollup_address = + let open Lwt_result_syntax in + let* saved_address = get_address index in + match saved_address with + | Some saved_address -> + fail_unless Sc_rollup.Address.(rollup_address = saved_address) + @@ Sc_rollup_node_errors.Unexpected_rollup + {rollup_address; saved_address} + | None -> ( + (* Address was never saved, we set it permanently if not in read-only + mode. *) + match mode with + | Store_sigs.Read_only -> return_unit + | Read_write -> set_address index rollup_address) end diff --git a/src/proto_alpha/lib_sc_rollup_node/context.mli b/src/proto_alpha/lib_sc_rollup_node/context.mli index 1a54302fd851..34de6bffba6e 100644 --- a/src/proto_alpha/lib_sc_rollup_node/context.mli +++ b/src/proto_alpha/lib_sc_rollup_node/context.mli @@ -162,9 +162,12 @@ end (** Static information about the rollup. *) module Rollup : sig - val set_address : - _ index -> Protocol.Alpha_context.Sc_rollup.Address.t -> unit tzresult Lwt.t - val get_address : _ index -> Protocol.Alpha_context.Sc_rollup.Address.t option tzresult Lwt.t + + val check_or_set_address : + 'a mode -> + 'a index -> + Protocol.Alpha_context.Sc_rollup.Address.t -> + unit tzresult Lwt.t end 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 f3d0be249b2d..30e159a02ac6 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.ml @@ -124,17 +124,6 @@ let get_last_published_commitment (cctxt : Protocol_client_context.full) | Ok None -> return_none | Ok (Some (_staked_hash, staked_commitment)) -> return_some staked_commitment -let check_and_set_rollup_address context rollup_address = - let open Lwt_result_syntax in - let* saved_address = Context.Rollup.get_address context in - match saved_address with - | None -> - (* Address was never saved, we set it permanently. *) - Context.Rollup.set_address context rollup_address - | Some saved_address -> - fail_unless Sc_rollup.Address.(rollup_address = saved_address) - @@ Sc_rollup_node_errors.Unexpected_rollup {rollup_address; saved_address} - let lock ~data_dir = let lockfile_path = Filename.concat data_dir "lock" in let lock_aux ~data_dir = @@ -306,7 +295,7 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file let*! context = Context.load mode (Configuration.default_context_dir data_dir) in - let* () = check_and_set_rollup_address context rollup_address in + let* () = Context.Rollup.check_or_set_address mode context rollup_address in let* l1_ctxt = Layer1.start ~name:"sc_rollup_node" ~reconnection_delay cctxt in -- GitLab From 0c6d511a8fc888d8188cac4113ffa4fe0ca0e8c0 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 12 May 2023 09:21:14 +0200 Subject: [PATCH 3/5] SCORU/Node: context versioning information --- src/proto_alpha/lib_sc_rollup_node/context.ml | 60 +++++++++++++++++++ .../lib_sc_rollup_node/context.mli | 2 +- .../lib_sc_rollup_node/node_context.ml | 4 +- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/proto_alpha/lib_sc_rollup_node/context.ml b/src/proto_alpha/lib_sc_rollup_node/context.ml index ec144bf3dcac..afbce3ba9481 100644 --- a/src/proto_alpha/lib_sc_rollup_node/context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/context.ml @@ -246,3 +246,63 @@ module Rollup = struct | Store_sigs.Read_only -> return_unit | Read_write -> set_address index rollup_address) end + +module Version = struct + type t = V0 + + let version = V0 + + let encoding = + let open Data_encoding in + conv + (fun V0 -> 0) + (function + | 0 -> V0 + | v -> + Format.ksprintf Stdlib.failwith "Unsupported context version %d" v) + int31 + + let path = ["context_version"] + + let set (index : rw_index) = + let open Lwt_result_syntax in + protect @@ fun () -> + let info () = + let date = + Time.(System.now () |> System.to_protocol |> Protocol.to_seconds) + in + IStore.Info.v date + in + let value = Data_encoding.Binary.to_bytes_exn encoding version in + let*! store = IStore.main index.repo in + let*! () = IStore.set_exn ~info store path value in + return_unit + + let get (index : _ index) = + let open Lwt_result_syntax in + protect @@ fun () -> + let*! store = IStore.main index.repo in + let*! value = IStore.find store path in + return @@ Option.map (Data_encoding.Binary.of_bytes_exn encoding) value + + let check (index : _ index) = + let open Lwt_result_syntax in + let* context_version = get index in + match context_version with None | Some V0 -> return_unit + + let check_and_set (index : _ index) = + let open Lwt_result_syntax in + let* context_version = get index in + match context_version with None -> set index | Some V0 -> return_unit +end + +let load : type a. a mode -> string -> a raw_index tzresult Lwt.t = + fun mode path -> + let open Lwt_result_syntax in + let*! index = load mode path in + let+ () = + match mode with + | Read_only -> Version.check index + | Read_write -> Version.check_and_set index + in + index diff --git a/src/proto_alpha/lib_sc_rollup_node/context.mli b/src/proto_alpha/lib_sc_rollup_node/context.mli index 34de6bffba6e..6a2f40660c12 100644 --- a/src/proto_alpha/lib_sc_rollup_node/context.mli +++ b/src/proto_alpha/lib_sc_rollup_node/context.mli @@ -55,7 +55,7 @@ type hash = Sc_rollup_context_hash.t type commit (** [load path] initializes from disk a context from [path]. *) -val load : 'a mode -> string -> 'a index Lwt.t +val load : 'a mode -> string -> 'a index tzresult Lwt.t (** [index context] is the repository of the context [context]. *) val index : 'a t -> 'a index 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 30e159a02ac6..3eee7f929669 100644 --- a/src/proto_alpha/lib_sc_rollup_node/node_context.ml +++ b/src/proto_alpha/lib_sc_rollup_node/node_context.ml @@ -292,7 +292,7 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file ~l2_blocks_cache_size Configuration.(default_storage_dir data_dir) in - let*! context = + let* context = Context.load mode (Configuration.default_context_dir data_dir) in let* () = Context.Rollup.check_or_set_address mode context rollup_address in @@ -929,7 +929,7 @@ module Internal_for_tests = struct ~l2_blocks_cache_size Configuration.(default_storage_dir data_dir) in - let*! context = + let* context = Context.load Read_write (Configuration.default_context_dir data_dir) in let genesis_info = -- GitLab From acc93d578c173fd93d626120eb28106ed3c41903 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 12 May 2023 00:31:05 +0200 Subject: [PATCH 4/5] SCORU/Node/Nairobi: backport !8715 to Nairobi rollup node - SCORU/Node: version information for store - SCORU/Node: correct r/w typing constraint on context rollup address - SCORU/Node: context versioning information --- .../lib_sc_rollup_node/context.ml | 80 ++++++++++++++++++- .../lib_sc_rollup_node/context.mli | 11 ++- .../lib_sc_rollup_node/node_context.ml | 17 +--- .../lib_sc_rollup_node/store_migration.ml | 34 +++++--- .../lib_sc_rollup_node/store_version.ml | 30 +++++++ .../lib_sc_rollup_node/store_version.mli | 6 ++ 6 files changed, 146 insertions(+), 32 deletions(-) diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/context.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/context.ml index cb60df692018..afbce3ba9481 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/context.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/context.ml @@ -204,7 +204,7 @@ end module Rollup = struct let path = ["rollup_address"] - let set_address (index : _ index) addr = + let set_address (index : rw_index) addr = let open Lwt_result_syntax in protect @@ fun () -> let info () = @@ -220,7 +220,7 @@ module Rollup = struct let*! () = IStore.set_exn ~info store path value in return_unit - let get_address (index : _ index) = + let get_address (index : _ raw_index) = let open Lwt_result_syntax in protect @@ fun () -> let*! store = IStore.main index.repo in @@ -229,4 +229,80 @@ module Rollup = struct @@ Option.map (Data_encoding.Binary.of_bytes_exn Sc_rollup.Address.encoding) value + + let check_or_set_address (type a) (mode : a mode) (index : a raw_index) + rollup_address = + let open Lwt_result_syntax in + let* saved_address = get_address index in + match saved_address with + | Some saved_address -> + fail_unless Sc_rollup.Address.(rollup_address = saved_address) + @@ Sc_rollup_node_errors.Unexpected_rollup + {rollup_address; saved_address} + | None -> ( + (* Address was never saved, we set it permanently if not in read-only + mode. *) + match mode with + | Store_sigs.Read_only -> return_unit + | Read_write -> set_address index rollup_address) end + +module Version = struct + type t = V0 + + let version = V0 + + let encoding = + let open Data_encoding in + conv + (fun V0 -> 0) + (function + | 0 -> V0 + | v -> + Format.ksprintf Stdlib.failwith "Unsupported context version %d" v) + int31 + + let path = ["context_version"] + + let set (index : rw_index) = + let open Lwt_result_syntax in + protect @@ fun () -> + let info () = + let date = + Time.(System.now () |> System.to_protocol |> Protocol.to_seconds) + in + IStore.Info.v date + in + let value = Data_encoding.Binary.to_bytes_exn encoding version in + let*! store = IStore.main index.repo in + let*! () = IStore.set_exn ~info store path value in + return_unit + + let get (index : _ index) = + let open Lwt_result_syntax in + protect @@ fun () -> + let*! store = IStore.main index.repo in + let*! value = IStore.find store path in + return @@ Option.map (Data_encoding.Binary.of_bytes_exn encoding) value + + let check (index : _ index) = + let open Lwt_result_syntax in + let* context_version = get index in + match context_version with None | Some V0 -> return_unit + + let check_and_set (index : _ index) = + let open Lwt_result_syntax in + let* context_version = get index in + match context_version with None -> set index | Some V0 -> return_unit +end + +let load : type a. a mode -> string -> a raw_index tzresult Lwt.t = + fun mode path -> + let open Lwt_result_syntax in + let*! index = load mode path in + let+ () = + match mode with + | Read_only -> Version.check index + | Read_write -> Version.check_and_set index + in + index diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/context.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/context.mli index 636bb700d1d9..d4c1acbc98e5 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/context.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/context.mli @@ -55,7 +55,7 @@ type hash = Sc_rollup_context_hash.t type commit (** [load path] initializes from disk a context from [path]. *) -val load : 'a mode -> string -> 'a index Lwt.t +val load : 'a mode -> string -> 'a index tzresult Lwt.t (** [index context] is the repository of the context [context]. *) val index : 'a t -> 'a index @@ -162,9 +162,12 @@ end (** Static information about the rollup. *) module Rollup : sig - val set_address : - _ index -> Protocol.Alpha_context.Sc_rollup.Address.t -> unit tzresult Lwt.t - val get_address : _ index -> Protocol.Alpha_context.Sc_rollup.Address.t option tzresult Lwt.t + + val check_or_set_address : + 'a mode -> + 'a index -> + Protocol.Alpha_context.Sc_rollup.Address.t -> + unit tzresult Lwt.t end 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 017d28c07b1f..9739dc6477ad 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 @@ -133,17 +133,6 @@ let get_last_published_commitment (cctxt : Protocol_client_context.full) | Ok None -> return_none | Ok (Some (_staked_hash, staked_commitment)) -> return_some staked_commitment -let check_and_set_rollup_address context rollup_address = - let open Lwt_result_syntax in - let* saved_address = Context.Rollup.get_address context in - match saved_address with - | None -> - (* Address was never saved, we set it permanently. *) - Context.Rollup.set_address context rollup_address - | Some saved_address -> - fail_unless Sc_rollup.Address.(rollup_address = saved_address) - @@ Sc_rollup_node_errors.Unexpected_rollup {rollup_address; saved_address} - let lock ~data_dir = let lockfile_path = Filename.concat data_dir "lock" in let lock_aux ~data_dir = @@ -316,10 +305,10 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file ~l2_blocks_cache_size Configuration.(default_storage_dir data_dir) in - let*! context = + let* context = Context.load mode (Configuration.default_context_dir data_dir) in - let* () = check_and_set_rollup_address context rollup_address in + let* () = Context.Rollup.check_or_set_address mode context rollup_address in let* l1_ctxt = Layer1.start ~name:"sc_rollup_node" ~reconnection_delay cctxt in @@ -937,7 +926,7 @@ module Internal_for_tests = struct ~l2_blocks_cache_size Configuration.(default_storage_dir data_dir) in - let*! context = + let* context = Context.load Read_write (Configuration.default_context_dir data_dir) in let genesis_info = diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/store_migration.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/store_migration.ml index 5e3c45dc772b..2c3fd7901eca 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/store_migration.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/store_migration.ml @@ -25,11 +25,13 @@ open Store_version +type version_result = Version_known | Unintialized_version + let messages_store_location ~storage_dir = let open Filename.Infix in storage_dir // "messages" -let version_of_unversionned_store ~storage_dir = +let version_of_unversioned_store ~storage_dir = let open Lwt_syntax in let path = messages_store_location ~storage_dir in let* messages_store_v0 = Store_v0.Messages.load ~path ~cache_size:1 Read_only @@ -59,14 +61,18 @@ let version_of_unversionned_store ~storage_dir = return_none | Error _, Error _ -> failwith - "Cannot determine unversionned store version (no messages decodable)" + "Cannot determine unversioned store version (no messages decodable)" in Lwt.finalize guess_version cleanup let version_of_store ~storage_dir = - (* TODO: https://gitlab.com/tezos/tezos/-/issues/5554 - Use store version information when available. *) - version_of_unversionned_store ~storage_dir + let open Lwt_result_syntax in + let* version = Store_version.read_version_file ~dir:storage_dir in + match version with + | Some v -> return_some (v, Version_known) + | None -> + let+ v = version_of_unversioned_store ~storage_dir in + Option.map (fun v -> (v, Unintialized_version)) v module type MIGRATION_ACTIONS = sig type from_store @@ -143,7 +149,7 @@ module Make Actions.final_actions ~storage_dir ~tmp_dir source_store dest_store in let*! () = Lwt_utils_unix.remove_dir tmp_dir in - return_unit + Store_version.write_version_file ~dir:storage_dir S_dest.version in Lwt.finalize run_migration cleanup @@ -182,12 +188,16 @@ let maybe_run_migration ~storage_dir = let last_version = Store.version in match (current_version, last_version) with | None, _ -> - (* Store not initialized, nothing to do *) - return_unit - | Some current, last when last = current -> - (* Up to date, nothing to do *) - return_unit - | Some current, last -> ( + (* Store not initialized, write last version *) + Store_version.write_version_file ~dir:storage_dir last_version + | Some (current, versioned), last when last = current -> ( + match versioned with + | Unintialized_version -> + Store_version.write_version_file ~dir:storage_dir last_version + | Version_known -> + (* Up to date, nothing to do *) + return_unit) + | Some (current, _), last -> ( let migrations = migration_path ~from:current ~dest:last in match migrations with | None -> diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/store_version.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/store_version.ml index ec294eb1a23f..cdb8252b3bae 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/store_version.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/store_version.ml @@ -27,3 +27,33 @@ type t = V0 | V1 let pp ppf v = Format.pp_print_string ppf @@ match v with V0 -> "v0" | V1 -> "v1" + +let encoding = + let open Data_encoding in + conv + (function V0 -> 0 | V1 -> 1) + (function + | 0 -> V0 + | 1 -> V1 + | v -> Format.ksprintf Stdlib.failwith "Unsupported store version %d" v) + (obj1 (req "store_version" int31)) + +let path ~dir = Filename.concat dir "version" + +let read_version_file ~dir = + let open Lwt_result_syntax in + protect @@ fun () -> + let filename = path ~dir in + let*! exists = Lwt_unix.file_exists filename in + if not exists then return_none + else + let* json = Lwt_utils_unix.Json.read_file filename in + return_some (Data_encoding.Json.destruct encoding json) + +let write_version_file ~dir version = + let open Lwt_result_syntax in + protect @@ fun () -> + let filename = path ~dir in + let*! () = Lwt_utils_unix.create_dir dir in + let json = Data_encoding.Json.construct encoding version in + Lwt_utils_unix.Json.write_file filename json diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/store_version.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/store_version.mli index 86b8485e19c1..870c76d05ba2 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/store_version.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/store_version.mli @@ -27,3 +27,9 @@ type t = V0 | V1 (** Pretty-printer for store versions *) val pp : Format.formatter -> t -> unit + +(** Read the version file from [dir]. *) +val read_version_file : dir:string -> t option tzresult Lwt.t + +(** Write a version to the version file in [dir]. *) +val write_version_file : dir:string -> t -> unit tzresult Lwt.t -- GitLab From 4e638a74a522220d093bcdf59adf05d66801919b Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 12 May 2023 00:31:05 +0200 Subject: [PATCH 5/5] SCORU/Node/Mumbai: backport !8715 to Mumbai rollup node - SCORU/Node: version information for store - SCORU/Node: correct r/w typing constraint on context rollup address - SCORU/Node: context versioning information --- .../lib_sc_rollup_node/context.ml | 80 ++++++++++++++++++- .../lib_sc_rollup_node/context.mli | 11 ++- .../lib_sc_rollup_node/node_context.ml | 17 +--- .../lib_sc_rollup_node/store_migration.ml | 34 +++++--- .../lib_sc_rollup_node/store_version.ml | 30 +++++++ .../lib_sc_rollup_node/store_version.mli | 6 ++ 6 files changed, 146 insertions(+), 32 deletions(-) diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/context.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/context.ml index cb60df692018..afbce3ba9481 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/context.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/context.ml @@ -204,7 +204,7 @@ end module Rollup = struct let path = ["rollup_address"] - let set_address (index : _ index) addr = + let set_address (index : rw_index) addr = let open Lwt_result_syntax in protect @@ fun () -> let info () = @@ -220,7 +220,7 @@ module Rollup = struct let*! () = IStore.set_exn ~info store path value in return_unit - let get_address (index : _ index) = + let get_address (index : _ raw_index) = let open Lwt_result_syntax in protect @@ fun () -> let*! store = IStore.main index.repo in @@ -229,4 +229,80 @@ module Rollup = struct @@ Option.map (Data_encoding.Binary.of_bytes_exn Sc_rollup.Address.encoding) value + + let check_or_set_address (type a) (mode : a mode) (index : a raw_index) + rollup_address = + let open Lwt_result_syntax in + let* saved_address = get_address index in + match saved_address with + | Some saved_address -> + fail_unless Sc_rollup.Address.(rollup_address = saved_address) + @@ Sc_rollup_node_errors.Unexpected_rollup + {rollup_address; saved_address} + | None -> ( + (* Address was never saved, we set it permanently if not in read-only + mode. *) + match mode with + | Store_sigs.Read_only -> return_unit + | Read_write -> set_address index rollup_address) end + +module Version = struct + type t = V0 + + let version = V0 + + let encoding = + let open Data_encoding in + conv + (fun V0 -> 0) + (function + | 0 -> V0 + | v -> + Format.ksprintf Stdlib.failwith "Unsupported context version %d" v) + int31 + + let path = ["context_version"] + + let set (index : rw_index) = + let open Lwt_result_syntax in + protect @@ fun () -> + let info () = + let date = + Time.(System.now () |> System.to_protocol |> Protocol.to_seconds) + in + IStore.Info.v date + in + let value = Data_encoding.Binary.to_bytes_exn encoding version in + let*! store = IStore.main index.repo in + let*! () = IStore.set_exn ~info store path value in + return_unit + + let get (index : _ index) = + let open Lwt_result_syntax in + protect @@ fun () -> + let*! store = IStore.main index.repo in + let*! value = IStore.find store path in + return @@ Option.map (Data_encoding.Binary.of_bytes_exn encoding) value + + let check (index : _ index) = + let open Lwt_result_syntax in + let* context_version = get index in + match context_version with None | Some V0 -> return_unit + + let check_and_set (index : _ index) = + let open Lwt_result_syntax in + let* context_version = get index in + match context_version with None -> set index | Some V0 -> return_unit +end + +let load : type a. a mode -> string -> a raw_index tzresult Lwt.t = + fun mode path -> + let open Lwt_result_syntax in + let*! index = load mode path in + let+ () = + match mode with + | Read_only -> Version.check index + | Read_write -> Version.check_and_set index + in + index diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/context.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/context.mli index 636bb700d1d9..d4c1acbc98e5 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/context.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/context.mli @@ -55,7 +55,7 @@ type hash = Sc_rollup_context_hash.t type commit (** [load path] initializes from disk a context from [path]. *) -val load : 'a mode -> string -> 'a index Lwt.t +val load : 'a mode -> string -> 'a index tzresult Lwt.t (** [index context] is the repository of the context [context]. *) val index : 'a t -> 'a index @@ -162,9 +162,12 @@ end (** Static information about the rollup. *) module Rollup : sig - val set_address : - _ index -> Protocol.Alpha_context.Sc_rollup.Address.t -> unit tzresult Lwt.t - val get_address : _ index -> Protocol.Alpha_context.Sc_rollup.Address.t option tzresult Lwt.t + + val check_or_set_address : + 'a mode -> + 'a index -> + Protocol.Alpha_context.Sc_rollup.Address.t -> + unit tzresult Lwt.t end 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 576c7b9c182a..9d563d818b69 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 @@ -133,17 +133,6 @@ let get_last_published_commitment (cctxt : Protocol_client_context.full) | Ok None -> return_none | Ok (Some (_staked_hash, staked_commitment)) -> return_some staked_commitment -let check_and_set_rollup_address context rollup_address = - let open Lwt_result_syntax in - let* saved_address = Context.Rollup.get_address context in - match saved_address with - | None -> - (* Address was never saved, we set it permanently. *) - Context.Rollup.set_address context rollup_address - | Some saved_address -> - fail_unless Sc_rollup.Address.(rollup_address = saved_address) - @@ Sc_rollup_node_errors.Unexpected_rollup {rollup_address; saved_address} - let lock ~data_dir = let lockfile_path = Filename.concat data_dir "lock" in let lock_aux ~data_dir = @@ -316,10 +305,10 @@ let init (cctxt : Protocol_client_context.full) ~data_dir ?log_kernel_debug_file ~l2_blocks_cache_size Configuration.(default_storage_dir data_dir) in - let*! context = + let* context = Context.load mode (Configuration.default_context_dir data_dir) in - let* () = check_and_set_rollup_address context rollup_address in + let* () = Context.Rollup.check_or_set_address mode context rollup_address in let* l1_ctxt = Layer1.start ~name:"sc_rollup_node" ~reconnection_delay cctxt in @@ -966,7 +955,7 @@ module Internal_for_tests = struct ~l2_blocks_cache_size Configuration.(default_storage_dir data_dir) in - let*! context = + let* context = Context.load Read_write (Configuration.default_context_dir data_dir) in let genesis_info = diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/store_migration.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/store_migration.ml index 5e3c45dc772b..2c3fd7901eca 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/store_migration.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/store_migration.ml @@ -25,11 +25,13 @@ open Store_version +type version_result = Version_known | Unintialized_version + let messages_store_location ~storage_dir = let open Filename.Infix in storage_dir // "messages" -let version_of_unversionned_store ~storage_dir = +let version_of_unversioned_store ~storage_dir = let open Lwt_syntax in let path = messages_store_location ~storage_dir in let* messages_store_v0 = Store_v0.Messages.load ~path ~cache_size:1 Read_only @@ -59,14 +61,18 @@ let version_of_unversionned_store ~storage_dir = return_none | Error _, Error _ -> failwith - "Cannot determine unversionned store version (no messages decodable)" + "Cannot determine unversioned store version (no messages decodable)" in Lwt.finalize guess_version cleanup let version_of_store ~storage_dir = - (* TODO: https://gitlab.com/tezos/tezos/-/issues/5554 - Use store version information when available. *) - version_of_unversionned_store ~storage_dir + let open Lwt_result_syntax in + let* version = Store_version.read_version_file ~dir:storage_dir in + match version with + | Some v -> return_some (v, Version_known) + | None -> + let+ v = version_of_unversioned_store ~storage_dir in + Option.map (fun v -> (v, Unintialized_version)) v module type MIGRATION_ACTIONS = sig type from_store @@ -143,7 +149,7 @@ module Make Actions.final_actions ~storage_dir ~tmp_dir source_store dest_store in let*! () = Lwt_utils_unix.remove_dir tmp_dir in - return_unit + Store_version.write_version_file ~dir:storage_dir S_dest.version in Lwt.finalize run_migration cleanup @@ -182,12 +188,16 @@ let maybe_run_migration ~storage_dir = let last_version = Store.version in match (current_version, last_version) with | None, _ -> - (* Store not initialized, nothing to do *) - return_unit - | Some current, last when last = current -> - (* Up to date, nothing to do *) - return_unit - | Some current, last -> ( + (* Store not initialized, write last version *) + Store_version.write_version_file ~dir:storage_dir last_version + | Some (current, versioned), last when last = current -> ( + match versioned with + | Unintialized_version -> + Store_version.write_version_file ~dir:storage_dir last_version + | Version_known -> + (* Up to date, nothing to do *) + return_unit) + | Some (current, _), last -> ( let migrations = migration_path ~from:current ~dest:last in match migrations with | None -> diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/store_version.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/store_version.ml index ec294eb1a23f..cdb8252b3bae 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/store_version.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/store_version.ml @@ -27,3 +27,33 @@ type t = V0 | V1 let pp ppf v = Format.pp_print_string ppf @@ match v with V0 -> "v0" | V1 -> "v1" + +let encoding = + let open Data_encoding in + conv + (function V0 -> 0 | V1 -> 1) + (function + | 0 -> V0 + | 1 -> V1 + | v -> Format.ksprintf Stdlib.failwith "Unsupported store version %d" v) + (obj1 (req "store_version" int31)) + +let path ~dir = Filename.concat dir "version" + +let read_version_file ~dir = + let open Lwt_result_syntax in + protect @@ fun () -> + let filename = path ~dir in + let*! exists = Lwt_unix.file_exists filename in + if not exists then return_none + else + let* json = Lwt_utils_unix.Json.read_file filename in + return_some (Data_encoding.Json.destruct encoding json) + +let write_version_file ~dir version = + let open Lwt_result_syntax in + protect @@ fun () -> + let filename = path ~dir in + let*! () = Lwt_utils_unix.create_dir dir in + let json = Data_encoding.Json.construct encoding version in + Lwt_utils_unix.Json.write_file filename json diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/store_version.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/store_version.mli index 86b8485e19c1..870c76d05ba2 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/store_version.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/store_version.mli @@ -27,3 +27,9 @@ type t = V0 | V1 (** Pretty-printer for store versions *) val pp : Format.formatter -> t -> unit + +(** Read the version file from [dir]. *) +val read_version_file : dir:string -> t option tzresult Lwt.t + +(** Write a version to the version file in [dir]. *) +val write_version_file : dir:string -> t -> unit tzresult Lwt.t -- GitLab