diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index fed767fe7f23e72c6f1c9e5e95472ff9ed98d7c2..d597c7a467dc52a801d4a8e0ebff9e1dbe47231a 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -421,6 +421,8 @@ opam:octez-smart-rollup-node-PtNairob: # Ignoring unreleased package octez-smart-rollup-node-alpha. +# Ignoring unreleased package octez-smart-rollup-sequencer. + # Ignoring unreleased package octez-smart-rollup-wasm-benchmark. opam:octez-smart-rollup-wasm-benchmark-lib: diff --git a/dune-project b/dune-project index f1e886b88b8ddc1a64f739665ea04348c2da27ef..5cde156fde6fe13eb81dfc0c38736840d1ea02d7 100644 --- a/dune-project +++ b/dune-project @@ -44,6 +44,7 @@ (package (name octez-smart-rollup-node-PtMumbai)) (package (name octez-smart-rollup-node-PtNairob)) (package (name octez-smart-rollup-node-alpha)) +(package (name octez-smart-rollup-sequencer)(allow_empty)) (package (name octez-smart-rollup-wasm-benchmark)(allow_empty)) (package (name octez-smart-rollup-wasm-benchmark-lib)(allow_empty)) (package (name octez-smart-rollup-wasm-debugger)) diff --git a/manifest/main.ml b/manifest/main.ml index ef2cdb0d493faf886d02e4a07c8c06c9e8d0a119..0ead154146e299d74e7aef7d3ea2ac8c28d4aace 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -4287,6 +4287,8 @@ module Protocol : sig val benchmarks_proto_exn : t -> target + val octez_sc_rollup_layer2 : t -> target option + val baking_exn : t -> target val genesis : t @@ -4402,12 +4404,13 @@ end = struct parameters : target option; benchmarks_proto : target option; baking : target option; + octez_sc_rollup_layer2 : target option; } let make ?client ?client_commands ?client_commands_registration ?baking_commands_registration ?plugin ?plugin_registerer ?dal ?dac - ?test_helpers ?parameters ?benchmarks_proto ?baking ~status ~name ~main - ~embedded () = + ?test_helpers ?parameters ?benchmarks_proto ?octez_sc_rollup_layer2 + ?baking ~status ~name ~main ~embedded () = { status; name; @@ -4425,6 +4428,7 @@ end = struct parameters; benchmarks_proto; baking; + octez_sc_rollup_layer2; } let all_rev : t list ref = ref [] @@ -4483,6 +4487,8 @@ end = struct let baking_exn p = mandatory "baking" p p.baking + let octez_sc_rollup_layer2 p = p.octez_sc_rollup_layer2 + (* N as in "protocol number in the Alpha family". *) module N = struct (* This function is asymmetrical on purpose: we don't want to compare @@ -6396,6 +6402,7 @@ let hash = Protocol.hash ?parameters ?benchmarks_proto ?baking + ?octez_sc_rollup_layer2 () let active = register_alpha_family Active @@ -7357,6 +7364,23 @@ let evm_proxy_lib = rope; ] +let _octez_scoru_sequencer = + private_lib + "octez_smart_rollup_sequencer" + ~path:"src/lib_scoru_sequencer" + ~opam:"octez-smart-rollup-sequencer" + ~synopsis:"Sequencer library for smart contract rollup" + ~deps: + [ + octez_base |> open_ |> open_ ~m:"TzPervasives" + |> open_ ~m:"TzPervasives.Error_monad.Legacy_monad_globals"; + Protocol.(octez_sc_rollup_layer2 alpha |> if_some |> open_); + Protocol.(main alpha) |> open_; + octez_rpc; + octez_rpc_http; + octez_rpc_http_server; + ] + let _evm_proxy = public_exe (sf "octez-evm-proxy-server") diff --git a/opam/octez-smart-rollup-sequencer.opam b/opam/octez-smart-rollup-sequencer.opam new file mode 100644 index 0000000000000000000000000000000000000000..e8c3b10c566cb17d1d75081fbd694dac00cb5952 --- /dev/null +++ b/opam/octez-smart-rollup-sequencer.opam @@ -0,0 +1,25 @@ +# 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-smart-rollup-layer2-alpha" + "tezos-protocol-alpha" + "tezos-rpc" + "tezos-rpc-http" + "tezos-rpc-http-server" +] +build: [ + ["rm" "-r" "vendors" "contrib"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Sequencer library for smart contract rollup" diff --git a/src/lib_scoru_sequencer/configuration.ml b/src/lib_scoru_sequencer/configuration.ml new file mode 100644 index 0000000000000000000000000000000000000000..cc358b05a3323698e2ec550492cf96aeee5b626f --- /dev/null +++ b/src/lib_scoru_sequencer/configuration.ml @@ -0,0 +1,27 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs, *) +(* Copyright (c) 2022-2023 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +type t = {rpc_addr : string; rpc_port : int} diff --git a/src/lib_scoru_sequencer/configuration.mli b/src/lib_scoru_sequencer/configuration.mli new file mode 100644 index 0000000000000000000000000000000000000000..cc358b05a3323698e2ec550492cf96aeee5b626f --- /dev/null +++ b/src/lib_scoru_sequencer/configuration.mli @@ -0,0 +1,27 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs, *) +(* Copyright (c) 2022-2023 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +type t = {rpc_addr : string; rpc_port : int} diff --git a/src/lib_scoru_sequencer/dune b/src/lib_scoru_sequencer/dune new file mode 100644 index 0000000000000000000000000000000000000000..81ad590e144fcc60b8b061345418af54bd10a686 --- /dev/null +++ b/src/lib_scoru_sequencer/dune @@ -0,0 +1,21 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name octez_smart_rollup_sequencer) + (package octez-smart-rollup-sequencer) + (instrumentation (backend bisect_ppx)) + (libraries + tezos-base + tezos-smart-rollup-layer2-alpha + tezos-protocol-alpha + tezos-rpc + tezos-rpc-http + tezos-rpc-http-server) + (flags + (:standard) + -open Tezos_base + -open Tezos_base.TzPervasives + -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals + -open Tezos_smart_rollup_layer2_alpha + -open Tezos_protocol_alpha)) diff --git a/src/lib_scoru_sequencer/rpc_server.ml b/src/lib_scoru_sequencer/rpc_server.ml new file mode 100644 index 0000000000000000000000000000000000000000..24b250b174a70aa3b4fb34230acd1ec2523bc80b --- /dev/null +++ b/src/lib_scoru_sequencer/rpc_server.ml @@ -0,0 +1,84 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs, *) +(* Copyright (c) 2022-2023 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Tezos_rpc_http_server +open RPC_directory_helpers + +module Local_directory = Make_directory (struct + include Sc_rollup_services.Local + + type context = unit + + type subcontext = unit + + let context_of_prefix _ll_node_ctxt () = return () +end) + +(* Register server handlers *) +let () = + let open Protocol.Alpha_context.Sc_rollup in + ( Local_directory.register0 + (Sequencer_services.Local.durable_state_value Kind.Wasm_2_0_0) + @@ fun () _key () -> failwith "Not implemented" ) ; + + ( Local_directory.register0 + (Sequencer_services.Local.durable_state_subkeys Kind.Wasm_2_0_0) + @@ fun () _key () -> failwith "Not implemented" ) ; + + Local_directory.register0 Sc_rollup_services.Local.injection + @@ fun _node_ctxt () _messages -> failwith "Not implemented" + +let register node_ctxt = + List.fold_left + (fun dir f -> Tezos_rpc.Directory.merge dir (f node_ctxt)) + Tezos_rpc.Directory.empty + [Local_directory.build_directory] + +let start node_ctxt configuration = + let open Lwt_result_syntax in + let Configuration.{rpc_addr; rpc_port; _} = configuration in + let rpc_addr = P2p_addr.of_string_exn rpc_addr in + let host = Ipaddr.V6.to_string rpc_addr in + let node = `TCP (`Port rpc_port) in + let acl = RPC_server.Acl.allow_all in + let dir = register node_ctxt in + let server = + RPC_server.init_server + dir + ~acl + ~media_types:Tezos_rpc_http.Media_type.all_media_types + in + protect @@ fun () -> + let*! () = + RPC_server.launch + ~host + server + ~callback:(RPC_server.resto_callback server) + node + in + return server + +let shutdown = RPC_server.shutdown diff --git a/src/lib_scoru_sequencer/rpc_server.mli b/src/lib_scoru_sequencer/rpc_server.mli new file mode 100644 index 0000000000000000000000000000000000000000..baa5f328d9c0e62fc3124b2f4f3cfe51d1de18ec --- /dev/null +++ b/src/lib_scoru_sequencer/rpc_server.mli @@ -0,0 +1,34 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2022 Nomadic Labs, *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Tezos_rpc_http_server + +(** [start node_ctxt config] starts an RPC server listening for requests on the + port [config.rpc_port] and address [config.rpc_addr]. *) +val start : unit -> Configuration.t -> RPC_server.server tzresult Lwt.t + +(** Shutdown a running RPC server. When this function is called, the rollup node + will stop listening to incoming requests. *) +val shutdown : RPC_server.server -> unit Lwt.t diff --git a/src/lib_scoru_sequencer/sequencer_services.ml b/src/lib_scoru_sequencer/sequencer_services.ml new file mode 100644 index 0000000000000000000000000000000000000000..765817c15237015e0c8412685d2867f06e4bc662 --- /dev/null +++ b/src/lib_scoru_sequencer/sequencer_services.ml @@ -0,0 +1,59 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2021 Nomadic Labs, *) +(* Copyright (c) 2023 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Protocol.Alpha_context +module Sc_services = Sc_rollup_services + +module Local = struct + open Tezos_rpc.Path + + include Sc_services.Make_services (struct + type prefix = unit + + let prefix = open_root / "local" + end) + + let durable_state_value (pvm_kind : Protocol.Alpha_context.Sc_rollup.Kind.t) = + Tezos_rpc.Service.get_service + ~description: + "Retrieve value by key from durable storage. PVM state corresponds to \ + the last L2 operation in the queue. Value returned in hex format." + ~query:Sc_services.Query.key_query + ~output:Data_encoding.(option bytes) + (path / "durable" / Sc_rollup.Kind.to_string pvm_kind / "value") + + let durable_state_subkeys (pvm_kind : Protocol.Alpha_context.Sc_rollup.Kind.t) + = + Tezos_rpc.Service.get_service + ~description: + "Retrieve value by key from durable storage. PVM state corresponds to \ + the last L2 operation in the queue." + ~query:Sc_services.Query.key_query + ~output:Data_encoding.(list string) + (path / "durable" / Sc_rollup.Kind.to_string pvm_kind / "subkeys") + + let injection = Sc_services.Local.injection +end diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.ml b/src/proto_016_PtMumbai/lib_sc_rollup_layer2/RPC_directory_helpers.ml similarity index 71% rename from src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.ml rename to src/proto_016_PtMumbai/lib_sc_rollup_layer2/RPC_directory_helpers.ml index b729005cdb98f3e0272e8f315c37d2d6dddaa694..6b0c8ec4337c8c6dae2ac52b02898395e0f3fa69 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_layer2/RPC_directory_helpers.ml @@ -23,8 +23,6 @@ (* *) (*****************************************************************************) -open Protocol - (* Conveniences to construct RPC directory against a subcontext of the Node_context *) @@ -33,13 +31,15 @@ module type PARAM = sig type context - val context_of_prefix : Node_context.rw -> prefix -> context tzresult Lwt.t + type subcontext + + val context_of_prefix : context -> prefix -> subcontext tzresult Lwt.t end module Make_directory (S : PARAM) = struct open S - let directory : context tzresult Tezos_rpc.Directory.t ref = + let directory : subcontext tzresult Tezos_rpc.Directory.t ref = ref Tezos_rpc.Directory.empty let register service f = @@ -64,32 +64,3 @@ module Make_directory (S : PARAM) = struct context_of_prefix node_ctxt prefix) |> Tezos_rpc.Directory.prefix prefix end - -module Block_directory_helpers = struct - let get_head store = - let open Lwt_result_syntax in - let* head = Node_context.last_processed_head_opt store in - match head with - | None -> failwith "No head" - | Some {header = {block_hash; _}; _} -> return block_hash - - let get_finalized node_ctxt = - let open Lwt_result_syntax in - let* level = Node_context.get_finalized_level node_ctxt in - Node_context.hash_of_level node_ctxt level - - let get_last_cemented (node_ctxt : _ Node_context.t) = - protect @@ fun () -> - let lcc = Reference.get node_ctxt.lcc in - Node_context.hash_of_level - node_ctxt - (Alpha_context.Raw_level.to_int32 lcc.level) - - let block_of_prefix node_ctxt block = - match block with - | `Head -> get_head node_ctxt - | `Hash b -> return b - | `Level l -> Node_context.hash_of_level node_ctxt l - | `Finalized -> get_finalized node_ctxt - | `Cemented -> get_last_cemented node_ctxt -end diff --git a/src/proto_alpha/lib_sc_rollup_node/RPC_directory_helpers.mli b/src/proto_016_PtMumbai/lib_sc_rollup_layer2/RPC_directory_helpers.mli similarity index 82% rename from src/proto_alpha/lib_sc_rollup_node/RPC_directory_helpers.mli rename to src/proto_016_PtMumbai/lib_sc_rollup_layer2/RPC_directory_helpers.mli index 72f9952c4bbe88ef66dc81ccda5e9f071fb68fc1..c98568773bf7228aa1ef842cc8fae10cdc40ae79 100644 --- a/src/proto_alpha/lib_sc_rollup_node/RPC_directory_helpers.mli +++ b/src/proto_016_PtMumbai/lib_sc_rollup_layer2/RPC_directory_helpers.mli @@ -33,7 +33,9 @@ module type PARAM = sig type context - val context_of_prefix : Node_context.rw -> prefix -> context tzresult Lwt.t + type subcontext + + val context_of_prefix : context -> prefix -> subcontext tzresult Lwt.t end (** This module is a helper to register your endpoints and @@ -42,7 +44,7 @@ module Make_directory (S : PARAM) : sig (** Register an endpoint with no parameters in the path. *) val register0 : ([< Resto.meth], 'prefix, 'prefix, 'query, 'input, 'output) Service.t -> - (S.context -> 'query -> 'input -> 'output tzresult Lwt.t) -> + (S.subcontext -> 'query -> 'input -> 'output tzresult Lwt.t) -> unit (** Register an endpoint with a single parameter in the path. *) @@ -54,18 +56,9 @@ module Make_directory (S : PARAM) : sig 'input, 'output ) Service.t -> - (S.context -> 'param1 -> 'query -> 'input -> 'output tzresult Lwt.t) -> + (S.subcontext -> 'param1 -> 'query -> 'input -> 'output tzresult Lwt.t) -> unit (** Build directory with registered endpoints with respect to Node_context. *) - val build_directory : Node_context.rw -> unit Tezos_rpc.Directory.t -end - -(** This module is a helper to extract a block hash - from block reference and Node_context *) -module Block_directory_helpers : sig - val block_of_prefix : - Node_context.rw -> - [< `Cemented | `Finalized | `Hash of Block_hash.t | `Head | `Level of int32] -> - Block_hash.t tzresult Lwt.t + val build_directory : S.context -> unit Tezos_rpc.Directory.t end diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_layer2/sc_rollup_services.ml b/src/proto_016_PtMumbai/lib_sc_rollup_layer2/sc_rollup_services.ml index 680ce69dc13c4beb3cd118df51c7b1568b8f38cb..c2a21f4160345f5d147ceeb720e74d05f23e4edb 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_layer2/sc_rollup_services.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_layer2/sc_rollup_services.ml @@ -24,8 +24,7 @@ (* *) (*****************************************************************************) -open Protocol -open Alpha_context +open Protocol.Alpha_context (* We distinguish RPC endpoints served by the rollup node into `global` and `local`. The difference between the two lies in whether the responses @@ -423,6 +422,71 @@ module Arg = struct () end +module Query = struct + let outbox_proof_query = + let open Tezos_rpc.Query in + let open Sc_rollup in + let invalid_message e = + raise + (Invalid + (Format.asprintf + "Invalid message (%a)" + Environment.Error_monad.pp_trace + e)) + in + query (fun outbox_level message_index serialized_outbox_message -> + let req name f = function + | None -> + raise + (Invalid (Format.sprintf "Query parameter %s is required" name)) + | Some arg -> f arg + in + let outbox_level = + req "outbox_level" Raw_level.of_int32_exn outbox_level + in + let message_index = req "message_index" Z.of_int64 message_index in + let message = + req + "serialized_outbox_message" + (fun s -> Outbox.Message.(unsafe_of_string s |> deserialize)) + serialized_outbox_message + in + match message with + | Error e -> invalid_message e + | Ok message -> {outbox_level; message_index; message}) + |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> + Some (Raw_level.to_int32 o.outbox_level)) + |+ opt_field "message_index" Tezos_rpc.Arg.int64 (fun o -> + Some (Z.to_int64 o.message_index)) + |+ opt_field "serialized_outbox_message" Tezos_rpc.Arg.string (fun o -> + match Outbox.Message.serialize o.message with + | Ok message -> Some (Outbox.Message.unsafe_to_string message) + | Error e -> invalid_message e) + |> seal + + type key_query = {key : string} + + let key_query : key_query Tezos_rpc.Query.t = + let open Tezos_rpc.Query in + query (fun key -> {key}) + |+ field "key" Tezos_rpc.Arg.string "" (fun t -> t.key) + |> seal + + let outbox_level_query = + let open Tezos_rpc.Query in + query (fun outbox_level -> + let req name f = function + | None -> + raise + (Invalid (Format.sprintf "Query parameter %s is required" name)) + | Some arg -> f arg + in + req "outbox_level" Raw_level.of_int32_exn outbox_level) + |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> + Some (Raw_level.to_int32 o)) + |> seal +end + module type PREFIX = sig type prefix @@ -496,52 +560,10 @@ module Global = struct let prefix = open_root / "helpers" end) - let outbox_proof_query = - let open Tezos_rpc.Query in - let open Sc_rollup in - let invalid_message e = - raise - (Invalid - (Format.asprintf - "Invalid message (%a)" - Environment.Error_monad.pp_trace - e)) - in - query (fun outbox_level message_index serialized_outbox_message -> - let req name f = function - | None -> - raise - (Invalid - (Format.sprintf "Query parameter %s is required" name)) - | Some arg -> f arg - in - let outbox_level = - req "outbox_level" Raw_level.of_int32_exn outbox_level - in - let message_index = req "message_index" Z.of_int64 message_index in - let message = - req - "serialized_outbox_message" - (fun s -> Outbox.Message.(unsafe_of_string s |> deserialize)) - serialized_outbox_message - in - match message with - | Error e -> invalid_message e - | Ok message -> {outbox_level; message_index; message}) - |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> - Some (Raw_level.to_int32 o.outbox_level)) - |+ opt_field "message_index" Tezos_rpc.Arg.int64 (fun o -> - Some (Z.to_int64 o.message_index)) - |+ opt_field "serialized_outbox_message" Tezos_rpc.Arg.string (fun o -> - match Outbox.Message.serialize o.message with - | Ok message -> Some (Outbox.Message.unsafe_to_string message) - | Error e -> invalid_message e) - |> seal - let outbox_proof = Tezos_rpc.Service.get_service ~description:"Generate serialized output proof for some outbox message" - ~query:outbox_proof_query + ~query:Query.outbox_proof_query ~output: Data_encoding.( obj2 @@ -622,33 +644,22 @@ module Global = struct ~output:(Data_encoding.option Raw_level.encoding) (path / "state_current_level") - type state_value_query = {key : string} - - let state_value_query : state_value_query Tezos_rpc.Query.t = - let open Tezos_rpc.Query in - query (fun key -> {key}) - |+ field "key" Tezos_rpc.Arg.string "" (fun t -> t.key) - |> seal - let state_value = Tezos_rpc.Service.get_service ~description:"Retrieve value from key is PVM state of specified block" - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.bytes (path / "state") - let durable_state_value (pvm_kind : Protocol.Alpha_context.Sc_rollup.Kind.t) - = + let durable_state_value (pvm_kind : Sc_rollup.Kind.t) = Tezos_rpc.Service.get_service ~description: "Retrieve value by key from PVM durable storage. PVM state is taken \ with respect to the specified block level. Value returned in hex \ format." - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.(option bytes) - (path / "durable" - / Protocol.Alpha_context.Sc_rollup.Kind.to_string pvm_kind - / "value") + (path / "durable" / Sc_rollup.Kind.to_string pvm_kind / "value") let durable_state_length (pvm_kind : Protocol.Alpha_context.Sc_rollup.Kind.t) = @@ -657,23 +668,18 @@ module Global = struct "Retrieve number of bytes in raw representation of value by key from \ PVM durable storage. PVM state is taken with respect to the \ specified block level." - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.(option int64) - (path / "durable" - / Protocol.Alpha_context.Sc_rollup.Kind.to_string pvm_kind - / "length") + (path / "durable" / Sc_rollup.Kind.to_string pvm_kind / "length") - let durable_state_subkeys - (pvm_kind : Protocol.Alpha_context.Sc_rollup.Kind.t) = + let durable_state_subkeys (pvm_kind : Sc_rollup.Kind.t) = Tezos_rpc.Service.get_service ~description: "Retrieve subkeys of the specified key from PVM durable storage. PVM \ state is taken with respect to the specified block level." - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.(list string) - (path / "durable" - / Protocol.Alpha_context.Sc_rollup.Kind.to_string pvm_kind - / "subkeys") + (path / "durable" / Sc_rollup.Kind.to_string pvm_kind / "subkeys") let status = Tezos_rpc.Service.get_service @@ -682,25 +688,10 @@ module Global = struct ~output:Data_encoding.string (path / "status") - let outbox_level_query = - let open Tezos_rpc.Query in - query (fun outbox_level -> - let req name f = function - | None -> - raise - (Invalid - (Format.sprintf "Query parameter %s is required" name)) - | Some arg -> f arg - in - req "outbox_level" Raw_level.of_int32_exn outbox_level) - |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> - Some (Raw_level.to_int32 o)) - |> seal - let outbox = Tezos_rpc.Service.get_service ~description:"Outbox at block for a given outbox level" - ~query:outbox_level_query + ~query:Query.outbox_level_query ~output:Data_encoding.(list Sc_rollup.output_encoding) (path / "outbox") diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml index 9ddaee3a4f052e9500103ec7638c3d48ea421628..a450fda0114871c81449ed4d2f3730e262d5cef5 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_server.ml @@ -98,7 +98,9 @@ let get_dal_slot_page node_ctxt block slot_index slot_page = module Global_directory = Make_directory (struct include Sc_rollup_services.Global - type context = Node_context.ro + type context = Node_context.rw + + type subcontext = Node_context.ro let context_of_prefix node_ctxt () = return (Node_context.readonly node_ctxt) end) @@ -110,13 +112,19 @@ module Proof_helpers_directory = Make_directory (struct commit on disk to generate the proofs. *) type context = Node_context.rw + (* The context needs to be accessed with write permissions because we need to + commit on disk to generate the proofs. *) + type subcontext = Node_context.rw + let context_of_prefix node_ctxt () = return node_ctxt end) module Local_directory = Make_directory (struct include Sc_rollup_services.Local - type context = Node_context.ro + type context = Node_context.rw + + type subcontext = Node_context.ro let context_of_prefix node_ctxt () = return (Node_context.readonly node_ctxt) end) @@ -124,7 +132,9 @@ end) module Block_directory = Make_directory (struct include Sc_rollup_services.Global.Block - type context = Node_context.ro * Block_hash.t + type context = Node_context.rw + + type subcontext = Node_context.ro * Block_hash.t let context_of_prefix node_ctxt (((), block) : prefix) = let open Lwt_result_syntax in @@ -135,7 +145,9 @@ end) module Outbox_directory = Make_directory (struct include Sc_rollup_services.Global.Block.Outbox - type context = Node_context.ro * Block_hash.t * Alpha_context.Raw_level.t + type context = Node_context.rw + + type subcontext = Node_context.ro * Block_hash.t * Alpha_context.Raw_level.t let context_of_prefix node_ctxt (((), block), level) = let open Lwt_result_syntax in diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/block_directory_helpers.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/block_directory_helpers.ml new file mode 100644 index 0000000000000000000000000000000000000000..a4ccb383a729f3407e0c9fc943fec33844276c84 --- /dev/null +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/block_directory_helpers.ml @@ -0,0 +1,56 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Protocol + +(* Conveniences to construct RPC directory + against a subcontext of the Node_context *) + +let get_head store = + let open Lwt_result_syntax in + let* head = Node_context.last_processed_head_opt store in + match head with + | None -> failwith "No head" + | Some {header = {block_hash; _}; _} -> return block_hash + +let get_finalized node_ctxt = + let open Lwt_result_syntax in + let* level = Node_context.get_finalized_level node_ctxt in + Node_context.hash_of_level node_ctxt level + +let get_last_cemented (node_ctxt : _ Node_context.t) = + protect @@ fun () -> + let lcc = Reference.get node_ctxt.lcc in + Node_context.hash_of_level + node_ctxt + (Alpha_context.Raw_level.to_int32 lcc.level) + +let block_of_prefix node_ctxt block = + match block with + | `Head -> get_head node_ctxt + | `Hash b -> return b + | `Level l -> Node_context.hash_of_level node_ctxt l + | `Finalized -> get_finalized node_ctxt + | `Cemented -> get_last_cemented node_ctxt diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/block_directory_helpers.mli b/src/proto_016_PtMumbai/lib_sc_rollup_node/block_directory_helpers.mli new file mode 100644 index 0000000000000000000000000000000000000000..3994a59f6f841c122d1025544476d58141a88167 --- /dev/null +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/block_directory_helpers.mli @@ -0,0 +1,32 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* Copyright (c) 2022-2023 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +(** This module is a helper to extract a block hash + from block reference and Node_context *) +val block_of_prefix : + _ Node_context.t -> + [< `Cemented | `Finalized | `Hash of Block_hash.t | `Head | `Level of int32] -> + Block_hash.t tzresult Lwt.t diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/wasm_2_0_0_rpc.ml b/src/proto_016_PtMumbai/lib_sc_rollup_node/wasm_2_0_0_rpc.ml index c5a2210f19fa66b0ce5c78a72b71f880d5582726..dd4c703fa4c57891080e2547ac40a3fd7f53ad83 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/wasm_2_0_0_rpc.ml +++ b/src/proto_016_PtMumbai/lib_sc_rollup_node/wasm_2_0_0_rpc.ml @@ -32,7 +32,9 @@ struct module Block_directory = Make_directory (struct include Sc_rollup_services.Global.Block - type context = Node_context.ro * Block_hash.t + type context = Node_context.rw + + type subcontext = Node_context.ro * Block_hash.t let context_of_prefix node_ctxt (((), block) : prefix) = let open Lwt_result_syntax in diff --git a/src/proto_alpha/lib_sc_rollup_node/RPC_directory_helpers.ml b/src/proto_017_PtNairob/lib_sc_rollup_layer2/RPC_directory_helpers.ml similarity index 71% rename from src/proto_alpha/lib_sc_rollup_node/RPC_directory_helpers.ml rename to src/proto_017_PtNairob/lib_sc_rollup_layer2/RPC_directory_helpers.ml index b729005cdb98f3e0272e8f315c37d2d6dddaa694..6b0c8ec4337c8c6dae2ac52b02898395e0f3fa69 100644 --- a/src/proto_alpha/lib_sc_rollup_node/RPC_directory_helpers.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_layer2/RPC_directory_helpers.ml @@ -23,8 +23,6 @@ (* *) (*****************************************************************************) -open Protocol - (* Conveniences to construct RPC directory against a subcontext of the Node_context *) @@ -33,13 +31,15 @@ module type PARAM = sig type context - val context_of_prefix : Node_context.rw -> prefix -> context tzresult Lwt.t + type subcontext + + val context_of_prefix : context -> prefix -> subcontext tzresult Lwt.t end module Make_directory (S : PARAM) = struct open S - let directory : context tzresult Tezos_rpc.Directory.t ref = + let directory : subcontext tzresult Tezos_rpc.Directory.t ref = ref Tezos_rpc.Directory.empty let register service f = @@ -64,32 +64,3 @@ module Make_directory (S : PARAM) = struct context_of_prefix node_ctxt prefix) |> Tezos_rpc.Directory.prefix prefix end - -module Block_directory_helpers = struct - let get_head store = - let open Lwt_result_syntax in - let* head = Node_context.last_processed_head_opt store in - match head with - | None -> failwith "No head" - | Some {header = {block_hash; _}; _} -> return block_hash - - let get_finalized node_ctxt = - let open Lwt_result_syntax in - let* level = Node_context.get_finalized_level node_ctxt in - Node_context.hash_of_level node_ctxt level - - let get_last_cemented (node_ctxt : _ Node_context.t) = - protect @@ fun () -> - let lcc = Reference.get node_ctxt.lcc in - Node_context.hash_of_level - node_ctxt - (Alpha_context.Raw_level.to_int32 lcc.level) - - let block_of_prefix node_ctxt block = - match block with - | `Head -> get_head node_ctxt - | `Hash b -> return b - | `Level l -> Node_context.hash_of_level node_ctxt l - | `Finalized -> get_finalized node_ctxt - | `Cemented -> get_last_cemented node_ctxt -end diff --git a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.mli b/src/proto_017_PtNairob/lib_sc_rollup_layer2/RPC_directory_helpers.mli similarity index 82% rename from src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.mli rename to src/proto_017_PtNairob/lib_sc_rollup_layer2/RPC_directory_helpers.mli index 72f9952c4bbe88ef66dc81ccda5e9f071fb68fc1..c98568773bf7228aa1ef842cc8fae10cdc40ae79 100644 --- a/src/proto_016_PtMumbai/lib_sc_rollup_node/RPC_directory_helpers.mli +++ b/src/proto_017_PtNairob/lib_sc_rollup_layer2/RPC_directory_helpers.mli @@ -33,7 +33,9 @@ module type PARAM = sig type context - val context_of_prefix : Node_context.rw -> prefix -> context tzresult Lwt.t + type subcontext + + val context_of_prefix : context -> prefix -> subcontext tzresult Lwt.t end (** This module is a helper to register your endpoints and @@ -42,7 +44,7 @@ module Make_directory (S : PARAM) : sig (** Register an endpoint with no parameters in the path. *) val register0 : ([< Resto.meth], 'prefix, 'prefix, 'query, 'input, 'output) Service.t -> - (S.context -> 'query -> 'input -> 'output tzresult Lwt.t) -> + (S.subcontext -> 'query -> 'input -> 'output tzresult Lwt.t) -> unit (** Register an endpoint with a single parameter in the path. *) @@ -54,18 +56,9 @@ module Make_directory (S : PARAM) : sig 'input, 'output ) Service.t -> - (S.context -> 'param1 -> 'query -> 'input -> 'output tzresult Lwt.t) -> + (S.subcontext -> 'param1 -> 'query -> 'input -> 'output tzresult Lwt.t) -> unit (** Build directory with registered endpoints with respect to Node_context. *) - val build_directory : Node_context.rw -> unit Tezos_rpc.Directory.t -end - -(** This module is a helper to extract a block hash - from block reference and Node_context *) -module Block_directory_helpers : sig - val block_of_prefix : - Node_context.rw -> - [< `Cemented | `Finalized | `Hash of Block_hash.t | `Head | `Level of int32] -> - Block_hash.t tzresult Lwt.t + val build_directory : S.context -> unit Tezos_rpc.Directory.t end diff --git a/src/proto_017_PtNairob/lib_sc_rollup_layer2/sc_rollup_services.ml b/src/proto_017_PtNairob/lib_sc_rollup_layer2/sc_rollup_services.ml index 303c65429a402b614ae5d7919755f9c11f1174bc..a6da8d1c06b43ad25be75fda95a3bfafe1ab104c 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_layer2/sc_rollup_services.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_layer2/sc_rollup_services.ml @@ -24,8 +24,7 @@ (* *) (*****************************************************************************) -open Protocol -open Alpha_context +open Protocol.Alpha_context (* We distinguish RPC endpoints served by the rollup node into `global` and `local`. The difference between the two lies in whether the responses @@ -423,6 +422,71 @@ module Arg = struct () end +module Query = struct + let outbox_proof_query = + let open Tezos_rpc.Query in + let open Sc_rollup in + let invalid_message e = + raise + (Invalid + (Format.asprintf + "Invalid message (%a)" + Environment.Error_monad.pp_trace + e)) + in + query (fun outbox_level message_index serialized_outbox_message -> + let req name f = function + | None -> + raise + (Invalid (Format.sprintf "Query parameter %s is required" name)) + | Some arg -> f arg + in + let outbox_level = + req "outbox_level" Raw_level.of_int32_exn outbox_level + in + let message_index = req "message_index" Z.of_int64 message_index in + let message = + req + "serialized_outbox_message" + (fun s -> Outbox.Message.(unsafe_of_string s |> deserialize)) + serialized_outbox_message + in + match message with + | Error e -> invalid_message e + | Ok message -> {outbox_level; message_index; message}) + |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> + Some (Raw_level.to_int32 o.outbox_level)) + |+ opt_field "message_index" Tezos_rpc.Arg.int64 (fun o -> + Some (Z.to_int64 o.message_index)) + |+ opt_field "serialized_outbox_message" Tezos_rpc.Arg.string (fun o -> + match Outbox.Message.serialize o.message with + | Ok message -> Some (Outbox.Message.unsafe_to_string message) + | Error e -> invalid_message e) + |> seal + + type key_query = {key : string} + + let key_query : key_query Tezos_rpc.Query.t = + let open Tezos_rpc.Query in + query (fun key -> {key}) + |+ field "key" Tezos_rpc.Arg.string "" (fun t -> t.key) + |> seal + + let outbox_level_query = + let open Tezos_rpc.Query in + query (fun outbox_level -> + let req name f = function + | None -> + raise + (Invalid (Format.sprintf "Query parameter %s is required" name)) + | Some arg -> f arg + in + req "outbox_level" Raw_level.of_int32_exn outbox_level) + |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> + Some (Raw_level.to_int32 o)) + |> seal +end + module type PREFIX = sig type prefix @@ -496,52 +560,10 @@ module Global = struct let prefix = open_root / "helpers" end) - let outbox_proof_query = - let open Tezos_rpc.Query in - let open Sc_rollup in - let invalid_message e = - raise - (Invalid - (Format.asprintf - "Invalid message (%a)" - Environment.Error_monad.pp_trace - e)) - in - query (fun outbox_level message_index serialized_outbox_message -> - let req name f = function - | None -> - raise - (Invalid - (Format.sprintf "Query parameter %s is required" name)) - | Some arg -> f arg - in - let outbox_level = - req "outbox_level" Raw_level.of_int32_exn outbox_level - in - let message_index = req "message_index" Z.of_int64 message_index in - let message = - req - "serialized_outbox_message" - (fun s -> Outbox.Message.(unsafe_of_string s |> deserialize)) - serialized_outbox_message - in - match message with - | Error e -> invalid_message e - | Ok message -> {outbox_level; message_index; message}) - |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> - Some (Raw_level.to_int32 o.outbox_level)) - |+ opt_field "message_index" Tezos_rpc.Arg.int64 (fun o -> - Some (Z.to_int64 o.message_index)) - |+ opt_field "serialized_outbox_message" Tezos_rpc.Arg.string (fun o -> - match Outbox.Message.serialize o.message with - | Ok message -> Some (Outbox.Message.unsafe_to_string message) - | Error e -> invalid_message e) - |> seal - let outbox_proof = Tezos_rpc.Service.get_service ~description:"Generate serialized output proof for some outbox message" - ~query:outbox_proof_query + ~query:Query.outbox_proof_query ~output: Data_encoding.( obj2 @@ -622,33 +644,22 @@ module Global = struct ~output:(Data_encoding.option Raw_level.encoding) (path / "state_current_level") - type state_value_query = {key : string} - - let state_value_query : state_value_query Tezos_rpc.Query.t = - let open Tezos_rpc.Query in - query (fun key -> {key}) - |+ field "key" Tezos_rpc.Arg.string "" (fun t -> t.key) - |> seal - let state_value = Tezos_rpc.Service.get_service ~description:"Retrieve value from key is PVM state of specified block" - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.bytes (path / "state") - let durable_state_value (pvm_kind : Protocol.Alpha_context.Sc_rollup.Kind.t) - = + let durable_state_value (pvm_kind : Sc_rollup.Kind.t) = Tezos_rpc.Service.get_service ~description: "Retrieve value by key from PVM durable storage. PVM state is taken \ with respect to the specified block level. Value returned in hex \ format." - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.(option bytes) - (path / "durable" - / Protocol.Alpha_context.Sc_rollup.Kind.to_string pvm_kind - / "value") + (path / "durable" / Sc_rollup.Kind.to_string pvm_kind / "value") let durable_state_length (pvm_kind : Protocol.Alpha_context.Sc_rollup.Kind.t) = @@ -657,23 +668,18 @@ module Global = struct "Retrieve number of bytes in raw representation of value by key from \ PVM durable storage. PVM state is taken with respect to the \ specified block level." - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.(option int64) - (path / "durable" - / Protocol.Alpha_context.Sc_rollup.Kind.to_string pvm_kind - / "length") + (path / "durable" / Sc_rollup.Kind.to_string pvm_kind / "length") - let durable_state_subkeys - (pvm_kind : Protocol.Alpha_context.Sc_rollup.Kind.t) = + let durable_state_subkeys (pvm_kind : Sc_rollup.Kind.t) = Tezos_rpc.Service.get_service ~description: "Retrieve subkeys of the specified key from PVM durable storage. PVM \ state is taken with respect to the specified block level." - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.(list string) - (path / "durable" - / Protocol.Alpha_context.Sc_rollup.Kind.to_string pvm_kind - / "subkeys") + (path / "durable" / Sc_rollup.Kind.to_string pvm_kind / "subkeys") let status = Tezos_rpc.Service.get_service @@ -682,25 +688,10 @@ module Global = struct ~output:Data_encoding.string (path / "status") - let outbox_level_query = - let open Tezos_rpc.Query in - query (fun outbox_level -> - let req name f = function - | None -> - raise - (Invalid - (Format.sprintf "Query parameter %s is required" name)) - | Some arg -> f arg - in - req "outbox_level" Raw_level.of_int32_exn outbox_level) - |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> - Some (Raw_level.to_int32 o)) - |> seal - let outbox = Tezos_rpc.Service.get_service ~description:"Outbox at block for a given outbox level" - ~query:outbox_level_query + ~query:Query.outbox_level_query ~output:Data_encoding.(list Sc_rollup.output_encoding) (path / "outbox") diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml index 1625e5be259afc84949694d5d4fb9a9403c879d2..a78d121505ed60ad6265ff4a339e8a0428173aeb 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_server.ml @@ -56,7 +56,9 @@ let get_dal_processed_slots node_ctxt block = module Global_directory = Make_directory (struct include Sc_rollup_services.Global - type context = Node_context.ro + type context = Node_context.rw + + type subcontext = Node_context.ro let context_of_prefix node_ctxt () = return (Node_context.readonly node_ctxt) end) @@ -68,13 +70,19 @@ module Proof_helpers_directory = Make_directory (struct commit on disk to generate the proofs. *) type context = Node_context.rw + (* The context needs to be accessed with write permissions because we need to + commit on disk to generate the proofs. *) + type subcontext = Node_context.rw + let context_of_prefix node_ctxt () = return node_ctxt end) module Local_directory = Make_directory (struct include Sc_rollup_services.Local - type context = Node_context.ro + type context = Node_context.rw + + type subcontext = Node_context.ro let context_of_prefix node_ctxt () = return (Node_context.readonly node_ctxt) end) @@ -82,7 +90,9 @@ end) module Block_directory = Make_directory (struct include Sc_rollup_services.Global.Block - type context = Node_context.ro * Block_hash.t + type context = Node_context.rw + + type subcontext = Node_context.ro * Block_hash.t let context_of_prefix node_ctxt (((), block) : prefix) = let open Lwt_result_syntax in @@ -93,7 +103,9 @@ end) module Outbox_directory = Make_directory (struct include Sc_rollup_services.Global.Block.Outbox - type context = Node_context.ro * Block_hash.t * Alpha_context.Raw_level.t + type context = Node_context.rw + + type subcontext = Node_context.ro * Block_hash.t * Alpha_context.Raw_level.t let context_of_prefix node_ctxt (((), block), level) = let open Lwt_result_syntax in diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/block_directory_helpers.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/block_directory_helpers.ml new file mode 100644 index 0000000000000000000000000000000000000000..a4ccb383a729f3407e0c9fc943fec33844276c84 --- /dev/null +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/block_directory_helpers.ml @@ -0,0 +1,56 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Protocol + +(* Conveniences to construct RPC directory + against a subcontext of the Node_context *) + +let get_head store = + let open Lwt_result_syntax in + let* head = Node_context.last_processed_head_opt store in + match head with + | None -> failwith "No head" + | Some {header = {block_hash; _}; _} -> return block_hash + +let get_finalized node_ctxt = + let open Lwt_result_syntax in + let* level = Node_context.get_finalized_level node_ctxt in + Node_context.hash_of_level node_ctxt level + +let get_last_cemented (node_ctxt : _ Node_context.t) = + protect @@ fun () -> + let lcc = Reference.get node_ctxt.lcc in + Node_context.hash_of_level + node_ctxt + (Alpha_context.Raw_level.to_int32 lcc.level) + +let block_of_prefix node_ctxt block = + match block with + | `Head -> get_head node_ctxt + | `Hash b -> return b + | `Level l -> Node_context.hash_of_level node_ctxt l + | `Finalized -> get_finalized node_ctxt + | `Cemented -> get_last_cemented node_ctxt diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/block_directory_helpers.mli b/src/proto_017_PtNairob/lib_sc_rollup_node/block_directory_helpers.mli new file mode 100644 index 0000000000000000000000000000000000000000..3994a59f6f841c122d1025544476d58141a88167 --- /dev/null +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/block_directory_helpers.mli @@ -0,0 +1,32 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* Copyright (c) 2022-2023 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +(** This module is a helper to extract a block hash + from block reference and Node_context *) +val block_of_prefix : + _ Node_context.t -> + [< `Cemented | `Finalized | `Hash of Block_hash.t | `Head | `Level of int32] -> + Block_hash.t tzresult Lwt.t diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/wasm_2_0_0_rpc.ml b/src/proto_017_PtNairob/lib_sc_rollup_node/wasm_2_0_0_rpc.ml index c5a2210f19fa66b0ce5c78a72b71f880d5582726..dd4c703fa4c57891080e2547ac40a3fd7f53ad83 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/wasm_2_0_0_rpc.ml +++ b/src/proto_017_PtNairob/lib_sc_rollup_node/wasm_2_0_0_rpc.ml @@ -32,7 +32,9 @@ struct module Block_directory = Make_directory (struct include Sc_rollup_services.Global.Block - type context = Node_context.ro * Block_hash.t + type context = Node_context.rw + + type subcontext = Node_context.ro * Block_hash.t let context_of_prefix node_ctxt (((), block) : prefix) = let open Lwt_result_syntax in diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory_helpers.ml b/src/proto_alpha/lib_sc_rollup_layer2/RPC_directory_helpers.ml similarity index 71% rename from src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory_helpers.ml rename to src/proto_alpha/lib_sc_rollup_layer2/RPC_directory_helpers.ml index b729005cdb98f3e0272e8f315c37d2d6dddaa694..6b0c8ec4337c8c6dae2ac52b02898395e0f3fa69 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory_helpers.ml +++ b/src/proto_alpha/lib_sc_rollup_layer2/RPC_directory_helpers.ml @@ -23,8 +23,6 @@ (* *) (*****************************************************************************) -open Protocol - (* Conveniences to construct RPC directory against a subcontext of the Node_context *) @@ -33,13 +31,15 @@ module type PARAM = sig type context - val context_of_prefix : Node_context.rw -> prefix -> context tzresult Lwt.t + type subcontext + + val context_of_prefix : context -> prefix -> subcontext tzresult Lwt.t end module Make_directory (S : PARAM) = struct open S - let directory : context tzresult Tezos_rpc.Directory.t ref = + let directory : subcontext tzresult Tezos_rpc.Directory.t ref = ref Tezos_rpc.Directory.empty let register service f = @@ -64,32 +64,3 @@ module Make_directory (S : PARAM) = struct context_of_prefix node_ctxt prefix) |> Tezos_rpc.Directory.prefix prefix end - -module Block_directory_helpers = struct - let get_head store = - let open Lwt_result_syntax in - let* head = Node_context.last_processed_head_opt store in - match head with - | None -> failwith "No head" - | Some {header = {block_hash; _}; _} -> return block_hash - - let get_finalized node_ctxt = - let open Lwt_result_syntax in - let* level = Node_context.get_finalized_level node_ctxt in - Node_context.hash_of_level node_ctxt level - - let get_last_cemented (node_ctxt : _ Node_context.t) = - protect @@ fun () -> - let lcc = Reference.get node_ctxt.lcc in - Node_context.hash_of_level - node_ctxt - (Alpha_context.Raw_level.to_int32 lcc.level) - - let block_of_prefix node_ctxt block = - match block with - | `Head -> get_head node_ctxt - | `Hash b -> return b - | `Level l -> Node_context.hash_of_level node_ctxt l - | `Finalized -> get_finalized node_ctxt - | `Cemented -> get_last_cemented node_ctxt -end diff --git a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory_helpers.mli b/src/proto_alpha/lib_sc_rollup_layer2/RPC_directory_helpers.mli similarity index 82% rename from src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory_helpers.mli rename to src/proto_alpha/lib_sc_rollup_layer2/RPC_directory_helpers.mli index 72f9952c4bbe88ef66dc81ccda5e9f071fb68fc1..c98568773bf7228aa1ef842cc8fae10cdc40ae79 100644 --- a/src/proto_017_PtNairob/lib_sc_rollup_node/RPC_directory_helpers.mli +++ b/src/proto_alpha/lib_sc_rollup_layer2/RPC_directory_helpers.mli @@ -33,7 +33,9 @@ module type PARAM = sig type context - val context_of_prefix : Node_context.rw -> prefix -> context tzresult Lwt.t + type subcontext + + val context_of_prefix : context -> prefix -> subcontext tzresult Lwt.t end (** This module is a helper to register your endpoints and @@ -42,7 +44,7 @@ module Make_directory (S : PARAM) : sig (** Register an endpoint with no parameters in the path. *) val register0 : ([< Resto.meth], 'prefix, 'prefix, 'query, 'input, 'output) Service.t -> - (S.context -> 'query -> 'input -> 'output tzresult Lwt.t) -> + (S.subcontext -> 'query -> 'input -> 'output tzresult Lwt.t) -> unit (** Register an endpoint with a single parameter in the path. *) @@ -54,18 +56,9 @@ module Make_directory (S : PARAM) : sig 'input, 'output ) Service.t -> - (S.context -> 'param1 -> 'query -> 'input -> 'output tzresult Lwt.t) -> + (S.subcontext -> 'param1 -> 'query -> 'input -> 'output tzresult Lwt.t) -> unit (** Build directory with registered endpoints with respect to Node_context. *) - val build_directory : Node_context.rw -> unit Tezos_rpc.Directory.t -end - -(** This module is a helper to extract a block hash - from block reference and Node_context *) -module Block_directory_helpers : sig - val block_of_prefix : - Node_context.rw -> - [< `Cemented | `Finalized | `Hash of Block_hash.t | `Head | `Level of int32] -> - Block_hash.t tzresult Lwt.t + val build_directory : S.context -> unit Tezos_rpc.Directory.t end diff --git a/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_services.ml b/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_services.ml index 303c65429a402b614ae5d7919755f9c11f1174bc..a6da8d1c06b43ad25be75fda95a3bfafe1ab104c 100644 --- a/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_services.ml +++ b/src/proto_alpha/lib_sc_rollup_layer2/sc_rollup_services.ml @@ -24,8 +24,7 @@ (* *) (*****************************************************************************) -open Protocol -open Alpha_context +open Protocol.Alpha_context (* We distinguish RPC endpoints served by the rollup node into `global` and `local`. The difference between the two lies in whether the responses @@ -423,6 +422,71 @@ module Arg = struct () end +module Query = struct + let outbox_proof_query = + let open Tezos_rpc.Query in + let open Sc_rollup in + let invalid_message e = + raise + (Invalid + (Format.asprintf + "Invalid message (%a)" + Environment.Error_monad.pp_trace + e)) + in + query (fun outbox_level message_index serialized_outbox_message -> + let req name f = function + | None -> + raise + (Invalid (Format.sprintf "Query parameter %s is required" name)) + | Some arg -> f arg + in + let outbox_level = + req "outbox_level" Raw_level.of_int32_exn outbox_level + in + let message_index = req "message_index" Z.of_int64 message_index in + let message = + req + "serialized_outbox_message" + (fun s -> Outbox.Message.(unsafe_of_string s |> deserialize)) + serialized_outbox_message + in + match message with + | Error e -> invalid_message e + | Ok message -> {outbox_level; message_index; message}) + |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> + Some (Raw_level.to_int32 o.outbox_level)) + |+ opt_field "message_index" Tezos_rpc.Arg.int64 (fun o -> + Some (Z.to_int64 o.message_index)) + |+ opt_field "serialized_outbox_message" Tezos_rpc.Arg.string (fun o -> + match Outbox.Message.serialize o.message with + | Ok message -> Some (Outbox.Message.unsafe_to_string message) + | Error e -> invalid_message e) + |> seal + + type key_query = {key : string} + + let key_query : key_query Tezos_rpc.Query.t = + let open Tezos_rpc.Query in + query (fun key -> {key}) + |+ field "key" Tezos_rpc.Arg.string "" (fun t -> t.key) + |> seal + + let outbox_level_query = + let open Tezos_rpc.Query in + query (fun outbox_level -> + let req name f = function + | None -> + raise + (Invalid (Format.sprintf "Query parameter %s is required" name)) + | Some arg -> f arg + in + req "outbox_level" Raw_level.of_int32_exn outbox_level) + |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> + Some (Raw_level.to_int32 o)) + |> seal +end + module type PREFIX = sig type prefix @@ -496,52 +560,10 @@ module Global = struct let prefix = open_root / "helpers" end) - let outbox_proof_query = - let open Tezos_rpc.Query in - let open Sc_rollup in - let invalid_message e = - raise - (Invalid - (Format.asprintf - "Invalid message (%a)" - Environment.Error_monad.pp_trace - e)) - in - query (fun outbox_level message_index serialized_outbox_message -> - let req name f = function - | None -> - raise - (Invalid - (Format.sprintf "Query parameter %s is required" name)) - | Some arg -> f arg - in - let outbox_level = - req "outbox_level" Raw_level.of_int32_exn outbox_level - in - let message_index = req "message_index" Z.of_int64 message_index in - let message = - req - "serialized_outbox_message" - (fun s -> Outbox.Message.(unsafe_of_string s |> deserialize)) - serialized_outbox_message - in - match message with - | Error e -> invalid_message e - | Ok message -> {outbox_level; message_index; message}) - |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> - Some (Raw_level.to_int32 o.outbox_level)) - |+ opt_field "message_index" Tezos_rpc.Arg.int64 (fun o -> - Some (Z.to_int64 o.message_index)) - |+ opt_field "serialized_outbox_message" Tezos_rpc.Arg.string (fun o -> - match Outbox.Message.serialize o.message with - | Ok message -> Some (Outbox.Message.unsafe_to_string message) - | Error e -> invalid_message e) - |> seal - let outbox_proof = Tezos_rpc.Service.get_service ~description:"Generate serialized output proof for some outbox message" - ~query:outbox_proof_query + ~query:Query.outbox_proof_query ~output: Data_encoding.( obj2 @@ -622,33 +644,22 @@ module Global = struct ~output:(Data_encoding.option Raw_level.encoding) (path / "state_current_level") - type state_value_query = {key : string} - - let state_value_query : state_value_query Tezos_rpc.Query.t = - let open Tezos_rpc.Query in - query (fun key -> {key}) - |+ field "key" Tezos_rpc.Arg.string "" (fun t -> t.key) - |> seal - let state_value = Tezos_rpc.Service.get_service ~description:"Retrieve value from key is PVM state of specified block" - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.bytes (path / "state") - let durable_state_value (pvm_kind : Protocol.Alpha_context.Sc_rollup.Kind.t) - = + let durable_state_value (pvm_kind : Sc_rollup.Kind.t) = Tezos_rpc.Service.get_service ~description: "Retrieve value by key from PVM durable storage. PVM state is taken \ with respect to the specified block level. Value returned in hex \ format." - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.(option bytes) - (path / "durable" - / Protocol.Alpha_context.Sc_rollup.Kind.to_string pvm_kind - / "value") + (path / "durable" / Sc_rollup.Kind.to_string pvm_kind / "value") let durable_state_length (pvm_kind : Protocol.Alpha_context.Sc_rollup.Kind.t) = @@ -657,23 +668,18 @@ module Global = struct "Retrieve number of bytes in raw representation of value by key from \ PVM durable storage. PVM state is taken with respect to the \ specified block level." - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.(option int64) - (path / "durable" - / Protocol.Alpha_context.Sc_rollup.Kind.to_string pvm_kind - / "length") + (path / "durable" / Sc_rollup.Kind.to_string pvm_kind / "length") - let durable_state_subkeys - (pvm_kind : Protocol.Alpha_context.Sc_rollup.Kind.t) = + let durable_state_subkeys (pvm_kind : Sc_rollup.Kind.t) = Tezos_rpc.Service.get_service ~description: "Retrieve subkeys of the specified key from PVM durable storage. PVM \ state is taken with respect to the specified block level." - ~query:state_value_query + ~query:Query.key_query ~output:Data_encoding.(list string) - (path / "durable" - / Protocol.Alpha_context.Sc_rollup.Kind.to_string pvm_kind - / "subkeys") + (path / "durable" / Sc_rollup.Kind.to_string pvm_kind / "subkeys") let status = Tezos_rpc.Service.get_service @@ -682,25 +688,10 @@ module Global = struct ~output:Data_encoding.string (path / "status") - let outbox_level_query = - let open Tezos_rpc.Query in - query (fun outbox_level -> - let req name f = function - | None -> - raise - (Invalid - (Format.sprintf "Query parameter %s is required" name)) - | Some arg -> f arg - in - req "outbox_level" Raw_level.of_int32_exn outbox_level) - |+ opt_field "outbox_level" Tezos_rpc.Arg.int32 (fun o -> - Some (Raw_level.to_int32 o)) - |> seal - let outbox = Tezos_rpc.Service.get_service ~description:"Outbox at block for a given outbox level" - ~query:outbox_level_query + ~query:Query.outbox_level_query ~output:Data_encoding.(list Sc_rollup.output_encoding) (path / "outbox") diff --git a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml index 1625e5be259afc84949694d5d4fb9a9403c879d2..a78d121505ed60ad6265ff4a339e8a0428173aeb 100644 --- a/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_alpha/lib_sc_rollup_node/RPC_server.ml @@ -56,7 +56,9 @@ let get_dal_processed_slots node_ctxt block = module Global_directory = Make_directory (struct include Sc_rollup_services.Global - type context = Node_context.ro + type context = Node_context.rw + + type subcontext = Node_context.ro let context_of_prefix node_ctxt () = return (Node_context.readonly node_ctxt) end) @@ -68,13 +70,19 @@ module Proof_helpers_directory = Make_directory (struct commit on disk to generate the proofs. *) type context = Node_context.rw + (* The context needs to be accessed with write permissions because we need to + commit on disk to generate the proofs. *) + type subcontext = Node_context.rw + let context_of_prefix node_ctxt () = return node_ctxt end) module Local_directory = Make_directory (struct include Sc_rollup_services.Local - type context = Node_context.ro + type context = Node_context.rw + + type subcontext = Node_context.ro let context_of_prefix node_ctxt () = return (Node_context.readonly node_ctxt) end) @@ -82,7 +90,9 @@ end) module Block_directory = Make_directory (struct include Sc_rollup_services.Global.Block - type context = Node_context.ro * Block_hash.t + type context = Node_context.rw + + type subcontext = Node_context.ro * Block_hash.t let context_of_prefix node_ctxt (((), block) : prefix) = let open Lwt_result_syntax in @@ -93,7 +103,9 @@ end) module Outbox_directory = Make_directory (struct include Sc_rollup_services.Global.Block.Outbox - type context = Node_context.ro * Block_hash.t * Alpha_context.Raw_level.t + type context = Node_context.rw + + type subcontext = Node_context.ro * Block_hash.t * Alpha_context.Raw_level.t let context_of_prefix node_ctxt (((), block), level) = let open Lwt_result_syntax in diff --git a/src/proto_alpha/lib_sc_rollup_node/block_directory_helpers.ml b/src/proto_alpha/lib_sc_rollup_node/block_directory_helpers.ml new file mode 100644 index 0000000000000000000000000000000000000000..a4ccb383a729f3407e0c9fc943fec33844276c84 --- /dev/null +++ b/src/proto_alpha/lib_sc_rollup_node/block_directory_helpers.ml @@ -0,0 +1,56 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +open Protocol + +(* Conveniences to construct RPC directory + against a subcontext of the Node_context *) + +let get_head store = + let open Lwt_result_syntax in + let* head = Node_context.last_processed_head_opt store in + match head with + | None -> failwith "No head" + | Some {header = {block_hash; _}; _} -> return block_hash + +let get_finalized node_ctxt = + let open Lwt_result_syntax in + let* level = Node_context.get_finalized_level node_ctxt in + Node_context.hash_of_level node_ctxt level + +let get_last_cemented (node_ctxt : _ Node_context.t) = + protect @@ fun () -> + let lcc = Reference.get node_ctxt.lcc in + Node_context.hash_of_level + node_ctxt + (Alpha_context.Raw_level.to_int32 lcc.level) + +let block_of_prefix node_ctxt block = + match block with + | `Head -> get_head node_ctxt + | `Hash b -> return b + | `Level l -> Node_context.hash_of_level node_ctxt l + | `Finalized -> get_finalized node_ctxt + | `Cemented -> get_last_cemented node_ctxt diff --git a/src/proto_alpha/lib_sc_rollup_node/block_directory_helpers.mli b/src/proto_alpha/lib_sc_rollup_node/block_directory_helpers.mli new file mode 100644 index 0000000000000000000000000000000000000000..3994a59f6f841c122d1025544476d58141a88167 --- /dev/null +++ b/src/proto_alpha/lib_sc_rollup_node/block_directory_helpers.mli @@ -0,0 +1,32 @@ +(*****************************************************************************) +(* *) +(* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) +(* Copyright (c) 2022-2023 TriliTech *) +(* *) +(* 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. *) +(* *) +(*****************************************************************************) + +(** This module is a helper to extract a block hash + from block reference and Node_context *) +val block_of_prefix : + _ Node_context.t -> + [< `Cemented | `Finalized | `Hash of Block_hash.t | `Head | `Level of int32] -> + Block_hash.t tzresult Lwt.t diff --git a/src/proto_alpha/lib_sc_rollup_node/wasm_2_0_0_rpc.ml b/src/proto_alpha/lib_sc_rollup_node/wasm_2_0_0_rpc.ml index c5a2210f19fa66b0ce5c78a72b71f880d5582726..dd4c703fa4c57891080e2547ac40a3fd7f53ad83 100644 --- a/src/proto_alpha/lib_sc_rollup_node/wasm_2_0_0_rpc.ml +++ b/src/proto_alpha/lib_sc_rollup_node/wasm_2_0_0_rpc.ml @@ -32,7 +32,9 @@ struct module Block_directory = Make_directory (struct include Sc_rollup_services.Global.Block - type context = Node_context.ro * Block_hash.t + type context = Node_context.rw + + type subcontext = Node_context.ro * Block_hash.t let context_of_prefix node_ctxt (((), block) : prefix) = let open Lwt_result_syntax in