From 68a2fa689d796fc1507633288c3f8ba2e5774fe5 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Wed, 21 Feb 2024 11:44:57 +0100 Subject: [PATCH 1/3] EVM/Node: introduce a version in the context --- etherlink/bin_node/lib_dev/evm_context.ml | 38 +++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/etherlink/bin_node/lib_dev/evm_context.ml b/etherlink/bin_node/lib_dev/evm_context.ml index 671a34b27234..085c0771ff4b 100644 --- a/etherlink/bin_node/lib_dev/evm_context.ml +++ b/etherlink/bin_node/lib_dev/evm_context.ml @@ -17,6 +17,43 @@ type t = { store : Store.t; } +module Version = struct + type version = V0 + + let current = V0 + + let encoding = + let open Data_encoding in + union + [case ~title:"v0" (Tag 0) unit (function V0 -> Some ()) (fun () -> V0)] + + let path data_dir = Filename.Infix.(data_dir // "version") + + type error += Cannot_store_version + + let set data_dir version = + let open Lwt_syntax in + let path = path data_dir in + let* res = + Lwt_utils_unix.with_open_out ~overwrite:true path (fun fd -> + let content = Data_encoding.Binary.to_string_exn encoding version in + Lwt_utils_unix.write_string fd content) + in + return (Result.map_error (fun _ -> [Cannot_store_version]) res) + + let get data_dir = + let open Lwt_result_syntax in + let path = path data_dir in + let*! version_exists = Lwt_unix.file_exists path in + if version_exists then + let*! content = Lwt_utils_unix.read_file path in + let version = Data_encoding.Binary.of_string_exn encoding content in + return version + else + let* () = set data_dir current in + return current +end + let store_path ~data_dir = Filename.Infix.(data_dir // "store") let load ~data_dir index = @@ -133,6 +170,7 @@ let apply_and_publish_blueprint (ctxt : t) (blueprint : Sequencer_blueprint.t) = let init ?kernel_path ~data_dir ~preimages ~smart_rollup_address () = let open Lwt_result_syntax in + let*! _version = Version.get data_dir in let* index = Irmin_context.load ~cache_size:100_000 Read_write (store_path ~data_dir) in -- GitLab From 718e012b825054da5c459f481644ffa7d18987af Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Wed, 21 Feb 2024 11:48:21 +0100 Subject: [PATCH 2/3] EVM/Node: migrate to V1 --- etherlink/bin_node/lib_dev/events.ml | 11 ++++ etherlink/bin_node/lib_dev/events.mli | 4 ++ etherlink/bin_node/lib_dev/evm_context.ml | 77 ++++++++++++++++++++++- 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/etherlink/bin_node/lib_dev/events.ml b/etherlink/bin_node/lib_dev/events.ml index e7bd48f542cd..a880dd4acbe2 100644 --- a/etherlink/bin_node/lib_dev/events.ml +++ b/etherlink/bin_node/lib_dev/events.ml @@ -63,6 +63,15 @@ let event_callback_log = ("method", Data_encoding.string) ("body", Data_encoding.string) +let migrating_data_dir = + Internal_event.Simple.declare_2 + ~section + ~name:"migration_data_dir" + ~msg:"Migrating from {before} to {after}" + ~level:Notice + ("before", Data_encoding.int8) + ("after", Data_encoding.int8) + let received_upgrade payload = emit received_upgrade payload let ignored_kernel_arg () = emit ignored_kernel_arg () @@ -75,3 +84,5 @@ let shutdown_rpc_server ~private_ = let shutdown_node ~exit_status = emit event_shutdown_node exit_status let callback_log ~uri ~meth ~body = emit event_callback_log (uri, meth, body) + +let migrating_data_dir ~before ~after = emit migrating_data_dir (before, after) diff --git a/etherlink/bin_node/lib_dev/events.mli b/etherlink/bin_node/lib_dev/events.mli index ade6c96e4061..051640a4a3b2 100644 --- a/etherlink/bin_node/lib_dev/events.mli +++ b/etherlink/bin_node/lib_dev/events.mli @@ -35,3 +35,7 @@ val shutdown_node : exit_status:int -> unit Lwt.t (** [callback_log ~uri ~meth ~body] is used as the debug event used as callback for resto to logs the requests. *) val callback_log : uri:string -> meth:string -> body:string -> unit Lwt.t + +(** [migrating_data_dir ~before ~after] advertises that the node is running + a data dir migration from [before] to [after]. *) +val migrating_data_dir : before:int -> after:int -> unit Lwt.t diff --git a/etherlink/bin_node/lib_dev/evm_context.ml b/etherlink/bin_node/lib_dev/evm_context.ml index 085c0771ff4b..e9c4e7560449 100644 --- a/etherlink/bin_node/lib_dev/evm_context.ml +++ b/etherlink/bin_node/lib_dev/evm_context.ml @@ -18,14 +18,29 @@ type t = { } module Version = struct - type version = V0 + type version = V0 | V1 let current = V0 let encoding = let open Data_encoding in union - [case ~title:"v0" (Tag 0) unit (function V0 -> Some ()) (fun () -> V0)] + [ + case + ~title:"v0" + (Tag 0) + unit + (function V0 -> Some () | _ -> None) + (fun () -> V0); + case + ~title:"v1" + (Tag 1) + unit + (function V1 -> Some () | _ -> None) + (fun () -> V1); + ] + + let to_int = function V0 -> 0 | V1 -> 1 let path data_dir = Filename.Infix.(data_dir // "version") @@ -168,9 +183,65 @@ let apply_and_publish_blueprint (ctxt : t) (blueprint : Sequencer_blueprint.t) = let* () = Blueprints_publisher.publish level blueprint.to_publish in return ctxt +module Migration = struct + type metadata = { + checkpoint : Context_hash.t; + next_blueprint_number : Ethereum_types.quantity; + current_block_hash : Ethereum_types.block_hash; + } + + let metadata_encoding = + let open Data_encoding in + conv + (fun {checkpoint; next_blueprint_number; current_block_hash} -> + (checkpoint, next_blueprint_number, current_block_hash)) + (fun (checkpoint, next_blueprint_number, current_block_hash) -> + {checkpoint; next_blueprint_number; current_block_hash}) + (obj3 + (req "checkpoint" Context_hash.encoding) + (req "next_blueprint_number" Ethereum_types.quantity_encoding) + (req "current_block_hash" Ethereum_types.block_hash_encoding)) +end + +let migrate_if_needed ~data_dir version = + let open Lwt_result_syntax in + match version with + | Version.V0 -> + let open Filename.Infix in + let after = Version.V1 in + let*! () = + Events.migrating_data_dir + ~before:(Version.to_int version) + ~after:(Version.to_int after) + in + let metadata_path = data_dir // "metadata" in + let*! exists = Lwt_unix.file_exists metadata_path in + if exists then + let*! contents = Lwt_utils_unix.read_file metadata_path in + let json = + match Data_encoding.Json.from_string contents with + | Ok json -> json + | Error _ -> Stdlib.failwith "Cannot parse metadata file" + in + let metadata = + Data_encoding.Json.(destruct Migration.metadata_encoding json) + in + let current = + match metadata.Migration.next_blueprint_number with + | Qty x -> Ethereum_types.Qty Z.(pred x) + in + let* store = Store.init ~data_dir in + let* () = + Store.Context_hashes.store store current metadata.checkpoint + in + Version.set data_dir after + else return_unit + | V1 -> return_unit + let init ?kernel_path ~data_dir ~preimages ~smart_rollup_address () = let open Lwt_result_syntax in - let*! _version = Version.get data_dir in + let* version = Version.get data_dir in + let* () = migrate_if_needed ~data_dir version in let* index = Irmin_context.load ~cache_size:100_000 Read_write (store_path ~data_dir) in -- GitLab From 2cffb2be96ef215131d80ef32255ede09905ae90 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Wed, 21 Feb 2024 13:39:32 +0100 Subject: [PATCH 3/3] EVM/Node: remove migration command --- etherlink/bin_node/main.ml | 56 -------------------------------------- 1 file changed, 56 deletions(-) diff --git a/etherlink/bin_node/main.ml b/etherlink/bin_node/main.ml index baa23f1e3a8d..a1dd2641c6fd 100644 --- a/etherlink/bin_node/main.ml +++ b/etherlink/bin_node/main.ml @@ -1032,61 +1032,6 @@ let init_from_rollup_node_command = ~data_dir ~rollup_node_data_dir) -module Migration = struct - type metadata = { - checkpoint : Context_hash.t; - next_blueprint_number : Ethereum_types.quantity; - current_block_hash : Ethereum_types.block_hash; - } - - let metadata_encoding = - let open Data_encoding in - conv - (fun {checkpoint; next_blueprint_number; current_block_hash} -> - (checkpoint, next_blueprint_number, current_block_hash)) - (fun (checkpoint, next_blueprint_number, current_block_hash) -> - {checkpoint; next_blueprint_number; current_block_hash}) - (obj3 - (req "checkpoint" Context_hash.encoding) - (req "next_blueprint_number" Ethereum_types.quantity_encoding) - (req "current_block_hash" Ethereum_types.block_hash_encoding)) -end - -let migrate_metadata_command = - let open Tezos_clic in - command - ~desc:"Migrate the old metadata json file to the new sqlite database" - (args1 data_dir_arg) - (prefixes ["migrate"; "metadata"; "file"] @@ stop) - (fun data_dir () -> - let open Filename.Infix in - let open Lwt_result_syntax in - let metadata_path = data_dir // "metadata" in - let*! exists = Lwt_unix.file_exists metadata_path in - if exists then - let*! contents = Lwt_utils_unix.read_file metadata_path in - let json = - match Data_encoding.Json.from_string contents with - | Ok json -> json - | Error _ -> Stdlib.failwith "Cannot parse metadata file" - in - let metadata = - Data_encoding.Json.(destruct Migration.metadata_encoding json) - in - let current = - match metadata.Migration.next_blueprint_number with - | Qty x -> Ethereum_types.Qty Z.(pred x) - in - let* store = Evm_node_lib_dev.Store.init ~data_dir in - let* () = - Evm_node_lib_dev.Store.Context_hashes.store - store - current - metadata.checkpoint - in - return_unit - else return_unit) - let dump_to_rlp = let open Tezos_clic in let open Lwt_result_syntax in @@ -1139,7 +1084,6 @@ let commands = chunker_command; make_upgrade_command; init_from_rollup_node_command; - migrate_metadata_command; dump_to_rlp; ] -- GitLab