From 1ad9ccab2e92dca57f1d3b1899890be5664836f6 Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Cornilleau Date: Mon, 10 Mar 2025 19:55:54 +0100 Subject: [PATCH 1/4] EVM Node: add a Evm_directory constructor from resto dir --- etherlink/bin_node/lib_dev/evm_directory.ml | 2 ++ etherlink/bin_node/lib_dev/evm_directory.mli | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/etherlink/bin_node/lib_dev/evm_directory.ml b/etherlink/bin_node/lib_dev/evm_directory.ml index 92b6694def7d..d892bb765d79 100644 --- a/etherlink/bin_node/lib_dev/evm_directory.ml +++ b/etherlink/bin_node/lib_dev/evm_directory.ml @@ -29,6 +29,8 @@ let empty = function Resto {dir = Tezos_rpc.Directory.empty; extra = EndpointMap.empty} | Configuration.Dream -> Dream [] +let init_from_resto_directory dir = Resto {dir; extra = EndpointMap.empty} + let register dir service handler = match dir with | Resto {dir; extra} -> diff --git a/etherlink/bin_node/lib_dev/evm_directory.mli b/etherlink/bin_node/lib_dev/evm_directory.mli index d657cd2ac2c1..babc994fadd6 100644 --- a/etherlink/bin_node/lib_dev/evm_directory.mli +++ b/etherlink/bin_node/lib_dev/evm_directory.mli @@ -29,6 +29,10 @@ type t = private (** An empty directory depending on the RPC server backend. *) val empty : Configuration.rpc_server -> t +(** A directory initialised with a resto directory. Will produce a [Resto] + value, so not compatible with Dream. *) +val init_from_resto_directory : unit Tezos_rpc.Directory.t -> t + (** {1 Registering services} *) (** {2 Generic functions} *) -- GitLab From 1c0cba36b52f70c16e5b96e7662a76ef5e94840d Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Cornilleau Date: Thu, 27 Feb 2025 17:52:25 +0100 Subject: [PATCH 2/4] Tezlink/EVM Node: import services from protocol --- etherlink/bin_node/lib_dev/tezos_services.ml | 173 ++++++++++++++++++ etherlink/bin_node/lib_dev/tezos_services.mli | 36 ++++ 2 files changed, 209 insertions(+) create mode 100644 etherlink/bin_node/lib_dev/tezos_services.ml create mode 100644 etherlink/bin_node/lib_dev/tezos_services.mli diff --git a/etherlink/bin_node/lib_dev/tezos_services.ml b/etherlink/bin_node/lib_dev/tezos_services.ml new file mode 100644 index 000000000000..8023ea5b0bcb --- /dev/null +++ b/etherlink/bin_node/lib_dev/tezos_services.ml @@ -0,0 +1,173 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2025 Nomadic Labs *) +(* *) +(*****************************************************************************) +module Imported_protocol = Tezos_protocol_021_PsQuebec +module Imported_protocol_plugin = Tezos_protocol_plugin_021_PsQuebec + +(* The output type of the current_level service but with less duplicated + information. Can be changed, as long as the [conversion_encoding] is also + changed. *) +type level = {level : int32; cycle : int32; cycle_position : int32} + +(** [convert_using_serialization ~dst ~src value] Conversion from one type with + encoding [src] to another with encoding [dst], through serialization. + Costly, but useful to build instances of a type when no builder is + accessible. *) +let convert_using_serialization ~dst ~src value = + let open Result_syntax in + let* bytes = + Data_encoding.Binary.to_bytes src value + |> Result.map_error_e (fun _ -> + Error_monad.error_with + "TODO: better message %s" + "failed to serialize") + in + Data_encoding.Binary.of_bytes dst bytes + |> Result.map_error_e (fun _ -> + Error_monad.error_with + "TODO: better message %s" + "failed to deserialize") + +(* Module importing, amending, and converting, protocol types. Those types + might be difficult to actually build, so we define conversion function from + local types to protocol types. *) +module Protocol_types = struct + module Alpha_context = Imported_protocol.Protocol.Alpha_context + module Raw_level = Alpha_context.Raw_level + + module Cycle = struct + include Alpha_context.Cycle + + (* This function is copied from [cycle_repr.ml] because it is not exposed + in [alpha_context.mli]. *) + let of_int32_exn i = + if Compare.Int32.(i >= 0l) then add root (Int32.to_int i) + else invalid_arg "Cycle_repr.of_int32_exn" + end + + module Level = struct + type t = Alpha_context.Level.t + + let encoding = Alpha_context.Level.encoding + + (** The sole purpose of this encoding is to reflect as closely as possible + the encoding of Alpha_context.Level.t, so it can be used to convert to + that type, with a serialization pass. This is necessary only because + there isn't a simple way to build that type. *) + let conversion_encoding = + let open Data_encoding in + conv + (fun ({level; cycle; cycle_position} : level) -> + ( Raw_level.of_int32_exn level, + Int32.pred level, + Cycle.of_int32_exn cycle, + cycle_position, + false )) + (fun ( level, + _level_position, + cycle, + cycle_position, + _expected_commitment ) -> + let level = Raw_level.to_int32 level in + let cycle = Cycle.to_int32 cycle in + {level; cycle; cycle_position}) + (obj5 + (req "level" Raw_level.encoding) + (req "level_position" int32) + (req "cycle" Cycle.encoding) + (req "cycle_position" int32) + (req "expected_commitment" bool)) + + let convert : level -> t tzresult = + convert_using_serialization ~dst:encoding ~src:conversion_encoding + end +end + +(** [wrap conversion service_implementation] changes the output type + of [service_implementation] using [conversion]. *) +let wrap conv impl p q i = + let open Lwt_result_syntax in + let* res = impl p q i in + let*? result = conv res in + return result + +(** [import_service s] makes it possible to substitute new [prefix] and [param] + types in the signature of the service [s]. *) +let import_service s = Tezos_rpc.Service.subst0 s + +let register_protocol_service ~dir ~service ~impl ~convert_output = + Tezos_rpc.Directory.register dir service (wrap convert_output impl) + +(* TODO *) +type tezlink_rpc_context = { + block : Tezos_shell_services.Block_services.block; + chain : Tezos_shell_services.Chain_services.chain; +} + +(** Builds a [tezlink_rpc_context] from paths parameters. *) +let make_env (chain : Tezos_shell_services.Chain_services.chain) + (block : Tezos_shell_services.Block_services.block) : + tezlink_rpc_context Lwt.t = + Lwt.return {block; chain} + +(* This is where we import service declarations from the protocol. *) +module Imported_services = struct + module Protocol_plugin_services = Imported_protocol_plugin.RPC.S + + type level_query = Protocol_plugin_services.level_query = {offset : int32} + + let current_level : + ( [`GET], + tezlink_rpc_context, + tezlink_rpc_context, + level_query, + unit, + Protocol_types.Level.t ) + Tezos_rpc.Service.t = + import_service Protocol_plugin_services.current_level +end + +type block = Tezos_shell_services.Block_services.block + +type chain = Tezos_shell_services.Chain_services.chain + +let block_directory_path = + Tezos_rpc.Path.subst2 + @@ Tezos_rpc.Path.prefix + Tezos_shell_services.Chain_services.path + Tezos_shell_services.Block_services.path + +type level_query = Imported_services.level_query = {offset : int32} + +type tezos_services_implementation = { + current_level : + chain -> block -> Imported_services.level_query -> level tzresult Lwt.t; +} + +(** Builds the directory registering services under `.../helpers`. *) +let build_helper_dir impl = + let dir : tezlink_rpc_context Tezos_rpc.Directory.t = + Tezos_rpc.Directory.empty + in + register_protocol_service + ~dir + ~service:Imported_services.current_level + ~impl:(fun {block; chain} query () -> impl.current_level chain block query) + ~convert_output:Protocol_types.Level.convert + +(** Builds the root director. *) +let build_dir impl = + let helper_dir = build_helper_dir impl in + Tezos_rpc.Directory.prefix + block_directory_path + (Tezos_rpc.Directory.map + (fun (((), chain), block) -> make_env chain block) + helper_dir) + +(* module entrypoint *) +let register_tezlink_services impl = + let tezlink_directory = build_dir impl in + Evm_directory.init_from_resto_directory tezlink_directory diff --git a/etherlink/bin_node/lib_dev/tezos_services.mli b/etherlink/bin_node/lib_dev/tezos_services.mli new file mode 100644 index 000000000000..bb669e12f44b --- /dev/null +++ b/etherlink/bin_node/lib_dev/tezos_services.mli @@ -0,0 +1,36 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2025 Nomadic Labs *) +(* *) +(*****************************************************************************) + +type level = { + level : int32; + (** The level of the block relative to genesis. This + is also the Shell's notion of level. *) + cycle : int32; + (** The current cycle's number. Note that cycles are a protocol-specific + notion. As a result, the cycle number starts at 0 with the first block of + the first version of protocol alpha. *) + cycle_position : int32; + (** The current level of the block relative to the first block of the current + cycle. *) +} + +(* Query types *) +type level_query = {offset : int32} + +(* Param types *) + +type block = Tezos_shell_services.Block_services.block + +type chain = Tezos_shell_services.Chain_services.chain + +(** Container for the implementations necessary to answer tezos RPC requests. *) +type tezos_services_implementation = { + current_level : chain -> block -> level_query -> level tzresult Lwt.t; +} + +(* THIS IS THE ENTRYPOINT *) +val register_tezlink_services : tezos_services_implementation -> Evm_directory.t -- GitLab From 897f6d21b71f08cf2fb08358bb4108b8f3497704 Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Cornilleau Date: Wed, 12 Mar 2025 11:08:09 +0100 Subject: [PATCH 3/4] Tezlink: define conversion error --- etherlink/bin_node/lib_dev/tezos_services.ml | 47 +++++++++++++++----- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/etherlink/bin_node/lib_dev/tezos_services.ml b/etherlink/bin_node/lib_dev/tezos_services.ml index 8023ea5b0bcb..6dbf9614fcd0 100644 --- a/etherlink/bin_node/lib_dev/tezos_services.ml +++ b/etherlink/bin_node/lib_dev/tezos_services.ml @@ -12,24 +12,48 @@ module Imported_protocol_plugin = Tezos_protocol_plugin_021_PsQuebec changed. *) type level = {level : int32; cycle : int32; cycle_position : int32} +type error += Serialization_for_conversion of string * string + +let () = + register_error_kind + `Permanent + ~id:"evm_node.dev.tezlink.conversion_failure" + ~title:"Failed to convert a value through serialization" + ~description: + "Failed to convert a value to a protocol private datatype through \ + serialization." + ~pp:(fun ppf (name, error) -> + Format.fprintf + ppf + "Failed to convert a value of type %s to a protocol private datatype \ + through serialization: %s" + name + error) + Data_encoding.(obj2 (req "type_name" string) (req "error_msg" string)) + (function + | Serialization_for_conversion (name, error) -> Some (name, error) + | _ -> None) + (fun (name, error) -> Serialization_for_conversion (name, error)) + (** [convert_using_serialization ~dst ~src value] Conversion from one type with encoding [src] to another with encoding [dst], through serialization. Costly, but useful to build instances of a type when no builder is accessible. *) -let convert_using_serialization ~dst ~src value = +let convert_using_serialization ~name ~dst ~src value = let open Result_syntax in let* bytes = Data_encoding.Binary.to_bytes src value - |> Result.map_error_e (fun _ -> - Error_monad.error_with - "TODO: better message %s" - "failed to serialize") + |> Result.map_error_e (fun e -> + tzfail + @@ Serialization_for_conversion + ( name, + Format.asprintf "%a" Data_encoding.Binary.pp_write_error e )) in Data_encoding.Binary.of_bytes dst bytes - |> Result.map_error_e (fun _ -> - Error_monad.error_with - "TODO: better message %s" - "failed to deserialize") + |> Result.map_error_e (fun e -> + tzfail + @@ Serialization_for_conversion + (name, Format.asprintf "%a" Data_encoding.Binary.pp_read_error e)) (* Module importing, amending, and converting, protocol types. Those types might be difficult to actually build, so we define conversion function from @@ -82,7 +106,10 @@ module Protocol_types = struct (req "expected_commitment" bool)) let convert : level -> t tzresult = - convert_using_serialization ~dst:encoding ~src:conversion_encoding + convert_using_serialization + ~name:"level" + ~dst:encoding + ~src:conversion_encoding end end -- GitLab From 651a0045fd0c7e4cd3c86a84665a08abe09f271b Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Cornilleau Date: Wed, 12 Mar 2025 15:43:07 +0100 Subject: [PATCH 4/4] Evm/Node: update regression --- .../EVM node- list events regression.out | 350 +++++++++--------- 1 file changed, 175 insertions(+), 175 deletions(-) diff --git a/etherlink/tezt/tests/expected/evm_rollup.ml/EVM node- list events regression.out b/etherlink/tezt/tests/expected/evm_rollup.ml/EVM node- list events regression.out index b652e2c9ae07..a2402c099342 100644 --- a/etherlink/tezt/tests/expected/evm_rollup.ml/EVM node- list events regression.out +++ b/etherlink/tezt/tests/expected/evm_rollup.ml/EVM node- list events regression.out @@ -338,168 +338,6 @@ evm_events_follower_started: { /* evm_events_follower_started version 0 */ "evm_events_follower_started.v0": any } -websocket_monitoring_exception: - description: monitoring for websocket {conn} raised exception {exception} - level: warning - section: evm_node.websocket - json format: - { /* websocket_monitoring_exception version 0 */ - "websocket_monitoring_exception.v0": - { "conn": $unistring, - "exception": $unistring } } - $unistring: - /* Universal string representation - Either a plain UTF8 string, or a sequence of bytes for strings that - contain invalid byte sequences. */ - string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } - -websocket_unsubscribe: - description: unsubscribe {id} for connection {conn}: {reason} - level: info - section: evm_node.websocket - json format: - { /* websocket_unsubscribe version 0 */ - "websocket_unsubscribe.v0": - { "conn": $unistring, - "id": $unistring, - "reason": $unistring } } - $unistring: - /* Universal string representation - Either a plain UTF8 string, or a sequence of bytes for strings that - contain invalid byte sequences. */ - string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } - -request_completed_debug: - description: {view} {worker_status} - level: debug - section: evm_node.websocket - json format: - { /* request_completed_debug version 0 */ - "request_completed_debug.v0": - { "view": - { "opcode": - "continuation" - || "text" - || "binary" - || "close" - || "ping" - || "pong" - || { /* ctrl */ - "ctrl": integer ∈ [-2^30, 2^30] } - || { /* nonctrl */ - "nonctrl": integer ∈ [-2^30, 2^30] }, - "extension": integer ∈ [-2^30, 2^30], - "final": boolean, - "content": $unistring }, - "worker_status": - { "pushed": $timestamp.system, - "treated": $timestamp.system, - "completed": $timestamp.system } } } - $int64: - /* 64 bit integers - Decimal representation of 64 bit integers */ - string - $timestamp.rfc: - /* RFC 3339 formatted timestamp - A date in RFC 3339 notation. */ - $unistring - $timestamp.system: - /* A timestamp as seen by the underlying, local computer: - subsecond-level precision, epoch or rfc3339 based. */ - $timestamp.rfc /* RFC encoding */ || $int64 /* Second since epoch */ - $unistring: - /* Universal string representation - Either a plain UTF8 string, or a sequence of bytes for strings that - contain invalid byte sequences. */ - string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } - -request_failed: - description: request {view} failed ({worker_status}): {errors} - level: warning - section: evm_node.websocket - json format: - { /* request_failed version 0 */ - "request_failed.v0": - { "view": - { "opcode": - "continuation" - || "text" - || "binary" - || "close" - || "ping" - || "pong" - || { /* ctrl */ - "ctrl": integer ∈ [-2^30, 2^30] } - || { /* nonctrl */ - "nonctrl": integer ∈ [-2^30, 2^30] }, - "extension": integer ∈ [-2^30, 2^30], - "final": boolean, - "content": $unistring }, - "worker_status": - { "pushed": $timestamp.system, - "treated": $timestamp.system, - "completed": $timestamp.system }, - "errors": any } } - $int64: - /* 64 bit integers - Decimal representation of 64 bit integers */ - string - $timestamp.rfc: - /* RFC 3339 formatted timestamp - A date in RFC 3339 notation. */ - $unistring - $timestamp.system: - /* A timestamp as seen by the underlying, local computer: - subsecond-level precision, epoch or rfc3339 based. */ - $timestamp.rfc /* RFC encoding */ || $int64 /* Second since epoch */ - $unistring: - /* Universal string representation - Either a plain UTF8 string, or a sequence of bytes for strings that - contain invalid byte sequences. */ - string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } - -websocket_missing_worker: - description: no worker for websocket connection {conn} - level: error - section: evm_node.websocket - json format: - { /* websocket_missing_worker version 0 */ - "websocket_missing_worker.v0": $unistring } - $unistring: - /* Universal string representation - Either a plain UTF8 string, or a sequence of bytes for strings that - contain invalid byte sequences. */ - string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } - -websocket_starting: - description: starting worker for websocket connection {conn} - level: notice - section: evm_node.websocket - json format: - { /* websocket_starting version 0 */ - "websocket_starting.v0": $unistring } - $unistring: - /* Universal string representation - Either a plain UTF8 string, or a sequence of bytes for strings that - contain invalid byte sequences. */ - string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } - -websocket_shutdown: - description: shutting down websocket worker for connection {conn}: {reason} ({subscriptions} subscriptions) - level: notice - section: evm_node.websocket - json format: - { /* websocket_shutdown version 0 */ - "websocket_shutdown.v0": - { "conn": $unistring, - "reason": $unistring, - "subscriptions": integer ∈ [-2^30, 2^30] } } - $unistring: - /* Universal string representation - Either a plain UTF8 string, or a sequence of bytes for strings that - contain invalid byte sequences. */ - string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } - evm_context_switch_history_mode: description: switching history mode from {from} to {to_} level: warning @@ -1242,6 +1080,168 @@ store_init: { /* store_init version 0 */ "store_init.v0": any } +websocket_monitoring_exception: + description: monitoring for websocket {conn} raised exception {exception} + level: warning + section: evm_node.websocket + json format: + { /* websocket_monitoring_exception version 0 */ + "websocket_monitoring_exception.v0": + { "conn": $unistring, + "exception": $unistring } } + $unistring: + /* Universal string representation + Either a plain UTF8 string, or a sequence of bytes for strings that + contain invalid byte sequences. */ + string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } + +websocket_unsubscribe: + description: unsubscribe {id} for connection {conn}: {reason} + level: info + section: evm_node.websocket + json format: + { /* websocket_unsubscribe version 0 */ + "websocket_unsubscribe.v0": + { "conn": $unistring, + "id": $unistring, + "reason": $unistring } } + $unistring: + /* Universal string representation + Either a plain UTF8 string, or a sequence of bytes for strings that + contain invalid byte sequences. */ + string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } + +request_completed_debug: + description: {view} {worker_status} + level: debug + section: evm_node.websocket + json format: + { /* request_completed_debug version 0 */ + "request_completed_debug.v0": + { "view": + { "opcode": + "continuation" + || "text" + || "binary" + || "close" + || "ping" + || "pong" + || { /* ctrl */ + "ctrl": integer ∈ [-2^30, 2^30] } + || { /* nonctrl */ + "nonctrl": integer ∈ [-2^30, 2^30] }, + "extension": integer ∈ [-2^30, 2^30], + "final": boolean, + "content": $unistring }, + "worker_status": + { "pushed": $timestamp.system, + "treated": $timestamp.system, + "completed": $timestamp.system } } } + $int64: + /* 64 bit integers + Decimal representation of 64 bit integers */ + string + $timestamp.rfc: + /* RFC 3339 formatted timestamp + A date in RFC 3339 notation. */ + $unistring + $timestamp.system: + /* A timestamp as seen by the underlying, local computer: + subsecond-level precision, epoch or rfc3339 based. */ + $timestamp.rfc /* RFC encoding */ || $int64 /* Second since epoch */ + $unistring: + /* Universal string representation + Either a plain UTF8 string, or a sequence of bytes for strings that + contain invalid byte sequences. */ + string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } + +request_failed: + description: request {view} failed ({worker_status}): {errors} + level: warning + section: evm_node.websocket + json format: + { /* request_failed version 0 */ + "request_failed.v0": + { "view": + { "opcode": + "continuation" + || "text" + || "binary" + || "close" + || "ping" + || "pong" + || { /* ctrl */ + "ctrl": integer ∈ [-2^30, 2^30] } + || { /* nonctrl */ + "nonctrl": integer ∈ [-2^30, 2^30] }, + "extension": integer ∈ [-2^30, 2^30], + "final": boolean, + "content": $unistring }, + "worker_status": + { "pushed": $timestamp.system, + "treated": $timestamp.system, + "completed": $timestamp.system }, + "errors": any } } + $int64: + /* 64 bit integers + Decimal representation of 64 bit integers */ + string + $timestamp.rfc: + /* RFC 3339 formatted timestamp + A date in RFC 3339 notation. */ + $unistring + $timestamp.system: + /* A timestamp as seen by the underlying, local computer: + subsecond-level precision, epoch or rfc3339 based. */ + $timestamp.rfc /* RFC encoding */ || $int64 /* Second since epoch */ + $unistring: + /* Universal string representation + Either a plain UTF8 string, or a sequence of bytes for strings that + contain invalid byte sequences. */ + string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } + +websocket_missing_worker: + description: no worker for websocket connection {conn} + level: error + section: evm_node.websocket + json format: + { /* websocket_missing_worker version 0 */ + "websocket_missing_worker.v0": $unistring } + $unistring: + /* Universal string representation + Either a plain UTF8 string, or a sequence of bytes for strings that + contain invalid byte sequences. */ + string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } + +websocket_starting: + description: starting worker for websocket connection {conn} + level: notice + section: evm_node.websocket + json format: + { /* websocket_starting version 0 */ + "websocket_starting.v0": $unistring } + $unistring: + /* Universal string representation + Either a plain UTF8 string, or a sequence of bytes for strings that + contain invalid byte sequences. */ + string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } + +websocket_shutdown: + description: shutting down websocket worker for connection {conn}: {reason} ({subscriptions} subscriptions) + level: notice + section: evm_node.websocket + json format: + { /* websocket_shutdown version 0 */ + "websocket_shutdown.v0": + { "conn": $unistring, + "reason": $unistring, + "subscriptions": integer ∈ [-2^30, 2^30] } } + $unistring: + /* Universal string representation + Either a plain UTF8 string, or a sequence of bytes for strings that + contain invalid byte sequences. */ + string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } + tracer_input: description: Tracer with input {inputs} level: debug @@ -2111,19 +2111,6 @@ evm_events_unreadable_event: { "index": integer ∈ [-2^30, 2^30], "level": integer ∈ [-2^31-1, 2^31] } } -websocket_missing_worker: - description: no worker for websocket connection {conn} - level: error - section: evm_node.websocket - json format: - { /* websocket_missing_worker version 0 */ - "websocket_missing_worker.v0": $unistring } - $unistring: - /* Universal string representation - Either a plain UTF8 string, or a sequence of bytes for strings that - contain invalid byte sequences. */ - string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } - evm_context_get_block_failed: description: get block by number failed for level {level}{trace} level: error @@ -2368,6 +2355,19 @@ migrations_from_the_future: { "applied": integer ∈ [-2^30, 2^30], "known": integer ∈ [-2^30, 2^30] } } +websocket_missing_worker: + description: no worker for websocket connection {conn} + level: error + section: evm_node.websocket + json format: + { /* websocket_missing_worker version 0 */ + "websocket_missing_worker.v0": $unistring } + $unistring: + /* Universal string representation + Either a plain UTF8 string, or a sequence of bytes for strings that + contain invalid byte sequences. */ + string || { "invalid_utf8_string": [ integer ∈ [0, 255] ... ] } + tx_pool_connection_lost: description: connection with the rollup node has been lost, retrying... level: error -- GitLab