From a22eba97ee20aa10d3234b71ea4cd8ff567dd782 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Cauderlier?= Date: Tue, 12 Nov 2024 11:20:37 +0100 Subject: [PATCH 1/3] Revert "DEBUG: PathNotFound error" This reverts commit 9edeaa1638240fb1242fea5c9e8dfd591b6f5483. --- .../kernel_evm/evm_evaluation/src/evalhost.rs | 6 ++---- .../evm_execution/src/account_storage.rs | 2 +- etherlink/kernel_evm/evm_execution/src/lib.rs | 2 +- .../kernel_evm/indexable_storage/src/lib.rs | 2 +- etherlink/kernel_evm/kernel/src/block.rs | 2 +- .../kernel_evm/kernel/src/blueprint_storage.rs | 2 +- etherlink/kernel_evm/kernel/src/migration.rs | 4 ++-- .../kernel_evm/runtime/src/relative_runtime.rs | 3 +-- etherlink/kernel_evm/runtime/src/runtime.rs | 5 ++--- etherlink/kernel_evm/runtime/src/safe_storage.rs | 9 +++------ etherlink/kernel_evm/storage/src/lib.rs | 8 ++++---- src/kernel_sdk/host/src/runtime.rs | 16 ++++++++-------- src/kernel_sdk/storage/src/layer.rs | 2 +- src/kernel_sdk/storage/src/lib.rs | 2 +- 14 files changed, 29 insertions(+), 36 deletions(-) diff --git a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs index 1874941a2ee4..05c7cdb25ad0 100644 --- a/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs +++ b/etherlink/kernel_evm/evm_evaluation/src/evalhost.rs @@ -40,14 +40,12 @@ const WORLD_STATE_PATH: RefPath = RefPath::assert_from(b"/evm/world_state" const TRACE_PATH: RefPath = RefPath::assert_from(b"/evm/trace"); fn world_state_path(p: &impl Path) -> Result, RuntimeError> { - concat(&WORLD_STATE_PATH, p) - .map_err(|_| RuntimeError::PathNotFound(format!("{} + {}", WORLD_STATE_PATH, p))) + concat(&WORLD_STATE_PATH, p).map_err(|_| RuntimeError::PathNotFound) } fn trace_path(p: &TracePath) -> Result, RuntimeError> { let TracePath(p) = p; - concat(&TRACE_PATH, p) - .map_err(|_| RuntimeError::PathNotFound(format!("{} + {}", TRACE_PATH, p))) + concat(&TRACE_PATH, p).map_err(|_| RuntimeError::PathNotFound) } impl<'a> SdkRuntime for EvalHost<'a> { diff --git a/etherlink/kernel_evm/evm_execution/src/account_storage.rs b/etherlink/kernel_evm/evm_execution/src/account_storage.rs index e608be1ad671..ec13d19d44c7 100644 --- a/etherlink/kernel_evm/evm_execution/src/account_storage.rs +++ b/etherlink/kernel_evm/evm_execution/src/account_storage.rs @@ -472,7 +472,7 @@ impl EthereumAccount { // would be dead code. match host.store_read_all(&path) { Ok(bytes) => Ok(bytes), - Err(RuntimeError::PathNotFound(_)) => { + Err(RuntimeError::PathNotFound) => { let code_hash = self.code_hash(host)?; code_storage::CodeStorage::get_code(host, &code_hash).map_err(Into::into) } diff --git a/etherlink/kernel_evm/evm_execution/src/lib.rs b/etherlink/kernel_evm/evm_execution/src/lib.rs index 1ac4bf57cf7e..9687881bbe28 100755 --- a/etherlink/kernel_evm/evm_execution/src/lib.rs +++ b/etherlink/kernel_evm/evm_execution/src/lib.rs @@ -52,7 +52,7 @@ use trace::{ use crate::storage::tracer; -#[derive(Error, Clone, Debug, Eq, PartialEq)] +#[derive(Error, Clone, Copy, Debug, Eq, PartialEq)] pub enum DurableStorageError { /// Some runtime error happened while using durable storage #[error("Runtime error: {0:?}")] diff --git a/etherlink/kernel_evm/indexable_storage/src/lib.rs b/etherlink/kernel_evm/indexable_storage/src/lib.rs index a98a53293f59..8a83012e4b96 100644 --- a/etherlink/kernel_evm/indexable_storage/src/lib.rs +++ b/etherlink/kernel_evm/indexable_storage/src/lib.rs @@ -107,7 +107,7 @@ impl IndexableStorage { Ok(l) => Ok(l), Err( GenStorageError::Runtime( - RuntimeError::PathNotFound(_) + RuntimeError::PathNotFound | RuntimeError::HostErr(tezos_smart_rollup_host::Error::StoreNotAValue) | RuntimeError::HostErr( tezos_smart_rollup_host::Error::StoreInvalidAccess, diff --git a/etherlink/kernel_evm/kernel/src/block.rs b/etherlink/kernel_evm/kernel/src/block.rs index dfd0a67e72f4..54cba4f9ea79 100644 --- a/etherlink/kernel_evm/kernel/src/block.rs +++ b/etherlink/kernel_evm/kernel/src/block.rs @@ -466,7 +466,7 @@ fn promote_block>( store_last_block_timestamp(host, ¤t_timestamp)?; Ok(()) } - Err(Error::Storage(StorageError::Runtime(PathNotFound(_)))) => { + Err(Error::Storage(StorageError::Runtime(PathNotFound))) => { // Blueprint has already been dropped, this means that a // block at this level has already been promoted for // another chain id so next blueprint number and last diff --git a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs index ff3f0ed55682..ec47950756da 100644 --- a/etherlink/kernel_evm/kernel/src/blueprint_storage.rs +++ b/etherlink/kernel_evm/kernel/src/blueprint_storage.rs @@ -186,7 +186,7 @@ pub fn read_next_blueprint_number>( host: &Host, ) -> anyhow::Result { match read_u256_le(host, &NEXT_BLUEPRINT_NUMBER) { - Err(GenStorageError::Runtime(RuntimeError::PathNotFound(_))) => Ok(U256::zero()), + Err(GenStorageError::Runtime(RuntimeError::PathNotFound)) => Ok(U256::zero()), res => Ok(res?), } } diff --git a/etherlink/kernel_evm/kernel/src/migration.rs b/etherlink/kernel_evm/kernel/src/migration.rs index d32d17945de0..16e8fdb1ba5c 100644 --- a/etherlink/kernel_evm/kernel/src/migration.rs +++ b/etherlink/kernel_evm/kernel/src/migration.rs @@ -52,7 +52,7 @@ fn is_etherlink_network( ) -> Result { match read_chain_id(host) { Ok(chain_id) => Ok(chain_id == expected_chain_id.into()), - Err(Error::Storage(StorageError::Runtime(RuntimeError::PathNotFound(_)))) => { + Err(Error::Storage(StorageError::Runtime(RuntimeError::PathNotFound))) => { Ok(false) } Err(err) => Err(err), @@ -63,7 +63,7 @@ fn is_etherlink_network( pub fn allow_path_not_found(res: Result<(), RuntimeError>) -> Result<(), RuntimeError> { match res { Ok(()) => Ok(()), - Err(RuntimeError::PathNotFound(_)) => Ok(()), + Err(RuntimeError::PathNotFound) => Ok(()), Err(err) => Err(err), } } diff --git a/etherlink/kernel_evm/runtime/src/relative_runtime.rs b/etherlink/kernel_evm/runtime/src/relative_runtime.rs index fbdc7ab46590..67566309f0ed 100644 --- a/etherlink/kernel_evm/runtime/src/relative_runtime.rs +++ b/etherlink/kernel_evm/runtime/src/relative_runtime.rs @@ -25,8 +25,7 @@ impl RelativeRuntime { &self, path: &impl Path, ) -> Result, RuntimeError> { - concat(&self.root, path) - .map_err(|_| RuntimeError::PathNotFound(format!("{}+{}", self.root, path))) + concat(&self.root, path).map_err(|_| RuntimeError::PathNotFound) } } diff --git a/etherlink/kernel_evm/runtime/src/runtime.rs b/etherlink/kernel_evm/runtime/src/runtime.rs index 54db8cb2d5a9..1617b1d41ef4 100644 --- a/etherlink/kernel_evm/runtime/src/runtime.rs +++ b/etherlink/kernel_evm/runtime/src/runtime.rs @@ -375,9 +375,8 @@ impl, Host: BorrowMut + Borrow, Internal: InternalRunt src: &[u8], ) -> Result<(), RuntimeError> { let TracePath(path) = path; - let absolute_path = concat(&TRACE_PATH, path).map_err(|_| { - RuntimeError::PathNotFound(format!("{}+{}", TRACE_PATH, path)) - })?; + let absolute_path = + concat(&TRACE_PATH, path).map_err(|_| RuntimeError::PathNotFound)?; self.store_write_all(&absolute_path, src) } } diff --git a/etherlink/kernel_evm/runtime/src/safe_storage.rs b/etherlink/kernel_evm/runtime/src/safe_storage.rs index 79cd115cdc10..72ad5fd39ade 100644 --- a/etherlink/kernel_evm/runtime/src/safe_storage.rs +++ b/etherlink/kernel_evm/runtime/src/safe_storage.rs @@ -26,15 +26,12 @@ pub const TRACE_PATH: RefPath = RefPath::assert_from(b"/evm/trace"); pub const TMP_TRACE_PATH: RefPath = RefPath::assert_from(b"/tmp/evm/trace"); pub fn safe_path(path: &impl Path) -> Result, RuntimeError> { - concat(&TMP_WORLD_STATE_PATH, path).map_err(|_| { - RuntimeError::PathNotFound(format!("{} + {}", TMP_WORLD_STATE_PATH, path)) - }) + concat(&TMP_WORLD_STATE_PATH, path).map_err(|_| RuntimeError::PathNotFound) } pub fn safe_trace_path(path: &TracePath) -> Result, RuntimeError> { let TracePath(path) = path; - concat(&TMP_TRACE_PATH, path) - .map_err(|_| RuntimeError::PathNotFound(format!("{} + {}", TMP_TRACE_PATH, path))) + concat(&TMP_TRACE_PATH, path).map_err(|_| RuntimeError::PathNotFound) } pub struct SafeStorage { @@ -262,7 +259,7 @@ impl<'a, Host: Runtime> SafeStorage<&'a mut Host> { match self.host.store_copy(&self.root, &TMP_WORLD_STATE_PATH) { // PathNotFound error means that self.root is empty, the // first write under TMP_WORLD_STATE_PATH will create it. - Ok(()) | Err(RuntimeError::PathNotFound(_)) => Ok(()), + Ok(()) | Err(RuntimeError::PathNotFound) => Ok(()), err => err, } } diff --git a/etherlink/kernel_evm/storage/src/lib.rs b/etherlink/kernel_evm/storage/src/lib.rs index aafc594585cd..276e3a97efaf 100644 --- a/etherlink/kernel_evm/storage/src/lib.rs +++ b/etherlink/kernel_evm/storage/src/lib.rs @@ -70,7 +70,7 @@ pub fn read_h256_be_opt( ) -> Result, Error> { match host.store_read_all(path) { Ok(bytes) if bytes.len() == WORD_SIZE => Ok(Some(H256::from_slice(&bytes))), - Ok(_) | Err(RuntimeError::PathNotFound(_)) => Ok(None), + Ok(_) | Err(RuntimeError::PathNotFound) => Ok(None), Err(err) => Err(err.into()), } } @@ -123,7 +123,7 @@ pub fn read_u256_le_default( ) -> Result { match host.store_read_all(path) { Ok(bytes) if bytes.len() == WORD_SIZE => Ok(U256::from_little_endian(&bytes)), - Ok(_) | Err(RuntimeError::PathNotFound(_)) => Ok(default), + Ok(_) | Err(RuntimeError::PathNotFound) => Ok(default), Err(err) => Err(err.into()), } } @@ -169,7 +169,7 @@ pub fn read_u64_le_default( .map_err(|_| Error::Runtime(RuntimeError::DecodingError))?; Ok(u64::from_le_bytes(bytes_array)) } - Ok(_) | Err(RuntimeError::PathNotFound(_)) => Ok(default), + Ok(_) | Err(RuntimeError::PathNotFound) => Ok(default), Err(err) => Err(err.into()), } } @@ -192,7 +192,7 @@ pub fn read_u16_le_default( .map_err(|_| Error::Runtime(RuntimeError::DecodingError))?; Ok(u16::from_le_bytes(bytes_array)) } - Ok(_) | Err(RuntimeError::PathNotFound(_)) => Ok(default), + Ok(_) | Err(RuntimeError::PathNotFound) => Ok(default), Err(err) => Err(err.into()), } } diff --git a/src/kernel_sdk/host/src/runtime.rs b/src/kernel_sdk/host/src/runtime.rs index 93009036bac5..41df8f387796 100644 --- a/src/kernel_sdk/host/src/runtime.rs +++ b/src/kernel_sdk/host/src/runtime.rs @@ -30,11 +30,11 @@ use tezos_smart_rollup_core::smart_rollup_core::ReadInputMessageInfo; #[cfg(feature = "alloc")] use alloc::string::String; -#[derive(Eq, PartialEq, Clone, Debug)] +#[derive(Copy, Eq, PartialEq, Clone, Debug)] /// Errors that may be returned when called [Runtime] methods. pub enum RuntimeError { /// Attempted to read from/delete a key that does not exist. - PathNotFound(String), + PathNotFound, /// Attempted to get a subkey at an out-of-bounds index. StoreListIndexOutOfBounds, /// Errors returned by the host functions @@ -55,7 +55,7 @@ impl std::error::Error for RuntimeError { impl core::fmt::Display for RuntimeError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { - Self::PathNotFound(s) => write!(f, "RuntimeError::PathNotFound {}", s), + Self::PathNotFound => write!(f, "RuntimeError::PathNotFound"), Self::HostErr(e) => e.fmt(f), Self::DecodingError => write!(f, "RuntimeError::DecodingError"), Self::StoreListIndexOutOfBounds => { @@ -485,7 +485,7 @@ where fn store_delete>(&mut self, path: &T) -> Result<(), RuntimeError> { if let Ok(None) = Runtime::store_has(self, path) { - return Err(RuntimeError::PathNotFound(format!("{}", path))); + return Err(RuntimeError::PathNotFound); } let res = @@ -731,13 +731,13 @@ fn check_path_has_value<'a>( runtime: &'a impl Runtime, path: &'a impl Path, ) -> impl FnOnce(RuntimeError) -> RuntimeError + 'a { - move |err| { + |err| { if let Ok(Some(ValueType::Value | ValueType::ValueWithSubtree)) = runtime.store_has(path) { err } else { - RuntimeError::PathNotFound(format!("{}", path)) + RuntimeError::PathNotFound } } } @@ -746,11 +746,11 @@ fn check_path_exists<'a, T: Path>( runtime: &'a impl Runtime, path: &'a T, ) -> impl FnOnce(RuntimeError) -> RuntimeError + 'a { - move |err| { + |err| { if let Ok(Some(_)) = runtime.store_has(path) { err } else { - RuntimeError::PathNotFound(format!("{}", path)) + RuntimeError::PathNotFound } } } diff --git a/src/kernel_sdk/storage/src/layer.rs b/src/kernel_sdk/storage/src/layer.rs index f1fffed3a35a..324eae4a2e6e 100644 --- a/src/kernel_sdk/storage/src/layer.rs +++ b/src/kernel_sdk/storage/src/layer.rs @@ -65,7 +65,7 @@ impl>> Layer Ok(copy), + Ok(()) | Err(RuntimeError::PathNotFound) => Ok(copy), Err(e) => Err(e.into()), } } diff --git a/src/kernel_sdk/storage/src/lib.rs b/src/kernel_sdk/storage/src/lib.rs index ff3b0a45abd2..0993331f1448 100644 --- a/src/kernel_sdk/storage/src/lib.rs +++ b/src/kernel_sdk/storage/src/lib.rs @@ -14,7 +14,7 @@ use thiserror::Error; /// All errors that may occur when using the accoun transaction API. When /// the error variant encapsulates some other error type, this is where the /// error originates from the durable storage interface on the host runtime. -#[derive(Error, Eq, PartialEq, Clone, Debug)] +#[derive(Error, Copy, Eq, PartialEq, Clone, Debug)] pub enum StorageError { /// Invalid accounts path. Could not get the string representation of /// the accounts storage path. -- GitLab From 9f06770e36a9ee02096d2431719d9b83c4dcdf3d Mon Sep 17 00:00:00 2001 From: arnaud Date: Thu, 16 Jan 2025 13:46:16 +0100 Subject: [PATCH 2/3] Introduce l2_chain in configuration.ml and changes command in main.ml according to the new configuration.mli This commit should not change the behavior of the command --- etherlink/bin_node/config/configuration.ml | 242 +++++++++++------- etherlink/bin_node/config/configuration.mli | 83 +++--- .../bin_node/lib_dev/encodings/l2_chain_id.ml | 2 + .../lib_dev/encodings/l2_chain_id.mli | 2 + etherlink/bin_node/main.ml | 131 ++++++---- etherlink/tezt/tests/evm_sequencer.ml | 59 +++++ 6 files changed, 348 insertions(+), 171 deletions(-) diff --git a/etherlink/bin_node/config/configuration.ml b/etherlink/bin_node/config/configuration.ml index 4f022f6d5754..f2237607c30e 100644 --- a/etherlink/bin_node/config/configuration.ml +++ b/etherlink/bin_node/config/configuration.ml @@ -178,6 +178,11 @@ let default_data_dir = Filename.concat (Sys.getenv "HOME") ".octez-evm-node" let config_filename ~data_dir = Filename.concat data_dir "config.json" +let config_l2_filename ~data_dir id = + Filename.concat + data_dir + (Format.asprintf "config_l2_%a.json" L2_chain_id.pp id) + let default_rpc_addr = "127.0.0.1" let default_rpc_port = 8545 @@ -285,6 +290,17 @@ let default_blueprints_publisher_config_with_dal = let default_fee_history = {max_count = Limit 1024; max_past = None} +let default_l2_chain id = + { + id; + public_rpc = default_rpc (); + private_rpc = None; + tx_pool_timeout_limit = default_tx_pool_timeout_limit; + tx_pool_addr_limit = default_tx_pool_addr_limit; + tx_pool_tx_per_addr_limit = default_tx_pool_tx_per_addr_limit; + fee_history = default_fee_history; + } + let make_pattern_restricted_rpcs raw = Pattern {raw; regex = Re.Perl.compile_pat raw} @@ -1220,7 +1236,7 @@ let encoding ?network data_dir : t Data_encoding.t = kernel_execution; finalized_view; } -> - ( ( l2_chains, + ( ( List.map (fun l2_chain -> l2_chain.id) l2_chains, log_filter, sequencer, threshold_encryption_sequencer, @@ -1231,7 +1247,7 @@ let encoding ?network data_dir : t Data_encoding.t = experimental_features, proxy ), (kernel_execution, finalized_view) )) - (fun ( ( l2_chains, + (fun ( ( l2_chain_ids, log_filter, sequencer, threshold_encryption_sequencer, @@ -1243,7 +1259,7 @@ let encoding ?network data_dir : t Data_encoding.t = proxy ), (kernel_execution, finalized_view) ) -> { - l2_chains; + l2_chains = List.map default_l2_chain l2_chain_ids; log_filter; sequencer; threshold_encryption_sequencer; @@ -1258,7 +1274,7 @@ let encoding ?network data_dir : t Data_encoding.t = }) (merge_objs (obj10 - (req "l2_chains" (list l2_chain_encoding)) + (req "l2_chains" (list L2_chain_id.encoding)) (dft "log_filter" log_filter_config_encoding @@ -1331,6 +1347,19 @@ let save ~force ~data_dir config = let*! () = Lwt_utils_unix.create_dir data_dir in Lwt_utils_unix.Json.write_file config_file json +let save_l2 ~force ~data_dir config = + let open Lwt_result_syntax in + let json = Data_encoding.Json.construct l2_chain_encoding config in + let config_file = config_l2_filename ~data_dir config.id in + let*! exists = Lwt_unix.file_exists config_file in + if exists && not force then + failwith + "Configuration file %S already exists. Use --force to overwrite." + config_file + else + 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 @@ -1394,6 +1423,8 @@ let precheck json = return_unit) (fun _exn -> failwith "Syntax error in the configuration file") +let default_chain_id = L2_chain_id.from_int 1 + let load_file ?network ~data_dir path = let open Lwt_result_syntax in let* json = Lwt_utils_unix.Json.read_file path in @@ -1404,6 +1435,15 @@ let load_file ?network ~data_dir path = let load ?network ~data_dir () = load_file ?network ~data_dir (config_filename ~data_dir) +let load_l2_file path = + let open Lwt_result_syntax in + let* json = Lwt_utils_unix.Json.read_file path in + let* () = precheck json in + let l2_config = Data_encoding.Json.destruct l2_chain_encoding json in + return l2_config + +let load_l2 ~data_dir id = load_l2_file (config_l2_filename ~data_dir id) + let error_missing_config ~name = [error_of_fmt "missing %s config" name] let sequencer_config_exn {sequencer; _} = @@ -1431,17 +1471,9 @@ let preimages_endpoint_resolved network preimages_endpoint = (Option.map default_preimages_endpoint network) module Cli = struct - let create ~data_dir ~l2_chain_id ?rpc_addr ?rpc_port ?rpc_batch_limit - ?cors_origins ?cors_headers ?tx_pool_timeout_limit ?tx_pool_addr_limit - ?tx_pool_tx_per_addr_limit ~keep_alive ?rollup_node_endpoint - ?dont_track_rollup_node ~verbose ?preimages ?preimages_endpoint - ?native_execution_policy ?time_between_blocks ?max_number_of_chunks - ?private_rpc_port ?sequencer_key ?evm_node_endpoint - ?threshold_encryption_bundler_endpoint ?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 ~finalized_view - ?proxy_ignore_block_param ?dal_slots ?network () = + let create_l2 ~l2_chain_id ?rpc_addr ?rpc_port ?tx_pool_timeout_limit + ?restricted_rpcs ?rpc_batch_limit ?cors_origins ?cors_headers + ?tx_pool_addr_limit ?tx_pool_tx_per_addr_limit ?private_rpc_port () = let public_rpc = default_rpc ?rpc_port @@ -1455,6 +1487,31 @@ module Cli = struct let private_rpc = Option.map (fun port -> default_rpc ~rpc_port:port ()) private_rpc_port in + { + id = l2_chain_id; + public_rpc; + private_rpc; + tx_pool_timeout_limit = + Option.value + ~default:default_tx_pool_timeout_limit + tx_pool_timeout_limit; + tx_pool_addr_limit = + Option.value ~default:default_tx_pool_addr_limit tx_pool_addr_limit; + tx_pool_tx_per_addr_limit = + Option.value + ~default:default_tx_pool_tx_per_addr_limit + tx_pool_tx_per_addr_limit; + fee_history = default_fee_history; + } + + let create ~data_dir ~l2_chains ~keep_alive ?rollup_node_endpoint + ?dont_track_rollup_node ~verbose ?preimages ?preimages_endpoint + ?native_execution_policy ?time_between_blocks ?max_number_of_chunks + ?sequencer_key ?evm_node_endpoint ?threshold_encryption_bundler_endpoint + ?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 ~finalized_view + ?proxy_ignore_block_param ?dal_slots ?network () = let sequencer = Option.map (fun sequencer -> @@ -1522,26 +1579,6 @@ module Cli = struct ?native_execution_policy () in - let l2_chains = - [ - { - id = l2_chain_id; - public_rpc; - private_rpc; - tx_pool_timeout_limit = - Option.value - ~default:default_tx_pool_timeout_limit - tx_pool_timeout_limit; - tx_pool_addr_limit = - Option.value ~default:default_tx_pool_addr_limit tx_pool_addr_limit; - tx_pool_tx_per_addr_limit = - Option.value - ~default:default_tx_pool_tx_per_addr_limit - tx_pool_tx_per_addr_limit; - fee_history = default_fee_history; - }; - ] - in { l2_chains; log_filter; @@ -1586,7 +1623,7 @@ module Cli = struct Option.value ~default:rpc.max_active_connections max_active_connections; } - let patch_l2_chain_configuration_from_args ?id ?rpc_addr ?rpc_port + let patch_l2_chain_configuration_from_args ?rpc_addr ?rpc_port ?rpc_batch_limit ?cors_origins ?cors_headers ?tx_pool_timeout_limit ?tx_pool_addr_limit ?tx_pool_tx_per_addr_limit ?private_rpc_port ?restricted_rpcs configuration = @@ -1606,7 +1643,7 @@ module Cli = struct configuration.private_rpc in { - id = Option.value ~default:configuration.id id; + id = configuration.id; public_rpc; private_rpc; tx_pool_timeout_limit = @@ -1624,33 +1661,14 @@ module Cli = struct fee_history = configuration.fee_history; } - let patch_configuration_from_args ?l2_chain_id ?rpc_addr ?rpc_port - ?rpc_batch_limit ?cors_origins ?cors_headers ?tx_pool_timeout_limit - ?tx_pool_addr_limit ?tx_pool_tx_per_addr_limit ?native_execution_policy + let patch_configuration_from_args ?l2_chains ?native_execution_policy ~keep_alive ?rollup_node_endpoint ?dont_track_rollup_node ~verbose ?preimages ?preimages_endpoint ?time_between_blocks ?max_number_of_chunks - ?private_rpc_port ?sequencer_key ?evm_node_endpoint - ?threshold_encryption_bundler_endpoint ?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 ~finalized_view + ?sequencer_key ?evm_node_endpoint ?threshold_encryption_bundler_endpoint + ?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 ~finalized_view ?proxy_ignore_block_param ~dal_slots configuration = - let l2_chains = - List.map - (patch_l2_chain_configuration_from_args - ?id:l2_chain_id - ?rpc_addr - ?rpc_port - ?rpc_batch_limit - ?cors_origins - ?cors_headers - ?tx_pool_timeout_limit - ?tx_pool_addr_limit - ?tx_pool_tx_per_addr_limit - ?private_rpc_port - ?restricted_rpcs) - configuration.l2_chains - in let sequencer = let sequencer_config = configuration.sequencer in match sequencer_config with @@ -1854,9 +1872,8 @@ module Cli = struct ~default:configuration.rollup_node_endpoint rollup_node_endpoint in - { - l2_chains; + l2_chains = Option.value l2_chains ~default:configuration.l2_chains; log_filter; kernel_execution; sequencer; @@ -1870,17 +1887,72 @@ module Cli = struct finalized_view = finalized_view || configuration.finalized_view; } - let create_or_read_config ~data_dir ~l2_chain_id ?rpc_addr ?rpc_port - ?rpc_batch_limit ?cors_origins ?cors_headers ?tx_pool_timeout_limit - ?tx_pool_addr_limit ?tx_pool_tx_per_addr_limit ~keep_alive + let create_or_read_l2_config ~data_dir ~l2_chain_id ?rpc_addr ?rpc_port + ?restricted_rpcs ?rpc_batch_limit ?cors_headers ?cors_origins + ?tx_pool_addr_limit ?tx_pool_tx_per_addr_limit ?tx_pool_timeout_limit + ?private_rpc_port () = + 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 + node *) + let* () = + let*! identity_file_in_data_dir_exists = + Lwt_unix.file_exists (data_dir // "identity.json") + in + if identity_file_in_data_dir_exists then + failwith + "Invalid data directory. This is a data directory for an Octez node, \ + please choose a different directory for the EVM node data." + else return_unit + in + let config_file = config_l2_filename ~data_dir l2_chain_id in + let*! exists_config = Lwt_unix.file_exists config_file in + if exists_config then + (* Read configuration from file and patch if user wanted to override + some fields with values provided by arguments. *) + let* configuration = load_l2 ~data_dir l2_chain_id in + let configuration = + patch_l2_chain_configuration_from_args + ?rpc_addr + ?rpc_port + ?tx_pool_timeout_limit + ?tx_pool_addr_limit + ?tx_pool_tx_per_addr_limit + ?private_rpc_port + ?rpc_batch_limit + ?cors_origins + ?cors_headers + ?restricted_rpcs + configuration + in + return configuration + else + let config = + create_l2 + ~l2_chain_id + ?rpc_addr + ?rpc_port + ?tx_pool_timeout_limit + ?tx_pool_addr_limit + ?tx_pool_tx_per_addr_limit + ?private_rpc_port + ?rpc_batch_limit + ?cors_origins + ?cors_headers + ?restricted_rpcs + () + in + return config + + let create_or_read_config ~data_dir ~l2_chains ~keep_alive ?rollup_node_endpoint ?dont_track_rollup_node ~verbose ?preimages ?preimages_endpoint ?native_execution_policy ?time_between_blocks - ?max_number_of_chunks ?private_rpc_port ?sequencer_key ?evm_node_endpoint + ?max_number_of_chunks ?sequencer_key ?evm_node_endpoint ?threshold_encryption_bundler_endpoint ?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 ~finalized_view - ?proxy_ignore_block_param ?dal_slots ?network () = + ?sequencer_sidecar_endpoint ~finalized_view ?proxy_ignore_block_param + ?dal_slots ?network () = 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 @@ -1895,20 +1967,23 @@ module Cli = struct please choose a different directory for the EVM node data." else return_unit in + let*! l2_chains = + match l2_chains with + | `Ids l2_chain_ids -> + all @@ List.map (fun chain -> load_l2 ~data_dir chain) l2_chain_ids + | `Config l2_chains -> return l2_chains + in + let l2_chains = match l2_chains with Error _ -> [] | Ok l -> l in let config_file = config_filename ~data_dir in let*! exists_config = Lwt_unix.file_exists config_file in if exists_config then (* Read configuration from file and patch if user wanted to override some fields with values provided by arguments. *) let* configuration = load ?network ~data_dir () in + let l2_chains = match l2_chains with [] -> None | l -> Some l in let configuration = patch_configuration_from_args - ~l2_chain_id - ?rpc_addr - ?rpc_port - ?rpc_batch_limit - ?cors_origins - ?cors_headers + ?l2_chains ~keep_alive ?sequencer_key ?evm_node_endpoint @@ -1918,14 +1993,10 @@ module Cli = struct ?native_execution_policy ?time_between_blocks ?max_number_of_chunks - ?private_rpc_port ?max_blueprints_lag ?max_blueprints_ahead ?max_blueprints_catchup ?catchup_cooldown - ?tx_pool_timeout_limit - ?tx_pool_addr_limit - ?tx_pool_tx_per_addr_limit ?rollup_node_endpoint ?dont_track_rollup_node ~verbose @@ -1933,7 +2004,6 @@ module Cli = struct ?log_filter_max_nb_logs ?log_filter_chunk_size ?sequencer_sidecar_endpoint - ?restricted_rpcs ~finalized_view ?proxy_ignore_block_param ~dal_slots @@ -1944,12 +2014,7 @@ module Cli = struct let config = create ~data_dir - ~l2_chain_id - ?rpc_addr - ?rpc_port - ?rpc_batch_limit - ?cors_origins - ?cors_headers + ~l2_chains ~keep_alive ?sequencer_key ?evm_node_endpoint @@ -1959,14 +2024,10 @@ module Cli = struct ?native_execution_policy ?time_between_blocks ?max_number_of_chunks - ?private_rpc_port ?max_blueprints_lag ?max_blueprints_ahead ?max_blueprints_catchup ?catchup_cooldown - ?tx_pool_timeout_limit - ?tx_pool_addr_limit - ?tx_pool_tx_per_addr_limit ?rollup_node_endpoint ?dont_track_rollup_node ~verbose @@ -1974,7 +2035,6 @@ module Cli = struct ?log_filter_max_nb_logs ?log_filter_chunk_size ?sequencer_sidecar_endpoint - ?restricted_rpcs ~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 abda3c1ac8f6..633ef660eb17 100644 --- a/etherlink/bin_node/config/configuration.mli +++ b/etherlink/bin_node/config/configuration.mli @@ -204,6 +204,11 @@ val config_filename : data_dir:string -> string are overwritten. *) val save : force:bool -> data_dir:string -> t -> unit tzresult Lwt.t +(** [save ~force ~data_dir configuration] writes the [configuration] + file in [data_dir]. If [force] is [true], existing configurations + are overwritten. *) +val save_l2 : force:bool -> data_dir:string -> l2_chain -> unit tzresult Lwt.t + val load_file : ?network:supported_network -> data_dir:string -> string -> t tzresult Lwt.t @@ -211,6 +216,9 @@ val load_file : val load : ?network:supported_network -> data_dir:string -> unit -> t tzresult Lwt.t +(* [default_chain_id] is the default chain_id and will be used by the command that are not multichain *) +val default_chain_id : L2_chain_id.t + (** [sequencer_config_exn config] returns the sequencer config of [config] or fails *) val sequencer_config_exn : t -> sequencer tzresult @@ -265,17 +273,24 @@ val observer_config_dft : val make_pattern_restricted_rpcs : string -> restricted_rpcs module Cli : sig + (* val create_l2 : + l2_chain_id:L2_chain_id.t -> + ?rpc_addr:string -> + ?rpc_port:int -> + ?tx_pool_timeout_limit:int64 -> + ?restricted_rpcs:restricted_rpcs -> + ?rpc_batch_limit:limit -> + ?cors_origins:string trace -> + ?cors_headers:string trace -> + ?tx_pool_addr_limit:int64 -> + ?tx_pool_tx_per_addr_limit:int64 -> + ?private_rpc_port:int -> + unit -> + l2_chain *) + val create : data_dir:string -> - l2_chain_id:L2_chain_id.t -> - ?rpc_addr:string -> - ?rpc_port:int -> - ?rpc_batch_limit:limit -> - ?cors_origins:string list -> - ?cors_headers:string list -> - ?tx_pool_timeout_limit:int64 -> - ?tx_pool_addr_limit:int64 -> - ?tx_pool_tx_per_addr_limit:int64 -> + l2_chains:l2_chain trace -> keep_alive:bool -> ?rollup_node_endpoint:Uri.t -> ?dont_track_rollup_node:bool -> @@ -285,7 +300,6 @@ module Cli : sig ?native_execution_policy:native_execution_policy -> ?time_between_blocks:time_between_blocks -> ?max_number_of_chunks:int -> - ?private_rpc_port:int -> ?sequencer_key:Client_keys.sk_uri -> ?evm_node_endpoint:Uri.t -> ?threshold_encryption_bundler_endpoint:Uri.t -> @@ -297,24 +311,15 @@ module Cli : sig ?max_blueprints_catchup:int -> ?catchup_cooldown:int -> ?sequencer_sidecar_endpoint:Uri.t -> - ?restricted_rpcs:restricted_rpcs -> finalized_view:bool -> ?proxy_ignore_block_param:bool -> - ?dal_slots:int list -> + ?dal_slots:int trace -> ?network:supported_network -> unit -> t val patch_configuration_from_args : - ?l2_chain_id:L2_chain_id.t -> - ?rpc_addr:string -> - ?rpc_port:int -> - ?rpc_batch_limit:limit -> - ?cors_origins:string trace -> - ?cors_headers:string trace -> - ?tx_pool_timeout_limit:int64 -> - ?tx_pool_addr_limit:int64 -> - ?tx_pool_tx_per_addr_limit:int64 -> + ?l2_chains:l2_chain list -> ?native_execution_policy:native_execution_policy -> keep_alive:bool -> ?rollup_node_endpoint:Uri.t -> @@ -324,7 +329,6 @@ module Cli : sig ?preimages_endpoint:Uri.t -> ?time_between_blocks:time_between_blocks -> ?max_number_of_chunks:int -> - ?private_rpc_port:int -> ?sequencer_key:Client_keys.sk_uri -> ?evm_node_endpoint:Uri.t -> ?threshold_encryption_bundler_endpoint:Uri.t -> @@ -336,16 +340,13 @@ module Cli : sig ?max_blueprints_catchup:int -> ?catchup_cooldown:int -> ?sequencer_sidecar_endpoint:Uri.t -> - ?restricted_rpcs:restricted_rpcs -> finalized_view:bool -> ?proxy_ignore_block_param:bool -> dal_slots:int trace option -> t -> t - val create_or_read_config : - data_dir:string -> - l2_chain_id:L2_chain_id.t -> + val patch_l2_chain_configuration_from_args : ?rpc_addr:string -> ?rpc_port:int -> ?rpc_batch_limit:limit -> @@ -354,6 +355,30 @@ module Cli : sig ?tx_pool_timeout_limit:int64 -> ?tx_pool_addr_limit:int64 -> ?tx_pool_tx_per_addr_limit:int64 -> + ?private_rpc_port:int -> + ?restricted_rpcs:restricted_rpcs -> + l2_chain -> + l2_chain + + val create_or_read_l2_config : + data_dir:string -> + l2_chain_id:L2_chain_id.t -> + ?rpc_addr:string -> + ?rpc_port:int -> + ?restricted_rpcs:restricted_rpcs -> + ?rpc_batch_limit:limit -> + ?cors_headers:string trace -> + ?cors_origins:string trace -> + ?tx_pool_addr_limit:int64 -> + ?tx_pool_tx_per_addr_limit:int64 -> + ?tx_pool_timeout_limit:int64 -> + ?private_rpc_port:int -> + unit -> + (l2_chain, tztrace) result Lwt.t + + val create_or_read_config : + data_dir:string -> + l2_chains:[`Ids of L2_chain_id.t list | `Config of l2_chain list] -> keep_alive:bool -> ?rollup_node_endpoint:Uri.t -> ?dont_track_rollup_node:bool -> @@ -363,7 +388,6 @@ module Cli : sig ?native_execution_policy:native_execution_policy -> ?time_between_blocks:time_between_blocks -> ?max_number_of_chunks:int -> - ?private_rpc_port:int -> ?sequencer_key:Client_keys.sk_uri -> ?evm_node_endpoint:Uri.t -> ?threshold_encryption_bundler_endpoint:Uri.t -> @@ -375,13 +399,12 @@ module Cli : sig ?log_filter_max_nb_logs:int -> ?log_filter_chunk_size:int -> ?sequencer_sidecar_endpoint:Uri.t -> - ?restricted_rpcs:restricted_rpcs -> finalized_view:bool -> ?proxy_ignore_block_param:bool -> - ?dal_slots:int list -> + ?dal_slots:int trace -> ?network:supported_network -> unit -> - t tzresult Lwt.t + (t, tztrace) result Lwt.t end val time_between_blocks_encoding : time_between_blocks Data_encoding.t diff --git a/etherlink/bin_node/lib_dev/encodings/l2_chain_id.ml b/etherlink/bin_node/lib_dev/encodings/l2_chain_id.ml index 5c91d550ab73..8cf3753ec837 100644 --- a/etherlink/bin_node/lib_dev/encodings/l2_chain_id.ml +++ b/etherlink/bin_node/lib_dev/encodings/l2_chain_id.ml @@ -40,6 +40,8 @@ let hash = Hashtbl.hash let from_int x = Z.of_int x +let compare = Z.compare + let to_z x = x let from_z x = x diff --git a/etherlink/bin_node/lib_dev/encodings/l2_chain_id.mli b/etherlink/bin_node/lib_dev/encodings/l2_chain_id.mli index 2d4e4518b9d3..262f966f13e4 100644 --- a/etherlink/bin_node/lib_dev/encodings/l2_chain_id.mli +++ b/etherlink/bin_node/lib_dev/encodings/l2_chain_id.mli @@ -16,6 +16,8 @@ val pp : Format.formatter -> t -> unit val equal : t -> t -> bool +val compare : t -> t -> int + val hash : t -> int val from_int : int -> t diff --git a/etherlink/bin_node/main.ml b/etherlink/bin_node/main.ml index 92841d2f1599..8a343f7b5567 100644 --- a/etherlink/bin_node/main.ml +++ b/etherlink/bin_node/main.ml @@ -771,25 +771,31 @@ let start_proxy ~data_dir ~keep_alive ~l2_chain_id ?rpc_addr ?rpc_port ?tx_pool_tx_per_addr_limit ?restricted_rpcs ~verbose ~read_only ~finalized_view ~ignore_block_param () = let open Lwt_result_syntax in - let* config = - Cli.create_or_read_config + let* l2_config = + Cli.create_or_read_l2_config ~data_dir ~l2_chain_id - ~keep_alive ?rpc_addr ?rpc_port ?rpc_batch_limit ?cors_origins ?cors_headers + ?tx_pool_addr_limit + ?tx_pool_timeout_limit + ?tx_pool_tx_per_addr_limit + ?restricted_rpcs + () + in + let* config = + Cli.create_or_read_config + ~data_dir + ~l2_chains:(`Config [l2_config]) + ~keep_alive ?log_filter_max_nb_blocks ?log_filter_max_nb_logs ?log_filter_chunk_size ?rollup_node_endpoint ?evm_node_endpoint - ?tx_pool_timeout_limit - ?tx_pool_addr_limit - ?tx_pool_tx_per_addr_limit - ?restricted_rpcs ~finalized_view ~proxy_ignore_block_param:ignore_block_param ~verbose @@ -884,8 +890,8 @@ let start_sequencer ?password_filename ~wallet_dir ~data_dir ~l2_chain_id (Client_keys.Secret_key.parse_source_string wallet_ctxt) sequencer_str in - let* configuration = - Cli.create_or_read_config + let* l2_config = + Cli.create_or_read_l2_config ~data_dir ~l2_chain_id ?rpc_addr @@ -893,9 +899,17 @@ let start_sequencer ?password_filename ~wallet_dir ~data_dir ~l2_chain_id ?rpc_batch_limit ?cors_origins ?cors_headers - ?tx_pool_timeout_limit ?tx_pool_addr_limit + ?tx_pool_timeout_limit ?tx_pool_tx_per_addr_limit + ?restricted_rpcs + ?private_rpc_port + () + in + let* configuration = + Cli.create_or_read_config + ~data_dir + ~l2_chains:(`Config [l2_config]) ~keep_alive ?rollup_node_endpoint ~verbose @@ -904,7 +918,6 @@ let start_sequencer ?password_filename ~wallet_dir ~data_dir ~l2_chain_id ?native_execution_policy ?time_between_blocks ?max_number_of_chunks - ?private_rpc_port ?sequencer_key ?max_blueprints_lag ?max_blueprints_ahead @@ -913,7 +926,6 @@ let start_sequencer ?password_filename ~wallet_dir ~data_dir ~l2_chain_id ?log_filter_max_nb_blocks ?log_filter_max_nb_logs ?log_filter_chunk_size - ?restricted_rpcs ?dal_slots ~finalized_view () @@ -968,7 +980,6 @@ let rpc_run_args = let rpc_command = let open Lwt_result_syntax in let open Tezos_clic in - let open Evm_node_lib_dev_encoding in command ~desc:"Start the EVM node in sequencer mode" (merge_options common_config_args rpc_run_args) @@ -1009,6 +1020,7 @@ let rpc_command = when_ Option.(is_some rollup_node_endpoint) @@ fun () -> failwith "unexpected --rollup-node-endpoint argument" in + let l2_chain_id = Configuration.default_chain_id in let* read_write_config = (* We read the configuration used for the read-write node, without altering it ([keep_alive] and [verbose] are @@ -1019,7 +1031,7 @@ let rpc_command = connect to the read-write node. *) Cli.create_or_read_config ~data_dir - ~l2_chain_id:(L2_chain_id.from_int 1) + ~l2_chains:(`Ids [l2_chain_id]) ~keep_alive ~verbose ~finalized_view @@ -1050,25 +1062,30 @@ let rpc_command = ~port:l2_chain_config.public_rpc.port () in - let config = - Cli.patch_configuration_from_args - ~keep_alive + let l2_chain_config = + Cli.patch_l2_chain_configuration_from_args ?cors_origins ?cors_headers ?rpc_batch_limit + ?tx_pool_timeout_limit + ?tx_pool_addr_limit + ?tx_pool_tx_per_addr_limit + ?restricted_rpcs + ~rpc_port + ?rpc_addr + l2_chain_config + in + let config = + Cli.patch_configuration_from_args + ~l2_chains:[l2_chain_config] + ~keep_alive ~verbose ?preimages ?preimages_endpoint ?native_execution_policy - ?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 - ~rpc_port - ?rpc_addr ~dal_slots:None read_write_config ~finalized_view @@ -1111,17 +1128,27 @@ let start_observer ~data_dir ~l2_chain_id ~keep_alive ?rpc_addr ?rpc_port ?log_filter_max_nb_logs ?log_filter_max_nb_blocks ?restricted_rpcs ?kernel ~no_sync ~init_from_snapshot ~finalized_view ?network () = let open Lwt_result_syntax in - let* config = - Cli.create_or_read_config + let* l2_config = + Cli.create_or_read_l2_config ~data_dir ~l2_chain_id - ~keep_alive ?rpc_addr ?rpc_port - ?private_rpc_port ?rpc_batch_limit ?cors_origins ?cors_headers + ?tx_pool_addr_limit + ?tx_pool_timeout_limit + ?tx_pool_tx_per_addr_limit + ?restricted_rpcs + ?private_rpc_port + () + in + let* config = + Cli.create_or_read_config + ~data_dir + ~l2_chains:(`Config [l2_config]) + ~keep_alive ?rollup_node_endpoint ?dont_track_rollup_node: (* If `dont_track_rollup_node` is false, it means the argument was @@ -1134,13 +1161,9 @@ let start_observer ~data_dir ~l2_chain_id ~keep_alive ?rpc_addr ?rpc_port ?native_execution_policy ?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 ?dal_slots:None ~finalized_view ?network @@ -1381,7 +1404,6 @@ let make_sequencer_upgrade_command = let init_from_rollup_node_command = let open Tezos_clic in - let open Evm_node_lib_dev_encoding in let rollup_node_data_dir_param = Tezos_clic.param ~name:"rollup-node-data-dir" @@ -1396,10 +1418,11 @@ let init_from_rollup_node_command = @@ rollup_node_data_dir_param @@ stop) (fun (data_dir, omit_delayed_tx_events) rollup_node_data_dir () -> let open Lwt_result_syntax in + let l2_chain_id = Configuration.default_chain_id in let* configuration = Cli.create_or_read_config ~data_dir - ~l2_chain_id:(L2_chain_id.from_int 0) + ~l2_chains:(`Ids [l2_chain_id]) ~keep_alive:false ~verbose:false ~finalized_view:false @@ -1485,7 +1508,6 @@ let reset_command = let replay_command = let open Tezos_clic in - let open Evm_node_lib_dev_encoding in command ~desc:"Replay a specific block level." (args7 @@ -1523,11 +1545,12 @@ let replay_command = in init ?config () in + let l2_chain_id = Configuration.default_chain_id in let* configuration = Cli.create_or_read_config ~keep_alive:false ~data_dir - ~l2_chain_id:(L2_chain_id.from_int 1) + ~l2_chains:(`Ids [l2_chain_id]) ~verbose:false ?preimages ?preimages_endpoint @@ -1545,7 +1568,6 @@ let replay_command = let patch_kernel_command = let open Tezos_clic in - let open Evm_node_lib_dev_encoding in command ~desc: "Patch the kernel used by the EVM node from its current HEAD. This is an \ @@ -1572,10 +1594,11 @@ let patch_kernel_command = let config = make_with_defaults ~verbosity:Warning () in init ~config () in + let l2_chain_id = Configuration.default_chain_id in let* configuration = Cli.create_or_read_config ~data_dir - ~l2_chain_id:(L2_chain_id.from_int 0) + ~l2_chains:(`Ids [l2_chain_id]) ~keep_alive:false ~verbose:false ~finalized_view:false @@ -1607,7 +1630,6 @@ let describe_config_command = let init_config_command = let open Tezos_clic in let open Lwt_result_syntax in - let open Evm_node_lib_dev_encoding in command ~desc: {|Create an initial config with default value. @@ -1700,15 +1722,29 @@ mode.|} Client_keys.Secret_key.parse_source_string wallet_ctxt str) sequencer_str in - let* config = - Cli.create_or_read_config + let l2_chain_id = Configuration.default_chain_id in + let* l2_config = + Cli.create_or_read_l2_config ~data_dir - ~l2_chain_id:(L2_chain_id.from_int 1) + ~l2_chain_id ?rpc_addr ?rpc_port ?rpc_batch_limit ?cors_origins ?cors_headers + ?tx_pool_timeout_limit + ?tx_pool_addr_limit + ?tx_pool_tx_per_addr_limit + ?private_rpc_port + ?restricted_rpcs + () + in + (* Save l2 configuration *) + let* () = Configuration.save_l2 ~force ~data_dir l2_config in + let* config = + Cli.create_or_read_config + ~data_dir + ~l2_chains:(`Config [l2_config]) ?log_filter_max_nb_blocks ?log_filter_max_nb_logs ?log_filter_chunk_size @@ -1719,15 +1755,11 @@ mode.|} omitted from the command-line. As a consequence, we default to the config value by passing [None]. *) (if dont_track_rollup_node then Some true else None) - ?tx_pool_timeout_limit - ?tx_pool_addr_limit - ?tx_pool_tx_per_addr_limit ?preimages ?preimages_endpoint ?native_execution_policy ?time_between_blocks ?max_number_of_chunks - ?private_rpc_port ?sequencer_key ?evm_node_endpoint ?threshold_encryption_bundler_endpoint @@ -1736,7 +1768,6 @@ mode.|} ?max_blueprints_ahead ?max_blueprints_catchup ?catchup_cooldown - ?restricted_rpcs ~verbose ?dal_slots ~finalized_view @@ -2395,7 +2426,6 @@ let snapshot_info_command = let patch_state_command = let open Tezos_clic in let open Lwt_result_syntax in - let open Evm_node_lib_dev_encoding in command ~desc: "Patches the state with an arbitrary value. This is an unsafe command, \ @@ -2420,10 +2450,11 @@ let patch_state_command = let config = make_with_defaults ~verbosity:Warning () in init ~config () in + let l2_chain_id = Configuration.default_chain_id in let* configuration = Cli.create_or_read_config ~data_dir - ~l2_chain_id:(L2_chain_id.from_int 0) + ~l2_chains:(`Ids [l2_chain_id]) ~keep_alive:false ~verbose:false ~finalized_view:false @@ -2442,7 +2473,6 @@ let patch_state_command = let preemptive_kernel_download_command = let open Tezos_clic in - let open Evm_node_lib_dev_encoding in command ~desc:"Transforms the JSON list of instructions to a RLP list" (args4 @@ -2461,10 +2491,11 @@ let preemptive_kernel_download_command = root_hash () -> let open Lwt_result_syntax in + let l2_chain_id = Configuration.default_chain_id in let* configuration = Cli.create_or_read_config ~data_dir - ~l2_chain_id:(L2_chain_id.from_int 1) + ~l2_chains:(`Ids [l2_chain_id]) ~keep_alive:false ~verbose:false ?preimages diff --git a/etherlink/tezt/tests/evm_sequencer.ml b/etherlink/tezt/tests/evm_sequencer.ml index 873148ab18e4..928a0de816f9 100644 --- a/etherlink/tezt/tests/evm_sequencer.ml +++ b/etherlink/tezt/tests/evm_sequencer.ml @@ -599,6 +599,64 @@ module Protocol = struct [@@warning "-unused-value-declaration"] end +let test_multi_chain = + register_all + ~time_between_blocks:Nothing + ~tags:["evm"; "sequencer"; "admin"] + ~title:"Remove sequencer via sequencer admin contract" + @@ fun { + sequencer; + proxy; + sc_rollup_node; + client; + sc_rollup_address; + l1_contracts; + observer; + _; + } + _protocol -> + (* Produce blocks to show that both the sequencer and proxy are not + progressing. *) + let* _ = + repeat 5 (fun () -> + let* _ = next_rollup_node_level ~sc_rollup_node ~client in + unit) + in + (* Both are at genesis *) + let*@ sequencer_head = Rpc.block_number sequencer in + let*@ proxy_head = Rpc.block_number proxy in + Check.((sequencer_head = 0l) int32) + ~error_msg:"Sequencer should be at genesis" ; + Check.((sequencer_head = proxy_head) int32) + ~error_msg:"Sequencer and proxy should have the same block number" ; + (* Remove the sequencer via the sequencer-admin contract. *) + let* () = + Client.transfer + ~amount:Tez.zero + ~giver:Constant.bootstrap2.public_key_hash + ~receiver:l1_contracts.sequencer_governance + ~arg:(sf "Pair %S 0x" sc_rollup_address) + ~burn_cap:Tez.one + client + in + let* exit_code = Evm_node.wait_for_shutdown_event sequencer + and* missing_block_nb = Evm_node.wait_for_rollup_node_ahead observer + and* () = + (* Produce L1 blocks to show that only the proxy is progressing *) + repeat 5 (fun () -> + let* _ = next_rollup_node_level ~sc_rollup_node ~client in + unit) + in + Check.((exit_code = Some 100) (option int)) + ~error_msg:"Expected exit code %R, got %L" ; + (* Sequencer is at genesis, proxy is at [advance]. *) + Check.((missing_block_nb = 1) int) + ~error_msg:"Sequencer should be missing block %L" ; + let*@ proxy_head = Rpc.block_number proxy in + Check.((proxy_head > 0l) int32) ~error_msg:"Proxy should have advanced" ; + + unit + let test_remove_sequencer = register_all ~time_between_blocks:Nothing @@ -9712,6 +9770,7 @@ let test_filling_max_slots_cant_lead_to_out_of_memory = let protocols = Protocol.all let () = + test_multi_chain protocols ; test_remove_sequencer protocols ; test_persistent_state protocols ; test_snapshots protocols ; -- GitLab From 06357d5f0723527e944eeef354b4aabc26e83d3e Mon Sep 17 00:00:00 2001 From: arnaud Date: Fri, 31 Jan 2025 16:26:51 +0100 Subject: [PATCH 3/3] Add new command to initialize multichain config and chain config --- etherlink/bin_node/main.ml | 234 +++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) diff --git a/etherlink/bin_node/main.ml b/etherlink/bin_node/main.ml index 8a343f7b5567..5216b24808db 100644 --- a/etherlink/bin_node/main.ml +++ b/etherlink/bin_node/main.ml @@ -237,6 +237,20 @@ let maximum_blueprints_lag_arg = before trying to send its backlog again." Params.int +let l2_chain_id_arg = + Tezos_clic.arg + ~long:"chain-id" + ~placeholder:"ID" + ~doc:"The chain id of the L2 chain" + Params.int + +let l2_chain_ids_arg = + Tezos_clic.multiple_arg + ~long:"chain-id" + ~placeholder:"ID" + ~doc:"The chain id of the L2 chain" + Params.int + let maximum_blueprints_ahead_arg = Tezos_clic.arg ~long:"maximum-blueprints-ahead" @@ -728,6 +742,18 @@ let common_config_args = whitelisted_rpcs_arg finalized_view_arg +let common_multichain_config_args = + Tezos_clic.args9 + data_dir_arg + l2_chain_ids_arg + log_filter_max_nb_blocks_arg + log_filter_max_nb_logs_arg + log_filter_chunk_size_arg + keep_alive_arg + rollup_node_endpoint_arg + verbose_arg + finalized_view_arg + let compress_on_the_fly_arg : (bool, unit) Tezos_clic.arg = Tezos_clic.switch ~long:"compress-on-the-fly" @@ -1782,6 +1808,212 @@ mode.|} let* () = websocket_checks config in Configuration.save ~force ~data_dir config) +let init_multichain_config_command = + let open Tezos_clic in + let open Lwt_result_syntax in + let open Evm_node_lib_dev_encoding in + command + ~desc: + {|Create an initial config with default value. + If the is set then adds the configuration for the proxy + mode. + If the is set,then adds the configuration for the sequencer and + threshold encryption sequencer modes. + If the is set then adds the configuration for the observer + mode.|} + (merge_options + common_multichain_config_args + (args18 + (* sequencer and observer config*) + preimages_arg + preimages_endpoint_arg + native_execution_policy_arg + time_between_blocks_arg + max_number_of_chunks_arg + sequencer_key_arg + maximum_blueprints_lag_arg + maximum_blueprints_ahead_arg + maximum_blueprints_catchup_arg + catchup_cooldown_arg + evm_node_endpoint_arg + bundler_node_endpoint_arg + sequencer_sidecar_endpoint_arg + (* others option *) + dont_track_rollup_node_arg + wallet_dir_arg + (Tezos_clic.switch + ~long:"force" + ~short:'f' + ~doc:"Overwrites the configuration file when it exists." + ()) + dal_slots_arg + (supported_network_arg + ~why: + "If set, some configuration options defaults to well-known \ + values for the selected network." + ()))) + (prefixes ["init"; "multichain"; "config"] @@ stop) + (fun ( ( data_dir, + l2_chain_ids, + log_filter_max_nb_blocks, + log_filter_max_nb_logs, + log_filter_chunk_size, + keep_alive, + rollup_node_endpoint, + verbose, + finalized_view ), + ( preimages, + preimages_endpoint, + native_execution_policy, + time_between_blocks, + max_number_of_chunks, + sequencer_str, + max_blueprints_lag, + max_blueprints_ahead, + max_blueprints_catchup, + catchup_cooldown, + evm_node_endpoint, + threshold_encryption_bundler_endpoint, + sequencer_sidecar_endpoint, + dont_track_rollup_node, + wallet_dir, + force, + dal_slots, + network ) ) + () -> + Evm_node_lib_dev.Data_dir.use ~data_dir @@ fun () -> + let* sequencer_key = + Option.map_es + (fun str -> + let wallet_ctxt = register_wallet ~wallet_dir () in + Client_keys.Secret_key.parse_source_string wallet_ctxt str) + sequencer_str + in + let l2_chain_ids = + match l2_chain_ids with + | None -> [] + | Some l2_chain_ids -> List.map L2_chain_id.from_int l2_chain_ids + in + let* config = + Cli.create_or_read_config + ~data_dir + ~l2_chains:(`Ids l2_chain_ids) + ?log_filter_max_nb_blocks + ?log_filter_max_nb_logs + ?log_filter_chunk_size + ~keep_alive + ?rollup_node_endpoint + ?dont_track_rollup_node: + (* If `dont_track_rollup_node` is false, it means the argument was + omitted from the command-line. As a consequence, we default to + the config value by passing [None]. *) + (if dont_track_rollup_node then Some true else None) + ?preimages + ?preimages_endpoint + ?native_execution_policy + ?time_between_blocks + ?max_number_of_chunks + ?sequencer_key + ?evm_node_endpoint + ?threshold_encryption_bundler_endpoint + ?sequencer_sidecar_endpoint + ?max_blueprints_lag + ?max_blueprints_ahead + ?max_blueprints_catchup + ?catchup_cooldown + ~verbose + ?dal_slots + ~finalized_view + ?network + () + in + let*! () = + let open Tezos_base_unix.Internal_event_unix in + let config = make_with_defaults ~verbosity:Warning () in + init ~config () + in + let* () = websocket_checks config in + Configuration.save ~force ~data_dir config) + +let init_chain_config_command = + let open Tezos_clic in + let open Lwt_result_syntax in + let open Evm_node_lib_dev_encoding in + command + ~desc: + {|Create an initial config with default value. + If the is set then adds the configuration for the proxy + mode. + If the is set,then adds the configuration for the sequencer and + threshold encryption sequencer modes. + If the is set then adds the configuration for the observer + mode.|} + (args15 + (* sequencer and observer config*) + data_dir_arg + l2_chain_id_arg + rpc_addr_arg + rpc_port_arg + rpc_batch_limit_arg + cors_allowed_headers_arg + cors_allowed_origins_arg + private_rpc_port_arg + tx_pool_addr_limit_arg + tx_pool_timeout_limit_arg + tx_pool_tx_per_addr_limit_arg + restricted_rpcs_arg + blacklisted_rpcs_arg + whitelisted_rpcs_arg + (Tezos_clic.switch + ~long:"force" + ~short:'f' + ~doc:"Overwrites the configuration file when it exists." + ())) + (prefixes ["init"; "chain"; "config"] @@ stop) + (fun ( data_dir, + l2_chain_id, + rpc_addr, + rpc_port, + rpc_batch_limit, + cors_headers, + cors_origins, + private_rpc_port, + tx_pool_addr_limit, + tx_pool_timeout_limit, + tx_pool_tx_per_addr_limit, + restricted_rpcs, + blacklisted_rpcs, + whitelisted_rpcs, + force ) + () -> + let l2_chain_id = + Option.fold + ~none:Configuration.default_chain_id + ~some:L2_chain_id.from_int + l2_chain_id + in + Evm_node_lib_dev.Data_dir.use ~data_dir @@ fun () -> + let* restricted_rpcs = + pick_restricted_rpcs restricted_rpcs whitelisted_rpcs blacklisted_rpcs + in + let* config_l2 = + Cli.create_or_read_l2_config + ~data_dir + ~l2_chain_id + ?rpc_addr + ?rpc_port + ?rpc_batch_limit + ?cors_headers + ?cors_origins + ?private_rpc_port + ?tx_pool_addr_limit + ?tx_pool_timeout_limit + ?restricted_rpcs + ?tx_pool_tx_per_addr_limit + () + in + Configuration.save_l2 ~force ~data_dir config_l2) + let check_config_command = let open Tezos_clic in let open Lwt_result_syntax in @@ -2572,6 +2804,8 @@ let commands = replay_command; patch_kernel_command; init_config_command; + init_chain_config_command; + init_multichain_config_command; check_config_command; describe_config_command; make_kernel_config_command; -- GitLab