From 2b61962a3514bbc88a05e5e185a6e081cf69cbe4 Mon Sep 17 00:00:00 2001 From: arnaud Date: Wed, 2 Apr 2025 14:26:41 +0200 Subject: [PATCH 1/7] Etherlink/Kernel: Kernel correction Use the to_bytes function to produce the hash of a Tezos block and add a missing '}' for Michelson chain family --- etherlink/kernel_latest/kernel/src/chains.rs | 2 +- etherlink/kernel_latest/tezos/src/block.rs | 13 ++----------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/etherlink/kernel_latest/kernel/src/chains.rs b/etherlink/kernel_latest/kernel/src/chains.rs index 911a973aaa90..7f82548251e7 100644 --- a/etherlink/kernel_latest/kernel/src/chains.rs +++ b/etherlink/kernel_latest/kernel/src/chains.rs @@ -136,7 +136,7 @@ impl std::fmt::Display for ChainConfig { ChainConfig::Michelson(chain_config) => { write!( f, - "{{Chain id: {}, Chain family: {}", + "{{Chain id: {}, Chain family: {}}}", chain_config.chain_id, ChainFamily::Michelson ) diff --git a/etherlink/kernel_latest/tezos/src/block.rs b/etherlink/kernel_latest/tezos/src/block.rs index 64725fb67b78..85de6ceff40f 100644 --- a/etherlink/kernel_latest/tezos/src/block.rs +++ b/etherlink/kernel_latest/tezos/src/block.rs @@ -25,17 +25,8 @@ impl TezBlock { } fn hash(&self) -> H256 { - let Self { - hash: _, - number, - timestamp, - previous_hash, - } = self; - let mut data = number.to_string(); - data.push_str(×tamp.i64().to_string()); - data.push_str(&previous_hash.to_string()); - let encoded_data = hex::encode(&data); - let hashed_data = digest_256(encoded_data.as_bytes()); + let encoded_data = self.to_bytes(); + let hashed_data = digest_256(&encoded_data); H256::from_slice(&hashed_data) } -- GitLab From 8ae01cb708b6df9b0e06233899909aa85fb82a22 Mon Sep 17 00:00:00 2001 From: arnaud Date: Mon, 17 Mar 2025 18:13:46 +0100 Subject: [PATCH 2/7] Evm/Tezlink/Node: apply_blueprint takes a chain_family to know how the block should be decoded --- etherlink/bin_node/config/configuration.ml | 6 ++++++ etherlink/bin_node/config/configuration.mli | 7 +++++++ etherlink/bin_node/lib_dev/evm_context.ml | 6 ++++++ etherlink/bin_node/lib_dev/evm_ro_context.ml | 1 + etherlink/bin_node/lib_dev/evm_state.ml | 7 ++++--- etherlink/bin_node/lib_dev/evm_state.mli | 1 + 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/etherlink/bin_node/config/configuration.ml b/etherlink/bin_node/config/configuration.ml index 03ca84194df8..4276d412fcdf 100644 --- a/etherlink/bin_node/config/configuration.ml +++ b/etherlink/bin_node/config/configuration.ml @@ -229,6 +229,12 @@ type t = { let is_tx_queue_enabled {experimental_features = {enable_tx_queue; _}; _} = Option.is_some enable_tx_queue +let retrieve_chain_family ~l2_chains = + match l2_chains with + | Some [l2_chain] -> l2_chain.chain_family + | None -> L2_types.EVM + | _ -> assert false + let default_filter_config ?max_nb_blocks ?max_nb_logs ?chunk_size () = { max_nb_blocks = Option.value ~default:100 max_nb_blocks; diff --git a/etherlink/bin_node/config/configuration.mli b/etherlink/bin_node/config/configuration.mli index bf0f7f62548f..3c266e6d9ca8 100644 --- a/etherlink/bin_node/config/configuration.mli +++ b/etherlink/bin_node/config/configuration.mli @@ -201,6 +201,13 @@ type t = { val is_tx_queue_enabled : t -> bool +(** [chain_family_from_l2_chains t] returns the chain_family in + the experimental feature if there's only one chain. + + This function will be removed when multichain is implemented *) +val retrieve_chain_family : + l2_chains:l2_chain list option -> L2_types.chain_family + val history_mode_encoding : history_mode Data_encoding.t val pp_history_mode_debug : Format.formatter -> history_mode -> unit diff --git a/etherlink/bin_node/lib_dev/evm_context.ml b/etherlink/bin_node/lib_dev/evm_context.ml index 360722d9b463..42d0c7b16336 100644 --- a/etherlink/bin_node/lib_dev/evm_context.ml +++ b/etherlink/bin_node/lib_dev/evm_context.ml @@ -673,6 +673,11 @@ module State = struct let time_processed = ref Ptime.Span.zero in + (* TODO: We should iterate when multichain https://gitlab.com/tezos/tezos/-/issues/7859 *) + let chain_family = + Configuration.retrieve_chain_family + ~l2_chains:ctxt.configuration.experimental_features.l2_chains + in let* try_apply = Misc.with_timing (fun time -> Lwt.return (time_processed := time)) @@ -682,6 +687,7 @@ module State = struct ctxt.configuration.kernel_execution.native_execution_policy ~wasm_pvm_fallback:(not @@ List.is_empty delayed_transactions) ~data_dir + ~chain_family ~config ctxt.session.evm_state payload) diff --git a/etherlink/bin_node/lib_dev/evm_ro_context.ml b/etherlink/bin_node/lib_dev/evm_ro_context.ml index 7259149cd5d2..097439e05a21 100644 --- a/etherlink/bin_node/lib_dev/evm_ro_context.ml +++ b/etherlink/bin_node/lib_dev/evm_ro_context.ml @@ -435,6 +435,7 @@ let replay ctxt ?(log_file = "replay") ?profile ~log_file ?profile ~data_dir:ctxt.data_dir + ~chain_family:EVM ~config:(pvm_config ctxt) ~native_execution_policy:ctxt.native_execution_policy evm_state diff --git a/etherlink/bin_node/lib_dev/evm_state.ml b/etherlink/bin_node/lib_dev/evm_state.ml index b27c6cf8224e..031927fa6a24 100644 --- a/etherlink/bin_node/lib_dev/evm_state.ml +++ b/etherlink/bin_node/lib_dev/evm_state.ml @@ -305,8 +305,9 @@ type apply_result = } | Apply_failure -let apply_blueprint ?wasm_pvm_fallback ?log_file ?profile ~data_dir ~config - ~native_execution_policy evm_state (blueprint : Blueprint_types.payload) = +let apply_blueprint ?wasm_pvm_fallback ?log_file ?profile ~data_dir + ~chain_family ~config ~native_execution_policy evm_state + (blueprint : Blueprint_types.payload) = let open Lwt_result_syntax in let exec_inputs = List.map @@ -331,7 +332,7 @@ let apply_blueprint ?wasm_pvm_fallback ?log_file ?profile ~data_dir ~config let*! bytes = inspect evm_state (Durable_storage_path.Block.by_hash block_hash) in - return (Option.map (L2_types.block_from_bytes ~chain_family:EVM) bytes) + return (Option.map (L2_types.block_from_bytes ~chain_family) bytes) in let export_gas_used (Qty gas) = match (profile, log_file) with diff --git a/etherlink/bin_node/lib_dev/evm_state.mli b/etherlink/bin_node/lib_dev/evm_state.mli index 48e3c21b463a..a2fd006904a2 100644 --- a/etherlink/bin_node/lib_dev/evm_state.mli +++ b/etherlink/bin_node/lib_dev/evm_state.mli @@ -99,6 +99,7 @@ val apply_blueprint : ?log_file:string -> ?profile:bool -> data_dir:string -> + chain_family:L2_types.chain_family -> config:Wasm_debugger.config -> native_execution_policy:Configuration.native_execution_policy -> t -> -- GitLab From 40d37db13fed93222d8705f8d1af6f4290767076 Mon Sep 17 00:00:00 2001 From: arnaud Date: Tue, 18 Mar 2025 11:28:14 +0100 Subject: [PATCH 3/7] Evm/Tezlink/Node: Load the context takes a list of chains In the future when the evm_node will be able to support multichain, instead of returning one current hash, it should return the list of current hash for all chains supported by the node --- etherlink/bin_node/lib_dev/evm_context.ml | 35 +++++++++++++++++++---- etherlink/bin_node/lib_dev/evm_state.ml | 6 ++-- etherlink/bin_node/lib_dev/evm_state.mli | 5 +++- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/etherlink/bin_node/lib_dev/evm_context.ml b/etherlink/bin_node/lib_dev/evm_context.ml index 42d0c7b16336..34f7e31f01a3 100644 --- a/etherlink/bin_node/lib_dev/evm_context.ml +++ b/etherlink/bin_node/lib_dev/evm_context.ml @@ -249,16 +249,20 @@ module State = struct Lwt.wakeup head_info_waker first_head end - let load ~data_dir ~store_perm:perm index = + let load ~l2_chains ~data_dir ~store_perm:perm index = let open Lwt_result_syntax in let* store = Evm_store.init ~data_dir ~perm () in Evm_store.use store @@ fun conn -> let* latest = Evm_store.Context_hashes.find_latest conn in + (* TODO: We should iterate when multichain https://gitlab.com/tezos/tezos/-/issues/7859 *) + let chain_family = Configuration.retrieve_chain_family ~l2_chains in match latest with | Some (Qty latest_blueprint_number, checkpoint) -> let*! context = Irmin_context.checkout_exn index checkpoint in let*! evm_state = Irmin_context.PVMState.get context in - let+ current_block_hash = Evm_state.current_block_hash evm_state in + let+ current_block_hash = + Evm_state.current_block_hash ~chain_family evm_state + in ( store, context, Ethereum_types.Qty Z.(succ latest_blueprint_number), @@ -266,11 +270,12 @@ module State = struct Loaded ) | None -> let context = Irmin_context.empty index in + let genesis_parent_hash = L2_types.genesis_parent_hash ~chain_family in return ( store, context, Ethereum_types.Qty Z.zero, - L2_types.genesis_parent_hash ~chain_family:EVM, + genesis_parent_hash, Created ) let commit store (context : Irmin_context.rw) evm_state number = @@ -475,7 +480,14 @@ module State = struct let* pending_upgrade = Evm_store.Kernel_upgrades.find_latest_pending conn in (* Update mutable session values. *) let next_blueprint_number = Ethereum_types.Qty.next l2_level in - let* current_block_hash = Evm_state.current_block_hash evm_state in + (* TODO: We should iterate when multichain https://gitlab.com/tezos/tezos/-/issues/7859 *) + let chain_family = + Configuration.retrieve_chain_family + ~l2_chains:ctxt.configuration.experimental_features.l2_chains + in + let* current_block_hash = + Evm_state.current_block_hash ~chain_family evm_state + in ctxt.session.next_blueprint_number <- next_blueprint_number ; ctxt.session.evm_state <- evm_state ; ctxt.session.current_block_hash <- current_block_hash ; @@ -1135,8 +1147,15 @@ module State = struct let* () = clear_head_delayed_inbox ctxt in (* Prepare an event list to be reapplied on current head *) let events = Evm_events.of_parts delayed_transactions lost_upgrade in + (* TODO: We should iterate when multichain https://gitlab.com/tezos/tezos/-/issues/7859 *) + let chain_family = + Configuration.retrieve_chain_family + ~l2_chains:ctxt.configuration.experimental_features.l2_chains + in (* Prepare a blueprint payload signed by the sequencer to execute locally. *) - let* parent_hash = Evm_state.current_block_hash ctxt.session.evm_state in + let* parent_hash = + Evm_state.current_block_hash ~chain_family ctxt.session.evm_state + in let* payload = prepare_local_flushed_blueprint ctxt parent_hash flushed_blueprint in @@ -1352,7 +1371,11 @@ module State = struct let* index = irmin_load ?snapshot_url ~data_dir configuration in let* store, context, next_blueprint_number, current_block_hash, init_status = - load ~data_dir ~store_perm index + load + ~l2_chains:configuration.experimental_features.l2_chains + ~data_dir + ~store_perm + index in Evm_store.use store @@ fun conn -> let* () = diff --git a/etherlink/bin_node/lib_dev/evm_state.ml b/etherlink/bin_node/lib_dev/evm_state.ml index 031927fa6a24..aad863899b2c 100644 --- a/etherlink/bin_node/lib_dev/evm_state.ml +++ b/etherlink/bin_node/lib_dev/evm_state.ml @@ -221,14 +221,14 @@ let current_block_height evm_state = let (Qty current_block_number) = decode_number_le current_block_number in return (Qty current_block_number) -let current_block_hash evm_state = +let current_block_hash ~chain_family evm_state = let open Lwt_result_syntax in let*! current_hash = inspect evm_state Durable_storage_path.Block.current_hash in match current_hash with | Some h -> return (decode_block_hash h) - | None -> return (L2_types.genesis_parent_hash ~chain_family:EVM) + | None -> return (L2_types.genesis_parent_hash ~chain_family) (* The Fast Execution engine relies on Lwt_preemptive to execute Wasmer in dedicated worker threads (`Lwt_preemptive.detach`), while pushing to lwt @@ -327,7 +327,7 @@ let apply_blueprint ?wasm_pvm_fallback ?log_file ?profile ~data_dir evm_state exec_inputs in - let* block_hash = current_block_hash evm_state in + let* block_hash = current_block_hash ~chain_family evm_state in let* block = let*! bytes = inspect evm_state (Durable_storage_path.Block.by_hash block_hash) diff --git a/etherlink/bin_node/lib_dev/evm_state.mli b/etherlink/bin_node/lib_dev/evm_state.mli index a2fd006904a2..efe5fe75fb31 100644 --- a/etherlink/bin_node/lib_dev/evm_state.mli +++ b/etherlink/bin_node/lib_dev/evm_state.mli @@ -77,7 +77,10 @@ val execute_and_inspect : val current_block_height : t -> Ethereum_types.quantity Lwt.t (** Same as {!current_block_height} for the block hash. *) -val current_block_hash : t -> Ethereum_types.block_hash tzresult Lwt.t +val current_block_hash : + chain_family:L2_types.chain_family -> + t -> + Ethereum_types.block_hash tzresult Lwt.t type apply_result = | Apply_success of { -- GitLab From 6c984b0918d16f4b8651b581260162275915da0b Mon Sep 17 00:00:00 2001 From: arnaud Date: Tue, 18 Mar 2025 11:34:39 +0100 Subject: [PATCH 4/7] Evm/Tezlink/Node: Generating the right genesis chunks depending on the chain family Later in multichain, this should produce multiple genesis chunks (one for each chain) --- etherlink/bin_node/lib_dev/sequencer.ml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/etherlink/bin_node/lib_dev/sequencer.ml b/etherlink/bin_node/lib_dev/sequencer.ml index 482e5f0d1dfe..76eac22422f2 100644 --- a/etherlink/bin_node/lib_dev/sequencer.ml +++ b/etherlink/bin_node/lib_dev/sequencer.ml @@ -170,6 +170,11 @@ let main ~data_dir ?(genesis_timestamp = Misc.now ()) ~cctxt in let* () = if status = Created then + (* TODO: We should iterate when multichain https://gitlab.com/tezos/tezos/-/issues/7859 *) + let chain_family = + Configuration.retrieve_chain_family + ~l2_chains:configuration.experimental_features.l2_chains + in (* Create the first empty block. *) let* genesis_chunks = Sequencer_blueprint.prepare @@ -179,7 +184,7 @@ let main ~data_dir ?(genesis_timestamp = Misc.now ()) ~cctxt ~transactions:[] ~delayed_transactions:[] ~number:Ethereum_types.(Qty Z.zero) - ~parent_hash:(L2_types.genesis_parent_hash ~chain_family:EVM) + ~parent_hash:(L2_types.genesis_parent_hash ~chain_family) in let genesis_payload = Sequencer_blueprint.create_inbox_payload -- GitLab From c48393c515a51614d346ddacd6f859e2565dff02 Mon Sep 17 00:00:00 2001 From: arnaud Date: Tue, 18 Mar 2025 11:47:50 +0100 Subject: [PATCH 5/7] EVM/Tezlink/Node: Get irmin hash takes a chain family to know how it should decode the block This commit parametrize get_irmin_hash_from_block_hash but the call to get_irmin_hash force the node to think it's in etherlink mode. The variant branch Block_hash where get_irmin_hash is call is a parameter specific to ethereum so we are naturally in EVM mode. For tezlink we'll call get_irmin_hash in another function. --- etherlink/bin_node/lib_dev/evm_ro_context.ml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/etherlink/bin_node/lib_dev/evm_ro_context.ml b/etherlink/bin_node/lib_dev/evm_ro_context.ml index 097439e05a21..df9656a4c9ae 100644 --- a/etherlink/bin_node/lib_dev/evm_ro_context.ml +++ b/etherlink/bin_node/lib_dev/evm_ro_context.ml @@ -156,7 +156,7 @@ let get_irmin_hash_from_number ctxt number = Ethereum_types.pp_quantity number -let get_irmin_hash_from_block_hash ctxt hash = +let get_irmin_hash_from_block_hash ~chain_family ctxt hash = let open Lwt_result_syntax in (* we use the latest state to read the contents of the block *) let* latest_hash = find_latest_hash ctxt in @@ -166,7 +166,7 @@ let get_irmin_hash_from_block_hash ctxt hash = in match res with | Some block_bytes -> - let block = L2_types.block_from_bytes ~chain_family:EVM block_bytes in + let block = L2_types.block_from_bytes ~chain_family block_bytes in get_irmin_hash_from_number ctxt (L2_types.block_number block) | None -> failwith "Unknown block %a" Ethereum_types.pp_block_hash hash @@ -203,7 +203,7 @@ let find_irmin_hash ctxt (block : Ethereum_types.Block_parameter.extended) = match context_hash_opt with | Some context_hash -> return context_hash | None -> failwith "Unknown block %a" Ethereum_types.pp_block_hash hash - else get_irmin_hash_from_block_hash ctxt hash + else get_irmin_hash_from_block_hash ~chain_family:L2_types.EVM ctxt hash module MakeBackend (Ctxt : sig val ctxt : t -- GitLab From 11f980709776107310c5c0ac13313ea07d5d4272 Mon Sep 17 00:00:00 2001 From: arnaud Date: Wed, 19 Mar 2025 17:29:21 +0100 Subject: [PATCH 6/7] EVM/Tezlink/Node: Deactivate pop_transactions if chain_family is Michelson Pass the l2_chains in the parameter of block_producer worker --- etherlink/bin_node/lib_dev/block_producer.ml | 18 ++++++--- etherlink/bin_node/lib_dev/block_producer.mli | 1 + etherlink/bin_node/lib_dev/sequencer.ml | 1 + etherlink/bin_node/lib_dev/tx_pool.ml | 39 +++++++++++-------- etherlink/bin_node/lib_dev/tx_pool.mli | 8 ++-- 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/etherlink/bin_node/lib_dev/block_producer.ml b/etherlink/bin_node/lib_dev/block_producer.ml index 2debcf02a78f..7b86cbc979ff 100644 --- a/etherlink/bin_node/lib_dev/block_producer.ml +++ b/etherlink/bin_node/lib_dev/block_producer.ml @@ -11,6 +11,7 @@ type parameters = { sequencer_key : Client_keys.sk_uri; maximum_number_of_chunks : int; uses_tx_queue : bool; + l2_chains : Configuration.l2_chain list option; } (* The size of a delayed transaction is overapproximated to the maximum size @@ -244,9 +245,9 @@ let tx_queue_pop_valid_tx (head_info : Evm_context.head) (** Produces a block if we find at least one valid transaction in the transaction pool or if [force] is true. *) -let produce_block_if_needed ~cctxt ~smart_rollup_address ~sequencer_key ~force - ~timestamp ~delayed_hashes ~remaining_cumulative_size ~uses_tx_queue - head_info = +let produce_block_if_needed ~cctxt ~l2_chains ~smart_rollup_address + ~sequencer_key ~force ~timestamp ~delayed_hashes ~remaining_cumulative_size + ~uses_tx_queue head_info = let open Lwt_result_syntax in let* transactions_and_objects = (* Low key optimization to avoid even checking the txpool if there is not @@ -258,7 +259,10 @@ let produce_block_if_needed ~cctxt ~smart_rollup_address ~sequencer_key ~force head_info ~maximum_cumulative_size:remaining_cumulative_size else + (* TODO: We should iterate when multichain https://gitlab.com/tezos/tezos/-/issues/7859 *) + let chain_family = Configuration.retrieve_chain_family ~l2_chains in Tx_pool.pop_transactions + ~chain_family ~maximum_cumulative_size:remaining_cumulative_size in let n = List.length transactions_and_objects + List.length delayed_hashes in @@ -301,8 +305,9 @@ let head_info_and_delayed_transactions ~with_delayed_transactions let*! head_info = Evm_context.head_info () in return (head_info, delayed_hashes, remaining_cumulative_size) -let produce_block ~uses_tx_queue ~cctxt ~smart_rollup_address ~sequencer_key - ~force ~timestamp ~maximum_number_of_chunks ~with_delayed_transactions = +let produce_block ~l2_chains ~uses_tx_queue ~cctxt ~smart_rollup_address + ~sequencer_key ~force ~timestamp ~maximum_number_of_chunks + ~with_delayed_transactions = let open Lwt_result_syntax in let* is_locked = if uses_tx_queue then Tx_queue.is_locked () else Tx_pool.is_locked () @@ -338,6 +343,7 @@ let produce_block ~uses_tx_queue ~cctxt ~smart_rollup_address ~sequencer_key else produce_block_if_needed ~cctxt + ~l2_chains ~sequencer_key ~timestamp ~smart_rollup_address @@ -365,10 +371,12 @@ module Handlers = struct sequencer_key; maximum_number_of_chunks; uses_tx_queue; + l2_chains; } = state in produce_block + ~l2_chains ~uses_tx_queue ~cctxt ~smart_rollup_address diff --git a/etherlink/bin_node/lib_dev/block_producer.mli b/etherlink/bin_node/lib_dev/block_producer.mli index 39ad2455b48a..877f1b1857f2 100644 --- a/etherlink/bin_node/lib_dev/block_producer.mli +++ b/etherlink/bin_node/lib_dev/block_producer.mli @@ -11,6 +11,7 @@ type parameters = { sequencer_key : Client_keys.sk_uri; maximum_number_of_chunks : int; uses_tx_queue : bool; + l2_chains : Configuration.l2_chain list option; } (** [start parameters] starts the events follower. *) diff --git a/etherlink/bin_node/lib_dev/sequencer.ml b/etherlink/bin_node/lib_dev/sequencer.ml index 76eac22422f2..509a1dc4e602 100644 --- a/etherlink/bin_node/lib_dev/sequencer.ml +++ b/etherlink/bin_node/lib_dev/sequencer.ml @@ -240,6 +240,7 @@ let main ~data_dir ?(genesis_timestamp = Misc.now ()) ~cctxt sequencer_key = sequencer_config.sequencer; maximum_number_of_chunks = sequencer_config.max_number_of_chunks; uses_tx_queue = Configuration.is_tx_queue_enabled configuration; + l2_chains = configuration.experimental_features.l2_chains; } in let* () = diff --git a/etherlink/bin_node/lib_dev/tx_pool.ml b/etherlink/bin_node/lib_dev/tx_pool.ml index b0d5914032ff..7a1c86a4a9f3 100644 --- a/etherlink/bin_node/lib_dev/tx_pool.ml +++ b/etherlink/bin_node/lib_dev/tx_pool.ml @@ -268,7 +268,11 @@ module Request = struct Ethereum_types.legacy_transaction_object * string -> ((Ethereum_types.hash, string) result, tztrace) t | Pop_transactions : - int + (* TODO: https://gitlab.com/tezos/tezos/-/issues/7889 *) + (* We need the chain_family to verify if we are in Tezlink mode *) + (* If so, deactivate the pop_transactions and returns an empty list *) + L2_types.chain_family + * int -> ((string * Ethereum_types.legacy_transaction_object) list, tztrace) t | Pop_and_inject_transactions : (unit, tztrace) t | Lock_transactions : (unit, tztrace) t @@ -306,15 +310,16 @@ module Request = struct case (Tag 1) ~title:"Pop_transactions" - (obj2 + (obj3 (req "request" (constant "pop_transactions")) + (req "chain_family" L2_types.Chain_family.encoding) (req "maximum_cumulatize_size" int31)) (function - | View (Pop_transactions maximum_cumulative_size) -> - Some ((), maximum_cumulative_size) + | View (Pop_transactions (chain_family, maximum_cumulative_size)) -> + Some ((), chain_family, maximum_cumulative_size) | _ -> None) - (fun ((), maximum_cumulative_size) -> - View (Pop_transactions maximum_cumulative_size)); + (fun ((), chain_family, maximum_cumulative_size) -> + View (Pop_transactions (chain_family, maximum_cumulative_size))); case (Tag 2) ~title:"Pop_and_inject_transactions" @@ -368,7 +373,7 @@ module Request = struct ppf "Add tx [%s] to tx-pool" (Hex.of_string tx_raw |> Hex.show) - | Pop_transactions maximum_cumulative_size -> + | Pop_transactions (_chain_family, maximum_cumulative_size) -> Format.fprintf ppf "Popping transactions of maximum cumulative size %d bytes" @@ -488,7 +493,7 @@ let transaction_timed_out ~tx_timeout_limit ~current_timestamp ~inclusion_timestamp = Time.Protocol.diff current_timestamp inclusion_timestamp >= tx_timeout_limit -let pop_transactions state ~maximum_cumulative_size = +let pop_transactions state ~chain_family ~maximum_cumulative_size = let open Lwt_result_syntax in let Types. { @@ -500,7 +505,7 @@ let pop_transactions state ~maximum_cumulative_size = } = state in - if locked then return [] + if locked || chain_family = L2_types.Michelson then return [] else (* Get all the addresses in the tx-pool. *) let addresses = Pool.addresses pool in @@ -618,7 +623,7 @@ let clear_popped_transactions state = state.Types.popped_txs <- [] are forwarded to a rollup node, in observer mode to the next evm node. The sequencer is not supposed to use this function, using it would make transaction disappear from the tx pool. *) -let pop_and_inject_transactions state = +let pop_and_inject_transactions ~chain_family state = let open Lwt_result_syntax in let open Types in (* We over approximate the number of transactions to pop in proxy and @@ -629,7 +634,7 @@ let pop_and_inject_transactions state = Sequencer_blueprint.maximum_usable_space_in_blueprint Sequencer_blueprint.maximum_chunks_per_l1_level in - let* txs = pop_transactions state ~maximum_cumulative_size in + let* txs = pop_transactions state ~chain_family ~maximum_cumulative_size in if not (List.is_empty txs) then let (module Backend : Services_backend_sig.S) = state.backend in let*! hashes = @@ -710,10 +715,12 @@ module Handlers = struct let* res = insert_valid_transaction state txn transaction_object in let* () = relay_self_inject_request w in return res - | Request.Pop_transactions maximum_cumulative_size -> - protect @@ fun () -> pop_transactions state ~maximum_cumulative_size + | Request.Pop_transactions (chain_family, maximum_cumulative_size) -> + protect @@ fun () -> + pop_transactions state ~chain_family ~maximum_cumulative_size | Request.Pop_and_inject_transactions -> - protect @@ fun () -> pop_and_inject_transactions state + protect @@ fun () -> + pop_and_inject_transactions ~chain_family:L2_types.EVM state | Request.Lock_transactions -> protect @@ fun () -> return (lock_transactions state) | Request.Unlock_transactions -> return (unlock_transactions state) @@ -830,12 +837,12 @@ let nonce pkey = in Pool.next_nonce pkey current_nonce pool -let pop_transactions ~maximum_cumulative_size = +let pop_transactions ~chain_family ~maximum_cumulative_size = let open Lwt_result_syntax in let*? worker = Lazy.force worker in Worker.Queue.push_request_and_wait worker - (Request.Pop_transactions maximum_cumulative_size) + (Request.Pop_transactions (chain_family, maximum_cumulative_size)) |> handle_request_error let pop_and_inject_transactions () = diff --git a/etherlink/bin_node/lib_dev/tx_pool.mli b/etherlink/bin_node/lib_dev/tx_pool.mli index 76f6fac292a0..f5c47df8c24b 100644 --- a/etherlink/bin_node/lib_dev/tx_pool.mli +++ b/etherlink/bin_node/lib_dev/tx_pool.mli @@ -44,10 +44,12 @@ val add : if no transactions are in the pool. *) val nonce : Ethereum_types.Address.t -> Ethereum_types.quantity tzresult Lwt.t -(** [pop_transactions maximum_cumulative_size] pops as much valid transactions - as possible from the pool, until their cumulative size exceeds - `maximum_cumulative_size`. Returns no transactions if the pool is locked. *) +(** [pop_transactions chain_family maximum_cumulative_size] pops as much + valid transactions as possible from the pool, until their cumulative + size exceeds `maximum_cumulative_size`. If the pool is locked or node + in tezlink mode, returns no transactions. *) val pop_transactions : + chain_family:L2_types.chain_family -> maximum_cumulative_size:int -> (string * Ethereum_types.legacy_transaction_object) list tzresult Lwt.t -- GitLab From 5dd520e18fd2fb1a20c3b49abf8cd67217824025 Mon Sep 17 00:00:00 2001 From: arnaud Date: Thu, 13 Mar 2025 13:34:18 +0100 Subject: [PATCH 7/7] Tezlink/Tezt: A tezt that setup the kernel and noe in tezlink and make the chain progress For now we need to patch the node configuration to force the node to expect tezlink block (otherwise apply blueprint function would fail because it can't decode the produced block) --- etherlink/tezt/lib/setup.ml | 8 ++++++++ etherlink/tezt/tests/evm_sequencer.ml | 27 ++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/etherlink/tezt/lib/setup.ml b/etherlink/tezt/lib/setup.ml index 7aa83c189986..e907c76962fb 100644 --- a/etherlink/tezt/lib/setup.ml +++ b/etherlink/tezt/lib/setup.ml @@ -337,8 +337,16 @@ let setup_kernel_multichain ~(l2_setups : Evm_node.l2_setup list) ~l1_contracts else bootstrap_accounts ) | _ -> assert false in + (* In the kernel, the multichain notion was not introduced yet. *) + (* The kernel rely on its chain id to know the chain_family. *) + (* We need to keep this as long as we register test as multichain + just for tezlink (and not real multichain) *) + let chain_id = + match l2_chain_ids with [chain_id] -> Some chain_id | _ -> None + in let*! () = Evm_node.make_kernel_installer_config + ?chain_id ~l2_chain_ids ?max_delayed_inbox_blueprint_length ~mainnet_compat diff --git a/etherlink/tezt/tests/evm_sequencer.ml b/etherlink/tezt/tests/evm_sequencer.ml index 074f824d1e1f..8a1366afc268 100644 --- a/etherlink/tezt/tests/evm_sequencer.ml +++ b/etherlink/tezt/tests/evm_sequencer.ml @@ -439,6 +439,7 @@ let register_upgrade_all ~title ~tags ~genesis_timestamp let register_tezlink_test ~title ~tags scenario protocols = register_all + ~kernels:[Kernel.Latest] ~title ~tags:("tezlink" :: tags) ~l2_setups: @@ -997,6 +998,29 @@ let test_observer_reset = unit +let test_tezlink_produceBlock = + register_tezlink_test + ~title:"Test Tezlink production block" + ~tags:["kernel"; "produce_block"] + @@ fun {sequencer; _} _protocol -> + let rpc_current_level_head sequencer = + let path = "/tezlink/chains/main/blocks/head/helpers/current_level" in + let* res = + Curl.get_raw ~args:["-v"] (Evm_node.endpoint sequencer ^ path) + |> Runnable.run + in + let json = JSON.parse ~origin:"curl_current_level" res in + return @@ JSON.(json |-> "level" |> as_int) + in + let* start_level = rpc_current_level_head sequencer in + let*@ _ = produce_block sequencer in + let*@ _ = produce_block sequencer in + let*@ _ = produce_block sequencer in + let* end_level = rpc_current_level_head sequencer in + Check.((start_level + 3 = end_level) int) + ~error_msg:"Expected new block number to be %L, but got: %R" ; + unit + module Protocol = struct include Protocol @@ -12609,4 +12633,5 @@ let () = test_block_producer_validation [Alpha] ; test_tezlink_current_level [Alpha] ; test_tezlink_protocols [Alpha] ; - test_tezlink_version [Alpha] + test_tezlink_version [Alpha] ; + test_tezlink_produceBlock [Alpha] -- GitLab