From ba09d52a99c4a78e6fe3eb9705f60810b56e69ba Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Wed, 29 Nov 2023 14:48:04 +0100 Subject: [PATCH 01/15] EVM/Sequencer: patch configuration placeholders --- etherlink/bin_evm_node/evm_node.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etherlink/bin_evm_node/evm_node.ml b/etherlink/bin_evm_node/evm_node.ml index 8eaaa1b08c7e..eb4f0b2aaac8 100644 --- a/etherlink/bin_evm_node/evm_node.ml +++ b/etherlink/bin_evm_node/evm_node.ml @@ -244,15 +244,15 @@ let data_parameter = let kernel_arg = Tezos_clic.arg ~long:"kernel" + ~placeholder:"evm_installer.wasm" ~doc:"Path to the EVM kernel" - ~placeholder:"_evm_installer_preimages" Params.string let preimages_arg = Tezos_clic.arg ~long:"preimage-dir" ~doc:"Path to the preimages directory" - ~placeholder:"evm_installer.wasm" + ~placeholder:"_evm_installer_preimages" Params.string let proxy_command = -- GitLab From 6ebf178393ea5f241e88998f9528cdadb326b955 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Thu, 30 Nov 2023 13:42:41 +0100 Subject: [PATCH 02/15] EVM/Node: extract inject transactions from on_head --- etherlink/bin_evm_node/lib_dev/tx_pool.ml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/etherlink/bin_evm_node/lib_dev/tx_pool.ml b/etherlink/bin_evm_node/lib_dev/tx_pool.ml index 917baac887b0..e71b896e2c01 100644 --- a/etherlink/bin_evm_node/lib_dev/tx_pool.ml +++ b/etherlink/bin_evm_node/lib_dev/tx_pool.ml @@ -205,12 +205,9 @@ let on_transaction state tx_raw = state.pool <- pool ; return (Ok hash) -let on_head state block_height = +let inject_transactions ~smart_rollup_address rollup_node pool = let open Lwt_result_syntax in - let open Types in - let {rollup_node = (module Rollup_node); smart_rollup_address; pool; _} = - state - in + let (module Rollup_node : Services_backend_sig.S) = rollup_node in (* Get all the addresses in the tx-pool. *) let addresses = Pool.addresses pool in (* Get the nonce related to each address. *) @@ -278,6 +275,13 @@ let on_head state block_height = "[tx-pool] Transaction %s sent to the rollup.\n%!" (Ethereum_types.hash_to_string hash)) hashes) ; + return pool + +let on_head state block_height = + let open Lwt_result_syntax in + let open Types in + let {rollup_node; smart_rollup_address; pool; _} = state in + let* pool = inject_transactions ~smart_rollup_address rollup_node pool in (* update the pool *) state.level <- block_height ; state.pool <- pool ; -- GitLab From a474adb6fa912babfb3f6145d713133993884f75 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Thu, 30 Nov 2023 14:00:18 +0100 Subject: [PATCH 03/15] EVM/Node: adapt the mempool routine based on mode --- etherlink/bin_evm_node/evm_node.ml | 14 +++++-- etherlink/bin_evm_node/lib_dev/tx_pool.ml | 48 ++++++++++++++-------- etherlink/bin_evm_node/lib_dev/tx_pool.mli | 15 +++++-- 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/etherlink/bin_evm_node/evm_node.ml b/etherlink/bin_evm_node/evm_node.ml index eb4f0b2aaac8..1897b80d3b60 100644 --- a/etherlink/bin_evm_node/evm_node.ml +++ b/etherlink/bin_evm_node/evm_node.ml @@ -305,8 +305,13 @@ let proxy_command = in return_unit else - let* rollup_config = rollup_node_config_dev ~rollup_node_endpoint in - let* () = Evm_node_lib_dev.Tx_pool.start rollup_config in + let* ((backend_rpc, smart_rollup_address) as rollup_config) = + rollup_node_config_dev ~rollup_node_endpoint + in + let* () = + Evm_node_lib_dev.Tx_pool.start + (backend_rpc, smart_rollup_address, Proxy) + in let* directory = dev_directory config rollup_config in let* server = start config ~directory in let (_ : Lwt_exit.clean_up_callback_id) = @@ -373,7 +378,10 @@ let sequencer_command = let ctxt = ctxt end) in (* Ignore the smart rollup address for now. *) - let* () = Tx_pool.start ((module Sequencer), "") in + let* () = + Tx_pool.start + ((module Sequencer), "", Sequencer {time_between_blocks = 5.}) + in let* directory = dev_directory config ((module Sequencer), "") in let* server = start config ~directory in let (_ : Lwt_exit.clean_up_callback_id) = install_finalizer_dev server in diff --git a/etherlink/bin_evm_node/lib_dev/tx_pool.ml b/etherlink/bin_evm_node/lib_dev/tx_pool.ml index e71b896e2c01..2f80a4c83f76 100644 --- a/etherlink/bin_evm_node/lib_dev/tx_pool.ml +++ b/etherlink/bin_evm_node/lib_dev/tx_pool.ml @@ -104,15 +104,18 @@ module Pool = struct aux current_nonce user_transactions |> Ethereum_types.quantity_of_z end +type mode = Proxy | Sequencer of {time_between_blocks : float} + module Types = struct type state = { rollup_node : (module Services_backend_sig.S); smart_rollup_address : string; mutable level : Ethereum_types.block_height; mutable pool : Pool.t; + mode : mode; } - type parameters = (module Services_backend_sig.S) * string + type parameters = (module Services_backend_sig.S) * string * mode end module Name = struct @@ -304,7 +307,7 @@ module Handlers = struct type launch_error = error trace - let on_launch _w () (rollup_node, smart_rollup_address) = + let on_launch _w () (rollup_node, smart_rollup_address, mode) = let state = Types. { @@ -312,6 +315,7 @@ module Handlers = struct smart_rollup_address; level = Block_height Z.zero; pool = Pool.empty; + mode; } in Lwt_result_syntax.return state @@ -356,12 +360,12 @@ TODO: https://gitlab.com/tezos/tezos/-/issues/6079 listen to the node instead of pulling the level each 5s *) let rec subscribe_l2_block worker = - let open Lwt_result_syntax in - let*! () = Lwt_unix.sleep 5.0 in + let open Lwt_syntax in + let* () = Lwt_unix.sleep 5.0 in let state = Worker.state worker in let Types.{rollup_node = (module Rollup_node_rpc); _} = state in (* Get the current eth level.*) - let*! res = Rollup_node_rpc.current_block_number () in + let* res = Rollup_node_rpc.current_block_number () in match res with | Error _ -> (* Kind of retry strategy *) @@ -370,25 +374,37 @@ let rec subscribe_l2_block worker = subscribe_l2_block worker | Ok block_number -> if state.level != block_number then - let*! _pushed = + let* _pushed = Worker.Queue.push_request worker (Request.New_l2_head block_number) in subscribe_l2_block worker else subscribe_l2_block worker -let start - ((module Rollup_node_rpc : Services_backend_sig.S), smart_rollup_address) = - let open Lwt_result_syntax in - let+ worker = - Worker.launch - table - () - ((module Rollup_node_rpc), smart_rollup_address) - (module Handlers) +let rec sequencer_produce_block ~time_between_blocks worker = + let open Lwt_syntax in + let* () = Lwt_unix.sleep time_between_blocks in + let state = Worker.state worker in + let Types.{rollup_node = (module Rollup_node_rpc); _} = state in + let* _pushed = + Worker.Queue.push_request + worker + (* The sequencer mode does not rely on the state.level, therefore we do not + care about the value we push. Also, note that this is state.level will + be completely removed when we stream L2 blocks. *) + (Request.New_l2_head (Ethereum_types.Block_height Z.zero)) in + sequencer_produce_block ~time_between_blocks worker + +let start ((_, _, mode) as parameters) = + let open Lwt_result_syntax in + let+ worker = Worker.launch table () parameters (module Handlers) in let () = Lwt.dont_wait - (fun () -> subscribe_l2_block worker) + (fun () -> + match mode with + | Proxy -> subscribe_l2_block worker + | Sequencer {time_between_blocks} -> + sequencer_produce_block ~time_between_blocks worker) (fun _ -> (* TODO: https://gitlab.com/tezos/tezos/-/issues/6569*) Format.printf "[tx-pool] Pool has been stopped.\n%!") diff --git a/etherlink/bin_evm_node/lib_dev/tx_pool.mli b/etherlink/bin_evm_node/lib_dev/tx_pool.mli index d21ba5f3602b..cc0fc69238a7 100644 --- a/etherlink/bin_evm_node/lib_dev/tx_pool.mli +++ b/etherlink/bin_evm_node/lib_dev/tx_pool.mli @@ -5,9 +5,18 @@ (* *) (*****************************************************************************) -(** [start config] starts the tx-pool. The [config] represents the - Rollup_node rpc module and the address of the smart rollup. *) -val start : (module Services_backend_sig.S) * string -> unit tzresult Lwt.t +(* TODO: https://gitlab.com/tezos/tezos/-/issues/6672 + It should be created by the configuration, or at least using values of + the configuration. *) +type mode = Proxy | Sequencer of {time_between_blocks : float} + +(** [start config] starts the tx-pool. The [config] represents: + - the backend rpc module, + - the address of the smart rollup, + - the mode of the node. +*) +val start : + (module Services_backend_sig.S) * string * mode -> unit tzresult Lwt.t (** [shutdown ()] stops the tx-pool, waiting for the ongoing request to be processed. *) -- GitLab From a04cd605500d18e6bdfbcce2abd562ed4d038c99 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Tue, 28 Nov 2023 16:50:39 +0100 Subject: [PATCH 04/15] EVM/Tezt: share the code for run and spawn_run --- tezt/lib_tezos/evm_node.ml | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/tezt/lib_tezos/evm_node.ml b/tezt/lib_tezos/evm_node.ml index 0a8325a5adb8..738b09abfb52 100644 --- a/tezt/lib_tezos/evm_node.ml +++ b/tezt/lib_tezos/evm_node.ml @@ -127,15 +127,13 @@ let rollup_node_endpoint evm_node = let data_dir evm_node = ["--data-dir"; evm_node.persistent_state.data_dir] +let run_args evm_node = + ["run"; "proxy"; "with"; "endpoint"] + @ [rollup_node_endpoint evm_node] + @ data_dir evm_node @ evm_node.persistent_state.arguments + let run evm_node = - let* () = - run - evm_node - {ready = false} - (["run"; "proxy"; "with"; "endpoint"] - @ [rollup_node_endpoint evm_node] - @ data_dir evm_node @ evm_node.persistent_state.arguments) - in + let* () = run evm_node {ready = false} (run_args evm_node) in let* () = wait_for_ready evm_node in unit @@ -145,13 +143,7 @@ let spawn_command evm_node args = (Uses.path Constant.octez_evm_node) @@ args -let spawn_run evm_node = - spawn_command - evm_node - (["run"; "proxy"; "with"; "endpoint"] - @ data_dir evm_node - @ [rollup_node_endpoint evm_node] - @ evm_node.persistent_state.arguments) +let spawn_run evm_node = spawn_command evm_node (run_args evm_node) let endpoint (evm_node : t) = Format.sprintf -- GitLab From 2854c271963823213aea2c283e1709a07c4df79e Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Tue, 28 Nov 2023 16:54:43 +0100 Subject: [PATCH 05/15] EVM/Tezt: sequencer mode --- tezt/lib_tezos/evm_node.ml | 40 ++++++++++++++++++++++++++++--------- tezt/lib_tezos/evm_node.mli | 17 ++++++++++++++-- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/tezt/lib_tezos/evm_node.ml b/tezt/lib_tezos/evm_node.ml index 738b09abfb52..529c111aa092 100644 --- a/tezt/lib_tezos/evm_node.ml +++ b/tezt/lib_tezos/evm_node.ml @@ -25,10 +25,13 @@ (* *) (*****************************************************************************) +type mode = Sequencer of {kernel : string; preimage_dir : string} | Proxy + module Parameters = struct type persistent_state = { arguments : string list; mutable pending_ready : unit option Lwt.u list; + mode : mode; data_dir : string; devmode : bool; rpc_addr : string; @@ -92,7 +95,8 @@ let wait_for_ready evm_node = resolver :: evm_node.persistent_state.pending_ready ; check_event evm_node event_ready_name promise -let create ?runner ?data_dir ~devmode ?rpc_addr ?rpc_port rollup_node = +let create ?runner ?(mode = Proxy) ?data_dir ~devmode ?rpc_addr ?rpc_port + rollup_node = let arguments, rpc_addr, rpc_port = connection_arguments ~devmode ?rpc_addr ?rpc_port () in @@ -107,6 +111,7 @@ let create ?runner ?data_dir ~devmode ?rpc_addr ?rpc_port rollup_node = { arguments; pending_ready = []; + mode; data_dir; devmode; rpc_addr; @@ -118,9 +123,9 @@ let create ?runner ?data_dir ~devmode ?rpc_addr ?rpc_port rollup_node = on_event evm_node (handle_event evm_node) ; evm_node -let create ?runner ?data_dir ?(devmode = false) ?rpc_addr ?rpc_port rollup_node - = - create ?runner ?data_dir ~devmode ?rpc_addr ?rpc_port rollup_node +let create ?runner ?mode ?data_dir ?(devmode = false) ?rpc_addr ?rpc_port + rollup_node = + create ?mode ?runner ?data_dir ~devmode ?rpc_addr ?rpc_port rollup_node let rollup_node_endpoint evm_node = Sc_rollup_node.endpoint evm_node.persistent_state.rollup_node @@ -128,9 +133,25 @@ let rollup_node_endpoint evm_node = let data_dir evm_node = ["--data-dir"; evm_node.persistent_state.data_dir] let run_args evm_node = - ["run"; "proxy"; "with"; "endpoint"] - @ [rollup_node_endpoint evm_node] - @ data_dir evm_node @ evm_node.persistent_state.arguments + let shared_args = data_dir evm_node @ evm_node.persistent_state.arguments in + let mode_args = + match evm_node.persistent_state.mode with + | Proxy -> + ["run"; "proxy"; "with"; "endpoint"; rollup_node_endpoint evm_node] + | Sequencer {kernel; preimage_dir} -> + [ + "run"; + "sequencer"; + "with"; + "endpoint"; + rollup_node_endpoint evm_node; + "--kernel"; + kernel; + "--preimage-dir"; + preimage_dir; + ] + in + mode_args @ shared_args let run evm_node = let* () = run evm_node {ready = false} (run_args evm_node) in @@ -151,9 +172,10 @@ let endpoint (evm_node : t) = evm_node.persistent_state.rpc_addr evm_node.persistent_state.rpc_port -let init ?runner ?data_dir ?(devmode = false) ?rpc_addr ?rpc_port rollup_node = +let init ?runner ?mode ?data_dir ?(devmode = false) ?rpc_addr ?rpc_port + rollup_node = let evm_node = - create ?runner ?data_dir ~devmode ?rpc_addr ?rpc_port rollup_node + create ?runner ?mode ?data_dir ~devmode ?rpc_addr ?rpc_port rollup_node in let* () = run evm_node in return evm_node diff --git a/tezt/lib_tezos/evm_node.mli b/tezt/lib_tezos/evm_node.mli index 6eff38698ce2..65ffad8527d2 100644 --- a/tezt/lib_tezos/evm_node.mli +++ b/tezt/lib_tezos/evm_node.mli @@ -28,7 +28,16 @@ (** EVM node server state. *) type t -(** [create ?runner ?data_dir ?devmode ?rpc_addr ?rpc_port +(** EVM node mode. *) +type mode = + | Sequencer of { + kernel : string; (** Path to the kernel used by the sequencer. *) + preimage_dir : string; + (** Path to the directory with the associated preimages. *) + } + | Proxy + +(** [create ?runner ?mode ?data_dir ?devmode ?rpc_addr ?rpc_port rollup_node] creates an EVM node server. The server listens to requests at address [rpc_addr] and the port @@ -40,9 +49,12 @@ type t The server communicates with a rollup-node and sets its endpoint via [rollup_node]. + + [mode] defaults to [Proxy]. *) val create : ?runner:Runner.t -> + ?mode:mode -> ?data_dir:string -> ?devmode:bool -> ?rpc_addr:string -> @@ -54,11 +66,12 @@ val create : given during {!create}. *) val run : t -> unit Lwt.t -(** [init ?runner ?data_dir ?devmode ?rpc_addr ?rpc_port rollup_node] +(** [init ?runner ?mode ?data_dir ?devmode ?rpc_addr ?rpc_port rollup_node] creates an EVM node server with {!create} and runs it with {!run}. *) val init : ?runner:Runner.t -> + ?mode:mode -> ?data_dir:string -> ?devmode:bool -> ?rpc_addr:string -> -- GitLab From 952fc577b6dc1e680202b4fd54721e61c79a98c7 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Tue, 28 Nov 2023 17:07:19 +0100 Subject: [PATCH 06/15] EVM/Tezt: extract installer configuration in helper module --- manifest/main.ml | 1 + tezt/lib_ethereum/configuration.ml | 47 +++++++++++++++++++++++++++ tezt/lib_ethereum/configuration.mli | 18 +++++++++++ tezt/lib_ethereum/dune | 6 ++-- tezt/tests/evm_rollup.ml | 49 +++-------------------------- 5 files changed, 74 insertions(+), 47 deletions(-) create mode 100644 tezt/lib_ethereum/configuration.ml create mode 100644 tezt/lib_ethereum/configuration.mli diff --git a/manifest/main.ml b/manifest/main.ml index 007fba324afc..e04bed4b14ca 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -2680,6 +2680,7 @@ let tezt_ethereum = tezt_lib |> open_ |> open_ ~m:"Base"; tezt_performance_regression |> open_; octez_crypto; + tezt_tezos |> open_; ] ~release_status:Unreleased diff --git a/tezt/lib_ethereum/configuration.ml b/tezt/lib_ethereum/configuration.ml new file mode 100644 index 000000000000..6c72086e99fb --- /dev/null +++ b/tezt/lib_ethereum/configuration.ml @@ -0,0 +1,47 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +let default_bootstrap_account_balance = Wei.of_eth_int 9999 + +let make_config ?bootstrap_accounts ?ticketer ?administrator () = + let open Sc_rollup_helpers.Installer_kernel_config in + let ticketer = + Option.fold + ~some:(fun ticketer -> + let value = Hex.(of_string ticketer |> show) in + let to_ = Durable_storage_path.ticketer in + [Set {value; to_}]) + ~none:[] + ticketer + in + let bootstrap_accounts = + Option.fold + ~some: + (Array.fold_left + (fun acc Eth_account.{address; _} -> + let value = + Wei.(to_le_bytes default_bootstrap_account_balance) + |> Hex.of_bytes |> Hex.show + in + let to_ = Durable_storage_path.balance address in + Set {value; to_} :: acc) + []) + ~none:[] + bootstrap_accounts + in + let administrator = + Option.fold + ~some:(fun administrator -> + let to_ = Durable_storage_path.admin in + let value = Hex.(of_string administrator |> show) in + [Set {value; to_}]) + ~none:[] + administrator + in + match ticketer @ bootstrap_accounts @ administrator with + | [] -> None + | res -> Some (`Config res) diff --git a/tezt/lib_ethereum/configuration.mli b/tezt/lib_ethereum/configuration.mli new file mode 100644 index 000000000000..386d5f2adfbd --- /dev/null +++ b/tezt/lib_ethereum/configuration.mli @@ -0,0 +1,18 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +(** Default balance given to bootstrap account. *) +val default_bootstrap_account_balance : Wei.t + +(** [make_config ?bootstrap_accounts ?ticketer ?administrator ()] creates + an installer configuration compatible with the EVM kernel. *) +val make_config : + ?bootstrap_accounts:Eth_account.t array -> + ?ticketer:string -> + ?administrator:string -> + unit -> + [> `Config of Sc_rollup_helpers.Installer_kernel_config.instr list] option diff --git a/tezt/lib_ethereum/dune b/tezt/lib_ethereum/dune index 671c6e21ce92..14d7d7996718 100644 --- a/tezt/lib_ethereum/dune +++ b/tezt/lib_ethereum/dune @@ -7,9 +7,11 @@ (libraries tezt tezt-tezos.tezt-performance-regression - octez-libs.crypto) + octez-libs.crypto + tezt-tezos) (flags (:standard) -open Tezt -open Tezt.Base - -open Tezt_tezos_tezt_performance_regression)) + -open Tezt_tezos_tezt_performance_regression + -open Tezt_tezos)) diff --git a/tezt/tests/evm_rollup.ml b/tezt/tests/evm_rollup.ml index b7d35490eb5b..8ffe2acb6268 100644 --- a/tezt/tests/evm_rollup.ml +++ b/tezt/tests/evm_rollup.ml @@ -263,47 +263,6 @@ let setup_l1_contracts ~admin client = return {exchanger; bridge; admin} -let default_bootstrap_account_balance = Wei.of_eth_int 9999 - -let make_config ?bootstrap_accounts ?ticketer ?administrator () = - let open Sc_rollup_helpers.Installer_kernel_config in - let ticketer = - Option.fold - ~some:(fun ticketer -> - let value = Hex.(of_string ticketer |> show) in - let to_ = Durable_storage_path.ticketer in - [Set {value; to_}]) - ~none:[] - ticketer - in - let bootstrap_accounts = - Option.fold - ~some: - (Array.fold_left - (fun acc Eth_account.{address; _} -> - let value = - Wei.(to_le_bytes default_bootstrap_account_balance) - |> Hex.of_bytes |> Hex.show - in - let to_ = Durable_storage_path.balance address in - Set {value; to_} :: acc) - []) - ~none:[] - bootstrap_accounts - in - let administrator = - Option.fold - ~some:(fun administrator -> - let to_ = Durable_storage_path.admin in - let value = Hex.(of_string administrator |> show) in - [Set {value; to_}]) - ~none:[] - administrator - in - match ticketer @ bootstrap_accounts @ administrator with - | [] -> None - | res -> Some (`Config res) - type kernel_installee = {base_installee : string; installee : string} let setup_evm_kernel ?config ?kernel_installee @@ -330,7 +289,7 @@ let setup_evm_kernel ?config ?kernel_installee Option.map (fun {admin; _} -> admin) l1_contracts else None in - make_config ~bootstrap_accounts ?ticketer ?administrator () + Configuration.make_config ~bootstrap_accounts ?ticketer ?administrator () in let config = match (config, base_config) with @@ -593,7 +552,7 @@ let test_rpc_getBalance = ~account:Eth_account.bootstrap_accounts.(0).address ~endpoint:evm_node_endpoint in - Check.((balance = default_bootstrap_account_balance) Wei.typ) + Check.((balance = Configuration.default_bootstrap_account_balance) Wei.typ) ~error_msg: (sf "Expected balance of %s should be %%R, but got %%L" @@ -1336,7 +1295,7 @@ let transfer ?data protocol = } = make_transfer ?data - ~value:Wei.(default_bootstrap_account_balance - one) + ~value:Wei.(Configuration.default_bootstrap_account_balance - one) ~sender ~receiver full_evm_setup @@ -2642,7 +2601,7 @@ let test_kernel_migration = let scenario_prior ~evm_setup = let* transfer_result = make_transfer - ~value:Wei.(default_bootstrap_account_balance - one) + ~value:Wei.(Configuration.default_bootstrap_account_balance - one) ~sender ~receiver evm_setup -- GitLab From 4b96e1c2b0f6fb911c3d7528c74bc3c72020ded7 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Tue, 28 Nov 2023 17:10:32 +0100 Subject: [PATCH 07/15] EVM/Tezt: support sequencer in configuration --- tezt/lib_ethereum/configuration.ml | 9 +++++++-- tezt/lib_ethereum/configuration.mli | 6 ++++-- tezt/lib_ethereum/durable_storage_path.ml | 2 ++ tezt/lib_ethereum/durable_storage_path.mli | 3 +++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/tezt/lib_ethereum/configuration.ml b/tezt/lib_ethereum/configuration.ml index 6c72086e99fb..396644d3f921 100644 --- a/tezt/lib_ethereum/configuration.ml +++ b/tezt/lib_ethereum/configuration.ml @@ -7,7 +7,8 @@ let default_bootstrap_account_balance = Wei.of_eth_int 9999 -let make_config ?bootstrap_accounts ?ticketer ?administrator () = +let make_config ?bootstrap_accounts ?ticketer ?administrator + ?(sequencer = false) () = let open Sc_rollup_helpers.Installer_kernel_config in let ticketer = Option.fold @@ -42,6 +43,10 @@ let make_config ?bootstrap_accounts ?ticketer ?administrator () = ~none:[] administrator in - match ticketer @ bootstrap_accounts @ administrator with + let sequencer = + if sequencer then [Set {value = "00"; to_ = Durable_storage_path.sequencer}] + else [] + in + match ticketer @ bootstrap_accounts @ administrator @ sequencer with | [] -> None | res -> Some (`Config res) diff --git a/tezt/lib_ethereum/configuration.mli b/tezt/lib_ethereum/configuration.mli index 386d5f2adfbd..9f8608e769fa 100644 --- a/tezt/lib_ethereum/configuration.mli +++ b/tezt/lib_ethereum/configuration.mli @@ -8,11 +8,13 @@ (** Default balance given to bootstrap account. *) val default_bootstrap_account_balance : Wei.t -(** [make_config ?bootstrap_accounts ?ticketer ?administrator ()] creates - an installer configuration compatible with the EVM kernel. *) +(** [make_config ?bootstrap_accounts ?ticketer ?administrator + ?sequencer ()] creates an installer configuration compatible with + the EVM kernel. *) val make_config : ?bootstrap_accounts:Eth_account.t array -> ?ticketer:string -> ?administrator:string -> + ?sequencer:bool -> unit -> [> `Config of Sc_rollup_helpers.Installer_kernel_config.instr list] option diff --git a/tezt/lib_ethereum/durable_storage_path.ml b/tezt/lib_ethereum/durable_storage_path.ml index 52b85db71645..5687e3cd83a9 100644 --- a/tezt/lib_ethereum/durable_storage_path.ml +++ b/tezt/lib_ethereum/durable_storage_path.ml @@ -48,4 +48,6 @@ let admin = evm "/admin" let ticketer = evm "/ticketer" +let sequencer = evm "/sequencer" + let kernel_boot_wasm = kernel "/boot.wasm" diff --git a/tezt/lib_ethereum/durable_storage_path.mli b/tezt/lib_ethereum/durable_storage_path.mli index 7096b642e4cb..9a9c4a5322a0 100644 --- a/tezt/lib_ethereum/durable_storage_path.mli +++ b/tezt/lib_ethereum/durable_storage_path.mli @@ -50,5 +50,8 @@ val admin : path (** [ticketer] is the path to the ticketer contract. *) val ticketer : path +(** [sequencer] is the path to the sequencer flag. *) +val sequencer : path + (** [kernel_boot_wasm] is the path to the kernel `boot.wasm`. *) val kernel_boot_wasm : path -- GitLab From 516dd47b1319c680e39a35532a70a096b7590a2a Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Wed, 29 Nov 2023 10:30:57 +0100 Subject: [PATCH 08/15] EVM/Tezt: use rollup_node_endpoint instead of rollup_node --- src/bin_testnet_scenarios/evm_rollup.ml | 4 +++- tezt/lib_tezos/evm_node.ml | 19 +++++++++++-------- tezt/lib_tezos/evm_node.mli | 14 +++++++------- tezt/tests/evm_rollup.ml | 14 ++++++++++---- 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/bin_testnet_scenarios/evm_rollup.ml b/src/bin_testnet_scenarios/evm_rollup.ml index bf404292373e..fa11001111a6 100644 --- a/src/bin_testnet_scenarios/evm_rollup.ml +++ b/src/bin_testnet_scenarios/evm_rollup.ml @@ -132,7 +132,9 @@ let setup_evm_infra ~config ~operator ?runner ?preexisting_rollup (* EVM Kernel installation level. *) let* current_level = Node.get_level node in let* _ = Sc_rollup_node.wait_for_level rollup_node current_level in - let* evm_node = Evm_node.init ~devmode:true ?runner rollup_node in + let* evm_node = + Evm_node.init ~devmode:true ?runner (Sc_rollup_node.endpoint rollup_node) + in Log.info "Node API is available at %s." (Evm_node.endpoint evm_node) ; return (rollup_address, rollup_node, evm_node) diff --git a/tezt/lib_tezos/evm_node.ml b/tezt/lib_tezos/evm_node.ml index 529c111aa092..68d8d4afca32 100644 --- a/tezt/lib_tezos/evm_node.ml +++ b/tezt/lib_tezos/evm_node.ml @@ -36,7 +36,7 @@ module Parameters = struct devmode : bool; rpc_addr : string; rpc_port : int; - rollup_node : Sc_rollup_node.t; + rollup_node_endpoint : string; runner : Runner.t option; } @@ -96,7 +96,7 @@ let wait_for_ready evm_node = check_event evm_node event_ready_name promise let create ?runner ?(mode = Proxy) ?data_dir ~devmode ?rpc_addr ?rpc_port - rollup_node = + rollup_node_endpoint = let arguments, rpc_addr, rpc_port = connection_arguments ~devmode ?rpc_addr ?rpc_port () in @@ -116,7 +116,7 @@ let create ?runner ?(mode = Proxy) ?data_dir ~devmode ?rpc_addr ?rpc_port devmode; rpc_addr; rpc_port; - rollup_node; + rollup_node_endpoint; runner; } in @@ -127,9 +127,6 @@ let create ?runner ?mode ?data_dir ?(devmode = false) ?rpc_addr ?rpc_port rollup_node = create ?mode ?runner ?data_dir ~devmode ?rpc_addr ?rpc_port rollup_node -let rollup_node_endpoint evm_node = - Sc_rollup_node.endpoint evm_node.persistent_state.rollup_node - let data_dir evm_node = ["--data-dir"; evm_node.persistent_state.data_dir] let run_args evm_node = @@ -137,14 +134,20 @@ let run_args evm_node = let mode_args = match evm_node.persistent_state.mode with | Proxy -> - ["run"; "proxy"; "with"; "endpoint"; rollup_node_endpoint evm_node] + [ + "run"; + "proxy"; + "with"; + "endpoint"; + evm_node.persistent_state.rollup_node_endpoint; + ] | Sequencer {kernel; preimage_dir} -> [ "run"; "sequencer"; "with"; "endpoint"; - rollup_node_endpoint evm_node; + evm_node.persistent_state.rollup_node_endpoint; "--kernel"; kernel; "--preimage-dir"; diff --git a/tezt/lib_tezos/evm_node.mli b/tezt/lib_tezos/evm_node.mli index 65ffad8527d2..1c6c91a360a6 100644 --- a/tezt/lib_tezos/evm_node.mli +++ b/tezt/lib_tezos/evm_node.mli @@ -38,7 +38,7 @@ type mode = | Proxy (** [create ?runner ?mode ?data_dir ?devmode ?rpc_addr ?rpc_port - rollup_node] creates an EVM node server. + rollup_node_endpoint] creates an EVM node server. The server listens to requests at address [rpc_addr] and the port [rpc_port]. [rpc_addr] defaults to ["127.0.0.1"] and a fresh port is @@ -48,7 +48,7 @@ type mode = set it to the one on production set [devmode] to [false] (or omit the parameter). The server communicates with a rollup-node and sets its endpoint via - [rollup_node]. + [rollup_node_endpoint]. [mode] defaults to [Proxy]. *) @@ -59,16 +59,16 @@ val create : ?devmode:bool -> ?rpc_addr:string -> ?rpc_port:int -> - Sc_rollup_node.t -> + string -> t (** [run evm_node] launches the EVM node server with the arguments given during {!create}. *) val run : t -> unit Lwt.t -(** [init ?runner ?mode ?data_dir ?devmode ?rpc_addr ?rpc_port rollup_node] - creates an EVM node server with {!create} and runs it with - {!run}. *) +(** [init ?runner ?mode ?data_dir ?devmode ?rpc_addr ?rpc_port + rollup_node_endpoint] creates an EVM node server with {!create} + and runs it with {!run}. *) val init : ?runner:Runner.t -> ?mode:mode -> @@ -76,7 +76,7 @@ val init : ?devmode:bool -> ?rpc_addr:string -> ?rpc_port:int -> - Sc_rollup_node.t -> + string -> t Lwt.t (** [spawn_run evm_node] same as {!run} but spawns a process. *) diff --git a/tezt/tests/evm_rollup.ml b/tezt/tests/evm_rollup.ml index 8ffe2acb6268..4e53cb57f80f 100644 --- a/tezt/tests/evm_rollup.ml +++ b/tezt/tests/evm_rollup.ml @@ -337,7 +337,9 @@ let setup_evm_kernel ?config ?kernel_installee let* () = Client.bake_for_and_wait client in let* level = Node.get_level node in let* _ = Sc_rollup_node.wait_for_level ~timeout:30. sc_rollup_node level in - let* evm_node = Evm_node.init ~devmode:true sc_rollup_node in + let* evm_node = + Evm_node.init ~devmode:true (Sc_rollup_node.endpoint sc_rollup_node) + in let endpoint = Evm_node.endpoint evm_node in return { @@ -486,7 +488,7 @@ let test_evm_node_connection = ~base_dir:(Client.base_dir tezos_client) ~default_operator:Constant.bootstrap1.alias in - let evm_node = Evm_node.create sc_rollup_node in + let evm_node = Evm_node.create (Sc_rollup_node.endpoint sc_rollup_node) in (* Tries to start the EVM node server without a listening rollup node. *) let process = Evm_node.spawn_run evm_node in let* () = Process.check ~expect_failure:true process in @@ -2562,7 +2564,11 @@ let gen_kernel_migration_test ?config ?(admin = Constant.bootstrap5) protocol in (* Load the EVM rollup's storage and sanity check results. *) - let* evm_node = Evm_node.init ~devmode:false evm_setup.sc_rollup_node in + let* evm_node = + Evm_node.init + ~devmode:false + (Sc_rollup_node.endpoint evm_setup.sc_rollup_node) + in let endpoint = Evm_node.endpoint evm_node in let* sanity_check = scenario_prior ~evm_setup:{evm_setup with evm_node; endpoint} @@ -2713,7 +2719,7 @@ let test_deposit_dailynet = smart_rollup_node_extra_args in - let* evm_node = Evm_node.init sc_rollup_node in + let* evm_node = Evm_node.init (Sc_rollup_node.endpoint sc_rollup_node) in let endpoint = Evm_node.endpoint evm_node in (* Deposit tokens to the EVM rollup. *) -- GitLab From bbae6ec043e1ca4a65d4dc10d5e10c89dbc30e24 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Wed, 29 Nov 2023 14:16:34 +0100 Subject: [PATCH 09/15] EVM/Tezt: extract eth_blockNumber RPC --- tezt/lib_ethereum/rpc.ml | 14 ++++++++++++++ tezt/lib_ethereum/rpc.mli | 9 +++++++++ tezt/tests/evm_rollup.ml | 21 +++++---------------- 3 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 tezt/lib_ethereum/rpc.ml create mode 100644 tezt/lib_ethereum/rpc.mli diff --git a/tezt/lib_ethereum/rpc.ml b/tezt/lib_ethereum/rpc.ml new file mode 100644 index 000000000000..d224d5d44c2f --- /dev/null +++ b/tezt/lib_ethereum/rpc.ml @@ -0,0 +1,14 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +let block_number evm_node = + let* json = + Evm_node.call_evm_rpc + evm_node + {method_ = "eth_blockNumber"; parameters = `A []} + in + return JSON.(json |-> "result" |> as_string |> Int32.of_string) diff --git a/tezt/lib_ethereum/rpc.mli b/tezt/lib_ethereum/rpc.mli new file mode 100644 index 000000000000..cdca83025f58 --- /dev/null +++ b/tezt/lib_ethereum/rpc.mli @@ -0,0 +1,9 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +(** [block_number evm_node] calls [eth_blockNumber]. *) +val block_number : Evm_node.t -> int32 Lwt.t diff --git a/tezt/tests/evm_rollup.ml b/tezt/tests/evm_rollup.ml index 4e53cb57f80f..719a47457346 100644 --- a/tezt/tests/evm_rollup.ml +++ b/tezt/tests/evm_rollup.ml @@ -1416,14 +1416,7 @@ let test_simulate = let* {evm_node; sc_rollup_node; _} = setup_past_genesis ~admin:None protocol in - let* json = - Evm_node.call_evm_rpc - evm_node - {method_ = "eth_blockNumber"; parameters = `A []} - in - let block_number = - JSON.(json |-> "result" |> as_string |> int_of_string) - in + let* block_number = Rpc.block_number evm_node in let* simulation_result = Sc_rollup_node.RPC.call sc_rollup_node @@ Sc_rollup_rpc.post_global_block_simulate @@ -1436,7 +1429,9 @@ let test_simulate = | [insight] -> Option.map Helpers.hex_string_to_int insight | _ -> None in - Check.((simulated_block_number = Some (block_number + 1)) (option int)) + Check.( + (simulated_block_number = Some (Int32.to_int block_number + 1)) + (option int)) ~error_msg:"The simulation should advance one L2 block" ; unit) @@ -1597,13 +1592,7 @@ let test_inject_100_transactions = ~error_msg:"Expected %R transactions in the latest block, got %L") ; let* _level = next_evm_level ~sc_rollup_node ~node ~client in - let* latest_evm_level = - Evm_node.( - call_evm_rpc evm_node {method_ = "eth_blockNumber"; parameters = `A []}) - in - let latest_evm_level = - latest_evm_level |> Evm_node.extract_result |> JSON.as_int32 - in + let* latest_evm_level = Rpc.block_number evm_node in (* At each loop, the kernel reads the previous block. Until the patch, the kernel failed to read the previous block if there was more than 64 hash, this test ensures it works by assessing new blocks are produced. *) -- GitLab From 8d38c99e8886f9d9b74e629a9c11c11198eac0a6 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Wed, 29 Nov 2023 14:46:54 +0100 Subject: [PATCH 10/15] EVM/Tezt: expose terminate --- tezt/lib_tezos/evm_node.mli | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tezt/lib_tezos/evm_node.mli b/tezt/lib_tezos/evm_node.mli index 1c6c91a360a6..9d05f3319880 100644 --- a/tezt/lib_tezos/evm_node.mli +++ b/tezt/lib_tezos/evm_node.mli @@ -82,6 +82,11 @@ val init : (** [spawn_run evm_node] same as {!run} but spawns a process. *) val spawn_run : t -> Process.t +(** Send SIGTERM and wait for the process to terminate. + + Default [timeout] is 30 seconds, after which SIGKILL is sent. *) +val terminate : ?timeout:float -> t -> unit Lwt.t + (** [endpoint evm_node] returns the endpoint to communicate with the [evm_node]. *) val endpoint : t -> string -- GitLab From d15a89eb02751495d44d8c09415f5e8c2554155a Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Thu, 30 Nov 2023 14:06:16 +0100 Subject: [PATCH 11/15] EVM/Tezt: stop and rerun sequencer to test persistency --- tezt/tests/evm_sequencer.ml | 57 ++++++++++++++++++++++++++++++++++++ tezt/tests/evm_sequencer.mli | 16 ++++++++++ tezt/tests/main.ml | 1 + 3 files changed, 74 insertions(+) create mode 100644 tezt/tests/evm_sequencer.ml create mode 100644 tezt/tests/evm_sequencer.mli diff --git a/tezt/tests/evm_sequencer.ml b/tezt/tests/evm_sequencer.ml new file mode 100644 index 000000000000..d22e163e5fce --- /dev/null +++ b/tezt/tests/evm_sequencer.ml @@ -0,0 +1,57 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +open Sc_rollup_helpers + +let setup_sequencer ?(bootstrap_accounts = Eth_account.bootstrap_accounts) () = + let preimages_dir = Temp.dir "preimages" in + let config = + Configuration.make_config ~bootstrap_accounts ~sequencer:true () + in + let* {output; _} = + prepare_installer_kernel + ~base_installee:"./" + ~preimages_dir + ?config + "evm_kernel" + in + let mode = + Evm_node.Sequencer {kernel = output; preimage_dir = preimages_dir} + in + Evm_node.init ~mode ~devmode:false "0.0.0.0:0" + +let test_persistent_state = + Protocol.register_test + ~__FILE__ + ~tags:["evm"; "sequencer"] + ~title:"Sequencer state is persistent across runs" + @@ fun _protocol -> + let* evm_node = setup_sequencer () in + (* Sleep to let the sequencer produce some blocks. *) + let* () = Lwt_unix.sleep 20. in + (* Ask for the current block. *) + let* block_number = Rpc.block_number evm_node in + Check.is_true + ~__LOC__ + (block_number > 0l) + ~error_msg:"The sequencer should have produced a block" ; + (* Terminate the sequencer. *) + let* () = Evm_node.terminate evm_node in + (* Restart it. *) + let* () = Evm_node.run evm_node in + (* Assert the block number is at least [block_number]. Asserting + that the block number is exactly the same as {!block_number} can + be flaky if a block is produced between the restart and the + RPC. *) + let* new_block_number = Rpc.block_number evm_node in + Check.is_true + ~__LOC__ + (new_block_number >= block_number) + ~error_msg:"The sequencer should have produced a block" ; + unit + +let register ~protocols = test_persistent_state protocols diff --git a/tezt/tests/evm_sequencer.mli b/tezt/tests/evm_sequencer.mli new file mode 100644 index 000000000000..dfd5caa382eb --- /dev/null +++ b/tezt/tests/evm_sequencer.mli @@ -0,0 +1,16 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2023 Nomadic Labs *) +(* *) +(*****************************************************************************) + +(* Testing + ------- + Component: Etherlink: sequencer + Requirement: make -f kernels.mk build + npm install eth-cli + Invocation: dune exec tezt/tests/main.exe -- --file evm_sequencer.ml +*) + +val register : protocols:Protocol.t list -> unit diff --git a/tezt/tests/main.ml b/tezt/tests/main.ml index ab67c6ebf5d2..2da7b89e2c9a 100644 --- a/tezt/tests/main.ml +++ b/tezt/tests/main.ml @@ -224,6 +224,7 @@ let register_protocol_tests_that_use_supports_correctly () = let register_protocol_specific_because_regression_tests () = Dal.register ~protocols:[Alpha] ; Evm_rollup.register ~protocols:[Alpha] ; + Evm_sequencer.register ~protocols:[Alpha] ; (* This can be safely removed after Nairobi is frozen *) Timelock_disabled.register ~protocols:[Nairobi] -- GitLab From c69791523f994716797e60ac608022f8a40f4277 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Fri, 1 Dec 2023 16:40:48 +0100 Subject: [PATCH 12/15] EVM/Node: use a struct for parameters The rollup node field is not properly renamed in this commit. It needs to be renamed at several location, adding more noise to this commit. --- etherlink/bin_evm_node/evm_node.ml | 8 ++++++-- etherlink/bin_evm_node/lib_dev/tx_pool.ml | 21 ++++++++++++++++----- etherlink/bin_evm_node/lib_dev/tx_pool.mli | 15 ++++++++------- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/etherlink/bin_evm_node/evm_node.ml b/etherlink/bin_evm_node/evm_node.ml index 1897b80d3b60..05070592309f 100644 --- a/etherlink/bin_evm_node/evm_node.ml +++ b/etherlink/bin_evm_node/evm_node.ml @@ -310,7 +310,7 @@ let proxy_command = in let* () = Evm_node_lib_dev.Tx_pool.start - (backend_rpc, smart_rollup_address, Proxy) + {rollup_node = backend_rpc; smart_rollup_address; mode = Proxy} in let* directory = dev_directory config rollup_config in let* server = start config ~directory in @@ -380,7 +380,11 @@ let sequencer_command = (* Ignore the smart rollup address for now. *) let* () = Tx_pool.start - ((module Sequencer), "", Sequencer {time_between_blocks = 5.}) + { + rollup_node = (module Sequencer); + smart_rollup_address = ""; + mode = Sequencer {time_between_blocks = 5.}; + } in let* directory = dev_directory config ((module Sequencer), "") in let* server = start config ~directory in diff --git a/etherlink/bin_evm_node/lib_dev/tx_pool.ml b/etherlink/bin_evm_node/lib_dev/tx_pool.ml index 2f80a4c83f76..551ab49e7698 100644 --- a/etherlink/bin_evm_node/lib_dev/tx_pool.ml +++ b/etherlink/bin_evm_node/lib_dev/tx_pool.ml @@ -106,6 +106,12 @@ end type mode = Proxy | Sequencer of {time_between_blocks : float} +type parameters = { + rollup_node : (module Services_backend_sig.S); + smart_rollup_address : string; + mode : mode; +} + module Types = struct type state = { rollup_node : (module Services_backend_sig.S); @@ -115,7 +121,7 @@ module Types = struct mode : mode; } - type parameters = (module Services_backend_sig.S) * string * mode + type nonrec parameters = parameters end module Name = struct @@ -307,7 +313,8 @@ module Handlers = struct type launch_error = error trace - let on_launch _w () (rollup_node, smart_rollup_address, mode) = + let on_launch _w () + ({rollup_node; smart_rollup_address; mode} : Types.parameters) = let state = Types. { @@ -363,7 +370,9 @@ let rec subscribe_l2_block worker = let open Lwt_syntax in let* () = Lwt_unix.sleep 5.0 in let state = Worker.state worker in - let Types.{rollup_node = (module Rollup_node_rpc); _} = state in + let (Types.{rollup_node = (module Rollup_node_rpc); _} : Types.state) = + state + in (* Get the current eth level.*) let* res = Rollup_node_rpc.current_block_number () in match res with @@ -384,7 +393,9 @@ let rec sequencer_produce_block ~time_between_blocks worker = let open Lwt_syntax in let* () = Lwt_unix.sleep time_between_blocks in let state = Worker.state worker in - let Types.{rollup_node = (module Rollup_node_rpc); _} = state in + let (Types.{rollup_node = (module Rollup_node_rpc); _} : Types.state) = + state + in let* _pushed = Worker.Queue.push_request worker @@ -395,7 +406,7 @@ let rec sequencer_produce_block ~time_between_blocks worker = in sequencer_produce_block ~time_between_blocks worker -let start ((_, _, mode) as parameters) = +let start ({mode; _} as parameters) = let open Lwt_result_syntax in let+ worker = Worker.launch table () parameters (module Handlers) in let () = diff --git a/etherlink/bin_evm_node/lib_dev/tx_pool.mli b/etherlink/bin_evm_node/lib_dev/tx_pool.mli index cc0fc69238a7..ec8cceb88998 100644 --- a/etherlink/bin_evm_node/lib_dev/tx_pool.mli +++ b/etherlink/bin_evm_node/lib_dev/tx_pool.mli @@ -10,13 +10,14 @@ the configuration. *) type mode = Proxy | Sequencer of {time_between_blocks : float} -(** [start config] starts the tx-pool. The [config] represents: - - the backend rpc module, - - the address of the smart rollup, - - the mode of the node. -*) -val start : - (module Services_backend_sig.S) * string * mode -> unit tzresult Lwt.t +type parameters = { + rollup_node : (module Services_backend_sig.S); (** The backend RPC module. *) + smart_rollup_address : string; (** The address of the smart rollup. *) + mode : mode; (** The mode of the node. *) +} + +(** [start parameters] starts the tx-pool *) +val start : parameters -> unit tzresult Lwt.t (** [shutdown ()] stops the tx-pool, waiting for the ongoing request to be processed. *) -- GitLab From 205a8734a3b2f2f60351ac766c06f2adcf556490 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Fri, 1 Dec 2023 16:42:29 +0100 Subject: [PATCH 13/15] EVM/Node: rename request to [Inject_transactions] --- etherlink/bin_evm_node/lib_dev/tx_pool.ml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/etherlink/bin_evm_node/lib_dev/tx_pool.ml b/etherlink/bin_evm_node/lib_dev/tx_pool.ml index 551ab49e7698..7e4d2dd1e3f2 100644 --- a/etherlink/bin_evm_node/lib_dev/tx_pool.ml +++ b/etherlink/bin_evm_node/lib_dev/tx_pool.ml @@ -142,7 +142,7 @@ module Request = struct | Add_transaction : string -> ((Ethereum_types.hash, string) result, tztrace) t - | New_l2_head : Ethereum_types.block_height -> (unit, tztrace) t + | Inject_transactions : Ethereum_types.block_height -> (unit, tztrace) t type view = View : _ t -> view @@ -163,12 +163,12 @@ module Request = struct (fun ((), messages) -> View (Add_transaction messages)); case (Tag 1) - ~title:"New_l2_head" + ~title:"Inject_transactions" (obj2 (req "request" (constant "new_l2_head")) (req "block_height" Ethereum_types.block_height_encoding)) - (function View (New_l2_head b) -> Some ((), b) | _ -> None) - (fun ((), b) -> View (New_l2_head b)); + (function View (Inject_transactions b) -> Some ((), b) | _ -> None) + (fun ((), b) -> View (Inject_transactions b)); ] let pp ppf (View r) = @@ -178,7 +178,7 @@ module Request = struct ppf "Add [%s] tx to tx-pool" (Hex.of_string transaction |> Hex.show) - | New_l2_head block_height -> + | Inject_transactions block_height -> let (Ethereum_types.Block_height block_height) = block_height in Format.fprintf ppf "New L2 head: %s" (Z.to_string block_height) end @@ -308,7 +308,7 @@ module Handlers = struct match request with | Request.Add_transaction raw_tx -> protect @@ fun () -> on_transaction state raw_tx - | Request.New_l2_head block_height -> + | Request.Inject_transactions block_height -> protect @@ fun () -> on_head state block_height type launch_error = error trace @@ -384,7 +384,9 @@ let rec subscribe_l2_block worker = | Ok block_number -> if state.level != block_number then let* _pushed = - Worker.Queue.push_request worker (Request.New_l2_head block_number) + Worker.Queue.push_request + worker + (Request.Inject_transactions block_number) in subscribe_l2_block worker else subscribe_l2_block worker @@ -402,7 +404,7 @@ let rec sequencer_produce_block ~time_between_blocks worker = (* The sequencer mode does not rely on the state.level, therefore we do not care about the value we push. Also, note that this is state.level will be completely removed when we stream L2 blocks. *) - (Request.New_l2_head (Ethereum_types.Block_height Z.zero)) + (Request.Inject_transactions (Ethereum_types.Block_height Z.zero)) in sequencer_produce_block ~time_between_blocks worker -- GitLab From cfe62d62e4596f65350745f4a7efe6ecbebe78b1 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Mon, 4 Dec 2023 14:16:29 +0100 Subject: [PATCH 14/15] WASM/Debugger: support hex file --- CHANGES.rst | 3 ++ .../bin_evm_node/lib_dev/sequencer_state.ml | 1 - src/lib_wasm_debugger/wasm_debugger.ml | 28 +++++++++++++------ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index cdc84d1873c7..daf7fcd84dbb 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -204,6 +204,9 @@ Smart Rollup WASM Debugger the debugger via the option ``--installer-config`` and will initialize the storage with this configuration. (MR :gl:`!9641`) +- The argument ``--kernel`` accepts hexadecimal files (suffixed by ``.hex``), it + is consired as an hexadecimal ``.wasm`` file. (MR :gl:`!11094`) + Data Availability Committee (DAC) --------------------------------- diff --git a/etherlink/bin_evm_node/lib_dev/sequencer_state.ml b/etherlink/bin_evm_node/lib_dev/sequencer_state.ml index 5e52f47da053..f92b1a40d15d 100644 --- a/etherlink/bin_evm_node/lib_dev/sequencer_state.ml +++ b/etherlink/bin_evm_node/lib_dev/sequencer_state.ml @@ -30,7 +30,6 @@ let init ctxt = Wasm.start ~tree:ctxt.Sequencer_context.evm_state Tezos_scoru_wasm.Wasm_pvm_state.V3 - true ctxt.kernel in let ctxt = {ctxt with evm_state} in diff --git a/src/lib_wasm_debugger/wasm_debugger.ml b/src/lib_wasm_debugger/wasm_debugger.ml index 136be971a834..46663521fb73 100644 --- a/src/lib_wasm_debugger/wasm_debugger.ml +++ b/src/lib_wasm_debugger/wasm_debugger.ml @@ -106,10 +106,27 @@ module Make (Wasm : Wasm_utils_intf.S) = struct let*! tree = Wasm.eval_until_input_requested tree in return tree - let start ?installer_config ?tree version binary file = + let start ?installer_config ?tree version file = let open Lwt_result_syntax in let module_name = Filename.(file |> basename |> chop_extension) in - let*! buffer = Repl_helpers.read_file file in + let* buffer, binary = + if Filename.(check_suffix file ".hex") then + let*! content = Repl_helpers.read_file file in + let*? content = + match Hex.to_string (`Hex content) with + | Some content -> Ok content + | None -> error_with "%S is not a valid hexadecimal file" file + in + return (content, true) + else + let*! content = Repl_helpers.read_file file in + let*? binary = + if Filename.check_suffix file ".wasm" then Ok true + else if Filename.check_suffix file ".wast" then Ok false + else error_with "Kernels should have .wasm or .wast file extension" + in + return (content, binary) + in handle_module ?installer_config ?tree version binary module_name buffer (* REPL main loop: reads an input, does something out of it, then loops. *) @@ -338,11 +355,6 @@ module Make (Wasm : Wasm_utils_intf.S) = struct | Some wasm_file -> Ok wasm_file | None -> error_with "A kernel file must be provided" in - let*? binary = - if Filename.check_suffix wasm_file ".wasm" then Ok true - else if Filename.check_suffix wasm_file ".wast" then Ok false - else error_with "Kernels should have .wasm or .wast file extension" - in let parse_json_config content = match Data_encoding.Json.from_string content with | Ok json -> ( @@ -366,7 +378,7 @@ module Make (Wasm : Wasm_utils_intf.S) = struct | `Json, content -> parse_json_config content) installer_config in - let* tree = start ?installer_config version binary wasm_file in + let* tree = start ?installer_config version wasm_file in let* inboxes = match inputs with | Some inputs -> Messages.parse_inboxes inputs config -- GitLab From bdfe81bba7a3d1785bb680c18722802269582bb3 Mon Sep 17 00:00:00 2001 From: Valentin Chaboche Date: Mon, 4 Dec 2023 15:17:19 +0100 Subject: [PATCH 15/15] EVM/Sequencer: update blueprints' format --- etherlink/bin_evm_node/evm_node.ml | 15 ++++++++--- etherlink/bin_evm_node/lib_dev/publisher.ml | 7 ++++-- etherlink/bin_evm_node/lib_dev/rollup_node.ml | 2 +- etherlink/bin_evm_node/lib_dev/sequencer.ml | 6 +++-- .../lib_dev/sequencer_blueprint.ml | 12 ++++++--- .../lib_dev/sequencer_blueprint.mli | 8 +++--- .../bin_evm_node/lib_dev/sequencer_context.ml | 18 +++++++++++-- .../lib_dev/sequencer_context.mli | 8 +++--- .../bin_evm_node/lib_dev/sequencer_state.ml | 7 ++++-- .../bin_evm_node/lib_dev/sequencer_state.mli | 8 ++++-- tezt/tests/evm_sequencer.ml | 25 +++++++++++++++---- 11 files changed, 88 insertions(+), 28 deletions(-) diff --git a/etherlink/bin_evm_node/evm_node.ml b/etherlink/bin_evm_node/evm_node.ml index 05070592309f..5d9584f8920f 100644 --- a/etherlink/bin_evm_node/evm_node.ml +++ b/etherlink/bin_evm_node/evm_node.ml @@ -367,13 +367,20 @@ let sequencer_command = in let* () = Configuration.save_sequencer ~force:true ~data_dir config in let open Evm_node_lib_dev in + let* smart_rollup_address = + Rollup_node_services.smart_rollup_address rollup_node_endpoint + in let* ctxt, loaded = Sequencer_context.init ~data_dir ~kernel:config.mode.kernel ~preimages:config.mode.preimages + ~smart_rollup_address + in + let* ctxt = + if loaded then return ctxt + else Sequencer_state.init ~smart_rollup_address ctxt in - let* ctxt = if loaded then return ctxt else Sequencer_state.init ctxt in let module Sequencer = Sequencer.Make (struct let ctxt = ctxt end) in @@ -382,11 +389,13 @@ let sequencer_command = Tx_pool.start { rollup_node = (module Sequencer); - smart_rollup_address = ""; + smart_rollup_address; mode = Sequencer {time_between_blocks = 5.}; } in - let* directory = dev_directory config ((module Sequencer), "") in + let* directory = + dev_directory config ((module Sequencer), smart_rollup_address) + in let* server = start config ~directory in let (_ : Lwt_exit.clean_up_callback_id) = install_finalizer_dev server in let wait, _resolve = Lwt.wait () in diff --git a/etherlink/bin_evm_node/lib_dev/publisher.ml b/etherlink/bin_evm_node/lib_dev/publisher.ml index b2301fa4537e..3332bda5ea81 100644 --- a/etherlink/bin_evm_node/lib_dev/publisher.ml +++ b/etherlink/bin_evm_node/lib_dev/publisher.ml @@ -15,7 +15,8 @@ module type TxEncoder = sig end module type Publisher = sig - val publish_messages : messages:string list -> unit tzresult Lwt.t + val publish_messages : + smart_rollup_address:string -> messages:string list -> unit tzresult Lwt.t end module Make (TxEncoder : TxEncoder) (Publisher : Publisher) = struct @@ -33,6 +34,8 @@ module Make (TxEncoder : TxEncoder) (Publisher : Publisher) = struct ([], []) transactions in - let* () = Publisher.publish_messages ~messages:to_publish in + let* () = + Publisher.publish_messages ~smart_rollup_address ~messages:to_publish + in return (List.rev rev_tx_hashes) end diff --git a/etherlink/bin_evm_node/lib_dev/rollup_node.ml b/etherlink/bin_evm_node/lib_dev/rollup_node.ml index f945a8f25955..8a326a150be7 100644 --- a/etherlink/bin_evm_node/lib_dev/rollup_node.ml +++ b/etherlink/bin_evm_node/lib_dev/rollup_node.ml @@ -43,7 +43,7 @@ end) : Services_backend_sig.Backend = struct end module Publisher = struct - let publish_messages ~messages = + let publish_messages ~smart_rollup_address:_ ~messages = let open Lwt_result_syntax in (* The injection's service returns a notion of L2 message hash (defined by the rollup node) used to track the message's injection in the batcher. diff --git a/etherlink/bin_evm_node/lib_dev/sequencer.ml b/etherlink/bin_evm_node/lib_dev/sequencer.ml index 5500f337145c..9c108c0cda6b 100644 --- a/etherlink/bin_evm_node/lib_dev/sequencer.ml +++ b/etherlink/bin_evm_node/lib_dev/sequencer.ml @@ -29,10 +29,12 @@ end) : Services_backend_sig.Backend = struct end module Publisher = struct - let publish_messages ~messages = + let publish_messages ~smart_rollup_address ~messages = let open Lwt_result_syntax in (* Create the blueprint with the messages. *) - let inputs = Sequencer_blueprint.create ~transactions:messages in + let inputs = + Sequencer_blueprint.create ~smart_rollup_address ~transactions:messages + in (* Execute the blueprint. *) let* ctxt = Sequencer_context.sync Ctxt.ctxt in let* _ctxt = Sequencer_state.execute ~commit:true ctxt inputs in diff --git a/etherlink/bin_evm_node/lib_dev/sequencer_blueprint.ml b/etherlink/bin_evm_node/lib_dev/sequencer_blueprint.ml index b18f80b73c45..0103ec77aa17 100644 --- a/etherlink/bin_evm_node/lib_dev/sequencer_blueprint.ml +++ b/etherlink/bin_evm_node/lib_dev/sequencer_blueprint.ml @@ -12,7 +12,7 @@ let now_bytes () = Time.Protocol.to_seconds timestamp |> Z.of_int64 |> Z.to_bits |> Bytes.of_string -let create ~transactions = +let create ~smart_rollup_address ~transactions = let timestamp = Rlp.Value (now_bytes ()) in let messages = Rlp.List @@ -23,5 +23,11 @@ let create ~transactions = let rlp_blueprint = Rlp.List [messages; timestamp] |> Rlp.encode |> Bytes.to_string in - (* External message tag. *) - ["\001" ^ rlp_blueprint] + + [ + "\001" (* External message *) ^ "\000" + (* Framed protocol *) ^ smart_rollup_address + ^ "\003" + ^ (* Blueprint *) + rlp_blueprint; + ] diff --git a/etherlink/bin_evm_node/lib_dev/sequencer_blueprint.mli b/etherlink/bin_evm_node/lib_dev/sequencer_blueprint.mli index b6852a4f03a3..5635611d53aa 100644 --- a/etherlink/bin_evm_node/lib_dev/sequencer_blueprint.mli +++ b/etherlink/bin_evm_node/lib_dev/sequencer_blueprint.mli @@ -5,6 +5,8 @@ (* *) (*****************************************************************************) -(** [create transactions] creates a sequencer blueprint containing - [transactions]. Returns the inputs to put in the inbox. *) -val create : transactions:string list -> string list +(** [create ~smart_rollup_address ~transactions] creates a sequencer + blueprint containing [transactions]. Returns the inputs to put in + the inbox. *) +val create : + smart_rollup_address:string -> transactions:string list -> string list diff --git a/etherlink/bin_evm_node/lib_dev/sequencer_context.ml b/etherlink/bin_evm_node/lib_dev/sequencer_context.ml index d504a1dfa2c6..43f9581f4a67 100644 --- a/etherlink/bin_evm_node/lib_dev/sequencer_context.ml +++ b/etherlink/bin_evm_node/lib_dev/sequencer_context.ml @@ -20,6 +20,7 @@ type t = { evm_state : evm_state; kernel : string; preimages : string; + smart_rollup_address : Tezos_crypto.Hashed.Smart_rollup_address.t; } (** The EVM/PVM local state used by the sequencer. *) @@ -65,11 +66,24 @@ let load_checkpoint ~data_dir index = let evm_state = Context.Tree.empty store in return (store, evm_state, false) -let init ~data_dir ~kernel ~preimages = +let init ~data_dir ~kernel ~preimages ~smart_rollup_address = let open Lwt_result_syntax in let*! index = Context.init (store_path ~data_dir) in let* store, evm_state, loaded = load_checkpoint ~data_dir index in - return ({index; store; data_dir; evm_state; kernel; preimages}, loaded) + let smart_rollup_address = + Tezos_crypto.Hashed.Smart_rollup_address.of_string_exn smart_rollup_address + in + return + ( { + index; + store; + data_dir; + evm_state; + kernel; + preimages; + smart_rollup_address; + }, + loaded ) let commit ctxt evm_state = let open Lwt_result_syntax in diff --git a/etherlink/bin_evm_node/lib_dev/sequencer_context.mli b/etherlink/bin_evm_node/lib_dev/sequencer_context.mli index d1508afdf102..4289f1f75fac 100644 --- a/etherlink/bin_evm_node/lib_dev/sequencer_context.mli +++ b/etherlink/bin_evm_node/lib_dev/sequencer_context.mli @@ -20,11 +20,12 @@ type t = { evm_state : evm_state; (** EVM local state of the sequencer. *) kernel : string; (** Path to the kernel to execute. *) preimages : string; (** Path to the preimages directory. *) + smart_rollup_address : Tezos_crypto.Hashed.Smart_rollup_address.t; } -(** [init ~data_dir ~kernel ~preimages] creates a context where it - initializes the {!type-index}, and use a checkpoint mechanism to load - the latest {!type-store} if any. +(** [init ~data_dir ~kernel ~preimages ~smart_rollup_address] creates + a context where it initializes the {!type-index}, and use a + checkpoint mechanism to load the latest {!type-store} if any. Also returns a boolean denoting whether the context was initialized or not. *) @@ -32,6 +33,7 @@ val init : data_dir:string -> kernel:string -> preimages:string -> + smart_rollup_address:string -> (t * bool) tzresult Lwt.t (** [commit ctxt evm_state] updates the [evm_state] in [ctxt], commits diff --git a/etherlink/bin_evm_node/lib_dev/sequencer_state.ml b/etherlink/bin_evm_node/lib_dev/sequencer_state.ml index f92b1a40d15d..1bd58da47455 100644 --- a/etherlink/bin_evm_node/lib_dev/sequencer_state.ml +++ b/etherlink/bin_evm_node/lib_dev/sequencer_state.ml @@ -17,6 +17,7 @@ let execute ?(commit = false) ctxt inbox = Config.config ~preimage_directory:ctxt.Sequencer_context.preimages ~kernel_debug:true + ~destination:ctxt.Sequencer_context.smart_rollup_address () in let* pvm_state, _, _, _ = @@ -24,7 +25,7 @@ let execute ?(commit = false) ctxt inbox = in if commit then Sequencer_context.commit ctxt pvm_state else return ctxt -let init ctxt = +let init ~smart_rollup_address ctxt = let open Lwt_result_syntax in let* evm_state = Wasm.start @@ -34,7 +35,9 @@ let init ctxt = in let ctxt = {ctxt with evm_state} in (* Create the first empty block. *) - let inputs = Sequencer_blueprint.create ~transactions:[] in + let inputs = + Sequencer_blueprint.create ~smart_rollup_address ~transactions:[] + in execute ~commit:true ctxt inputs let inspect evm_state key = diff --git a/etherlink/bin_evm_node/lib_dev/sequencer_state.mli b/etherlink/bin_evm_node/lib_dev/sequencer_state.mli index 19443b2c8a92..87ac577c6de4 100644 --- a/etherlink/bin_evm_node/lib_dev/sequencer_state.mli +++ b/etherlink/bin_evm_node/lib_dev/sequencer_state.mli @@ -13,8 +13,12 @@ val execute : string list -> Sequencer_context.t tzresult Lwt.t -(** [init ctxt] initializes the local state in [ctxt], bakes the genesis block. *) -val init : Sequencer_context.t -> Sequencer_context.t tzresult Lwt.t +(** [init ~smart_rollup_address ctxt] initializes the local state in + [ctxt], bakes the genesis block. *) +val init : + smart_rollup_address:string -> + Sequencer_context.t -> + Sequencer_context.t tzresult Lwt.t (** [inspect evm_state key] inspects [key] in [evm_state]. *) val inspect : Sequencer_context.evm_state -> string -> bytes option Lwt.t diff --git a/tezt/tests/evm_sequencer.ml b/tezt/tests/evm_sequencer.ml index d22e163e5fce..9c7288c5833d 100644 --- a/tezt/tests/evm_sequencer.ml +++ b/tezt/tests/evm_sequencer.ml @@ -7,8 +7,13 @@ open Sc_rollup_helpers -let setup_sequencer ?(bootstrap_accounts = Eth_account.bootstrap_accounts) () = - let preimages_dir = Temp.dir "preimages" in +let setup_sequencer ?(bootstrap_accounts = Eth_account.bootstrap_accounts) + protocol = + let* node, client = setup_l1 protocol in + let sc_rollup_node = + Sc_rollup_node.create Observer node ~base_dir:(Client.base_dir client) + in + let preimages_dir = Sc_rollup_node.data_dir sc_rollup_node // "wasm_2_0_0" in let config = Configuration.make_config ~bootstrap_accounts ~sequencer:true () in @@ -19,18 +24,28 @@ let setup_sequencer ?(bootstrap_accounts = Eth_account.bootstrap_accounts) () = ?config "evm_kernel" in + let* sc_rollup_address = + originate_sc_rollup + ~kind:"wasm_2_0_0" + ~boot_sector:("file:" ^ output) + ~parameters_ty:"unit" + client + in + let* () = + Sc_rollup_node.run sc_rollup_node sc_rollup_address ["--log-kernel-debug"] + in let mode = Evm_node.Sequencer {kernel = output; preimage_dir = preimages_dir} in - Evm_node.init ~mode ~devmode:false "0.0.0.0:0" + Evm_node.init ~mode ~devmode:false (Sc_rollup_node.endpoint sc_rollup_node) let test_persistent_state = Protocol.register_test ~__FILE__ ~tags:["evm"; "sequencer"] ~title:"Sequencer state is persistent across runs" - @@ fun _protocol -> - let* evm_node = setup_sequencer () in + @@ fun protocol -> + let* evm_node = setup_sequencer protocol in (* Sleep to let the sequencer produce some blocks. *) let* () = Lwt_unix.sleep 20. in (* Ask for the current block. *) -- GitLab