From bc1b3dcd0b0db3974d25715dce1c4075255ffcb7 Mon Sep 17 00:00:00 2001 From: Thomas Letan Date: Tue, 27 Aug 2024 09:36:13 +0200 Subject: [PATCH] EVM Node: Make the sequencer mode use the read-only context for RPCs This changeset has several short term benefits 1. Relying on the read-write `Evm_context` module to implement the RPC services means that everytime we need to checkout an EVM state, we need to go through the worker. 2. This is simpler, and remove code. 3. We want to move towards spawning RPC nodes anyway, and this is a move in that direction. Semantically, this is a no-op patch, but pragramtically, it is possible that RPCs targeting the `latest` state becomes a bit slower. --- etherlink/bin_node/lib_dev/evm_ro_context.ml | 48 ++++++++------ etherlink/bin_node/lib_dev/evm_ro_context.mli | 13 +++- etherlink/bin_node/lib_dev/observer.ml | 3 +- etherlink/bin_node/lib_dev/rpc.ml | 2 +- etherlink/bin_node/lib_dev/sequencer.ml | 65 ++++--------------- 5 files changed, 54 insertions(+), 77 deletions(-) diff --git a/etherlink/bin_node/lib_dev/evm_ro_context.ml b/etherlink/bin_node/lib_dev/evm_ro_context.ml index fb9bb41fb361..d69bb7e7fa83 100644 --- a/etherlink/bin_node/lib_dev/evm_ro_context.ml +++ b/etherlink/bin_node/lib_dev/evm_ro_context.ml @@ -14,15 +14,18 @@ type t = { index : Irmin_context.ro_index; } -let load ~data_dir ~preimages ?preimages_endpoint () = +let load ?smart_rollup_address ~data_dir ~preimages ?preimages_endpoint () = let open Lwt_result_syntax in let* store = Evm_store.init ~data_dir ~perm:`Read_only () in let* index = Irmin_context.( load ~cache_size:100_000 Read_only (Evm_state.irmin_store_path ~data_dir)) in - Evm_store.use store @@ fun conn -> - let+ smart_rollup_address = Evm_store.Metadata.get conn in + let+ smart_rollup_address = + match smart_rollup_address with + | None -> Evm_store.(use store Metadata.get) + | Some smart_rollup_address -> return smart_rollup_address + in {store; index; data_dir; preimages; preimages_endpoint; smart_rollup_address} let get_evm_state ctxt hash = @@ -94,7 +97,7 @@ let find_irmin_hash ctxt (block : Ethereum_types.Block_parameter.extended) = module MakeBackend (Ctxt : sig val ctxt : t - val evm_node_endpoint : Uri.t + val evm_node_endpoint : Uri.t option val keep_alive : bool end) = @@ -169,21 +172,24 @@ struct let publish_messages ~timestamp:_ ~smart_rollup_address:_ ~messages = let open Rollup_services in let open Lwt_result_syntax in - let methods = List.map send_raw_transaction_method messages in - - let* response = - call_service - ~keep_alive:Ctxt.keep_alive - ~base:Ctxt.evm_node_endpoint - (Services.dispatch_service ~path:Resto.Path.root) - () - () - (Batch methods) - in - - let* () = check_batched_response response in - - return_unit + match Ctxt.evm_node_endpoint with + | Some evm_node_endpoint -> + let methods = List.map send_raw_transaction_method messages in + + let* response = + call_service + ~keep_alive:Ctxt.keep_alive + ~base:evm_node_endpoint + (Services.dispatch_service ~path:Resto.Path.root) + () + () + (Batch methods) + in + + let* () = check_batched_response response in + + return_unit + | None -> assert false end module SimulatorBackend = struct @@ -259,7 +265,7 @@ module Make (Base : sig val ctxt : t - val evm_node_endpoint : Uri.t + val evm_node_endpoint : Uri.t option val keep_alive : bool end) = @@ -291,7 +297,7 @@ let replay ctxt ?(log_file = "replay") ?profile evm_state blueprint.blueprint.payload -let ro_backend ctxt config evm_node_endpoint = +let ro_backend ?evm_node_endpoint ctxt config = (module Make (struct module Executor = struct let pvm_config = pvm_config ctxt diff --git a/etherlink/bin_node/lib_dev/evm_ro_context.mli b/etherlink/bin_node/lib_dev/evm_ro_context.mli index 37a2b59a4550..a8b0aa974e9a 100644 --- a/etherlink/bin_node/lib_dev/evm_ro_context.mli +++ b/etherlink/bin_node/lib_dev/evm_ro_context.mli @@ -15,9 +15,13 @@ type t = { } (** [load ~data_dir ~preimages ()] creates a new read-only handler on the - node’s context. You can have as many read-only handlers as you want - split over as many processes. *) + node’s context. You can have as many read-only handlers as you want split + over as many processes. + + If [smart_rollup_address] is omitted, the argument is fetched from the + store. *) val load : + ?smart_rollup_address:Address.t -> data_dir:string -> preimages:string -> ?preimages_endpoint:Uri.t -> @@ -36,7 +40,10 @@ val preload_kernel_from_level : val next_blueprint_number : t -> Ethereum_types.quantity tzresult Lwt.t val ro_backend : - t -> Configuration.t -> Uri.t -> (module Services_backend_sig.S) + ?evm_node_endpoint:Uri.t -> + t -> + Configuration.t -> + (module Services_backend_sig.S) val replay : t -> diff --git a/etherlink/bin_node/lib_dev/observer.ml b/etherlink/bin_node/lib_dev/observer.ml index bc3b5deee70c..e3d3e94690f6 100644 --- a/etherlink/bin_node/lib_dev/observer.ml +++ b/etherlink/bin_node/lib_dev/observer.ml @@ -83,6 +83,7 @@ let main ?kernel_path ~data_dir ~(config : Configuration.t) () = in let* ro_ctxt = Evm_ro_context.load + ~smart_rollup_address ~data_dir ~preimages:config.kernel_execution.preimages ?preimages_endpoint:config.kernel_execution.preimages_endpoint @@ -95,7 +96,7 @@ let main ?kernel_path ~data_dir ~(config : Configuration.t) () = | None -> evm_node_endpoint in let observer_backend = - Evm_ro_context.ro_backend ro_ctxt config evm_node_endpoint + Evm_ro_context.ro_backend ro_ctxt config ~evm_node_endpoint in let* () = diff --git a/etherlink/bin_node/lib_dev/rpc.ml b/etherlink/bin_node/lib_dev/rpc.ml index 87758db3c6a3..6a640fe2b4f5 100644 --- a/etherlink/bin_node/lib_dev/rpc.ml +++ b/etherlink/bin_node/lib_dev/rpc.ml @@ -28,7 +28,7 @@ let main ~data_dir ~evm_node_endpoint ~(config : Configuration.t) = () in let* () = Evm_ro_context.preload_known_kernels ctxt in - let rpc_backend = Evm_ro_context.ro_backend ctxt config evm_node_endpoint in + let rpc_backend = Evm_ro_context.ro_backend ctxt config ~evm_node_endpoint in let* () = Tx_pool.start diff --git a/etherlink/bin_node/lib_dev/sequencer.ml b/etherlink/bin_node/lib_dev/sequencer.ml index 33b91bfc9d0a..2300e06384b7 100644 --- a/etherlink/bin_node/lib_dev/sequencer.ml +++ b/etherlink/bin_node/lib_dev/sequencer.ml @@ -6,41 +6,6 @@ (* *) (*****************************************************************************) -module MakeBackend (Ctxt : sig - val smart_rollup_address : Tezos_crypto.Hashed.Smart_rollup_address.t -end) : Services_backend_sig.Backend = struct - module Reader = Evm_context_based_reader - module SimulatorBackend = Evm_context_based_reader - - module TxEncoder = struct - type transactions = (string * Ethereum_types.transaction_object) list - - type messages = transactions - - let encode_transactions ~smart_rollup_address:_ ~transactions:_ = - assert false - end - - module Publisher = struct - type messages = TxEncoder.messages - - let publish_messages ~timestamp:_ ~smart_rollup_address:_ ~messages:_ = - assert false - end - - module Tracer = Tracer - - let block_param_to_block_number = Evm_context.block_param_to_block_number - - let smart_rollup_address = - Tezos_crypto.Hashed.Smart_rollup_address.to_string Ctxt.smart_rollup_address -end - -module Make (Ctxt : sig - val smart_rollup_address : Tezos_crypto.Hashed.Smart_rollup_address.t -end) = - Services_backend_sig.Make (MakeBackend (Ctxt)) - let install_finalizer_seq server_public_finalizer server_private_finalizer = let open Lwt_syntax in Lwt_exit.register_clean_up_callback ~loc:__LOC__ @@ fun exit_status -> @@ -157,18 +122,20 @@ let main ~data_dir ?(genesis_timestamp = Misc.now ()) ~cctxt Blueprints_publisher.publish Z.zero genesis else return_unit in - - let module Rollup_rpc = - Make - (struct - let smart_rollup_address = smart_rollup_address_typed - end) - (Evm_context) + let* ro_ctxt = + Evm_ro_context.load + ~smart_rollup_address:smart_rollup_address_typed + ~data_dir + ~preimages:configuration.kernel_execution.preimages + ?preimages_endpoint:configuration.kernel_execution.preimages_endpoint + () in + + let backend = Evm_ro_context.ro_backend ro_ctxt configuration in let* () = Tx_pool.start { - rollup_node = (module Rollup_rpc); + rollup_node = backend; smart_rollup_address; mode = Sequencer; tx_timeout_limit = configuration.tx_pool_timeout_limit; @@ -212,20 +179,16 @@ let main ~data_dir ?(genesis_timestamp = Misc.now ()) ~cctxt let* finalizer_public_server = Rpc_server.start_public_server ~evm_services: - { - next_blueprint_number = Evm_context.next_blueprint_number; - find_blueprint = Evm_context.blueprint; - smart_rollup_address = smart_rollup_address_typed; - time_between_blocks = sequencer_config.time_between_blocks; - } + Evm_ro_context.( + evm_services_methods ro_ctxt sequencer_config.time_between_blocks) configuration - ((module Rollup_rpc), smart_rollup_address_typed) + (backend, smart_rollup_address_typed) in let* finalizer_private_server = Rpc_server.start_private_server ~block_production:`Single_node configuration - ((module Rollup_rpc), smart_rollup_address_typed) + (backend, smart_rollup_address_typed) in let (_ : Lwt_exit.clean_up_callback_id) = install_finalizer_seq finalizer_public_server finalizer_private_server -- GitLab