From b05a5d90ad85eda98ab8b68cf2029b85b10ca185 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Thu, 21 Aug 2025 18:15:22 +0200 Subject: [PATCH 1/3] EVM node: configuration performance_profile to change GC parameters Performance profile improves performances by reducing GC pauses at the cost of a slight increase in memory consumption. --- etherlink/bin_node/config/configuration.ml | 27 ++++++++-- etherlink/bin_node/config/configuration.mli | 5 ++ etherlink/bin_node/main.ml | 59 +++++++++++++++++++-- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/etherlink/bin_node/config/configuration.ml b/etherlink/bin_node/config/configuration.ml index 9e7db3293cfc..26d221ccb169 100644 --- a/etherlink/bin_node/config/configuration.ml +++ b/etherlink/bin_node/config/configuration.ml @@ -232,6 +232,8 @@ type rpc = { type db = {pool_size : int; max_conn_reuse_count : int option} +type performance_profile = Default | Performance + type t = { public_rpc : rpc; private_rpc : rpc option; @@ -252,6 +254,7 @@ type t = { db : db; opentelemetry : Octez_telemetry.Opentelemetry_config.t; tx_queue : tx_queue; + performance_profile : performance_profile; } let retrieve_chain_family ~l2_chains = @@ -421,6 +424,8 @@ let default_blueprints_publisher_config_with_dal = let default_fee_history = {max_count = Limit 1024; max_past = None} +let default_performance_profile = Default + let make_pattern_restricted_rpcs raw = Pattern {raw; regex = Re.Perl.compile_pat raw} @@ -1481,6 +1486,9 @@ let db_encoding = ~description:"Maximum number of times a connection can be reused" int31)) +let performance_profile_encoding = + Data_encoding.string_enum [("default", Default); ("performance", Performance)] + let encoding ?network data_dir : t Data_encoding.t = let open Data_encoding in let observer_field name encoding = @@ -1517,6 +1525,7 @@ let encoding ?network data_dir : t Data_encoding.t = db; opentelemetry; tx_queue; + performance_profile; } -> ( (log_filter, sequencer, observer), @@ -1538,7 +1547,8 @@ let encoding ?network data_dir : t Data_encoding.t = history_mode, db, opentelemetry, - tx_queue ) ) )) + tx_queue, + performance_profile ) ) )) (fun ( (log_filter, sequencer, observer), ( ( _tx_pool_timeout_limit, _tx_pool_addr_limit, @@ -1558,7 +1568,8 @@ let encoding ?network data_dir : t Data_encoding.t = history_mode, db, opentelemetry, - tx_queue ) ) ) + tx_queue, + performance_profile ) ) ) -> { public_rpc; @@ -1580,6 +1591,7 @@ let encoding ?network data_dir : t Data_encoding.t = db; opentelemetry; tx_queue; + performance_profile; }) (merge_objs (obj3 @@ -1636,7 +1648,7 @@ let encoding ?network data_dir : t Data_encoding.t = (dft "proxy" proxy_encoding (default_proxy ())) (dft "gcp_kms" gcp_kms_encoding default_gcp_kms) (dft "fee_history" fee_history_encoding default_fee_history)) - (obj9 + (obj10 (dft "kernel_execution" (kernel_execution_encoding ?network data_dir) @@ -1674,7 +1686,12 @@ let encoding ?network data_dir : t Data_encoding.t = "tx_pool" ~description:"Configuration for the tx pool" tx_queue_encoding - default_tx_queue)))) + default_tx_queue) + (dft + "performance_profile" + ~description:"Performance profile for EVM node GC" + performance_profile_encoding + default_performance_profile)))) let pp_print_json ~data_dir fmt config = let json = @@ -1924,6 +1941,7 @@ module Cli = struct db = default_db; opentelemetry = Octez_telemetry.Opentelemetry_config.default; tx_queue = default_tx_queue; + performance_profile = default_performance_profile; } let patch_kernel_execution_config kernel_execution ?preimages @@ -2151,6 +2169,7 @@ module Cli = struct db = configuration.db; opentelemetry; tx_queue; + performance_profile = configuration.performance_profile; } let create ~data_dir ?rpc_addr ?rpc_port ?rpc_batch_limit ?cors_origins diff --git a/etherlink/bin_node/config/configuration.mli b/etherlink/bin_node/config/configuration.mli index a412f5a91cfd..53f8af7290c5 100644 --- a/etherlink/bin_node/config/configuration.mli +++ b/etherlink/bin_node/config/configuration.mli @@ -202,6 +202,8 @@ type gcp_kms = { gcloud_path : string; } +type performance_profile = Default | Performance + type t = { public_rpc : rpc; private_rpc : rpc option; @@ -222,6 +224,7 @@ type t = { db : db; opentelemetry : Octez_telemetry.Opentelemetry_config.t; tx_queue : tx_queue; + performance_profile : performance_profile; } (** [chain_family_from_l2_chains t] returns the chain_family in @@ -239,6 +242,8 @@ val pp_history_mode_info : Format.formatter -> history_mode -> unit val native_execution_policy_encoding : native_execution_policy Data_encoding.t +val performance_profile_encoding : performance_profile Data_encoding.t + (** [encoding data_dir] is the encoding of {!t} based on data dir [data_dir]. If [encoding] is passed, some default values are set according to the diff --git a/etherlink/bin_node/main.ml b/etherlink/bin_node/main.ml index fdd19729cebb..db0d813ef378 100644 --- a/etherlink/bin_node/main.ml +++ b/etherlink/bin_node/main.ml @@ -30,10 +30,12 @@ open Configuration let config_env name = "EVM_NODE_" ^ name module Event = struct + include Internal_event.Simple + let section = ["evm_node"] let event_starting = - Internal_event.Simple.declare_1 + declare_1 ~section ~name:"start" ~msg:"starting the EVM node ({mode})" @@ -41,7 +43,7 @@ module Event = struct ("mode", Data_encoding.string) let sequencer_disabled_native_execution = - Internal_event.Simple.declare_0 + declare_0 ~section ~name:"sequencer_disabled_native_execution" ~msg:"native execution is disabled in sequencer mode" @@ -49,7 +51,7 @@ module Event = struct () let buggy_dream_websocket = - Internal_event.Simple.declare_0 + declare_0 ~section ~name:"dream_websocket" ~msg: @@ -57,6 +59,24 @@ module Event = struct as an RPC server or disabling websockets" ~level:Warning () + + let ignored_performance_profile = + declare_0 + ~section + ~name:"ignored_performance_profile" + ~msg: + "GC parameters were changed through OCAMLRUNPARAM, ignoring \ + performance profile" + ~level:Warning + () + + let performance_profile = + declare_1 + ~section + ~name:"performance_profile" + ~msg:"running with {profile} profile" + ~level:Notice + ("profile", Configuration.performance_profile_encoding) end module Params = struct @@ -979,6 +999,31 @@ let init_logs ~daily_logs ?rpc_mode_port ~data_dir configuration = in init ~config () +(** Performance GC parameters include: + - A minor heap size to 8M words, instead of 256k words by default + - A space overhead of 120%, which restores the default OCaml setting + from the one set in {!Tezos_base_unix.Event_loop.main_run}. + These settings reduce GC pauses for the EVM node at the cost of a + slight increase in memory consumption. +*) +let performance_gc_params = (8388608 (* 8M *), 120) + +let set_gc_parameters (config : Configuration.t) = + let open Lwt_syntax in + match + Tezos_base_unix.Gc_setup. + (get_ocamlrunparam_param "s", get_ocamlrunparam_param "o") + with + | Some _, _ | _, Some _ -> Event.(emit ignored_performance_profile) () + | None, None -> ( + let+ () = Event.(emit performance_profile) config.performance_profile in + match config.performance_profile with + | Default -> () + | Performance -> + let params = Gc.get () in + let minor_heap_size, space_overhead = performance_gc_params in + Gc.set {params with minor_heap_size; space_overhead}) + let start_proxy ~data_dir ~config_file ~keep_alive ?rpc_addr ?rpc_port ?rpc_batch_limit ?cors_origins ?cors_headers ?enable_websocket ?log_filter_max_nb_blocks ?log_filter_max_nb_logs ?log_filter_chunk_size @@ -1026,6 +1071,7 @@ let start_proxy ~data_dir ~config_file ~keep_alive ?rpc_addr ?rpc_port } in let*! () = init_logs ~daily_logs:true ~data_dir config in + let*! () = set_gc_parameters config in let*! () = Internal_event.Simple.emit Event.event_starting "proxy" in let* () = Evm_node_lib_dev.Proxy.main config in let wait, _resolve = Lwt.wait () in @@ -1168,6 +1214,7 @@ let start_sequencer ~wallet_ctxt ~data_dir ?sequencer_key ?rpc_addr ?rpc_port | _ -> Lwt.return configuration in let* () = websocket_checks configuration in + let*! () = set_gc_parameters configuration in let*! () = Internal_event.Simple.emit Event.event_starting "sequencer" in let* signer = @@ -1310,6 +1357,7 @@ let rpc_command = init_logs ~daily_logs:true ~rpc_mode_port:rpc_port ~data_dir config in let* () = websocket_checks config in + let*! () = set_gc_parameters config in let*! () = Internal_event.Simple.emit Event.event_starting "rpc" in Evm_node_lib_dev.Rpc.main ~data_dir @@ -1365,6 +1413,7 @@ let start_observer ~data_dir ~keep_alive ?rpc_addr ?rpc_port ?rpc_batch_limit in let*! () = init_logs ~daily_logs:true ~data_dir config in let* () = websocket_checks config in + let*! () = set_gc_parameters config in let*! () = Internal_event.Simple.emit Event.event_starting "observer" in Evm_node_lib_dev.Observer.main ?network @@ -1768,6 +1817,7 @@ let replay_many_command = config_file in let*! () = init_logs ~daily_logs:false ~data_dir configuration in + let*! () = set_gc_parameters configuration in Evm_node_lib_dev.Replay.main ~disable_da_fees ?kernel @@ -1818,6 +1868,7 @@ let replay_command = config_file in let*! () = init_logs ~daily_logs:false ~data_dir configuration in + let*! () = set_gc_parameters configuration in Evm_node_lib_dev.Replay.main ~disable_da_fees ?kernel @@ -2949,7 +3000,7 @@ let export_snapshot Configuration.Cli.create_or_read_config ~data_dir config_file in let*! () = init_logs ~daily_logs:false ~data_dir configuration in - + let*! () = set_gc_parameters configuration in let compression = match (compress_on_the_fly, uncompressed) with | true, true -> -- GitLab From 4268b2224a2c1275673226f0c55d651a384cabc3 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 22 Aug 2025 10:09:45 +0200 Subject: [PATCH 2/3] Tezt: regressions for EVM node config --- .../evm_sequencer.ml/Alpha- Configuration RPC.out | 9 ++++++--- .../evm_sequencer.ml/EVM Node- describe config.out | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) 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 71f2dbb4bf4a..25333dc8cf52 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 @@ -75,7 +75,8 @@ "max_transaction_batch_length": null, "max_lifespan": 4, "tx_per_addr_limit": "16" - } + }, + "performance_profile": "default" } { "log_filter": { @@ -154,7 +155,8 @@ "max_transaction_batch_length": null, "max_lifespan": 4, "tx_per_addr_limit": "16" - } + }, + "performance_profile": "default" } { "log_filter": { @@ -238,5 +240,6 @@ "max_transaction_batch_length": null, "max_lifespan": 4, "tx_per_addr_limit": "16" - } + }, + "performance_profile": "default" } 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 4ed91548788f..5372c6d907b4 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 @@ -361,7 +361,8 @@ "max_transaction_batch_length"?: integer ∈ [-2^30, 2^30] /* Some */ || null /* None */, "max_lifespan"?: integer ∈ [-2^30, 2^30], - "tx_per_addr_limit"?: $int64 } } + "tx_per_addr_limit"?: $int64 }, + "performance_profile"?: "performance" | "default" } $bignum: /* Big number Decimal representation of a big number */ -- GitLab From ec5c6db98bcba74c627ce04dedd9b56229a57be2 Mon Sep 17 00:00:00 2001 From: Alain Mebsout Date: Fri, 22 Aug 2025 14:56:33 +0200 Subject: [PATCH 3/3] Tezt: regressions for EVM node events --- .../EVM node- list events regression.out | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/etherlink/tezt/tests/expected/evm_rollup.ml/EVM node- list events regression.out b/etherlink/tezt/tests/expected/evm_rollup.ml/EVM node- list events regression.out index 8464212a1b59..23154d26e5c4 100644 --- a/etherlink/tezt/tests/expected/evm_rollup.ml/EVM node- list events regression.out +++ b/etherlink/tezt/tests/expected/evm_rollup.ml/EVM node- list events regression.out @@ -1124,6 +1124,14 @@ ignored_kernel_arg: { /* ignored_kernel_arg version 0 */ "ignored_kernel_arg.v0": any } +ignored_performance_profile: + description: GC parameters were changed through OCAMLRUNPARAM, ignoring performance profile + level: warning + section: evm_node + json format: + { /* ignored_performance_profile version 0 */ + "ignored_performance_profile.v0": any } + ignored_periodic_snapshot_arg: description: ignored the periodic snapshot feature since the EVM node is running in Archive mode level: warning @@ -1458,6 +1466,14 @@ pending_upgrade: contain invalid byte sequences. */ string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } +performance_profile: + description: running with {profile} profile + level: notice + section: evm_node + json format: + { /* performance_profile version 0 */ + "performance_profile.v0": "performance" | "default" } + predownload_kernel: description: kernel {version} successfully predownloaded level: notice -- GitLab