From 076dd42115f0b26fd57cd540f8dc2a84389c7fbc Mon Sep 17 00:00:00 2001 From: Thomas Letan Date: Thu, 26 Sep 2024 12:04:41 +0200 Subject: [PATCH] EVM Node: Generalize the `--finalized-view` CLI argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a previous episode, we’ve added `--finalized-view` to the proxy mode to provide a lightweight node whose main purpose would be to only expose to its users the “finalized” block of an Etherlink instance. With this changeset, we generalize this mode to make it work with all the EVM node modes. In such a mode and as far as RPC are concerned, the `latest` block parameter becomes a synonym for `finalized`. We deprecate the previous option, add a warning to make it clear it will be removed in a future release, and we update the existing test. --- etherlink/CHANGES_NODE.md | 6 + etherlink/bin_node/config/configuration.ml | 108 ++++++++++++++---- etherlink/bin_node/config/configuration.mli | 9 +- etherlink/bin_node/lib_dev/events.ml | 10 ++ etherlink/bin_node/lib_dev/events.mli | 2 + etherlink/bin_node/lib_dev/evm_ro_context.ml | 36 ++++-- etherlink/bin_node/lib_dev/evm_ro_context.mli | 2 + etherlink/bin_node/lib_dev/observer.ml | 1 + etherlink/bin_node/lib_dev/proxy.ml | 16 ++- etherlink/bin_node/lib_dev/replay.ml | 10 +- etherlink/bin_node/lib_dev/rpc.ml | 1 + etherlink/bin_node/lib_dev/sequencer.ml | 1 + .../lib_dev/threshold_encryption_sequencer.ml | 1 + etherlink/bin_node/main.ml | 61 ++++++---- etherlink/tezt/lib/evm_node.ml | 79 ++++++++++--- etherlink/tezt/lib/evm_node.mli | 7 +- etherlink/tezt/lib/helpers.ml | 2 +- etherlink/tezt/lib/setup.ml | 2 +- etherlink/tezt/tests/evm_rollup.ml | 10 +- etherlink/tezt/tests/evm_sequencer.ml | 57 ++++++--- .../Alpha- Configuration RPC.out | 13 ++- .../EVM Node- describe config.out | 13 ++- .../evm_sequencer.ml/EVM Node- man.out | 25 ++-- src/bin_testnet_scenarios/evm_rollup.ml | 5 +- tezt/tests/cloud/dal.ml | 5 +- 25 files changed, 357 insertions(+), 125 deletions(-) diff --git a/etherlink/CHANGES_NODE.md b/etherlink/CHANGES_NODE.md index b65582254c5b..fd129faaa419 100644 --- a/etherlink/CHANGES_NODE.md +++ b/etherlink/CHANGES_NODE.md @@ -6,6 +6,12 @@ #### RPCs +- Generalized the support for the `--finalized-view` CLI argument. When + enabled, the `latest` block parameter becomes a synonym for `finalized`. + As a consequence, the `proxy.finalized_view` configuration parameter is + **deprecated**, in favor of the newly introduced `finalized_view` toplevel + configuration parameter. `proxy.finalized_view` will be removed in a future + version. (!15080) - **Experimental:** Introduce the experimental feature `ovewrite_simulation_tick_limit`. When enabled, the `eth_call` RPC is no longer subject to the kernel tick limit. This can be useful to execute calls diff --git a/etherlink/bin_node/config/configuration.ml b/etherlink/bin_node/config/configuration.ml index 6835e093bfbd..cef8106f2f15 100644 --- a/etherlink/bin_node/config/configuration.ml +++ b/etherlink/bin_node/config/configuration.ml @@ -61,7 +61,7 @@ type observer = { } type proxy = { - finalized_view : bool; + finalized_view : bool option; evm_node_endpoint : Uri.t option; ignore_block_param : bool; } @@ -106,6 +106,7 @@ type t = { verbose : Internal_event.level; experimental_features : experimental_features; fee_history : fee_history; + finalized_view : bool; } let default_filter_config ?max_nb_blocks ?max_nb_logs ?chunk_size () = @@ -721,13 +722,19 @@ let proxy_encoding = ignore_block_param; }) @@ obj3 - (dft "finalized_view" bool false) + (opt + ~description: + "When enabled, the node only expose blocks that are finalized, \ + i.e., the `latest` block parameter becomes a synonym for \ + `finalized`. DEPRECATED: use the top level `finalized_view` \ + option instead." + "finalized_view" + bool) (opt "evm_node_endpoint" string) (dft "ignore_block_param" bool false) -let default_proxy ?(finalized_view = false) ?evm_node_endpoint - ?(ignore_block_param = false) () = - {finalized_view; evm_node_endpoint; ignore_block_param} +let default_proxy ?evm_node_endpoint ?(ignore_block_param = false) () = + {finalized_view = None; evm_node_endpoint; ignore_block_param} let fee_history_encoding = let open Data_encoding in @@ -857,6 +864,7 @@ let encoding data_dir : t Data_encoding.t = experimental_features; fee_history; kernel_execution; + finalized_view; } -> ( (log_filter, sequencer, threshold_encryption_sequencer, observer), ( ( tx_pool_timeout_limit, @@ -868,7 +876,7 @@ let encoding data_dir : t Data_encoding.t = experimental_features, proxy, fee_history ), - (kernel_execution, public_rpc, private_rpc) ) )) + (kernel_execution, public_rpc, private_rpc, finalized_view) ) )) (fun ( (log_filter, sequencer, threshold_encryption_sequencer, observer), ( ( tx_pool_timeout_limit, tx_pool_addr_limit, @@ -879,7 +887,7 @@ let encoding data_dir : t Data_encoding.t = experimental_features, proxy, fee_history ), - (kernel_execution, public_rpc, private_rpc) ) ) -> + (kernel_execution, public_rpc, private_rpc, finalized_view) ) ) -> { public_rpc; private_rpc; @@ -897,6 +905,7 @@ let encoding data_dir : t Data_encoding.t = experimental_features; fee_history; kernel_execution; + finalized_view; }) (merge_objs (obj4 @@ -954,13 +963,21 @@ let encoding data_dir : t Data_encoding.t = default_experimental_features) (dft "proxy" proxy_encoding (default_proxy ())) (dft "fee_history" fee_history_encoding default_fee_history)) - (obj3 + (obj4 (dft "kernel_execution" (kernel_execution_encoding data_dir) (kernel_execution_config_dft ~data_dir ())) (dft "public_rpc" rpc_encoding (default_rpc ())) - (opt "private_rpc" rpc_encoding)))) + (opt "private_rpc" rpc_encoding) + (dft + ~description: + "When enabled, the node only expose blocks that are \ + finalized, i.e., the `latest` block parameter becomes a \ + synonym for `finalized`." + "finalized_view" + bool + false)))) let pp_print_json ~data_dir fmt config = let json = @@ -984,11 +1001,51 @@ let save ~force ~data_dir config = let*! () = Lwt_utils_unix.create_dir data_dir in Lwt_utils_unix.Json.write_file config_file json +module Json_syntax = struct + let ( |-?> ) json field = + match json with + | `O assoc -> List.assoc ~equal:String.equal field assoc + | _ -> None + + let ( |?-?> ) json field = + match json with + | Some (`O assoc) -> List.assoc ~equal:String.equal field assoc + | _ -> None + + let ( |?> ) x f = match x with Some x -> f x | None -> None + + let as_bool_opt = function `Bool b -> Some b | _ -> None +end + +(* Syntactic checks related to deprecations *) +let precheck json = + let open Lwt_result_syntax in + Lwt.catch + (fun () -> + let open Json_syntax in + (* Conflicts between [.proxy.finalized_view] and [.finalized_view] *) + let proxy_conf = + json |-?> "proxy" |?-?> "finalized_view" |?> as_bool_opt + in + let toplevel_conf = json |-?> "finalized_view" |?> as_bool_opt in + let* () = + match (proxy_conf, toplevel_conf) with + | Some b, Some b' -> + when_ (b <> b') @@ fun () -> + failwith + "`proxy.finalized_view` and `finalized_view` are inconsistent." + | _ -> return_unit + in + + return_unit) + (fun _exn -> failwith "Syntax error in the configuration file") + let load_file ~data_dir path = let open Lwt_result_syntax in - let+ json = Lwt_utils_unix.Json.read_file path in + let* json = Lwt_utils_unix.Json.read_file path in + let* () = precheck json in let config = Data_encoding.Json.destruct (encoding data_dir) json in - config + return config let load ~data_dir = load_file ~data_dir (config_filename ~data_dir) @@ -1016,7 +1073,7 @@ module Cli = struct ?log_filter_max_nb_blocks ?log_filter_max_nb_logs ?log_filter_chunk_size ?max_blueprints_lag ?max_blueprints_ahead ?max_blueprints_catchup ?catchup_cooldown ?sequencer_sidecar_endpoint ?restricted_rpcs - ?proxy_finalized_view ?proxy_ignore_block_param ?dal_slots () = + ~finalized_view ?proxy_ignore_block_param ?dal_slots () = let public_rpc = default_rpc ?rpc_port @@ -1074,7 +1131,6 @@ module Cli = struct in let proxy = default_proxy - ?finalized_view:proxy_finalized_view ?evm_node_endpoint ?ignore_block_param:proxy_ignore_block_param () @@ -1116,6 +1172,7 @@ module Cli = struct verbose = (if verbose then Debug else Internal_event.Notice); experimental_features = default_experimental_features; fee_history = default_fee_history; + finalized_view; } let patch_kernel_execution_config kernel_execution ?preimages @@ -1151,7 +1208,7 @@ module Cli = struct ?log_filter_max_nb_blocks ?log_filter_max_nb_logs ?log_filter_chunk_size ?max_blueprints_lag ?max_blueprints_ahead ?max_blueprints_catchup ?catchup_cooldown ?sequencer_sidecar_endpoint ?restricted_rpcs - ?proxy_finalized_view ?proxy_ignore_block_param ~dal_slots configuration = + ~finalized_view ?proxy_ignore_block_param ~dal_slots configuration = let public_rpc = patch_rpc ?rpc_addr @@ -1329,11 +1386,17 @@ module Cli = struct evm_node_endpoint in let proxy = - default_proxy - ?finalized_view:proxy_finalized_view - ?evm_node_endpoint - ?ignore_block_param:proxy_ignore_block_param - () + { + evm_node_endpoint = + Option.either evm_node_endpoint configuration.proxy.evm_node_endpoint; + ignore_block_param = + Option.value + ~default:configuration.proxy.ignore_block_param + proxy_ignore_block_param; + finalized_view = + (if finalized_view then Some true + else configuration.proxy.finalized_view); + } in let log_filter = { @@ -1390,6 +1453,7 @@ module Cli = struct verbose = (if verbose then Debug else configuration.verbose); experimental_features = configuration.experimental_features; fee_history = configuration.fee_history; + finalized_view = finalized_view || configuration.finalized_view; } let create_or_read_config ~data_dir ?rpc_addr ?rpc_port ?rpc_batch_limit @@ -1401,7 +1465,7 @@ module Cli = struct ?max_blueprints_lag ?max_blueprints_ahead ?max_blueprints_catchup ?catchup_cooldown ?log_filter_max_nb_blocks ?log_filter_max_nb_logs ?log_filter_chunk_size ?sequencer_sidecar_endpoint ?restricted_rpcs - ?proxy_finalized_view ?proxy_ignore_block_param ?dal_slots () = + ~finalized_view ?proxy_ignore_block_param ?dal_slots () = let open Lwt_result_syntax in let open Filename.Infix in (* Check if the data directory of the evm node is not the one of Octez @@ -1453,7 +1517,7 @@ module Cli = struct ?log_filter_chunk_size ?sequencer_sidecar_endpoint ?restricted_rpcs - ?proxy_finalized_view + ~finalized_view ?proxy_ignore_block_param ~dal_slots configuration @@ -1492,7 +1556,7 @@ module Cli = struct ?log_filter_chunk_size ?sequencer_sidecar_endpoint ?restricted_rpcs - ?proxy_finalized_view + ~finalized_view ?proxy_ignore_block_param ?dal_slots () diff --git a/etherlink/bin_node/config/configuration.mli b/etherlink/bin_node/config/configuration.mli index a3e53277b9b9..8ec32153941f 100644 --- a/etherlink/bin_node/config/configuration.mli +++ b/etherlink/bin_node/config/configuration.mli @@ -88,7 +88,7 @@ type observer = { } type proxy = { - finalized_view : bool; + finalized_view : bool option; (** Provide a view on the latest final state of the rollup, not its current HEAD. *) evm_node_endpoint : Uri.t option; @@ -135,6 +135,7 @@ type t = { verbose : Internal_event.level; experimental_features : experimental_features; fee_history : fee_history; + finalized_view : bool; } (** [encoding data_dir] is the encoding of {!t} based on data dir [data_dir]. *) @@ -242,7 +243,7 @@ module Cli : sig ?catchup_cooldown:int -> ?sequencer_sidecar_endpoint:Uri.t -> ?restricted_rpcs:restricted_rpcs -> - ?proxy_finalized_view:bool -> + finalized_view:bool -> ?proxy_ignore_block_param:bool -> ?dal_slots:int list -> unit -> @@ -278,7 +279,7 @@ module Cli : sig ?catchup_cooldown:int -> ?sequencer_sidecar_endpoint:Uri.t -> ?restricted_rpcs:restricted_rpcs -> - ?proxy_finalized_view:bool -> + finalized_view:bool -> ?proxy_ignore_block_param:bool -> dal_slots:int trace option -> t -> @@ -315,7 +316,7 @@ module Cli : sig ?log_filter_chunk_size:int -> ?sequencer_sidecar_endpoint:Uri.t -> ?restricted_rpcs:restricted_rpcs -> - ?proxy_finalized_view:bool -> + finalized_view:bool -> ?proxy_ignore_block_param:bool -> ?dal_slots:int list -> unit -> diff --git a/etherlink/bin_node/lib_dev/events.ml b/etherlink/bin_node/lib_dev/events.ml index 389a6c2d98a0..431f47383f7b 100644 --- a/etherlink/bin_node/lib_dev/events.ml +++ b/etherlink/bin_node/lib_dev/events.ml @@ -119,6 +119,14 @@ let event_retrying_connect = ("endpoint", Data_encoding.string) ("delay", Data_encoding.float) +let event_deprecation_note = + Internal_event.Simple.declare_1 + ~section + ~name:"deprecation_note" + ~msg:"{msg}" + ~level:Warning + ("msg", Data_encoding.string) + type kernel_log_kind = Application | Simulation type kernel_log_level = Debug | Info | Error | Fatal @@ -264,3 +272,5 @@ let cannot_fetch_time_between_blocks fallback trace = let invalid_node_da_fees ~node_da_fees ~kernel_da_fees = emit invalid_node_da_fees (node_da_fees, kernel_da_fees) + +let deprecation_note msg = emit event_deprecation_note msg diff --git a/etherlink/bin_node/lib_dev/events.mli b/etherlink/bin_node/lib_dev/events.mli index e5f69ace774b..71b94d54d250 100644 --- a/etherlink/bin_node/lib_dev/events.mli +++ b/etherlink/bin_node/lib_dev/events.mli @@ -87,3 +87,5 @@ val cannot_fetch_time_between_blocks : Configuration.time_between_blocks -> tztrace -> unit Lwt.t val invalid_node_da_fees : node_da_fees:Z.t -> kernel_da_fees:Z.t -> unit Lwt.t + +val deprecation_note : string -> unit Lwt.t diff --git a/etherlink/bin_node/lib_dev/evm_ro_context.ml b/etherlink/bin_node/lib_dev/evm_ro_context.ml index a5d754e2a456..d9bbc318cd7c 100644 --- a/etherlink/bin_node/lib_dev/evm_ro_context.ml +++ b/etherlink/bin_node/lib_dev/evm_ro_context.ml @@ -12,9 +12,11 @@ type t = { store : Evm_store.t; smart_rollup_address : Tezos_crypto.Hashed.Smart_rollup_address.t; index : Irmin_context.ro_index; + finalized_view : bool; } -let load ?smart_rollup_address ~data_dir ~preimages ?preimages_endpoint () = +let load ?smart_rollup_address ~data_dir ~preimages ?preimages_endpoint + ~finalized_view () = let open Lwt_result_syntax in let* store = Evm_store.init ~data_dir ~perm:`Read_only () in let* index = @@ -26,7 +28,15 @@ let load ?smart_rollup_address ~data_dir ~preimages ?preimages_endpoint () = | None -> Evm_store.(use store Metadata.get) | Some smart_rollup_address -> return smart_rollup_address in - {store; index; data_dir; preimages; preimages_endpoint; smart_rollup_address} + { + store; + index; + data_dir; + preimages; + preimages_endpoint; + smart_rollup_address; + finalized_view; + } let get_evm_state ctxt hash = let open Lwt_result_syntax in @@ -42,6 +52,13 @@ let find_latest_hash ctxt = | Some (_, hash) -> return hash | None -> failwith "No state available" +let find_finalized_hash ctxt = + let open Lwt_result_syntax in + let* res = Evm_store.(use ctxt.store Context_hashes.find_finalized) in + match res with + | Some (_, hash) -> return hash + | None -> failwith "No state available" + let find_irmin_hash_from_number ctxt number = let open Lwt_result_syntax in let* res = @@ -58,17 +75,15 @@ let find_irmin_hash_from_number ctxt number = let find_irmin_hash ctxt (block : Ethereum_types.Block_parameter.extended) = let open Lwt_result_syntax in match block with + | Block_parameter (Latest | Pending) when ctxt.finalized_view -> + find_finalized_hash ctxt | Block_parameter (Latest | Pending) -> find_latest_hash ctxt | Block_parameter Earliest -> ( let* res = Evm_store.(use ctxt.store Context_hashes.find_earliest) in match res with | Some (_, hash) -> return hash | None -> failwith "No state available") - | Block_parameter Finalized -> ( - let* res = Evm_store.(use ctxt.store Context_hashes.find_finalized) in - match res with - | Some (_, hash) -> return hash - | None -> failwith "No state available") + | Block_parameter Finalized -> find_finalized_hash ctxt | Block_parameter (Number number) -> ( let* res = Evm_store.( @@ -236,6 +251,13 @@ struct let open Lwt_result_syntax in match block_param with | Block_parameter (Number n) -> return n + | Block_parameter (Latest | Pending) when Ctxt.ctxt.finalized_view -> ( + let* res = + Evm_store.(use Ctxt.ctxt.store Context_hashes.find_finalized) + in + match res with + | Some (latest, _) -> return latest + | None -> failwith "The EVM node does not have any state available") | Block_parameter (Latest | Pending) -> ( let* res = Evm_store.(use Ctxt.ctxt.store Context_hashes.find_latest) in match res with diff --git a/etherlink/bin_node/lib_dev/evm_ro_context.mli b/etherlink/bin_node/lib_dev/evm_ro_context.mli index a8b0aa974e9a..4f1d2b357ad2 100644 --- a/etherlink/bin_node/lib_dev/evm_ro_context.mli +++ b/etherlink/bin_node/lib_dev/evm_ro_context.mli @@ -12,6 +12,7 @@ type t = { store : Evm_store.t; smart_rollup_address : Tezos_crypto.Hashed.Smart_rollup_address.t; index : Irmin_context.ro_index; + finalized_view : bool; } (** [load ~data_dir ~preimages ()] creates a new read-only handler on the @@ -25,6 +26,7 @@ val load : data_dir:string -> preimages:string -> ?preimages_endpoint:Uri.t -> + finalized_view:bool -> unit -> t tzresult Lwt.t diff --git a/etherlink/bin_node/lib_dev/observer.ml b/etherlink/bin_node/lib_dev/observer.ml index 8acbb17d7aeb..b44a374f0da3 100644 --- a/etherlink/bin_node/lib_dev/observer.ml +++ b/etherlink/bin_node/lib_dev/observer.ml @@ -83,6 +83,7 @@ let main ?kernel_path ~data_dir ~(config : Configuration.t) ~no_sync () = ~data_dir ~preimages:config.kernel_execution.preimages ?preimages_endpoint:config.kernel_execution.preimages_endpoint + ~finalized_view:config.finalized_view () in diff --git a/etherlink/bin_node/lib_dev/proxy.ml b/etherlink/bin_node/lib_dev/proxy.ml index d2ff77e4ffb1..d0483b1fb1f2 100644 --- a/etherlink/bin_node/lib_dev/proxy.ml +++ b/etherlink/bin_node/lib_dev/proxy.ml @@ -45,6 +45,20 @@ let main ~keep_alive:config.keep_alive rollup_node_endpoint in + let* () = + when_ Option.(is_some config.proxy.finalized_view) @@ fun () -> + let*! () = + Events.deprecation_note + "proxy.finalized_view has been deprecated and will be removed in a \ + future version" + in + return_unit + in + let* finalized_view = + match (config.proxy.finalized_view, config.finalized_view) with + | Some fv, false -> return fv + | _, fv -> return fv + in let module Rollup_node_rpc = Rollup_node.Make (struct let base = rollup_node_endpoint @@ -54,7 +68,7 @@ let main let smart_rollup_address = smart_rollup_address - let finalized = config.proxy.finalized_view + let finalized = finalized_view let ignore_block_param = config.proxy.ignore_block_param end) in diff --git a/etherlink/bin_node/lib_dev/replay.ml b/etherlink/bin_node/lib_dev/replay.ml index 5ae547cefa1b..3f12930b2502 100644 --- a/etherlink/bin_node/lib_dev/replay.ml +++ b/etherlink/bin_node/lib_dev/replay.ml @@ -19,7 +19,15 @@ let patch_kernel ~kernel_path evm_state = let main ?profile ?kernel_path ~data_dir ~preimages ~preimages_endpoint number = let open Lwt_result_syntax in let* ro_ctxt = - Evm_ro_context.load ~data_dir ~preimages ?preimages_endpoint () + Evm_ro_context.load + ~data_dir + ~preimages + ?preimages_endpoint + ~finalized_view: + (* The block parameter won’t be used so this parameter is effectively + ignored during a replay *) + false + () in let alter_evm_state = match kernel_path with diff --git a/etherlink/bin_node/lib_dev/rpc.ml b/etherlink/bin_node/lib_dev/rpc.ml index 96eed53bbe16..42d32d02f9fc 100644 --- a/etherlink/bin_node/lib_dev/rpc.ml +++ b/etherlink/bin_node/lib_dev/rpc.ml @@ -39,6 +39,7 @@ let main ~data_dir ~evm_node_endpoint ~(config : Configuration.t) = ~data_dir ~preimages:config.kernel_execution.preimages ?preimages_endpoint:config.kernel_execution.preimages_endpoint + ~finalized_view:config.finalized_view () in let* () = Evm_ro_context.preload_known_kernels ctxt in diff --git a/etherlink/bin_node/lib_dev/sequencer.ml b/etherlink/bin_node/lib_dev/sequencer.ml index 159228c11afe..68811d21405e 100644 --- a/etherlink/bin_node/lib_dev/sequencer.ml +++ b/etherlink/bin_node/lib_dev/sequencer.ml @@ -136,6 +136,7 @@ let main ~data_dir ?(genesis_timestamp = Misc.now ()) ~cctxt ~data_dir ~preimages:configuration.kernel_execution.preimages ?preimages_endpoint:configuration.kernel_execution.preimages_endpoint + ~finalized_view:configuration.finalized_view () in diff --git a/etherlink/bin_node/lib_dev/threshold_encryption_sequencer.ml b/etherlink/bin_node/lib_dev/threshold_encryption_sequencer.ml index 5fc00f5dc831..b772df25abb2 100644 --- a/etherlink/bin_node/lib_dev/threshold_encryption_sequencer.ml +++ b/etherlink/bin_node/lib_dev/threshold_encryption_sequencer.ml @@ -105,6 +105,7 @@ let main ~data_dir ?(genesis_timestamp = Misc.now ()) ~cctxt ~data_dir ~preimages:configuration.kernel_execution.preimages ?preimages_endpoint:configuration.kernel_execution.preimages_endpoint + ~finalized_view:configuration.finalized_view () in let ro_backend = Evm_ro_context.ro_backend ro_ctxt configuration in diff --git a/etherlink/bin_node/main.ml b/etherlink/bin_node/main.ml index 592d2d42791b..9f0cfeddd038 100644 --- a/etherlink/bin_node/main.ml +++ b/etherlink/bin_node/main.ml @@ -538,8 +538,8 @@ let read_only_arg = let finalized_view_arg = Tezos_clic.switch ~doc: - "If the flag is set, the node exposes a view of the latest final state \ - of the rollup, not its current HEAD." + "If the flag is set, the node will use the latest final state of the \ + rollup, not its current HEAD, for any read-only operation." ~long:"finalized-view" () @@ -617,7 +617,7 @@ let num_download_retries = Params.int let common_config_args = - Tezos_clic.args18 + Tezos_clic.args19 data_dir_arg rpc_addr_arg rpc_port_arg @@ -636,6 +636,7 @@ let common_config_args = restricted_rpcs_arg blacklisted_rpcs_arg whitelisted_rpcs_arg + finalized_view_arg let compress_on_the_fly_arg : (bool, unit) Tezos_clic.arg = Tezos_clic.switch @@ -692,7 +693,7 @@ let start_proxy ~data_dir ~keep_alive ?rpc_addr ?rpc_port ?rpc_batch_limit ?tx_pool_addr_limit ?tx_pool_tx_per_addr_limit ?restricted_rpcs - ~proxy_finalized_view:finalized_view + ~finalized_view ~proxy_ignore_block_param:ignore_block_param ~verbose () @@ -741,7 +742,7 @@ let start_sequencer ?password_filename ~wallet_dir ~data_dir ?rpc_addr ?rpc_port ?max_blueprints_lag ?max_blueprints_ahead ?max_blueprints_catchup ?catchup_cooldown ?log_filter_max_nb_blocks ?log_filter_max_nb_logs ?log_filter_chunk_size ?genesis_timestamp ?restricted_rpcs ?kernel - ?dal_slots ?sandbox_key () = + ?dal_slots ?sandbox_key ~finalized_view () = let open Lwt_result_syntax in let wallet_ctxt = register_wallet ?password_filename ~wallet_dir () in let* sequencer_key = @@ -783,6 +784,7 @@ let start_sequencer ?password_filename ~wallet_dir ~data_dir ?rpc_addr ?rpc_port ?log_filter_chunk_size ?restricted_rpcs ?dal_slots + ~finalized_view () in let*! () = @@ -825,7 +827,7 @@ let start_threshold_encryption_sequencer ?password_filename ~wallet_dir ?max_blueprints_lag ?max_blueprints_ahead ?max_blueprints_catchup ?catchup_cooldown ?log_filter_max_nb_blocks ?log_filter_max_nb_logs ?log_filter_chunk_size ?genesis_timestamp ?restricted_rpcs ?kernel - ?sequencer_sidecar_endpoint ?dal_slots () = + ?sequencer_sidecar_endpoint ?dal_slots ~finalized_view () = let open Lwt_result_syntax in let wallet_ctxt = register_wallet ?password_filename ~wallet_dir () in let* sequencer_key = @@ -863,6 +865,7 @@ let start_threshold_encryption_sequencer ?password_filename ~wallet_dir ?sequencer_sidecar_endpoint ?restricted_rpcs ?dal_slots + ~finalized_view () in let*! () = @@ -922,7 +925,8 @@ let rpc_command = verbose, restricted_rpcs, blacklisted_rpcs, - whitelisted_rpcs ), + whitelisted_rpcs, + finalized_view ), (evm_node_endpoint, preimages, preimages_endpoint) ) () -> let* restricted_rpcs = @@ -945,7 +949,12 @@ let rpc_command = This config will be used to infer what is the endpoint to use to connect to the read-write node. *) - Cli.create_or_read_config ~data_dir ~keep_alive ~verbose () + Cli.create_or_read_config + ~data_dir + ~keep_alive + ~verbose + ~finalized_view + () in let evm_node_endpoint = match evm_node_endpoint with @@ -987,6 +996,7 @@ let rpc_command = ?rpc_addr ~dal_slots:None read_write_config + ~finalized_view in let*! () = let open Tezos_base_unix.Internal_event_unix in @@ -1019,7 +1029,7 @@ let start_observer ~data_dir ~keep_alive ?rpc_addr ?rpc_port ?rpc_batch_limit ?evm_node_endpoint ?threshold_encryption_bundler_endpoint ?tx_pool_timeout_limit ?tx_pool_addr_limit ?tx_pool_tx_per_addr_limit ?log_filter_chunk_size ?log_filter_max_nb_logs ?log_filter_max_nb_blocks - ?restricted_rpcs ?kernel ~no_sync () = + ?restricted_rpcs ?kernel ~no_sync ~finalized_view () = let open Lwt_result_syntax in let* config = Cli.create_or_read_config @@ -1050,6 +1060,7 @@ let start_observer ~data_dir ~keep_alive ?rpc_addr ?rpc_port ?rpc_batch_limit ?log_filter_max_nb_blocks ?restricted_rpcs ?dal_slots:None + ~finalized_view () in let*! () = @@ -1522,7 +1533,8 @@ mode.|} verbose, restricted_rpcs, blacklisted_rpcs, - whitelisted_rpcs ), + whitelisted_rpcs, + finalized_view ), ( preimages, preimages_endpoint, time_between_blocks, @@ -1588,6 +1600,7 @@ mode.|} ?restricted_rpcs ~verbose ?dal_slots + ~finalized_view () in Configuration.save ~force ~data_dir config) @@ -1756,11 +1769,7 @@ let proxy_command = ~desc:"Start the EVM node in proxy mode." (merge_options common_config_args - (args4 - read_only_arg - finalized_view_arg - ignore_block_param_arg - evm_node_endpoint_arg)) + (args3 read_only_arg ignore_block_param_arg evm_node_endpoint_arg)) (prefixes ["run"; "proxy"] @@ stop) (fun ( ( data_dir, rpc_addr, @@ -1779,8 +1788,9 @@ let proxy_command = verbose, restricted_rpcs, blacklisted_rpcs, - whitelisted_rpcs ), - (read_only, finalized_view, ignore_block_param, evm_node_endpoint) ) + whitelisted_rpcs, + finalized_view ), + (read_only, ignore_block_param, evm_node_endpoint) ) () -> let open Lwt_result_syntax in let* restricted_rpcs = @@ -1862,7 +1872,8 @@ let sequencer_command = verbose, restricted_rpcs, blacklisted_rpcs, - whitelisted_rpcs ), + whitelisted_rpcs, + finalized_view ), ( preimages, preimages_endpoint, time_between_blocks, @@ -1915,6 +1926,7 @@ let sequencer_command = ?restricted_rpcs ?kernel ?dal_slots + ~finalized_view ()) let sandbox_command = @@ -1943,7 +1955,8 @@ let sandbox_command = verbose, restricted_rpcs, blacklisted_rpcs, - whitelisted_rpcs ), + whitelisted_rpcs, + finalized_view ), ( preimages, preimages_endpoint, time_between_blocks, @@ -1995,6 +2008,7 @@ let sandbox_command = ?restricted_rpcs ?kernel ~sandbox_key:(pk, sk) + ~finalized_view ()) let threshold_encryption_sequencer_config_args = @@ -2041,7 +2055,8 @@ let threshold_encryption_sequencer_command = verbose, restricted_rpcs, blacklisted_rpcs, - whitelisted_rpcs ), + whitelisted_rpcs, + finalized_view ), ( preimages, preimages_endpoint, time_between_blocks, @@ -2096,6 +2111,7 @@ let threshold_encryption_sequencer_command = ?restricted_rpcs ?kernel ?dal_slots + ~finalized_view ()) let observer_run_args = @@ -2131,7 +2147,8 @@ let observer_command = verbose, restricted_rpcs, blacklisted_rpcs, - whitelisted_rpcs ), + whitelisted_rpcs, + finalized_view ), ( evm_node_endpoint, threshold_encryption_bundler_endpoint, preimages, @@ -2168,6 +2185,7 @@ let observer_command = ?restricted_rpcs ?kernel ~no_sync + ~finalized_view ()) let export_snapshot (data_dir, snapshot_file, compress_on_the_fly, uncompressed) @@ -2314,6 +2332,7 @@ let preemptive_kernel_download_command = ~verbose:false ?preimages ?preimages_endpoint + ~finalized_view:false () in let kernel_execution_config = configuration.kernel_execution in diff --git a/etherlink/tezt/lib/evm_node.ml b/etherlink/tezt/lib/evm_node.ml index 40ddc6c2ba93..8f13ff5b7a11 100644 --- a/etherlink/tezt/lib/evm_node.ml +++ b/etherlink/tezt/lib/evm_node.ml @@ -90,7 +90,7 @@ type mode = sequencer_sidecar_endpoint : string; dal_slots : int list option; } - | Proxy of {finalized_view : bool} + | Proxy | Rpc of mode module Per_level_map = Map.Make (Int) @@ -103,6 +103,9 @@ module Parameters = struct mutable pending_blueprint_injected : unit option Lwt.u list Per_level_map.t; mutable last_applied_level : int; mutable pending_blueprint_applied : unit option Lwt.u list Per_level_map.t; + mutable last_finalized_level : int; + mutable pending_blueprint_finalized : + unit option Lwt.u list Per_level_map.t; mode : mode; data_dir : string; rpc_addr : string; @@ -127,7 +130,14 @@ let mode t = t.persistent_state.mode let is_sequencer t = match t.persistent_state.mode with | Sequencer _ | Sandbox _ | Threshold_encryption_sequencer _ -> true - | Observer _ | Threshold_encryption_observer _ | Proxy _ | Rpc _ -> false + | Observer _ | Threshold_encryption_observer _ | Proxy | Rpc _ -> false + +let is_observer t = + match t.persistent_state.mode with + | Sequencer _ | Sandbox _ | Threshold_encryption_sequencer _ | Proxy | Rpc _ + -> + false + | Observer _ | Threshold_encryption_observer _ -> true let initial_kernel t = let rec from_mode = function @@ -138,7 +148,7 @@ let initial_kernel t = | Threshold_encryption_observer {initial_kernel; _} -> initial_kernel | Rpc mode -> from_mode mode - | Proxy _ -> Test.fail "cannot start a RPC node from a proxy node" + | Proxy -> Test.fail "cannot start a RPC node from a proxy node" in from_mode t.persistent_state.mode @@ -147,7 +157,7 @@ let can_apply_blueprint t = | Sequencer _ | Sandbox _ | Threshold_encryption_sequencer _ | Observer _ | Threshold_encryption_observer _ -> true - | Proxy _ | Rpc _ -> false + | Proxy | Rpc _ -> false let connection_arguments ?rpc_addr ?rpc_port ?runner () = let rpc_port = @@ -178,6 +188,15 @@ let trigger_blueprint_injected evm_node level = List.iter (fun pending -> Lwt.wakeup_later pending (Some ())) @@ Option.value ~default:[] pending_for_level +let trigger_blueprint_finalized evm_node level = + let pending = evm_node.persistent_state.pending_blueprint_finalized in + let pending_for_level = Per_level_map.find_opt level pending in + evm_node.persistent_state.last_finalized_level <- level ; + evm_node.persistent_state.pending_blueprint_finalized <- + Per_level_map.remove level pending ; + List.iter (fun pending -> Lwt.wakeup_later pending (Some ())) + @@ Option.value ~default:[] pending_for_level + let trigger_blueprint_applied evm_node level = let pending = evm_node.persistent_state.pending_blueprint_applied in let pending_for_level = Per_level_map.find_opt level pending in @@ -197,6 +216,9 @@ let event_ready_name = "is_ready.v0" let event_blueprint_injected_name = "blueprint_injection.v0" +let event_blueprint_finalized_name = + "evm_events_follower_upstream_blueprint_applied.v0" + let event_blueprint_applied_name = "blueprint_application.v0" let handle_is_ready_event (evm_node : t) {name; value = _; timestamp = _} = @@ -208,6 +230,12 @@ let handle_blueprint_injected_event (evm_node : t) {name; value; timestamp = _} trigger_blueprint_injected evm_node JSON.(value |> as_int) else () +let handle_blueprint_finalized_event (evm_node : t) {name; value; timestamp = _} + = + if name = event_blueprint_finalized_name then + trigger_blueprint_finalized evm_node JSON.(value |-> "level" |> as_int) + else () + let handle_blueprint_applied_event (evm_node : t) {name; value; timestamp = _} = if name = event_blueprint_applied_name then trigger_blueprint_applied evm_node @@ -252,6 +280,29 @@ let wait_for_ready ?timeout evm_node = resolver :: evm_node.persistent_state.pending_ready ; wait_for_event_listener ?timeout evm_node ~event:event_ready_name promise +let wait_for_blueprint_finalized ?timeout evm_node level = + match evm_node.status with + | Running {session_state = {ready = true; _}; _} + when is_sequencer evm_node || is_observer evm_node -> + let current_level = evm_node.persistent_state.last_finalized_level in + if level <= current_level then unit + else + let promise, resolver = Lwt.task () in + evm_node.persistent_state.pending_blueprint_finalized <- + Per_level_map.update + level + (fun pending -> Some (resolver :: Option.value ~default:[] pending)) + evm_node.persistent_state.pending_blueprint_finalized ; + wait_for_event_listener + ?timeout + evm_node + ~event:event_blueprint_finalized_name + promise + | Running {session_state = {ready = true; _}; _} -> + failwith "EVM node is not a stateful node" + | Not_running | Running {session_state = {ready = false; _}; _} -> + failwith "EVM node is not ready" + let wait_for_blueprint_injected ?timeout evm_node level = match evm_node.status with | Running {session_state = {ready = true; _}; _} when is_sequencer evm_node -> @@ -487,14 +538,13 @@ let wait_for_tx_pool_add_transaction ?timeout evm_node = @@ JSON.as_string_opt let create ?(path = Uses.path Constant.octez_evm_node) ?name ?runner - ?(mode = Proxy {finalized_view = false}) ?data_dir ?rpc_addr ?rpc_port - ?restricted_rpcs endpoint = + ?(mode = Proxy) ?data_dir ?rpc_addr ?rpc_port ?restricted_rpcs endpoint = let arguments, rpc_addr, rpc_port = connection_arguments ?rpc_addr ?rpc_port ?runner () in let new_name () = match mode with - | Proxy _ -> "proxy_" ^ fresh_name () + | Proxy -> "proxy_" ^ fresh_name () | Sequencer _ -> "sequencer_" ^ fresh_name () | Sandbox _ -> "sandbox_" ^ fresh_name () | Threshold_encryption_sequencer _ -> "te_sequencer_" ^ fresh_name () @@ -518,6 +568,8 @@ let create ?(path = Uses.path Constant.octez_evm_node) ?name ?runner pending_blueprint_injected = Per_level_map.empty; last_applied_level = 0; pending_blueprint_applied = Per_level_map.empty; + last_finalized_level = 0; + pending_blueprint_finalized = Per_level_map.empty; mode; data_dir; rpc_addr; @@ -530,6 +582,7 @@ let create ?(path = Uses.path Constant.octez_evm_node) ?name ?runner on_event evm_node (handle_is_ready_event evm_node) ; on_event evm_node (handle_blueprint_injected_event evm_node) ; on_event evm_node (handle_blueprint_applied_event evm_node) ; + on_event evm_node (handle_blueprint_finalized_event evm_node) ; evm_node let name evm_node = evm_node.name @@ -548,9 +601,7 @@ let run_args evm_node = in let mode_args = match evm_node.persistent_state.mode with - | Proxy {finalized_view} -> - ["run"; "proxy"] - @ Cli_arg.optional_switch "finalized-view" finalized_view + | Proxy -> ["run"; "proxy"] | Sequencer {initial_kernel; genesis_timestamp; wallet_dir; _} -> ["run"; "sequencer"; "--initial-kernel"; initial_kernel] @ Cli_arg.optional_arg @@ -690,7 +741,7 @@ let spawn_init_config ?(extra_arguments = []) evm_node = in let mode_args = match evm_node.persistent_state.mode with - | Proxy _ -> ["--rollup-node-endpoint"; evm_node.persistent_state.endpoint] + | Proxy -> ["--rollup-node-endpoint"; evm_node.persistent_state.endpoint] | Rpc _ -> [] | Sequencer { @@ -933,7 +984,7 @@ let rpc_endpoint ?(local = false) ?(private_ = false) (evm_node : t) = | Threshold_encryption_sequencer {private_rpc_port = None; _} -> Test.fail "Threshold encryption sequencer doesn't have a private RPC server" - | Proxy _ -> Test.fail "Proxy doesn't have a private RPC server" + | Proxy -> Test.fail "Proxy doesn't have a private RPC server" | Observer _ -> Test.fail "Observer doesn't have a private RPC server" | Rpc _ -> Test.fail "Rpc node doesn't have a private RPC server" | Threshold_encryption_observer _ -> @@ -1327,7 +1378,7 @@ let preimages_dir evm_node = | Observer {preimages_dir; _} | Threshold_encryption_observer {preimages_dir; _} -> preimages_dir - | Proxy _ -> Test.fail "cannot start a RPC node from a proxy node" + | Proxy -> Test.fail "cannot start a RPC node from a proxy node" in from_node ~data_dir:(data_dir evm_node) evm_node.persistent_state.mode @@ -1336,6 +1387,6 @@ let supports_threshold_encryption evm_node = | Sandbox _ | Sequencer _ | Observer _ -> false | Threshold_encryption_observer _ | Threshold_encryption_sequencer _ -> true | Rpc mode -> from_node mode - | Proxy _ -> Test.fail "cannot start a RPC node from a proxy node" + | Proxy -> Test.fail "cannot start a RPC node from a proxy node" in from_node evm_node.persistent_state.mode diff --git a/etherlink/tezt/lib/evm_node.mli b/etherlink/tezt/lib/evm_node.mli index b6c025fca104..65bc8313a4bc 100644 --- a/etherlink/tezt/lib/evm_node.mli +++ b/etherlink/tezt/lib/evm_node.mli @@ -118,10 +118,7 @@ type mode = proposals are forwarded, and from where preblocks are fetched. *) dal_slots : int list option; } - | Proxy of { - finalized_view : bool; - (** Expose the latest final block of the rollup instead of its current head *) - } + | Proxy | Rpc of mode (** Returns the mode of the EVM node. *) @@ -181,6 +178,8 @@ val wait_for_ready : ?timeout:float -> t -> unit Lwt.t [evm_node] has applied a blueprint locally for level [level]. *) val wait_for_blueprint_applied : ?timeout:float -> t -> int -> unit Lwt.t +val wait_for_blueprint_finalized : ?timeout:float -> t -> int -> unit Lwt.t + (** [wait_for_predownload_kernel ?timeout evm_node ~root_hash] waits until [evm_node] has download a kernel with [root_hash]. *) val wait_for_predownload_kernel : diff --git a/etherlink/tezt/lib/helpers.ml b/etherlink/tezt/lib/helpers.ml index 51c8db59d633..fcb2f4f31027 100644 --- a/etherlink/tezt/lib/helpers.ml +++ b/etherlink/tezt/lib/helpers.ml @@ -81,7 +81,7 @@ let produce_block ?(wait_on_blueprint_applied = true) ?timestamp evm_node = let next_evm_level ~evm_node ~sc_rollup_node ~client = match Evm_node.mode evm_node with - | Proxy _ -> + | Proxy -> let* _l1_level = next_rollup_node_level ~sc_rollup_node ~client in unit | Sequencer _ | Sandbox _ | Threshold_encryption_sequencer _ -> diff --git a/etherlink/tezt/lib/setup.ml b/etherlink/tezt/lib/setup.ml index 4e9498df57cc..f3620f6c53c0 100644 --- a/etherlink/tezt/lib/setup.ml +++ b/etherlink/tezt/lib/setup.ml @@ -320,7 +320,7 @@ let setup_sequencer ?block_storage_sqlite3 ?sequencer_rpc_port let* proxy = Evm_node.init ~patch_config - ~mode:(Proxy {finalized_view = false}) + ~mode:Proxy (Sc_rollup_node.endpoint sc_rollup_node) in return diff --git a/etherlink/tezt/tests/evm_rollup.ml b/etherlink/tezt/tests/evm_rollup.ml index 687493a46697..1e0cbdfcfaf7 100644 --- a/etherlink/tezt/tests/evm_rollup.ml +++ b/etherlink/tezt/tests/evm_rollup.ml @@ -442,7 +442,7 @@ let setup_evm_kernel ?additional_config ?(setup_kernel_root_hash = true) let* produce_block, evm_node = match setup_mode with | Setup_proxy -> - let mode = Evm_node.(Proxy {finalized_view = false}) in + let mode = Evm_node.Proxy in let* evm_node = Evm_node.init ~patch_config @@ -3151,9 +3151,7 @@ let gen_kernel_migration_test ~from ~to_ ?bootstrap_accounts ?chain_id in (* Load the EVM rollup's storage and sanity check results. *) let* evm_node = - Evm_node.init - ~mode:(Proxy {finalized_view = false}) - (Sc_rollup_node.endpoint evm_setup.sc_rollup_node) + Evm_node.init ~mode:Proxy (Sc_rollup_node.endpoint evm_setup.sc_rollup_node) in let endpoint = Evm_node.endpoint evm_node in let* sanity_check = @@ -3172,9 +3170,7 @@ let gen_kernel_migration_test ~from ~to_ ?bootstrap_accounts ?chain_id ~client:evm_setup.client in let* evm_node = - Evm_node.init - ~mode:(Proxy {finalized_view = false}) - (Sc_rollup_node.endpoint evm_setup.sc_rollup_node) + Evm_node.init ~mode:Proxy (Sc_rollup_node.endpoint evm_setup.sc_rollup_node) in let evm_setup = {evm_setup with evm_node} in (* Check the values after the upgrade with [sanity_check] results. *) diff --git a/etherlink/tezt/tests/evm_sequencer.ml b/etherlink/tezt/tests/evm_sequencer.ml index d90c8b0397d2..070aaaaec55f 100644 --- a/etherlink/tezt/tests/evm_sequencer.ml +++ b/etherlink/tezt/tests/evm_sequencer.ml @@ -3186,9 +3186,7 @@ let test_force_kernel_upgrade_too_early = (* Wait for the sequencer to publish its genesis block. *) let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in let* proxy = - Evm_node.init - ~mode:(Proxy {finalized_view = false}) - (Sc_rollup_node.endpoint sc_rollup_node) + Evm_node.init ~mode:Proxy (Sc_rollup_node.endpoint sc_rollup_node) in (* Assert the kernel version is the same at start up. *) @@ -3250,9 +3248,7 @@ let test_force_kernel_upgrade = (* Wait for the sequencer to publish its genesis block. *) let* () = bake_until_sync ~sc_rollup_node ~client ~sequencer ~proxy () in let* proxy = - Evm_node.init - ~mode:(Proxy {finalized_view = false}) - (Sc_rollup_node.endpoint sc_rollup_node) + Evm_node.init ~mode:Proxy (Sc_rollup_node.endpoint sc_rollup_node) in (* Assert the kernel version is the same at start up. *) @@ -6003,7 +5999,7 @@ let test_patch_kernel = in unit -let test_proxy_finalized_view = +let test_finalized_view = register_all ~kernels: [ @@ -6012,17 +6008,28 @@ let test_proxy_finalized_view = ] ~tags:["evm"; "finalized_view"] ~time_between_blocks:Nothing - ~title: - "--finalized-view of the proxy node returns the latest final block of \ - the sequencer" + ~title:"--finalized-view returns the latest final block of the sequencer" ~da_fee:Wei.zero @@ fun {sc_rollup_node; client; sequencer; proxy; _} _protocol -> (* Start a proxy node with --finalized-view enabled *) let* finalized_proxy = Evm_node.init - ~mode:(Proxy {finalized_view = true}) + ~patch_config: + JSON.( + fun json -> + put ("finalized_view", annotate ~origin:"" (`Bool true)) json) + ~mode:Proxy (Sc_rollup_node.endpoint sc_rollup_node) in + let* finalized_observer = + run_new_observer_node + ~patch_config: + JSON.( + fun json -> + put ("finalized_view", annotate ~origin:"" (`Bool true)) json) + ~sc_rollup_node + sequencer + in (* Produce a few EVM blocks *) let* _ = repeat 4 @@ fun () -> @@ -6047,18 +6054,34 @@ let test_proxy_finalized_view = consensus algorithm, so the finalized proxy does not have a head yet. *) let*@? _ = Rpc.block_number finalized_proxy in - (* We produce two more L1 blocks to finalize the L2 blocks. - 2 here is hardcoded because it’s Tenderbake magic number. *) + (* By default the stateful node assume the block 0 is finalized *) + let*@ finalized_block = Rpc.block_number finalized_observer in + Check.((finalized_block = 0l) int32) + ~error_msg: + "The stateful node should assume the block 0 is finalized, but %L is \ + returned" ; + + (* We produce more L1 blocks to finalize the L2 blocks and to give some time + to the EVM nodes to catch-up. *) let* _ = - repeat 2 @@ fun () -> + Evm_node.wait_for_blueprint_finalized + finalized_observer + (Int32.to_int sequencer_head) + and* _ = + repeat 3 @@ fun () -> let* _ = next_rollup_node_level ~sc_rollup_node ~client in unit in - let*@ _ = Rpc.block_number finalized_proxy in - Check.((proxy_head = sequencer_head) int32) + let*@ finalized_proxy_block = Rpc.block_number finalized_proxy in + let*@ finalized_observer_block = Rpc.block_number finalized_observer in + Check.((finalized_proxy_block = sequencer_head) int32) ~error_msg: "Finalized proxy head should be equal to sequencer head (%R), but is %L \ instead" ; + Check.((finalized_observer_block = sequencer_head) int32) + ~error_msg: + "Finalized observer head should be equal to sequencer head (%R), but is \ + %L instead" ; unit let test_finalized_block_param = @@ -6611,7 +6634,7 @@ let () = test_fa_bridge_feature_flag protocols ; test_trace_call protocols ; test_patch_kernel protocols ; - test_proxy_finalized_view protocols ; + test_finalized_view protocols ; test_finalized_block_param protocols ; test_regression_block_hash_gen protocols ; test_sequencer_sandbox () ; diff --git a/etherlink/tezt/tests/expected/evm_sequencer.ml/Alpha- Configuration RPC.out b/etherlink/tezt/tests/expected/evm_sequencer.ml/Alpha- Configuration RPC.out index 85394d5c77c5..4206583c3435 100644 --- a/etherlink/tezt/tests/expected/evm_sequencer.ml/Alpha- Configuration RPC.out +++ b/etherlink/tezt/tests/expected/evm_sequencer.ml/Alpha- Configuration RPC.out @@ -18,7 +18,6 @@ "overwrite_simulation_tick_limit": false }, "proxy": { - "finalized_view": false, "ignore_block_param": false }, "fee_history": {}, @@ -33,7 +32,8 @@ "batch_limit": "unlimited", "restricted_rpcs": "unrestricted", "max_active_connections": "unlimited" - } + }, + "finalized_view": false } { "log_filter": { @@ -66,7 +66,6 @@ "overwrite_simulation_tick_limit": false }, "proxy": { - "finalized_view": false, "ignore_block_param": false }, "fee_history": {}, @@ -81,7 +80,8 @@ "batch_limit": "unlimited", "restricted_rpcs": "unrestricted", "max_active_connections": "unlimited" - } + }, + "finalized_view": false } { "log_filter": { @@ -107,7 +107,7 @@ "overwrite_simulation_tick_limit": false }, "proxy": { - "finalized_view": false, + "evm_node_endpoint": "hidden", "ignore_block_param": false }, "fee_history": {}, @@ -122,5 +122,6 @@ "batch_limit": "unlimited", "restricted_rpcs": "unrestricted", "max_active_connections": "unlimited" - } + }, + "finalized_view": false } diff --git a/etherlink/tezt/tests/expected/evm_sequencer.ml/EVM Node- describe config.out b/etherlink/tezt/tests/expected/evm_sequencer.ml/EVM Node- describe config.out index be3579c67c7c..f5872aef23b1 100644 --- a/etherlink/tezt/tests/expected/evm_sequencer.ml/EVM Node- describe config.out +++ b/etherlink/tezt/tests/expected/evm_sequencer.ml/EVM Node- describe config.out @@ -135,7 +135,12 @@ frontend does to prepare swaps). However, it can lead to confusing UX for users, where eth_estimateGas fails when eth_call succeeded. */ }, "proxy"?: - { "finalized_view"?: boolean, + { "finalized_view"?: + boolean + /* When enabled, the node only expose blocks that are finalized, + i.e., the `latest` block parameter becomes a synonym for + `finalized`. DEPRECATED: use the top level `finalized_view` option + instead. */, "evm_node_endpoint"?: $unistring, "ignore_block_param"?: boolean }, "fee_history"?: @@ -224,7 +229,11 @@ || { /* blacklist The list of JSON RPC API methods disallowed for this server. */ "blacklist": [ $unistring ... ] }, - "max_active_connections"?: $max_active_rpc_connections } } + "max_active_connections"?: $max_active_rpc_connections }, + "finalized_view"?: + boolean + /* When enabled, the node only expose blocks that are finalized, i.e., + the `latest` block parameter becomes a synonym for `finalized`. */ } $int64: /* 64 bit integers Decimal representation of 64 bit integers */ diff --git a/etherlink/tezt/tests/expected/evm_sequencer.ml/EVM Node- man.out b/etherlink/tezt/tests/expected/evm_sequencer.ml/EVM Node- man.out index 6cc6a8d0f15a..edd5458fdf7f 100644 --- a/etherlink/tezt/tests/expected/evm_sequencer.ml/EVM Node- man.out +++ b/etherlink/tezt/tests/expected/evm_sequencer.ml/EVM Node- man.out @@ -45,7 +45,7 @@ Miscellaneous commands: [--tx-pool-addr-limit <4_000>] [--tx-pool-tx-per-addr-limit <16>] [-v --verbose] [--restricted-rpcs ] [--blacklisted-rpcs ] [--whitelisted-rpcs ] - [--preimages-dir <_evm_installer_preimages>] + [--finalized-view] [--preimages-dir <_evm_installer_preimages>] [--preimages-endpoint ] [--time-between-blocks <10.>] [--max-number-of-chunks <10.>] [--private-rpc-port ] [--genesis-timestamp <[TIMESTAMP]>] @@ -70,6 +70,7 @@ Miscellaneous commands: --restricted-rpcs : Disable methods that matches the given Perl-like regular expression. Cannot be used with --whitelisted-rpcs or --blacklisted-rpcs. --blacklisted-rpcs : Disable the RPC methods which are part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. --whitelisted-rpcs : Disable the RPC methods which are not part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. + --finalized-view: If the flag is set, the node will use the latest final state of the rollup, not its current HEAD, for any read-only operation. --preimages-dir <_evm_installer_preimages>: Path to the preimages directory --preimages-endpoint : The address of a service which provides pre-images for the rollup. Missing pre-images will be downloaded remotely if they are not already present on disk. --time-between-blocks <10.>: Interval (in seconds) at which the sequencer creates an empty block by default. If set to `none`, blocks are produced on demand only (see private method produceBlock). @@ -88,7 +89,7 @@ Miscellaneous commands: [--tx-pool-addr-limit <4_000>] [--tx-pool-tx-per-addr-limit <16>] [-v --verbose] [--restricted-rpcs ] [--blacklisted-rpcs ] [--whitelisted-rpcs ] - [--read-only] [--finalized-view] [--ignore-block-param] + [--finalized-view] [--read-only] [--ignore-block-param] [--evm-node-endpoint ] Start the EVM node in proxy mode. --data-dir : The path to the EVM node data directory @@ -109,8 +110,8 @@ Miscellaneous commands: --restricted-rpcs : Disable methods that matches the given Perl-like regular expression. Cannot be used with --whitelisted-rpcs or --blacklisted-rpcs. --blacklisted-rpcs : Disable the RPC methods which are part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. --whitelisted-rpcs : Disable the RPC methods which are not part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. + --finalized-view: If the flag is set, the node will use the latest final state of the rollup, not its current HEAD, for any read-only operation. --read-only: If the flag is set, the node refuses transactions - --finalized-view: If the flag is set, the node exposes a view of the latest final state of the rollup, not its current HEAD. --ignore-block-param: If the flag is set, the node in proxy mode ignores the block parameter submitted by the client and defaults to the latest block for unsupported blocks. --evm-node-endpoint : The address of an EVM node to connect to. @@ -122,7 +123,7 @@ Miscellaneous commands: [--tx-pool-timeout-limit <3_600>] [--tx-pool-addr-limit <4_000>] [--tx-pool-tx-per-addr-limit <16>] [-v --verbose] [--restricted-rpcs ] [--blacklisted-rpcs ] - [--whitelisted-rpcs ] + [--whitelisted-rpcs ] [--finalized-view] [--preimages-dir <_evm_installer_preimages>] [--preimages-endpoint ] [--time-between-blocks <10.>] [--max-number-of-chunks <10.>] [--private-rpc-port ] @@ -152,6 +153,7 @@ Miscellaneous commands: --restricted-rpcs : Disable methods that matches the given Perl-like regular expression. Cannot be used with --whitelisted-rpcs or --blacklisted-rpcs. --blacklisted-rpcs : Disable the RPC methods which are part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. --whitelisted-rpcs : Disable the RPC methods which are not part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. + --finalized-view: If the flag is set, the node will use the latest final state of the rollup, not its current HEAD, for any read-only operation. --preimages-dir <_evm_installer_preimages>: Path to the preimages directory --preimages-endpoint : The address of a service which provides pre-images for the rollup. Missing pre-images will be downloaded remotely if they are not already present on disk. --time-between-blocks <10.>: Interval (in seconds) at which the sequencer creates an empty block by default. If set to `none`, blocks are produced on demand only (see private method produceBlock). @@ -176,7 +178,7 @@ Miscellaneous commands: [--tx-pool-timeout-limit <3_600>] [--tx-pool-addr-limit <4_000>] [--tx-pool-tx-per-addr-limit <16>] [-v --verbose] [--restricted-rpcs ] [--blacklisted-rpcs ] - [--whitelisted-rpcs ] + [--whitelisted-rpcs ] [--finalized-view] [--preimages-dir <_evm_installer_preimages>] [--preimages-endpoint ] [--time-between-blocks <10.>] [--max-number-of-chunks <10.>] [--private-rpc-port ] @@ -207,6 +209,7 @@ Miscellaneous commands: --restricted-rpcs : Disable methods that matches the given Perl-like regular expression. Cannot be used with --whitelisted-rpcs or --blacklisted-rpcs. --blacklisted-rpcs : Disable the RPC methods which are part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. --whitelisted-rpcs : Disable the RPC methods which are not part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. + --finalized-view: If the flag is set, the node will use the latest final state of the rollup, not its current HEAD, for any read-only operation. --preimages-dir <_evm_installer_preimages>: Path to the preimages directory --preimages-endpoint : The address of a service which provides pre-images for the rollup. Missing pre-images will be downloaded remotely if they are not already present on disk. --time-between-blocks <10.>: Interval (in seconds) at which the sequencer creates an empty block by default. If set to `none`, blocks are produced on demand only (see private method produceBlock). @@ -232,8 +235,8 @@ Miscellaneous commands: [--tx-pool-timeout-limit <3_600>] [--tx-pool-addr-limit <4_000>] [--tx-pool-tx-per-addr-limit <16>] [-v --verbose] [--restricted-rpcs ] [--blacklisted-rpcs ] - [--whitelisted-rpcs ] [--evm-node-endpoint ] - [--bundler-node-endpoint ] + [--whitelisted-rpcs ] [--finalized-view] + [--evm-node-endpoint ] [--bundler-node-endpoint ] [--preimages-dir <_evm_installer_preimages>] [--preimages-endpoint ] [--initial-kernel ] [--dont-track-rollup-node] [--no-sync] @@ -256,6 +259,7 @@ Miscellaneous commands: --restricted-rpcs : Disable methods that matches the given Perl-like regular expression. Cannot be used with --whitelisted-rpcs or --blacklisted-rpcs. --blacklisted-rpcs : Disable the RPC methods which are part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. --whitelisted-rpcs : Disable the RPC methods which are not part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. + --finalized-view: If the flag is set, the node will use the latest final state of the rollup, not its current HEAD, for any read-only operation. --evm-node-endpoint : The address of an EVM node to connect to. --bundler-node-endpoint : The address of a service which encrypts incoming transactions for the rollup. --preimages-dir <_evm_installer_preimages>: Path to the preimages directory @@ -272,7 +276,8 @@ Miscellaneous commands: [--tx-pool-timeout-limit <3_600>] [--tx-pool-addr-limit <4_000>] [--tx-pool-tx-per-addr-limit <16>] [-v --verbose] [--restricted-rpcs ] [--blacklisted-rpcs ] - [--whitelisted-rpcs ] [--evm-node-endpoint ] + [--whitelisted-rpcs ] [--finalized-view] + [--evm-node-endpoint ] [--preimages-dir <_evm_installer_preimages>] [--preimages-endpoint ] Start the EVM node in sequencer mode @@ -294,6 +299,7 @@ Miscellaneous commands: --restricted-rpcs : Disable methods that matches the given Perl-like regular expression. Cannot be used with --whitelisted-rpcs or --blacklisted-rpcs. --blacklisted-rpcs : Disable the RPC methods which are part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. --whitelisted-rpcs : Disable the RPC methods which are not part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. + --finalized-view: If the flag is set, the node will use the latest final state of the rollup, not its current HEAD, for any read-only operation. --evm-node-endpoint : The address of an EVM node to connect to. --preimages-dir <_evm_installer_preimages>: Path to the preimages directory --preimages-endpoint : The address of a service which provides pre-images for the rollup. Missing pre-images will be downloaded remotely if they are not already present on disk. @@ -379,7 +385,7 @@ Miscellaneous commands: [--tx-pool-addr-limit <4_000>] [--tx-pool-tx-per-addr-limit <16>] [-v --verbose] [--restricted-rpcs ] [--blacklisted-rpcs ] [--whitelisted-rpcs ] - [--preimages-dir <_evm_installer_preimages>] + [--finalized-view] [--preimages-dir <_evm_installer_preimages>] [--preimages-endpoint ] [--time-between-blocks <10.>] [--max-number-of-chunks <10.>] [--private-rpc-port ] [--sequencer-key ] [--maximum-blueprints-lag ] @@ -408,6 +414,7 @@ Miscellaneous commands: --restricted-rpcs : Disable methods that matches the given Perl-like regular expression. Cannot be used with --whitelisted-rpcs or --blacklisted-rpcs. --blacklisted-rpcs : Disable the RPC methods which are part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. --whitelisted-rpcs : Disable the RPC methods which are not part of the provided list. Cannot be used with --restricted-rpcs or --blacklisted-rpcs. + --finalized-view: If the flag is set, the node will use the latest final state of the rollup, not its current HEAD, for any read-only operation. --preimages-dir <_evm_installer_preimages>: Path to the preimages directory --preimages-endpoint : The address of a service which provides pre-images for the rollup. Missing pre-images will be downloaded remotely if they are not already present on disk. --time-between-blocks <10.>: Interval (in seconds) at which the sequencer creates an empty block by default. If set to `none`, blocks are produced on demand only (see private method produceBlock). diff --git a/src/bin_testnet_scenarios/evm_rollup.ml b/src/bin_testnet_scenarios/evm_rollup.ml index 489798bc7f83..5954fd8d9be5 100644 --- a/src/bin_testnet_scenarios/evm_rollup.ml +++ b/src/bin_testnet_scenarios/evm_rollup.ml @@ -133,10 +133,7 @@ let setup_evm_infra ~config ~operator ?runner ?preexisting_rollup let* current_level = Node.get_level node in let* _ = Sc_rollup_node.wait_for_level rollup_node current_level in let* evm_node = - Evm_node.init - ~mode:(Proxy {finalized_view = false}) - ?runner - (Sc_rollup_node.endpoint rollup_node) + Evm_node.init ~mode:Proxy ?runner (Sc_rollup_node.endpoint rollup_node) in Log.info "Node API is available at %s." (Evm_node.endpoint evm_node) ; return (rollup_address, rollup_node, evm_node) diff --git a/tezt/tests/cloud/dal.ml b/tezt/tests/cloud/dal.ml index af3ec6d16195..84623a1de708 100644 --- a/tezt/tests/cloud/dal.ml +++ b/tezt/tests/cloud/dal.ml @@ -1749,10 +1749,7 @@ let init_etherlink_operator_setup cloud configuration name ~bootstrap ~dal_slots } in let endpoint = Sc_rollup_node.endpoint sc_rollup_node in - let mode = - if is_sequencer then sequencer_mode - else Evm_node.Proxy {finalized_view = false} - in + let mode = if is_sequencer then sequencer_mode else Evm_node.Proxy in let* evm_node = Tezos.Evm_node.Agent.init ~name:(Format.asprintf "etherlink-%s-evm-node" name) -- GitLab