diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index e1870250ba04048b2aad68d051863401fb6b3b05..fed767fe7f23e72c6f1c9e5e95472ff9ed98d7c2 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -306,8 +306,12 @@ opam:octez-distributed-lwt-internal: # Ignoring unreleased package octez-epoxy-tx. +# Ignoring unreleased package octez-evm-chunker. + # Ignoring unreleased package octez-evm-proxy. +# Ignoring unreleased package octez-evm-proxy-lib. + opam:octez-injector: extends: - .opam_template diff --git a/dune-project b/dune-project index ecba220094a088b7d76b42ec3c5453ca7ae307c1..f1e886b88b8ddc1a64f739665ea04348c2da27ef 100644 --- a/dune-project +++ b/dune-project @@ -24,7 +24,9 @@ (package (name octez-distributed-lwt-internal)) (package (name octez-distributed-plonk)) (package (name octez-epoxy-tx)) +(package (name octez-evm-chunker)(allow_empty)) (package (name octez-evm-proxy)) +(package (name octez-evm-proxy-lib)(allow_empty)) (package (name octez-injector)) (package (name octez-mec)) (package (name octez-node)) diff --git a/manifest/main.ml b/manifest/main.ml index dd80993fcb6d87f9a761fe579eb97bf3b7b37bb8..95b089ed6634a3321f745579dc67f573dd24eeb3 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -7326,6 +7326,23 @@ let _octez_scoru_wasm_debugger = octez_webassembly_interpreter_extra |> open_; ] +let evm_proxy_lib = + private_lib + "evm_proxy_lib" + ~path:"src/bin_evm_proxy/lib" + ~opam:"octez-evm-proxy-lib" + ~synopsis: + "An implementation of a subset of Ethereum JSON-RPC API for the EVM \ + rollup" + ~deps: + [ + octez_base |> open_ ~m:"TzPervasives"; + octez_rpc_http |> open_; + octez_rpc_http_client_unix; + octez_version; + lwt_exit; + ] + let _evm_proxy = public_exe (sf "octez-evm-proxy-server") @@ -7341,18 +7358,20 @@ let _evm_proxy = octez_base |> open_ ~m:"TzPervasives"; octez_base_unix; octez_clic; - octez_rpc; octez_rpc_http |> open_; octez_rpc_http_server; - octez_rpc_http_client_unix; - octez_stdlib_unix |> open_; - octez_crypto |> open_; - octez_stdlib |> open_; - octez_version; - lwt_exit; + evm_proxy_lib; ] ~bisect_ppx:Yes +let _octez_evm_chunker_exe = + private_exe + "octez_evm_chunker" + ~path:"src/bin_evm_proxy/chunker" + ~synopsis:"EVM kernel transaction chunker" + ~opam:"octez-evm-chunker" + ~deps:[octez_base |> open_ ~m:"TzPervasives"; evm_proxy_lib] + let octez_scoru_wasm_regressions = private_lib "tezos_scoru_wasm_regressions" diff --git a/opam/octez-evm-chunker.opam b/opam/octez-evm-chunker.opam new file mode 100644 index 0000000000000000000000000000000000000000..6e8269ac529c862d8a80b917172db105f07a8c20 --- /dev/null +++ b/opam/octez-evm-chunker.opam @@ -0,0 +1,21 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "tezos-base" + "octez-evm-proxy-lib" +] +build: [ + ["rm" "-r" "vendors" "contrib"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "EVM kernel transaction chunker" diff --git a/opam/octez-evm-proxy-lib.opam b/opam/octez-evm-proxy-lib.opam new file mode 100644 index 0000000000000000000000000000000000000000..c4bb4d7f759bb6a816c1ce6d4664158e3c1b20a6 --- /dev/null +++ b/opam/octez-evm-proxy-lib.opam @@ -0,0 +1,24 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "tezos-base" + "tezos-rpc-http" + "tezos-rpc-http-client-unix" + "tezos-version" + "lwt-exit" +] +build: [ + ["rm" "-r" "vendors" "contrib"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "An implementation of a subset of Ethereum JSON-RPC API for the EVM rollup" diff --git a/opam/octez-evm-proxy.opam b/opam/octez-evm-proxy.opam index b6f3bbe879f31d47c8c409a07737ea76ba2925e4..a2c5932a07bfbe50c08b757ffdb5604bfc927ff6 100644 --- a/opam/octez-evm-proxy.opam +++ b/opam/octez-evm-proxy.opam @@ -12,15 +12,9 @@ depends: [ "ocaml" { >= "4.14" } "tezos-base" "tezos-clic" - "tezos-rpc" "tezos-rpc-http" "tezos-rpc-http-server" - "tezos-rpc-http-client-unix" - "tezos-stdlib-unix" - "tezos-crypto" - "tezos-stdlib" - "tezos-version" - "lwt-exit" + "octez-evm-proxy-lib" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/src/bin_evm_proxy/chunker/dune b/src/bin_evm_proxy/chunker/dune new file mode 100644 index 0000000000000000000000000000000000000000..7905401d8be2abb0bf32b2a95c7022a832701274 --- /dev/null +++ b/src/bin_evm_proxy/chunker/dune @@ -0,0 +1,12 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(executable + (name octez_evm_chunker) + (instrumentation (backend bisect_ppx)) + (libraries + tezos-base + evm_proxy_lib) + (flags + (:standard) + -open Tezos_base.TzPervasives)) diff --git a/src/bin_evm_proxy/chunker/octez_evm_chunker.ml b/src/bin_evm_proxy/chunker/octez_evm_chunker.ml new file mode 100644 index 0000000000000000000000000000000000000000..fe4d0598f12fd8278842e617f30f80a6d53f6b33 --- /dev/null +++ b/src/bin_evm_proxy/chunker/octez_evm_chunker.ml @@ -0,0 +1,85 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Marigold *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Chunk transactions + ------- + Component: EVM kernel + Invocation: dune exec octez_evm_chunker.exe rollup_address raw_tx + - rollup_address : string in sr1... format. If the address + is omitted then the zero address will be used. + - raw_tx : string in hex format (with or without 0x prefix) + Subject: Split a raw transactions into chunks accepted by the evm_kernel + + example: + dune exec src/bin_evm_proxy/chunker/octez_evm_chunker.exe \ + "sr1SKEeoKZizGDczpS8JgYiAdkjyN8Am6TcK" \ + "f901f2808506fc23ac00831000008080b9019f608060405234801561001057600080fd5b5061017f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80634e70b1dc1461004657806360fe47b1146100645780636d4ce63c14610080575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61007e6004803603810190610079919061011c565b6100a4565b005b6100886100ae565b60405161009591906100d0565b60405180910390f35b60005481565b8060008190555050565b60008054905090565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea2646970667358221220ec57e49a647342208a1f5c9b1f2049bf1a27f02e19940819f38929bf67670a5964736f6c6343000812003325a0e0d5dd3ddec07eb85eb066c7782ab64a4f9f47f22e444c147708d3277dba6d68a03e358c75e5c2436ada1dcebe4aa1391797658950a9a5abae90ccff61ce5e7f34" + + dune exec src/bin_evm_proxy/chunker/octez_evm_chunker.exe \ + "f901f2808506fc23ac00831000008080b9019f608060405234801561001057600080fd5b5061017f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80634e70b1dc1461004657806360fe47b1146100645780636d4ce63c14610080575b600080fd5b61004e61009e565b60405161005b91906100d0565b60405180910390f35b61007e6004803603810190610079919061011c565b6100a4565b005b6100886100ae565b60405161009591906100d0565b60405180910390f35b60005481565b8060008190555050565b60008054905090565b6000819050919050565b6100ca816100b7565b82525050565b60006020820190506100e560008301846100c1565b92915050565b600080fd5b6100f9816100b7565b811461010457600080fd5b50565b600081359050610116816100f0565b92915050565b600060208284031215610132576101316100eb565b5b600061014084828501610107565b9150509291505056fea2646970667358221220ec57e49a647342208a1f5c9b1f2049bf1a27f02e19940819f38929bf67670a5964736f6c6343000812003325a0e0d5dd3ddec07eb85eb066c7782ab64a4f9f47f22e444c147708d3277dba6d68a03e358c75e5c2436ada1dcebe4aa1391797658950a9a5abae90ccff61ce5e7f34" +*) + +open Evm_proxy_lib + +let zero_address = Tezos_crypto.Hashed.Smart_rollup_address.(zero |> to_string) + +let encode_address address = + let open Result_syntax in + let open Tezos_crypto.Hashed.Smart_rollup_address in + let* s = of_b58check address in + let s = to_string s in + return s + +let main args = + let open Lwt_result_syntax in + let print_chunks smart_rollup_address s = + let*? _, messages = + Rollup_node.make_encoded_messages + ~smart_rollup_address + (Hash (Ethereum_types.strip_0x s)) + in + Format.printf "Chunked transactions :\n%!" ; + List.iter (Format.printf "%s\n%!") messages ; + return_unit + in + match args with + | Some [s] -> print_chunks zero_address s + | Some [smart_rollup_address; s] -> + let*? smart_rollup_address = encode_address smart_rollup_address in + print_chunks smart_rollup_address s + | _ -> + Format.printf + "Usage: octez_evm_chunker
\n\ + -
: Smart rollup address (Optional)\n\ + - : Ethereum transaction hash\n\ + %!" ; + return_unit + +let () = + let args = Array.to_list Sys.argv |> List.tl in + match Lwt_main.run (main args) with + | Ok _ -> () + | Error errs -> + List.iter (fun e -> Format.eprintf "%a\n%!" Error_monad.pp e) errs diff --git a/src/bin_evm_proxy/dune b/src/bin_evm_proxy/dune index efd838ce7229579eddd2e9391b509cbc60bfb7b1..4bb9082cc57f53fecd21b9abbfceb179dab83f58 100644 --- a/src/bin_evm_proxy/dune +++ b/src/bin_evm_proxy/dune @@ -10,22 +10,13 @@ tezos-base tezos-base.unix tezos-clic - tezos-rpc tezos-rpc-http tezos-rpc-http-server - tezos-rpc-http-client-unix - tezos-stdlib-unix - tezos-crypto - tezos-stdlib - tezos-version - lwt-exit) + evm_proxy_lib) (link_flags (:standard) (:include %{workspace_root}/static-link-flags.sexp)) (flags (:standard) -open Tezos_base.TzPervasives - -open Tezos_rpc_http - -open Tezos_stdlib_unix - -open Tezos_crypto - -open Tezos_stdlib)) + -open Tezos_rpc_http)) diff --git a/src/bin_evm_proxy/evm_proxy.ml b/src/bin_evm_proxy/evm_proxy.ml index 29259b5b9a775c9746a3109f44ddf28177d0601d..eb5e4a9f44b37edd73bf9b8226390c0c4aa5a175 100644 --- a/src/bin_evm_proxy/evm_proxy.ml +++ b/src/bin_evm_proxy/evm_proxy.ml @@ -23,6 +23,8 @@ (* *) (*****************************************************************************) +open Evm_proxy_lib + type rollup_node_endpoint = Mockup | Endpoint of Uri.t type config = { diff --git a/src/bin_evm_proxy/lib/dune b/src/bin_evm_proxy/lib/dune new file mode 100644 index 0000000000000000000000000000000000000000..27377ae3641b43c4cdb303709a5d5300252838c1 --- /dev/null +++ b/src/bin_evm_proxy/lib/dune @@ -0,0 +1,17 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name evm_proxy_lib) + (package octez-evm-proxy-lib) + (instrumentation (backend bisect_ppx)) + (libraries + tezos-base + tezos-rpc-http + tezos-rpc-http-client-unix + tezos-version + lwt-exit) + (flags + (:standard) + -open Tezos_base.TzPervasives + -open Tezos_rpc_http)) diff --git a/src/bin_evm_proxy/ethereum_types.ml b/src/bin_evm_proxy/lib/ethereum_types.ml similarity index 99% rename from src/bin_evm_proxy/ethereum_types.ml rename to src/bin_evm_proxy/lib/ethereum_types.ml index c528da50eb03e5b13eede78e38c76d3d54b6f037..cfe27ad40c9c1e7de72d9a24210a018d3cf0dbaf 100644 --- a/src/bin_evm_proxy/ethereum_types.ml +++ b/src/bin_evm_proxy/lib/ethereum_types.ml @@ -579,6 +579,8 @@ let call_encoding = values. I.e., the `txpool_` encodes it as: ``` + {@js[ + { "address1" : { "counter1" : , "counter2" : , @@ -591,6 +593,7 @@ let call_encoding = }, ... } + ]} ``` As such, the encoding uses Ezjsonm representation directly to encode and diff --git a/src/bin_evm_proxy/mockup.ml b/src/bin_evm_proxy/lib/mockup.ml similarity index 100% rename from src/bin_evm_proxy/mockup.ml rename to src/bin_evm_proxy/lib/mockup.ml diff --git a/src/bin_evm_proxy/rollup_node.ml b/src/bin_evm_proxy/lib/rollup_node.ml similarity index 90% rename from src/bin_evm_proxy/rollup_node.ml rename to src/bin_evm_proxy/lib/rollup_node.ml index d3c24facc325fca9b5973c0f1e90c94867050768..2f18a9e244d6b395f9d8308d10dc8d5db72fa748 100644 --- a/src/bin_evm_proxy/rollup_node.ml +++ b/src/bin_evm_proxy/lib/rollup_node.ml @@ -25,6 +25,73 @@ open Ethereum_types +let u16_to_bytes n = + let bytes = Bytes.make 2 'a' in + Bytes.set_uint16_le bytes 0 n ; + Bytes.to_string bytes + +(* The hard limit is 4096 but it needs to add the external message tag. *) +let max_input_size = 4095 + +let smart_rollup_address_size = 20 + +type transaction = + | Simple of string + | NewChunked of (string * int) + | Chunk of string + +let encode_transaction ~smart_rollup_address kind = + let data = + match kind with + | Simple data -> "\000" ^ data + | NewChunked (hash, len) -> + let number_of_chunks_bytes = u16_to_bytes len in + "\001" ^ hash ^ number_of_chunks_bytes + | Chunk data -> "\002" ^ data + in + smart_rollup_address ^ data + +let make_evm_inbox_transactions tx_raw = + let open Result_syntax in + (* Maximum size describes the maximum size of [tx_raw] to fit + in a simple transaction. *) + let transaction_tag_size = 1 in + let maximum_size = + max_input_size - smart_rollup_address_size - transaction_tag_size + - Ethereum_types.transaction_hash_size + in + let tx_hash = Tx_hash.hash_to_string tx_raw in + if String.length tx_raw <= maximum_size then + (* Simple transaction, fits in a single input. *) + let tx_hash = Tx_hash.hash_to_string tx_raw in + let tx = Simple (tx_hash ^ tx_raw) in + return (tx_hash, [tx]) + else + let size_per_chunk = + max_input_size - smart_rollup_address_size - transaction_tag_size - 2 + (* Index as u16 *) - Ethereum_types.transaction_hash_size + in + let* chunks = String.chunk_bytes size_per_chunk (Bytes.of_string tx_raw) in + let new_chunk_transaction = NewChunked (tx_hash, List.length chunks) in + let chunks = + List.mapi (fun i chunk -> Chunk (tx_hash ^ u16_to_bytes i ^ chunk)) chunks + in + return (tx_hash, new_chunk_transaction :: chunks) + +let make_encoded_messages ~smart_rollup_address tx_raw = + let open Result_syntax in + let tx_raw = Ethereum_types.hash_to_bytes tx_raw in + let* tx_hash, messages = make_evm_inbox_transactions tx_raw in + let messages = + List.map + (fun x -> + x + |> encode_transaction ~smart_rollup_address + |> Hex.of_string |> Hex.show) + messages + in + return (tx_hash, messages) + (** [chunks bytes size] returns [Bytes.length bytes / size] chunks of size [size]. *) let chunks bytes size = @@ -235,7 +302,6 @@ module RPC = struct let inject_raw_transaction base tx = let open Lwt_result_syntax in - let tx = Hex.of_string tx |> Hex.show 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. We do not wish to follow the message's inclusion, and thus, ignore @@ -243,69 +309,10 @@ module RPC = struct let* _answer = call_service ~base batcher_injection () () [tx] in return_unit - let u16_to_bytes n = - let bytes = Bytes.make 2 'a' in - Bytes.set_uint16_le bytes 0 n ; - Bytes.to_string bytes - - (* The hard limit is 4096 but it needs to add the external message tag. *) - let max_input_size = 4095 - - let smart_rollup_address_size = 20 - - type transaction = - | Simple of string - | NewChunked of (string * int) - | Chunk of string - - let encode_transaction ~smart_rollup_address kind = - let data = - match kind with - | Simple data -> "\000" ^ data - | NewChunked (hash, len) -> - let number_of_chunks_bytes = u16_to_bytes len in - "\001" ^ hash ^ number_of_chunks_bytes - | Chunk data -> "\002" ^ data - in - smart_rollup_address ^ data - - let make_evm_inbox_transactions tx_raw = - let open Lwt_result_syntax in - (* Maximum size describes the maximum size of [tx_raw] to fit - in a simple transaction. *) - let transaction_tag_size = 1 in - let maximum_size = - max_input_size - smart_rollup_address_size - transaction_tag_size - - Ethereum_types.transaction_hash_size - in - let tx_hash = Tx_hash.hash_to_string tx_raw in - if String.length tx_raw <= maximum_size then - (* Simple transaction, fits in a single input. *) - let tx_hash = Tx_hash.hash_to_string tx_raw in - let tx = Simple (tx_hash ^ tx_raw) in - return (tx_hash, [tx]) - else - let size_per_chunk = - max_input_size - smart_rollup_address_size - transaction_tag_size - 2 - (* Index as u16 *) - Ethereum_types.transaction_hash_size - in - let*? chunks = - String.chunk_bytes size_per_chunk (Bytes.of_string tx_raw) - in - let new_chunk_transaction = NewChunked (tx_hash, List.length chunks) in - let chunks = - List.mapi - (fun i chunk -> Chunk (tx_hash ^ u16_to_bytes i ^ chunk)) - chunks - in - return (tx_hash, new_chunk_transaction :: chunks) - let inject_raw_transaction base ~smart_rollup_address tx_raw = let open Lwt_result_syntax in - let tx_raw = Ethereum_types.hash_to_bytes tx_raw in - let* tx_hash, messages = make_evm_inbox_transactions tx_raw in - let messages = - List.map (encode_transaction ~smart_rollup_address) messages + let*? tx_hash, messages = + make_encoded_messages ~smart_rollup_address tx_raw in let* () = List.iter_es (inject_raw_transaction base) messages in return (Ethereum_types.Hash Hex.(of_string tx_hash |> show)) diff --git a/src/bin_evm_proxy/rollup_node.mli b/src/bin_evm_proxy/lib/rollup_node.mli similarity index 89% rename from src/bin_evm_proxy/rollup_node.mli rename to src/bin_evm_proxy/lib/rollup_node.mli index d89089548d343c222bf507eee357ff71d6f33544..2d5377bb2cbbddb467815dc7eaebdd274808c687 100644 --- a/src/bin_evm_proxy/rollup_node.mli +++ b/src/bin_evm_proxy/lib/rollup_node.mli @@ -23,6 +23,18 @@ (* *) (*****************************************************************************) +(** [make_encoded_messages ~smart_rollup_address raw_tx] returns the + hash of the transaction, and a list of transactions to include in the inbox. + - [smart_rollup_address] is encoded on 20 bytes + - [raw_tx] is an ethereum transaction in hex format (without the 0x prefix). + + All messages go through the same encoding, but will only be chunked if + necessary. *) +val make_encoded_messages : + smart_rollup_address:string -> + Ethereum_types.hash -> + (string * string list, 'a) result + (** List of services supported to communicate with a rollup node. *) module type S = sig (** [smart_rollup_address] asks for the smart rollup node's address. *) diff --git a/src/bin_evm_proxy/rpc_encodings.ml b/src/bin_evm_proxy/lib/rpc_encodings.ml similarity index 100% rename from src/bin_evm_proxy/rpc_encodings.ml rename to src/bin_evm_proxy/lib/rpc_encodings.ml diff --git a/src/bin_evm_proxy/rpc_encodings.mli b/src/bin_evm_proxy/lib/rpc_encodings.mli similarity index 96% rename from src/bin_evm_proxy/rpc_encodings.mli rename to src/bin_evm_proxy/lib/rpc_encodings.mli index cd4b6a6532832c4c6b9705feaeef4bf2cc9ecb73..bdadb0da5564d04bc6df820c183518c9431dd81a 100644 --- a/src/bin_evm_proxy/rpc_encodings.mli +++ b/src/bin_evm_proxy/lib/rpc_encodings.mli @@ -40,11 +40,13 @@ module JSONRPC : sig type id = id_repr option (** JSON-RPC Request object: - { "jsonrpc" : "2.0", - "method": , - "params": , //optional - "id": //optional - } + {@js[ + { "jsonrpc" : "2.0", + "method": , + "params": , //optional + "id": //optional + } + ]} *) type 'params request = { method_ : string; @@ -56,21 +58,25 @@ module JSONRPC : sig string -> 'a Data_encoding.t -> 'a request Data_encoding.t (** JSON-RPC Error representation. + {@js[ { "code" : , "message": , "data": } + ]} *) type 'data error = {code : int; message : string; data : 'data option} val error_encoding : 'a Data_encoding.t -> 'a error Data_encoding.t (** JSON-RPC Response object: + {@js[ { "jsonrpc": "2.0", "result": , "error": , "id": } + ]} Note that `result` and `error` cannot appear at the same time, hence the choice of using the result type as representation. *) @@ -133,7 +139,7 @@ module type METHOD = sig (** Variant representing the method's response. *) type output += Output of m_output rpc_result - (** See {METHOD_DEF.method_}. *) + (** See METHOD_DEF.method_ *) val method_ : string val request_encoding : m_input JSONRPC.request Data_encoding.t @@ -162,7 +168,7 @@ module MethodMaker : functor (M : METHOD_DEF) -> val methods : (module METHOD) list (** [Input] defines the input encoding matching the defined methods in - {methods}. *) + [methods]. *) module Input : sig type t = input @@ -170,7 +176,7 @@ module Input : sig end (** [Output] defines the output encoding matching the defined methods in - {methods}. *) + [methods]. *) module Output : sig type nonrec 'a result = ('a, error JSONRPC.error) result diff --git a/src/bin_evm_proxy/services.ml b/src/bin_evm_proxy/lib/services.ml similarity index 100% rename from src/bin_evm_proxy/services.ml rename to src/bin_evm_proxy/lib/services.ml diff --git a/src/bin_evm_proxy/tx_hash.ml b/src/bin_evm_proxy/lib/tx_hash.ml similarity index 100% rename from src/bin_evm_proxy/tx_hash.ml rename to src/bin_evm_proxy/lib/tx_hash.ml diff --git a/src/bin_evm_proxy/tx_hash.mli b/src/bin_evm_proxy/lib/tx_hash.mli similarity index 100% rename from src/bin_evm_proxy/tx_hash.mli rename to src/bin_evm_proxy/lib/tx_hash.mli