From 3c8bac0d47ea90e41b5b5f212440eb0f02947f45 Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Thu, 7 Nov 2024 11:06:58 +0100 Subject: [PATCH 1/4] EVM/Node: add subscription's input types --- .../lib_dev/encodings/ethereum_types.ml | 55 +++++++++++++++++++ .../lib_dev/encodings/ethereum_types.mli | 16 ++++++ 2 files changed, 71 insertions(+) diff --git a/etherlink/bin_node/lib_dev/encodings/ethereum_types.ml b/etherlink/bin_node/lib_dev/encodings/ethereum_types.ml index 0b4d3b8453b8..e676a3287092 100644 --- a/etherlink/bin_node/lib_dev/encodings/ethereum_types.ml +++ b/etherlink/bin_node/lib_dev/encodings/ethereum_types.ml @@ -1121,3 +1121,58 @@ let state_override_empty = AddressMap.empty let state_override_encoding = AddressMap.associative_array_encoding state_account_override_encoding + +module Subscription = struct + exception Unknown_subscription + + type logs = {address : address; topics : hash list} + + let logs_encoding = + let open Data_encoding in + conv + (fun {address; topics} -> (address, topics)) + (fun (address, topics) -> {address; topics}) + (obj2 + (req "address" address_encoding) + (req "topics" (list hash_encoding))) + + type kind = NewHeads | Logs of logs | NewPendingTransactions | Syncing + + let kind_encoding = + let open Data_encoding in + union + [ + case + ~title:"params_size_two" + (Tag 0) + (tup2 string logs_encoding) + (function Logs logs -> Some ("logs", logs) | _ -> None) + (function + | "logs", logs -> Logs logs | _ -> raise Unknown_subscription); + case + ~title:"params_size_one" + (Tag 1) + (tup1 string) + (function + | NewHeads -> Some "newHeads" + | NewPendingTransactions -> Some "newPendingTransactions" + | Syncing -> Some "syncing" + | _ -> None) + (function + | "newHeads" -> NewHeads + | "newPendingTransactions" -> NewPendingTransactions + | "syncing" -> Syncing + | _ -> raise Unknown_subscription); + ] + + type id = Id of hex [@@ocaml.unboxed] + + let id_of_string s = Id (hex_of_string (String.lowercase_ascii s)) + + let id_to_string (Id a) = hex_to_string a + + let id_encoding = Data_encoding.(conv id_to_string id_of_string string) + + let id_input_encoding = + Data_encoding.(conv id_to_string id_of_string (tup1 string)) +end diff --git a/etherlink/bin_node/lib_dev/encodings/ethereum_types.mli b/etherlink/bin_node/lib_dev/encodings/ethereum_types.mli index f40a9bf75857..d5dfc2bc90c4 100644 --- a/etherlink/bin_node/lib_dev/encodings/ethereum_types.mli +++ b/etherlink/bin_node/lib_dev/encodings/ethereum_types.mli @@ -309,3 +309,19 @@ module From_rlp : sig val decode_hex : Rlp.item -> hex tzresult end + +module Subscription : sig + exception Unknown_subscription + + type logs = {address : address; topics : hash list} + + type kind = NewHeads | Logs of logs | NewPendingTransactions | Syncing + + val kind_encoding : kind Data_encoding.t + + type id = Id of hex [@@ocaml.unboxed] + + val id_encoding : id Data_encoding.t + + val id_input_encoding : id Data_encoding.t +end -- GitLab From e350c37e63f8fe03531c5dbb82281c5073a8bc27 Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Fri, 8 Nov 2024 11:17:08 +0100 Subject: [PATCH 2/4] EVM/Node: add subscription's output types --- .../lib_dev/encodings/ethereum_types.ml | 73 +++++++++++++++++++ .../lib_dev/encodings/ethereum_types.mli | 18 +++++ 2 files changed, 91 insertions(+) diff --git a/etherlink/bin_node/lib_dev/encodings/ethereum_types.ml b/etherlink/bin_node/lib_dev/encodings/ethereum_types.ml index e676a3287092..0646e5d3ca23 100644 --- a/etherlink/bin_node/lib_dev/encodings/ethereum_types.ml +++ b/etherlink/bin_node/lib_dev/encodings/ethereum_types.ml @@ -1175,4 +1175,77 @@ module Subscription = struct let id_input_encoding = Data_encoding.(conv id_to_string id_of_string (tup1 string)) + + type sync_status = { + startingBlock : quantity; + currentBlock : quantity; + highestBlock : quantity; + pulledStates : quantity; + knownStates : quantity; + } + + let sync_status_encoding = + let open Data_encoding in + conv + (fun { + startingBlock; + currentBlock; + highestBlock; + pulledStates; + knownStates; + } -> + (startingBlock, currentBlock, highestBlock, pulledStates, knownStates)) + (fun (startingBlock, currentBlock, highestBlock, pulledStates, knownStates) -> + {startingBlock; currentBlock; highestBlock; pulledStates; knownStates}) + (obj5 + (req "startingBlock" quantity_encoding) + (req "currentBlock" quantity_encoding) + (req "highestBlock" quantity_encoding) + (req "pulledStates" quantity_encoding) + (req "knownStates" quantity_encoding)) + + type sync_output = {syncing : bool; status : sync_status} + + let sync_output_encoding = + let open Data_encoding in + conv + (fun {syncing; status} -> (syncing, status)) + (fun (syncing, status) -> {syncing; status}) + (obj2 (req "syncing" bool) (req "status" sync_status_encoding)) + + type output = + | NewHeads of block + | Logs of logs + | NewPendingTransactions of hash + | Syncing of sync_output + + let output_encoding = + let open Data_encoding in + union + [ + case + ~title:"newHeads" + (Tag 0) + block_encoding + (function NewHeads b -> Some b | _ -> None) + (fun b -> NewHeads b); + case + ~title:"logs" + (Tag 1) + logs_encoding + (function Logs l -> Some l | _ -> None) + (fun l -> Logs l); + case + ~title:"pendingTxs" + (Tag 2) + hash_encoding + (function NewPendingTransactions l -> Some l | _ -> None) + (fun l -> NewPendingTransactions l); + case + ~title:"sync" + (Tag 3) + sync_output_encoding + (function Syncing l -> Some l | _ -> None) + (fun l -> Syncing l); + ] end diff --git a/etherlink/bin_node/lib_dev/encodings/ethereum_types.mli b/etherlink/bin_node/lib_dev/encodings/ethereum_types.mli index d5dfc2bc90c4..c659ae805143 100644 --- a/etherlink/bin_node/lib_dev/encodings/ethereum_types.mli +++ b/etherlink/bin_node/lib_dev/encodings/ethereum_types.mli @@ -324,4 +324,22 @@ module Subscription : sig val id_encoding : id Data_encoding.t val id_input_encoding : id Data_encoding.t + + type sync_status = { + startingBlock : quantity; + currentBlock : quantity; + highestBlock : quantity; + pulledStates : quantity; + knownStates : quantity; + } + + type sync_output = {syncing : bool; status : sync_status} + + type output = + | NewHeads of block + | Logs of logs + | NewPendingTransactions of hash + | Syncing of sync_output + + val output_encoding : output Data_encoding.t end -- GitLab From 087a64b00fc3c859c2256dd63c31990aefb7a47b Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Thu, 7 Nov 2024 11:07:19 +0100 Subject: [PATCH 3/4] EVM/Node: add subscription's RPC encodings --- etherlink/bin_node/lib_dev/rpc_encodings.ml | 34 ++++++++++++++++++++ etherlink/bin_node/lib_dev/rpc_encodings.mli | 8 +++++ 2 files changed, 42 insertions(+) diff --git a/etherlink/bin_node/lib_dev/rpc_encodings.ml b/etherlink/bin_node/lib_dev/rpc_encodings.ml index c70e1fd49369..01da246c05ff 100644 --- a/etherlink/bin_node/lib_dev/rpc_encodings.ml +++ b/etherlink/bin_node/lib_dev/rpc_encodings.ml @@ -858,6 +858,38 @@ module Coinbase = struct type ('input, 'output) method_ += Method : (input, output) method_ end +module Subscribe = struct + open Ethereum_types + + type input = Subscription.kind + + type output = Subscription.id + + let input_encoding = Subscription.kind_encoding + + let output_encoding = Subscription.id_encoding + + let method_ = "eth_subscribe" + + type ('input, 'output) method_ += Method : (input, output) method_ +end + +module Unsubscribe = struct + open Ethereum_types + + type input = Subscription.id + + type output = bool + + let input_encoding = Subscription.id_input_encoding + + let output_encoding = Data_encoding.bool + + let method_ = "eth_unsubscribe" + + type ('input, 'output) method_ += Method : (input, output) method_ +end + type map_result = | Method : ('input, 'output) method_ @@ -911,6 +943,8 @@ let supported_methods : (module METHOD) list = (module Eth_fee_history); (module Coinbase); (module Trace_call); + (module Subscribe); + (module Unsubscribe); ] let unsupported_methods : string list = diff --git a/etherlink/bin_node/lib_dev/rpc_encodings.mli b/etherlink/bin_node/lib_dev/rpc_encodings.mli index 8564844961e9..09f75e9b86d6 100644 --- a/etherlink/bin_node/lib_dev/rpc_encodings.mli +++ b/etherlink/bin_node/lib_dev/rpc_encodings.mli @@ -314,6 +314,14 @@ module Eth_fee_history : module Coinbase : METHOD with type input = unit and type output = Ethereum_types.address +module Subscribe : + METHOD + with type input = Ethereum_types.Subscription.kind + and type output = Ethereum_types.Subscription.id + +module Unsubscribe : + METHOD with type input = Ethereum_types.Subscription.id and type output = bool + type map_result = | Method : ('input, 'output) method_ -- GitLab From 38e59e9626ec55e55761feba7c637a291c54d087 Mon Sep 17 00:00:00 2001 From: Rodi-Can Bozman Date: Tue, 12 Nov 2024 11:11:46 +0100 Subject: [PATCH 4/4] EVM/Node: generic subscription encoding (data sent through the websocket periodically) --- etherlink/bin_node/lib_dev/rpc_encodings.ml | 32 ++++++++++++++++++++ etherlink/bin_node/lib_dev/rpc_encodings.mli | 20 ++++++++++++ 2 files changed, 52 insertions(+) diff --git a/etherlink/bin_node/lib_dev/rpc_encodings.ml b/etherlink/bin_node/lib_dev/rpc_encodings.ml index 01da246c05ff..1b95cd3216aa 100644 --- a/etherlink/bin_node/lib_dev/rpc_encodings.ml +++ b/etherlink/bin_node/lib_dev/rpc_encodings.ml @@ -112,6 +112,38 @@ module JSONRPC = struct (req "id" (option id_repr_encoding)))) end +module Subscription = struct + let version = JSONRPC.version + + let method_ = "eth_subscription" + + type result = { + result : Data_encoding.json; + subscription : Ethereum_types.Subscription.id; + } + + let result_encoding = + Data_encoding.( + conv + (fun {result; subscription} -> (result, subscription)) + (fun (result, subscription) -> {result; subscription}) + (obj2 + (req "result" Data_encoding.json) + (req "subscription" Ethereum_types.Subscription.id_encoding))) + + type response = {params : result} + + let response_encoding = + Data_encoding.( + conv + (fun {params} -> ((), (), params)) + (fun ((), (), params) -> {params}) + (obj3 + (req "jsonrpc" (constant version)) + (req "method" (constant method_)) + (req "params" result_encoding))) +end + module Error = struct type t = unit diff --git a/etherlink/bin_node/lib_dev/rpc_encodings.mli b/etherlink/bin_node/lib_dev/rpc_encodings.mli index 09f75e9b86d6..7c73dde06c25 100644 --- a/etherlink/bin_node/lib_dev/rpc_encodings.mli +++ b/etherlink/bin_node/lib_dev/rpc_encodings.mli @@ -87,6 +87,26 @@ module JSONRPC : sig val response_encoding : response Data_encoding.t end +(* This isn't the JSON-RPC request that is sent to request websocket events but + the generic outputed data that is sent through the websocket periodically once + the appropriate websocket request was sent (see module [Subscribe]). *) +module Subscription : sig + val version : string + + val method_ : string + + type result = { + result : Data_encoding.json; + subscription : Ethereum_types.Subscription.id; + } + + val result_encoding : result Data_encoding.t + + type response = {params : result} + + val response_encoding : response Data_encoding.t +end + (* Errors returned by the RPC server, to be embedded as data to the JSON-RPC error object. *) module Error : sig -- GitLab