diff --git a/src/proto_018_Proxford/lib_sc_rollup/context_helpers.ml b/src/proto_018_Proxford/lib_sc_rollup/context_helpers.ml index 2ab44f26d043bd2b8a6555207e4353249d3af583..febdce5843101cc988978fd2dd83574780345c1e 100644 --- a/src/proto_018_Proxford/lib_sc_rollup/context_helpers.ml +++ b/src/proto_018_Proxford/lib_sc_rollup/context_helpers.ml @@ -22,6 +22,32 @@ (* DEALINGS IN THE SOFTWARE. *) (* *) (*****************************************************************************) +open Protocol.Alpha_context + +module type P = sig + module Tree : + Tezos_context_sigs.Context.TREE + with type key = string list + and type value = bytes + + type tree = Tree.tree + + val hash_tree : tree -> Sc_rollup.State_hash.t + + type proof + + val proof_encoding : proof Data_encoding.t + + val proof_before : proof -> Sc_rollup.State_hash.t + + val proof_after : proof -> Sc_rollup.State_hash.t + + val verify_proof : + proof -> (tree -> (tree * 'a) Lwt.t) -> (tree * 'a) option Lwt.t + + val produce_proof : + Tree.t -> tree -> (tree -> (tree * 'a) Lwt.t) -> (proof * 'a) option Lwt.t +end module In_memory = struct open Tezos_context_memory diff --git a/src/proto_018_Proxford/lib_sc_rollup/context_helpers.mli b/src/proto_018_Proxford/lib_sc_rollup/context_helpers.mli index 35ba7e64cf5a87a71b700a24c56b3ab441b1be3d..a7611201c86dd29f0a56a2f0dd4793657e718e5d 100644 --- a/src/proto_018_Proxford/lib_sc_rollup/context_helpers.mli +++ b/src/proto_018_Proxford/lib_sc_rollup/context_helpers.mli @@ -22,6 +22,32 @@ (* DEALINGS IN THE SOFTWARE. *) (* *) (*****************************************************************************) +open Protocol.Alpha_context + +module type P = sig + module Tree : + Tezos_context_sigs.Context.TREE + with type key = string list + and type value = bytes + + type tree = Tree.tree + + val hash_tree : tree -> Sc_rollup.State_hash.t + + type proof + + val proof_encoding : proof Data_encoding.t + + val proof_before : proof -> Sc_rollup.State_hash.t + + val proof_after : proof -> Sc_rollup.State_hash.t + + val verify_proof : + proof -> (tree -> (tree * 'a) Lwt.t) -> (tree * 'a) option Lwt.t + + val produce_proof : + Tree.t -> tree -> (tree -> (tree * 'a) Lwt.t) -> (proof * 'a) option Lwt.t +end (** [In_memory] is a context that can be used to instantiate an Arith or Wasm PVM. It's signature is @@ -29,8 +55,10 @@ {!Protocol.Alpha_context.Sc_rollup.Wasm_2_0_0PVM.P} *) module In_memory : sig include - Protocol.Alpha_context.Sc_rollup.ArithPVM.P - with type proof = + P + with type Tree.tree = Tezos_context_memory.Context_binary.tree + and type Tree.t = Tezos_context_memory.Context_binary.t + and type proof = Tezos_context_memory.Context.Proof.tree Tezos_context_memory.Context.Proof.t diff --git a/src/proto_018_Proxford/lib_sc_rollup/pvm_in_memory.ml b/src/proto_018_Proxford/lib_sc_rollup/pvm_in_memory.ml index eedebb959617b85ce33ac7b5051af2d9b4626e11..e626aa543a963adc4c7595e091f9eb05b1d80f00 100644 --- a/src/proto_018_Proxford/lib_sc_rollup/pvm_in_memory.ml +++ b/src/proto_018_Proxford/lib_sc_rollup/pvm_in_memory.ml @@ -27,11 +27,11 @@ open Protocol.Alpha_context module type S = Sc_rollup.PVM.S - with type context = Context_helpers.In_memory.Tree.t - and type state = Context_helpers.In_memory.tree + with type context = Tezos_context_memory.Context_binary.t + and type state = Tezos_context_memory.Context_binary.tree and type proof = - Tezos_context_memory.Context.Proof.tree - Tezos_context_memory.Context.Proof.t + Tezos_context_memory.Context_binary.Proof.tree + Tezos_context_memory.Context_binary.Proof.t module Arith : S = Sc_rollup.ArithPVM.Make (Context_helpers.In_memory) diff --git a/src/proto_018_Proxford/lib_sc_rollup/pvm_in_memory.mli b/src/proto_018_Proxford/lib_sc_rollup/pvm_in_memory.mli index 3871cb4c4a9fcec3a32c2a768534a06c8298296e..c0ae57cf3e9fb862cd6bcd6e5029176cf2636406 100644 --- a/src/proto_018_Proxford/lib_sc_rollup/pvm_in_memory.mli +++ b/src/proto_018_Proxford/lib_sc_rollup/pvm_in_memory.mli @@ -27,11 +27,11 @@ open Protocol.Alpha_context module type S = Sc_rollup.PVM.S - with type context = Context_helpers.In_memory.Tree.t - and type state = Context_helpers.In_memory.tree + with type context = Tezos_context_memory.Context_binary.t + and type state = Tezos_context_memory.Context_binary.tree and type proof = - Tezos_context_memory.Context.Proof.tree - Tezos_context_memory.Context.Proof.t + Tezos_context_memory.Context_binary.Proof.tree + Tezos_context_memory.Context_binary.Proof.t (** [Arith]: Arith PVM with an in memory context {!Tezos_context_memory}. *) module Arith : S diff --git a/src/proto_018_Proxford/lib_sc_rollup_layer2/l1_operation.ml b/src/proto_018_Proxford/lib_sc_rollup_layer2/l1_operation.ml deleted file mode 100644 index 79594a70bcc4258cb8a2c60a3bff35f09f890e42..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_layer2/l1_operation.ml +++ /dev/null @@ -1,172 +0,0 @@ -(*****************************************************************************) -(* *) -(* 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.Alpha_context - -type t = - | Add_messages of {messages : string list} - | Cement of {rollup : Sc_rollup.t} - | Publish of {rollup : Sc_rollup.t; commitment : Sc_rollup.Commitment.t} - | Refute of { - rollup : Sc_rollup.t; - opponent : Sc_rollup.Staker.t; - refutation : Sc_rollup.Game.refutation; - } - | Timeout of {rollup : Sc_rollup.t; stakers : Sc_rollup.Game.Index.t} - -let encoding : t Data_encoding.t = - let open Data_encoding in - let case tag kind encoding proj inj = - case - ~title:kind - (Tag tag) - (merge_objs (obj1 (req "kind" (constant kind))) encoding) - (fun o -> Option.map (fun p -> ((), p)) (proj o)) - (fun ((), p) -> inj p) - in - def "sc_rollup_node_l1_operation" - @@ union - [ - case - 0 - "add_messages" - (obj1 (req "message" (list (string' Hex)))) - (function Add_messages {messages} -> Some messages | _ -> None) - (fun messages -> Add_messages {messages}); - case - 1 - "cement" - (obj1 (req "rollup" Sc_rollup.Address.encoding)) - (function Cement {rollup} -> Some rollup | _ -> None) - (fun rollup -> Cement {rollup}); - case - 2 - "publish" - (obj2 - (req "rollup" Sc_rollup.Address.encoding) - (req "commitment" Sc_rollup.Commitment.encoding)) - (function - | Publish {rollup; commitment} -> Some (rollup, commitment) - | _ -> None) - (fun (rollup, commitment) -> Publish {rollup; commitment}); - case - 3 - "refute" - (obj3 - (req "rollup" Sc_rollup.Address.encoding) - (req "opponent" Sc_rollup.Staker.encoding) - (req "refutation" Sc_rollup.Game.refutation_encoding)) - (function - | Refute {rollup; opponent; refutation} -> - Some (rollup, opponent, refutation) - | _ -> None) - (fun (rollup, opponent, refutation) -> - Refute {rollup; opponent; refutation}); - case - 4 - "timeout" - (obj2 - (req "rollup" Sc_rollup.Address.encoding) - (req "stakers" Sc_rollup.Game.Index.encoding)) - (function - | Timeout {rollup; stakers} -> Some (rollup, stakers) | _ -> None) - (fun (rollup, stakers) -> Timeout {rollup; stakers}); - ] - -let pp ppf = function - | Add_messages {messages} -> - Format.fprintf - ppf - "publishing %d messages to smart rollups' inbox" - (List.length messages) - | Cement {rollup = _} -> Format.fprintf ppf "cementing commitment" - | Publish {rollup = _; commitment = Sc_rollup.Commitment.{inbox_level; _}} -> - Format.fprintf - ppf - "publish commitment for level %a" - Raw_level.pp - inbox_level - | Refute {rollup = _; opponent; refutation = Start _} -> - Format.fprintf - ppf - "start refutation game against %a" - Signature.Public_key_hash.pp - opponent - | Refute - { - rollup = _; - opponent; - refutation = Move {step = Dissection (first :: _ as d); _}; - } -> - let last = List.last first d in - Format.fprintf - ppf - "dissection between ticks %a and %a (against %a)" - Sc_rollup.Tick.pp - first.tick - Sc_rollup.Tick.pp - last.tick - Signature.Public_key_hash.pp - opponent - | Refute {rollup = _; opponent; refutation = Move {step = Dissection []; _}} - -> - Format.fprintf - ppf - "dissection (against %a)" - Signature.Public_key_hash.pp - opponent - | Refute {rollup = _; opponent; refutation = Move {choice; step = Proof _}} -> - Format.fprintf - ppf - "proof for tick %a (against %a)" - Sc_rollup.Tick.pp - choice - Signature.Public_key_hash.pp - opponent - | Timeout {rollup = _; stakers = _} -> Format.fprintf ppf "timeout" - -let to_manager_operation : t -> packed_manager_operation = function - | Add_messages {messages} -> Manager (Sc_rollup_add_messages {messages}) - | Cement {rollup} -> Manager (Sc_rollup_cement {rollup}) - | Publish {rollup; commitment} -> - Manager (Sc_rollup_publish {rollup; commitment}) - | Refute {rollup; opponent; refutation} -> - Manager (Sc_rollup_refute {rollup; opponent; refutation}) - | Timeout {rollup; stakers} -> Manager (Sc_rollup_timeout {rollup; stakers}) - -let of_manager_operation : type kind. kind manager_operation -> t option = - function - | Sc_rollup_add_messages {messages} -> Some (Add_messages {messages}) - | Sc_rollup_cement {rollup} -> Some (Cement {rollup}) - | Sc_rollup_publish {rollup; commitment} -> - Some (Publish {rollup; commitment}) - | Sc_rollup_refute {rollup; opponent; refutation} -> - Some (Refute {rollup; opponent; refutation}) - | Sc_rollup_timeout {rollup; stakers} -> Some (Timeout {rollup; stakers}) - | _ -> None - -let unique = function - | Add_messages _ | Cement _ -> false - | Publish _ | Refute _ | Timeout _ -> true diff --git a/src/proto_018_Proxford/lib_sc_rollup_layer2/l1_operation.mli b/src/proto_018_Proxford/lib_sc_rollup_layer2/l1_operation.mli deleted file mode 100644 index d743c0bb694b0e3a33b2ea8163b67e80b45461d0..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_layer2/l1_operation.mli +++ /dev/null @@ -1,53 +0,0 @@ -(*****************************************************************************) -(* *) -(* 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.Alpha_context - -(** L1 operations produced (and injected) by the rollup node. *) -type t = - | Add_messages of {messages : string list} - | Cement of {rollup : Sc_rollup.t} - | Publish of {rollup : Sc_rollup.t; commitment : Sc_rollup.Commitment.t} - | Refute of { - rollup : Sc_rollup.t; - opponent : Sc_rollup.Staker.t; - refutation : Sc_rollup.Game.refutation; - } - | Timeout of {rollup : Sc_rollup.t; stakers : Sc_rollup.Game.Index.t} - -(** Encoding for L1 operations (used by injector for on-disk persistence). *) -val encoding : t Data_encoding.t - -(** Manager operation for a given L1 operation. *) -val to_manager_operation : t -> packed_manager_operation - -(** L1 operation corresponding to a manager operation if any. *) -val of_manager_operation : 'a manager_operation -> t option - -(** Pretty printer (human readable) for L1 operations. *) -val pp : Format.formatter -> t -> unit - -(** [false] if the injector will accept duplicate such operations. *) -val unique : t -> bool diff --git a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_block.ml b/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_block.ml deleted file mode 100644 index 4f832b00e6fb3e9518fbf1f47ddc02e27455daa8..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_block.ml +++ /dev/null @@ -1,199 +0,0 @@ -(*****************************************************************************) -(* *) -(* 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 Protocol -open Alpha_context - -type header = { - block_hash : Block_hash.t; - level : Raw_level.t; - predecessor : Block_hash.t; - commitment_hash : Sc_rollup.Commitment.Hash.t option; - previous_commitment_hash : Sc_rollup.Commitment.Hash.t; - context : Sc_rollup_context_hash.t; - inbox_witness : Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t; - inbox_hash : Sc_rollup.Inbox.Hash.t; -} - -type content = { - inbox : Sc_rollup.Inbox.t; - messages : Sc_rollup.Inbox_message.t list; - commitment : Sc_rollup.Commitment.t option; -} - -type ('header, 'content) block = { - header : 'header; - content : 'content; - initial_tick : Sc_rollup.Tick.t; - num_ticks : int64; -} - -type t = (header, unit) block - -type full = (header, content) block - -let commitment_hash_opt_encoding = - let open Data_encoding in - let binary = - conv - (Option.value ~default:Sc_rollup.Commitment.Hash.zero) - (fun h -> if Sc_rollup.Commitment.Hash.(h = zero) then None else Some h) - Sc_rollup.Commitment.Hash.encoding - in - let json = option Sc_rollup.Commitment.Hash.encoding in - splitted ~binary ~json - -let header_encoding = - let open Data_encoding in - conv - (fun { - block_hash; - level; - predecessor; - commitment_hash; - previous_commitment_hash; - context; - inbox_witness; - inbox_hash; - } -> - ( block_hash, - level, - predecessor, - commitment_hash, - previous_commitment_hash, - context, - inbox_witness, - inbox_hash )) - (fun ( block_hash, - level, - predecessor, - commitment_hash, - previous_commitment_hash, - context, - inbox_witness, - inbox_hash ) -> - { - block_hash; - level; - predecessor; - commitment_hash; - previous_commitment_hash; - context; - inbox_witness; - inbox_hash; - }) - @@ obj8 - (req "block_hash" Block_hash.encoding ~description:"Tezos block hash.") - (req - "level" - Raw_level.encoding - ~description: - "Level of the block, corresponds to the level of the tezos block.") - (req - "predecessor" - Block_hash.encoding - ~description:"Predecessor hash of the Tezos block.") - (req - "commitment_hash" - commitment_hash_opt_encoding - ~description: - "Hash of this block's commitment if any was computed for it.") - (req - "previous_commitment_hash" - Sc_rollup.Commitment.Hash.encoding - ~description: - "Previous commitment hash in the chain. If there is a commitment \ - for this block, this field contains the commitment that was \ - previously computed.") - (req - "context" - Sc_rollup_context_hash.encoding - ~description:"Hash of the layer 2 context for this block.") - (req - "inbox_witness" - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.encoding - ~description: - "Witness for the inbox for this block, i.e. the Merkle hash of \ - payloads of messages.") - (req - "inbox_hash" - Sc_rollup.Inbox.Hash.encoding - ~description:"Hash of the inbox for this block.") - -let header_size = - WithExceptions.Option.get ~loc:__LOC__ - @@ Data_encoding.Binary.fixed_length header_encoding - -let content_encoding = - let open Data_encoding in - conv - (fun {inbox; messages; commitment} -> (inbox, messages, commitment)) - (fun (inbox, messages, commitment) -> {inbox; messages; commitment}) - @@ obj3 - (req - "inbox" - Sc_rollup.Inbox.encoding - ~description:"Inbox for this block.") - (req - "messages" - (list (dynamic_size Sc_rollup.Inbox_message.encoding)) - ~description:"Messages added to the inbox in this block.") - (opt - "commitment" - Sc_rollup.Commitment.encoding - ~description:"Commitment, if any is computed for this block.") - -let block_encoding header_encoding content_encoding = - let open Data_encoding in - conv - (fun {header; content; initial_tick; num_ticks} -> - (header, (content, (initial_tick, num_ticks)))) - (fun (header, (content, (initial_tick, num_ticks))) -> - {header; content; initial_tick; num_ticks}) - @@ merge_objs header_encoding - @@ merge_objs content_encoding - @@ obj2 - (req - "initial_tick" - Sc_rollup.Tick.encoding - ~description: - "Initial tick of the PVM at this block, i.e. before evaluation of \ - the messages.") - (req - "num_ticks" - int64 - ~description: - "Number of ticks produced by the evaluation of the messages in \ - this block.") - -let encoding = block_encoding header_encoding Data_encoding.unit - -let full_encoding = block_encoding header_encoding content_encoding - -let most_recent_commitment (header : header) = - Option.value header.commitment_hash ~default:header.previous_commitment_hash - -let final_tick {initial_tick; num_ticks; _} = - Sc_rollup.Tick.jump initial_tick (Z.of_int64 num_ticks) diff --git a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_block.mli b/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_block.mli deleted file mode 100644 index 1f0f8c7b4bbd75dcc5c3f500c51b5f5c3adbf6d6..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_block.mli +++ /dev/null @@ -1,111 +0,0 @@ -(*****************************************************************************) -(* *) -(* 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 Protocol -open Alpha_context - -(** {2 Structure of layer 2 blocks} *) - -(** A layer 2 block header contains information about the inbox and commitment - with respect to a layer 1 block, but without the inbox content of - messages. *) -type header = { - block_hash : Block_hash.t; (** Tezos block hash. *) - level : Raw_level.t; - (** Level of the block, corresponds to the level of the tezos block. *) - predecessor : Block_hash.t; (** Predecessor hash of the Tezos block. *) - commitment_hash : Sc_rollup.Commitment.Hash.t option; - (** Hash of this block's commitment if any was computed for it. *) - previous_commitment_hash : Sc_rollup.Commitment.Hash.t; - (** Previous commitment hash in the chain. If there is a commitment for this - block, this field contains the commitment that was previously - computed. *) - context : Sc_rollup_context_hash.t; - (** Hash of the layer 2 context for this block. *) - inbox_witness : Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t; - (** Witness for the inbox for this block, i.e. the Merkle hash of payloads - of messages. *) - inbox_hash : Sc_rollup.Inbox.Hash.t; (** Hash of the inbox for this block. *) -} - -(** Contents of blocks which include the actual content of the inbox and - messages. *) -type content = { - inbox : Sc_rollup.Inbox.t; (** Inbox for this block. *) - messages : Sc_rollup.Inbox_message.t list; - (** Messages added to the inbox in this block. *) - commitment : Sc_rollup.Commitment.t option; - (** Commitment, if any is computed for this block. [header.commitment = - Some h] iff [commitment = Some c] and [hash c = h]. *) -} - -(** Block parameterized by a header and content. The parameters are here to - allow to split the header and rest of the block. *) -type ('header, 'content) block = { - header : 'header; (** Header of this block. *) - content : 'content; (** Content of the block. *) - initial_tick : Sc_rollup.Tick.t; - (** Initial tick of the PVM at this block, i.e. before evaluation of the - messages. *) - num_ticks : int64; - (** Number of ticks produced by the evaluation of the messages in this - block. *) -} - -(** The type of layer 2 blocks. This type corresponds to what is stored on disk - for L2 blocks. The contents is stored in separate tables because it can be - large to read is is not always necessary. *) -type t = (header, unit) block - -(** The type of layer 2 blocks including their content (inbox, messages, commitment). *) -type full = (header, content) block - -(** {2 Encodings} *) - -val header_encoding : header Data_encoding.t - -val header_size : int - -val content_encoding : content Data_encoding.t - -val block_encoding : - 'header Data_encoding.t -> - 'content Data_encoding.t -> - ('header, 'content) block Data_encoding.t - -val encoding : t Data_encoding.t - -val full_encoding : full Data_encoding.t - -(** {2 Helper functions} *) - -(** [most_recent_commitment header] returns the most recent commitment - information at the block of with [header]. It is either the commitment for - this block if there is one or the previous commitment otherwise. *) -val most_recent_commitment : header -> Sc_rollup.Commitment.Hash.t - -(** [final_tick block] is the final tick, after evaluation of the messages in - the [block], i.e. [block.initial_tick + block.num_ticks]. *) -val final_tick : ('a, 'b) block -> Sc_rollup.Tick.t diff --git a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_context_hash.ml b/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_context_hash.ml deleted file mode 100644 index 000536a07aa55fea3f79d2ce6506e8b777dab8bb..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_context_hash.ml +++ /dev/null @@ -1,41 +0,0 @@ -(*****************************************************************************) -(* *) -(* 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_crypto - -include - Blake2B.Make - (Base58) - (struct - let name = "Smart_rollup_context_hash" - - let title = "A base58-check encoded hash of a Smart rollup node context" - - let b58check_prefix = "\008\209\216\166" - - let size = None - end) - -let () = Base58.check_encoded_prefix b58check_encoding "SRCo" 54 diff --git a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_proto_types.ml b/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_proto_types.ml index e30ee96557553dfb2fcf87d2f1581fb13fda801f..b94153ed4d8acd9f446ef89ac4712b7b3d37516a 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_proto_types.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_proto_types.ml @@ -236,3 +236,88 @@ module Kind = struct | Example_arith -> Example_arith | Wasm_2_0_0 -> Wasm_2_0_0 end + +module Dal = struct + module Slot_index = struct + type t = Dal.Slot_index.t + + let of_octez (i : Octez_smart_rollup.Dal.Slot_index.t) : t = + match Dal.Slot_index.of_int_opt i with + | None -> Format.ksprintf invalid_arg "Dal.Slot_index.of_octez: %d" i + | Some i -> i + + let to_octez : t -> Octez_smart_rollup.Dal.Slot_index.t = + Dal.Slot_index.to_int + end + + module Page_index = struct + type t = Dal.Page.Index.t + + let of_octez : Octez_smart_rollup.Dal.Page_index.t -> t = Fun.id + + let to_octez : t -> Octez_smart_rollup.Dal.Page_index.t = Fun.id + end + + module Slot_header = struct + type t = Dal.Slot.Header.t + + let of_octez + Octez_smart_rollup.Dal.Slot_header. + {id = {published_level; index}; commitment} : t = + Dal.Slot.Header. + { + id = + { + published_level = Raw_level.of_int32_exn published_level; + index = Slot_index.of_octez index; + }; + commitment; + } + + let to_octez Dal.Slot.Header.{id = {published_level; index}; commitment} : + Octez_smart_rollup.Dal.Slot_header.t = + Octez_smart_rollup.Dal.Slot_header. + { + id = + { + published_level = Raw_level.to_int32 published_level; + index = Slot_index.to_octez index; + }; + commitment; + } + end + + module Slot_history = struct + type t = Dal.Slots_history.t + + let of_octez (h : Octez_smart_rollup.Dal.Slot_history.t) : t = + h + |> Data_encoding.Binary.to_bytes_exn + Octez_smart_rollup.Dal.Slot_history.encoding + |> Data_encoding.Binary.of_bytes_exn Dal.Slots_history.encoding + + let to_octez (h : t) : Octez_smart_rollup.Dal.Slot_history.t = + h + |> Data_encoding.Binary.to_bytes_exn Dal.Slots_history.encoding + |> Data_encoding.Binary.of_bytes_exn + Octez_smart_rollup.Dal.Slot_history.encoding + end + + module Slot_history_cache = struct + type t = Dal.Slots_history.History_cache.t + + let of_octez (h : Octez_smart_rollup.Dal.Slot_history_cache.t) : t = + h + |> Data_encoding.Binary.to_bytes_exn + Octez_smart_rollup.Dal.Slot_history_cache.encoding + |> Data_encoding.Binary.of_bytes_exn + Dal.Slots_history.History_cache.encoding + + let to_octez (h : t) : Octez_smart_rollup.Dal.Slot_history_cache.t = + h + |> Data_encoding.Binary.to_bytes_exn + Dal.Slots_history.History_cache.encoding + |> Data_encoding.Binary.of_bytes_exn + Octez_smart_rollup.Dal.Slot_history_cache.encoding + end +end diff --git a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_proto_types.mli b/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_proto_types.mli index d24bfcd9c6ee4dc4015473e5eab5a3561de48a10..905a7b7bde6dc484c26a08fdd5f47eaf8d4c951b 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_proto_types.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_proto_types.mli @@ -116,3 +116,45 @@ module Kind : sig val to_octez : t -> Octez_smart_rollup.Kind.t end + +module Dal : sig + module Slot_index : sig + type t = Dal.Slot_index.t + + val of_octez : Octez_smart_rollup.Dal.Slot_index.t -> t + + val to_octez : t -> Octez_smart_rollup.Dal.Slot_index.t + end + + module Page_index : sig + type t = Dal.Page.Index.t + + val of_octez : Octez_smart_rollup.Dal.Page_index.t -> t + + val to_octez : t -> Octez_smart_rollup.Dal.Page_index.t + end + + module Slot_header : sig + type t = Dal.Slot.Header.t + + val of_octez : Octez_smart_rollup.Dal.Slot_header.t -> t + + val to_octez : t -> Octez_smart_rollup.Dal.Slot_header.t + end + + module Slot_history : sig + type t = Dal.Slots_history.t + + val of_octez : Octez_smart_rollup.Dal.Slot_history.t -> t + + val to_octez : t -> Octez_smart_rollup.Dal.Slot_history.t + end + + module Slot_history_cache : sig + type t = Dal.Slots_history.History_cache.t + + val of_octez : Octez_smart_rollup.Dal.Slot_history_cache.t -> t + + val to_octez : t -> Octez_smart_rollup.Dal.Slot_history_cache.t + end +end diff --git a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_services.ml b/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_services.ml index a6da8d1c06b43ad25be75fda95a3bfafe1ab104c..62664a971c3a37a5e7bca2e095468d650bbf3d6a 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_services.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_services.ml @@ -100,8 +100,8 @@ type message_status = cemented : bool; commitment : Sc_rollup.Commitment.t; commitment_hash : Sc_rollup.Commitment.Hash.t; - first_published_at_level : Raw_level.t; - published_at_level : Raw_level.t; + first_published_at_level : int32; + published_at_level : int32; } module Encodings = struct @@ -116,8 +116,8 @@ module Encodings = struct obj4 (req "commitment" Sc_rollup.Commitment.encoding) (req "hash" Sc_rollup.Commitment.Hash.encoding) - (opt "first_published_at_level" Raw_level.encoding) - (opt "published_at_level" Raw_level.encoding) + (opt "first_published_at_level" int32) + (opt "published_at_level" int32) let hex_string = conv Bytes.of_string Bytes.to_string bytes @@ -322,8 +322,8 @@ module Encodings = struct (req "cemented" bool) (req "commitment" Sc_rollup.Commitment.encoding) (req "hash" Sc_rollup.Commitment.Hash.encoding) - (req "first_published_at_level" Raw_level.encoding) - (req "published_at_level" Raw_level.encoding)) + (req "first_published_at_level" int32) + (req "published_at_level" int32)) (function | Committed { diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.ml b/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.ml index a78d121505ed60ad6265ff4a339e8a0428173aeb..6f049377dd2ba8ec9eeb7d6876646a1497c070c0 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.ml @@ -39,10 +39,7 @@ let get_head_hash_opt node_ctxt = let get_head_level_opt node_ctxt = let open Lwt_result_syntax in let+ res = Node_context.last_processed_head_opt node_ctxt in - Option.map - (fun Sc_rollup_block.{header = {level; _}; _} -> - Alpha_context.Raw_level.to_int32 level) - res + Option.map (fun Sc_rollup_block.{header = {level; _}; _} -> level) res module Slot_pages_map = struct open Protocol @@ -125,7 +122,10 @@ module Common = struct let open Lwt_result_syntax in let* l2_block = Node_context.get_l2_block node_ctxt block in let+ num_messages = - Node_context.get_num_messages node_ctxt l2_block.header.inbox_witness + Node_context.get_num_messages + node_ctxt + (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.of_octez + l2_block.header.inbox_witness) in Z.of_int num_messages @@ -272,6 +272,7 @@ let () = | Some head -> let commitment_hash = Sc_rollup_block.most_recent_commitment head.header + |> Sc_rollup_proto_types.Commitment_hash.of_octez in let+ commitment = Node_context.find_commitment node_ctxt commitment_hash @@ -460,6 +461,7 @@ let () = WithExceptions.Option.get ~loc:__LOC__ block.header.commitment_hash + |> Sc_rollup_proto_types.Commitment_hash.of_octez in (* Commitment computed *) let* published_at = diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.mli b/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.mli index 6ce3fd2f3ec98de44ba3d2e209aaf903e50a1b0c..425bba0d9e7c269d67799eaa28b53ae9b9214e4f 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/RPC_server.mli @@ -23,4 +23,13 @@ (* *) (*****************************************************************************) -include Daemon_components.RPC_server_sig +(** [start node_ctxt config] starts an RPC server listening for requests on the + port [config.rpc_port] and address [config.rpc_addr]. *) +val start : + Node_context.rw -> + Configuration.t -> + Tezos_rpc_http_server.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 : Tezos_rpc_http_server.RPC_server.server -> unit Lwt.t diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/batcher.mli b/src/proto_018_Proxford/lib_sc_rollup_node/batcher.mli index f38610bade8e27745ce4bdab2d7f0bfdb09ce572..baac151308971d85936cd756ef5b531d32f19602 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/batcher.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/batcher.mli @@ -23,7 +23,25 @@ (* *) (*****************************************************************************) -include Daemon_components.Batcher_sig +(** [init config ~signer node_ctxt] initializes and starts the batcher for + [signer]. If [config.simulation] is [true] (the default), messages added to + the batcher are simulated in an incremental simulation context. *) +val init : + Configuration.batcher -> + signer:Signature.public_key_hash -> + _ Node_context.t -> + unit tzresult Lwt.t + +(** Create L2 batches of operations from the queue and pack them in an L1 batch + operation. The batch operation is queued in the injector for injection on + the Tezos node. *) +val batch : unit -> unit tzresult Lwt.t + +(** Notify a new L2 head to the batcher worker. *) +val new_head : Layer1.head -> unit tzresult Lwt.t + +(** Shutdown the batcher, waiting for the ongoing request to be processed. *) +val shutdown : unit -> unit Lwt.t (** The type for the status of messages in the batcher. *) type status = diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/context.ml b/src/proto_018_Proxford/lib_sc_rollup_node/context.ml deleted file mode 100644 index afbce3ba94818b3f4dc36bbec434bf1691937479..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/context.ml +++ /dev/null @@ -1,308 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 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 -open Alpha_context -open Store_sigs -module Context_encoding = Tezos_context_encoding.Context_binary - -(* We shadow [Tezos_context_encoding] to prevent accidentally using - [Tezos_context_encoding.Context] instead of - [Tezos_context_encoding.Context_binary] during a future - refactoring.*) -module Tezos_context_encoding = struct end - -module Maker = Irmin_pack_unix.Maker (Context_encoding.Conf) - -module IStore = struct - include Maker.Make (Context_encoding.Schema) - module Schema = Context_encoding.Schema -end - -module IStoreTree = - Tezos_context_helpers.Context.Make_tree (Context_encoding.Conf) (IStore) - -type tree = IStore.tree - -type 'a raw_index = {path : string; repo : IStore.Repo.t} - -type 'a index = 'a raw_index constraint 'a = [< `Read | `Write > `Read] - -type rw_index = [`Read | `Write] index - -type ro_index = [`Read] index - -type 'a t = {index : 'a index; tree : tree} - -type rw = [`Read | `Write] t - -type ro = [`Read] t - -type commit = IStore.commit - -type hash = Sc_rollup_context_hash.t - -type path = string list - -let () = assert (Sc_rollup_context_hash.size = IStore.Hash.hash_size) - -let hash_to_istore_hash h = - Sc_rollup_context_hash.to_string h |> IStore.Hash.unsafe_of_raw_string - -let istore_hash_to_hash h = - IStore.Hash.to_raw_string h |> Sc_rollup_context_hash.of_string_exn - -let load : type a. a mode -> string -> a raw_index Lwt.t = - fun mode path -> - let open Lwt_syntax in - let readonly = match mode with Read_only -> true | Read_write -> false in - let+ repo = - IStore.Repo.v - (Irmin_pack.config - ~readonly - ~indexing_strategy:Irmin_pack.Indexing_strategy.minimal - path) - in - {path; repo} - -let close ctxt = IStore.Repo.close ctxt.repo - -let readonly (index : [> `Read] index) = (index :> [`Read] index) - -let raw_commit ?(message = "") index tree = - let info = IStore.Info.v ~author:"Tezos" 0L ~message in - IStore.Commit.v index.repo ~info ~parents:[] tree - -let commit ?message ctxt = - let open Lwt_syntax in - let+ commit = raw_commit ?message ctxt.index ctxt.tree in - IStore.Commit.hash commit |> istore_hash_to_hash - -let checkout index key = - let open Lwt_syntax in - let* o = IStore.Commit.of_hash index.repo (hash_to_istore_hash key) in - match o with - | None -> return_none - | Some commit -> - let tree = IStore.Commit.tree commit in - return_some {index; tree} - -let empty index = {index; tree = IStore.Tree.empty ()} - -let is_empty ctxt = IStore.Tree.is_empty ctxt.tree - -let index context = context.index - -module Proof (Hash : sig - type t - - val of_context_hash : Context_hash.t -> t -end) (Proof_encoding : sig - val proof_encoding : - Environment.Context.Proof.tree Environment.Context.Proof.t Data_encoding.t -end) = -struct - module IStoreProof = - Tezos_context_helpers.Context.Make_proof (IStore) (Context_encoding.Conf) - - module Tree = struct - include IStoreTree - - type t = rw_index - - type tree = IStore.tree - - type key = path - - type value = bytes - end - - type tree = Tree.tree - - type proof = IStoreProof.Proof.tree IStoreProof.Proof.t - - let hash_tree tree = Hash.of_context_hash (Tree.hash tree) - - let proof_encoding = Proof_encoding.proof_encoding - - let proof_before proof = - let (`Value hash | `Node hash) = proof.IStoreProof.Proof.before in - Hash.of_context_hash hash - - let proof_after proof = - let (`Value hash | `Node hash) = proof.IStoreProof.Proof.after in - Hash.of_context_hash hash - - let produce_proof index tree step = - let open Lwt_syntax in - (* Committing the context is required by Irmin to produce valid proofs. *) - let* _commit_key = raw_commit index tree in - match Tree.kinded_key tree with - | Some k -> - let* p = IStoreProof.produce_tree_proof index.repo k step in - return (Some p) - | None -> return None - - let verify_proof proof step = - (* The rollup node is not supposed to verify proof. We keep - this part in case this changes in the future. *) - let open Lwt_syntax in - let* result = IStoreProof.verify_tree_proof proof step in - match result with - | Ok v -> return (Some v) - | Error _ -> - (* We skip the error analysis here since proof verification is not a - job for the rollup node. *) - return None -end - -module Inbox = struct - include Sc_rollup.Inbox - module Message = Sc_rollup.Inbox_message -end - -(** State of the PVM that this rollup node deals with. *) -module PVMState = struct - type value = tree - - let key = ["pvm_state"] - - let empty () = IStore.Tree.empty () - - let find ctxt = IStore.Tree.find_tree ctxt.tree key - - let lookup tree path = IStore.Tree.find tree path - - let set ctxt state = - let open Lwt_syntax in - let+ tree = IStore.Tree.add_tree ctxt.tree key state in - {ctxt with tree} -end - -module Rollup = struct - let path = ["rollup_address"] - - let set_address (index : rw_index) addr = - let open Lwt_result_syntax in - protect @@ fun () -> - let info () = - let date = - Time.(System.now () |> System.to_protocol |> Protocol.to_seconds) - in - IStore.Info.v date - in - let value = - Data_encoding.Binary.to_bytes_exn Sc_rollup.Address.encoding addr - in - let*! store = IStore.main index.repo in - let*! () = IStore.set_exn ~info store path value in - return_unit - - let get_address (index : _ raw_index) = - let open Lwt_result_syntax in - protect @@ fun () -> - let*! store = IStore.main index.repo in - let*! value = IStore.find store path in - return - @@ Option.map - (Data_encoding.Binary.of_bytes_exn Sc_rollup.Address.encoding) - value - - let check_or_set_address (type a) (mode : a mode) (index : a raw_index) - rollup_address = - let open Lwt_result_syntax in - let* saved_address = get_address index in - match saved_address with - | Some saved_address -> - fail_unless Sc_rollup.Address.(rollup_address = saved_address) - @@ Sc_rollup_node_errors.Unexpected_rollup - {rollup_address; saved_address} - | None -> ( - (* Address was never saved, we set it permanently if not in read-only - mode. *) - match mode with - | Store_sigs.Read_only -> return_unit - | Read_write -> set_address index rollup_address) -end - -module Version = struct - type t = V0 - - let version = V0 - - let encoding = - let open Data_encoding in - conv - (fun V0 -> 0) - (function - | 0 -> V0 - | v -> - Format.ksprintf Stdlib.failwith "Unsupported context version %d" v) - int31 - - let path = ["context_version"] - - let set (index : rw_index) = - let open Lwt_result_syntax in - protect @@ fun () -> - let info () = - let date = - Time.(System.now () |> System.to_protocol |> Protocol.to_seconds) - in - IStore.Info.v date - in - let value = Data_encoding.Binary.to_bytes_exn encoding version in - let*! store = IStore.main index.repo in - let*! () = IStore.set_exn ~info store path value in - return_unit - - let get (index : _ index) = - let open Lwt_result_syntax in - protect @@ fun () -> - let*! store = IStore.main index.repo in - let*! value = IStore.find store path in - return @@ Option.map (Data_encoding.Binary.of_bytes_exn encoding) value - - let check (index : _ index) = - let open Lwt_result_syntax in - let* context_version = get index in - match context_version with None | Some V0 -> return_unit - - let check_and_set (index : _ index) = - let open Lwt_result_syntax in - let* context_version = get index in - match context_version with None -> set index | Some V0 -> return_unit -end - -let load : type a. a mode -> string -> a raw_index tzresult Lwt.t = - fun mode path -> - let open Lwt_result_syntax in - let*! index = load mode path in - let+ () = - match mode with - | Read_only -> Version.check index - | Read_write -> Version.check_and_set index - in - index diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/context.mli b/src/proto_018_Proxford/lib_sc_rollup_node/context.mli deleted file mode 100644 index 6a2f40660c1200aa296c9635c218032388586d34..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/context.mli +++ /dev/null @@ -1,173 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 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 Store_sigs - -(** The type of indexed repository for contexts. The parameter indicates if the - index can be written or only read. *) -type 'a index constraint 'a = [< `Read | `Write > `Read] - -(** Read/write {!type:index}. *) -type rw_index = [`Read | `Write] index - -(** Read only {!type:index}. *) -type ro_index = [`Read] index - -(** The type of trees stored in the context, i.e. the actual data. *) -type tree - -(** The type of context with its content. *) -type 'a t constraint 'a = [< `Read | `Write > `Read] - -(** Read/write context {!t}. *) -type rw = [`Read | `Write] t - -(** Read-only context {!t}. *) -type ro = [`Read] t - -(** A context hash is the hash produced when the data of the context is - committed to disk, i.e. the {!type:commit} hash. *) -type hash = Sc_rollup_context_hash.t - -(** The type of commits for the context. *) -type commit - -(** [load path] initializes from disk a context from [path]. *) -val load : 'a mode -> string -> 'a index tzresult Lwt.t - -(** [index context] is the repository of the context [context]. *) -val index : 'a t -> 'a index - -(** [close ctxt] closes the context index [ctxt]. *) -val close : _ index -> unit Lwt.t - -(** [readonly index] returns a read-only version of the index. *) -val readonly : [> `Read] index -> [`Read] index - -(** [raw_commit ?message ctxt tree] commits the [tree] in the context repository - [ctxt] on disk, and return the commit. *) -val raw_commit : ?message:string -> [> `Write] index -> tree -> commit Lwt.t - -(** [commit ?message context] commits content of the context [context] on disk, - and return the commit hash. *) -val commit : ?message:string -> [> `Write] t -> hash Lwt.t - -(** [checkout ctxt hash] checkouts the content that corresponds to the commit - hash [hash] in the repository [ctxt] and returns the corresponding - context. If there is no commit that corresponds to [hash], it returns - [None]. *) -val checkout : 'a index -> hash -> 'a t option Lwt.t - -(** [empty ctxt] is the context with an empty content for the repository [ctxt]. *) -val empty : 'a index -> 'a t - -(** [is_empty context] returns [true] iff the context content of [context] is - empty. *) -val is_empty : _ t -> bool - -(** Module for generating and verifying proofs for a context *) -module Proof (Hash : sig - type t - - val of_context_hash : Context_hash.t -> t -end) (Proof_encoding : sig - val proof_encoding : - Environment.Context.Proof.tree Environment.Context.Proof.t Data_encoding.t -end) : sig - (** Tree representation for proof generation. - - NOTE: The index needs to be accessed with write permissions because we - need to commit on disk to generate the proofs (e.g. in - {!Inbox.produce_proof}, {!PVM.produce_proof}. or - {!PVM.produce_output_proof}). *) - module Tree : - Tezos_context_sigs.Context.TREE - with type key = string list - and type value = bytes - and type t = rw_index - and type tree = tree - - type tree = Tree.tree - - (** See {!Sc_rollup_PVM_sem.proof} *) - type proof - - val hash_tree : tree -> Hash.t - - (** See {!Sc_rollup_PVM_sem.proof_encoding} *) - val proof_encoding : proof Data_encoding.t - - (** [proof_before proof] is the hash of the state before the step that - generated [rpoof]. *) - val proof_before : proof -> Hash.t - - (** [proof_after proof] is the hash of the state after the step that generated - [rpoof]. *) - val proof_after : proof -> Hash.t - - (** [produce_proof ctxt tree f] produces and returns a proof for the execution - of [f] on the state [tree]. *) - val produce_proof : - rw_index -> tree -> (tree -> (tree * 'a) Lwt.t) -> (proof * 'a) option Lwt.t - - (** [verify_proof proof f] verifies that [f] produces the proof [proof] and - returns the resulting [tree], or [None] if the proof cannot be - verified. *) - val verify_proof : - proof -> (tree -> (tree * 'a) Lwt.t) -> (tree * 'a) option Lwt.t -end - -(** State of the PVM that this rollup node deals with *) -module PVMState : sig - (** The value of a PVM state *) - type value = tree - - (** [empty ()] is the empty PVM state. *) - val empty : unit -> value - - (** [find context] returns the PVM state stored in the [context], if any. *) - val find : _ t -> value option Lwt.t - - (** [lookup state path] returns the data stored for the path [path] in the PVM - state [state]. *) - val lookup : value -> string list -> bytes option Lwt.t - - (** [set context state] saves the PVM state [state] in the context and returns - the updated context. Note: [set] does not perform any write on disk, this - information must be committed using {!val:commit}. *) - val set : 'a t -> value -> 'a t Lwt.t -end - -(** Static information about the rollup. *) -module Rollup : sig - val get_address : - _ index -> Protocol.Alpha_context.Sc_rollup.Address.t option tzresult Lwt.t - - val check_or_set_address : - 'a mode -> - 'a index -> - Protocol.Alpha_context.Sc_rollup.Address.t -> - unit tzresult Lwt.t -end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml b/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml index 210ecfdbb4a534eb6679b3e0266f3bfe87fe53ec..bf66812a90f44752f0a8dcabb3c41ad80a019f7a 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/daemon.ml @@ -42,6 +42,7 @@ let is_refutable_commitment node_ctxt let* our_commitment_and_hash = Option.filter_map_es (fun hash -> + let hash = Sc_rollup_proto_types.Commitment_hash.of_octez hash in let+ commitment = Node_context.find_commitment node_ctxt hash in Option.map (fun c -> (c, hash)) commitment) l2_block.header.commitment_hash @@ -102,8 +103,8 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) node_ctxt commitment_hash { - first_published_at_level = published_at_level; - published_at_level = Some (Raw_level.of_int32_exn head.Layer1.level); + first_published_at_level = Raw_level.to_int32 published_at_level; + published_at_level = Some head.Layer1.level; } in let*! () = @@ -136,7 +137,8 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) node_ctxt their_commitment_hash { - first_published_at_level = published_at_level; + first_published_at_level = + Raw_level.to_int32 published_at_level; published_at_level = None; } in @@ -160,17 +162,18 @@ let process_included_l1_operation (type kind) (node_ctxt : Node_context.rw) in let*? () = (* We stop the node if we disagree with a cemented commitment *) + let our_commitment_hash = + Option.map + Sc_rollup_proto_types.Commitment_hash.of_octez + inbox_block.header.commitment_hash + in error_unless (Option.equal Sc_rollup.Commitment.Hash.( = ) - inbox_block.header.commitment_hash + our_commitment_hash (Some commitment_hash)) (Sc_rollup_node_errors.Disagree_with_cemented - { - inbox_level; - ours = inbox_block.header.commitment_hash; - on_l1 = commitment_hash; - }) + {inbox_level; ours = our_commitment_hash; on_l1 = commitment_hash}) in let lcc = Reference.get node_ctxt.lcc in let*! () = @@ -256,7 +259,7 @@ let process_l1_operation (type kind) node_ctxt (head : Layer1.header) ~source let process_l1_block_operations node_ctxt (head : Layer1.header) = let open Lwt_result_syntax in let* block = - Layer1.fetch_tezos_block node_ctxt.Node_context.l1_ctxt head.hash + Layer1_helpers.fetch_tezos_block node_ctxt.Node_context.l1_ctxt head.hash in let apply (type kind) accu ~source (operation : kind manager_operation) result = @@ -355,6 +358,11 @@ let rec process_head (daemon_components : (module Daemon_components.S)) let* inbox_hash, inbox, inbox_witness, messages = Inbox.process_head node_ctxt ~predecessor head in + let inbox_witness = + Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez + inbox_witness + in + let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in let* () = when_ (Node_context.dal_supported node_ctxt) @@ fun () -> Dal_slots_tracker.process_head node_ctxt (Layer1.head_of_header head) @@ -375,6 +383,11 @@ let rec process_head (daemon_components : (module Daemon_components.S)) let* commitment_hash = Publisher.process_head node_ctxt ~predecessor:predecessor.hash head ctxt in + let commitment_hash = + Option.map + Sc_rollup_proto_types.Commitment_hash.to_octez + commitment_hash + in let* () = unless (catching_up && Option.is_none commitment_hash) @@ fun () -> Inbox.same_as_layer_1 node_ctxt head.hash inbox @@ -383,7 +396,9 @@ let rec process_head (daemon_components : (module Daemon_components.S)) let* previous_commitment_hash = if level = node_ctxt.genesis_info.Sc_rollup.Commitment.level then (* Previous commitment for rollup genesis is itself. *) - return node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash + return + (Sc_rollup_proto_types.Commitment_hash.to_octez + node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash) else let+ pred = Node_context.get_l2_block node_ctxt predecessor.hash in Sc_rollup_block.most_recent_commitment pred.header @@ -392,7 +407,7 @@ let rec process_head (daemon_components : (module Daemon_components.S)) Sc_rollup_block. { block_hash = head.hash; - level; + level = head.level; predecessor = predecessor.hash; commitment_hash; previous_commitment_hash; @@ -402,7 +417,13 @@ let rec process_head (daemon_components : (module Daemon_components.S)) } in let l2_block = - Sc_rollup_block.{header; content = (); num_ticks; initial_tick} + Sc_rollup_block. + { + header; + content = (); + num_ticks; + initial_tick = Sc_rollup.Tick.to_z initial_tick; + } in let* () = Node_context.mark_finalized_level @@ -415,6 +436,7 @@ let rec process_head (daemon_components : (module Daemon_components.S)) let*! () = Daemon_event.new_head_processed head.hash head.level process_time in + Metrics.Inbox.set_process_time process_time ; return_unit (* [on_layer_1_head node_ctxt head] processes a new head from the L1. It @@ -427,12 +449,7 @@ let on_layer_1_head (daemon_components : (module Daemon_components.S)) node_ctxt let old_head = match old_head with | Some h -> - `Head - Layer1. - { - hash = h.header.block_hash; - level = Raw_level.to_int32 h.header.level; - } + `Head Layer1.{hash = h.header.block_hash; level = h.header.level} | None -> (* if no head has been processed yet, we want to handle all blocks since, and including, the rollup origination. *) @@ -478,7 +495,7 @@ let on_layer_1_head (daemon_components : (module Daemon_components.S)) node_ctxt let* () = List.iter_es (fun (block, to_prefetch) -> - Layer1.prefetch_tezos_blocks node_ctxt.l1_ctxt to_prefetch ; + Layer1_helpers.prefetch_tezos_blocks node_ctxt.l1_ctxt to_prefetch ; let* header = get_header block in let catching_up = block.level < head.level in process_head daemon_components node_ctxt ~catching_up header) @@ -593,7 +610,16 @@ let run node_ctxt configuration unless (signers = []) @@ fun () -> Injector.init node_ctxt.cctxt - (Node_context.readonly node_ctxt) + { + cctxt = (node_ctxt.cctxt :> Client_context.full); + fee_parameters = configuration.fee_parameters; + minimal_block_delay = + node_ctxt.protocol_constants.Constants.parametric + .minimal_block_delay |> Period.to_seconds; + delay_increment_per_round = + node_ctxt.protocol_constants.Constants.parametric + .delay_increment_per_round |> Period.to_seconds; + } ~data_dir:node_ctxt.data_dir ~signers ~retention_period:configuration.injector.retention_period @@ -656,6 +682,11 @@ module Internal_for_tests = struct head messages in + let inbox_witness = + Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez + inbox_witness + in + let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in let* ctxt, _num_messages, num_ticks, initial_tick = Interpreter.process_head node_ctxt ctxt ~predecessor head (inbox, messages) in @@ -667,11 +698,16 @@ module Internal_for_tests = struct head ctxt in + let commitment_hash = + Option.map Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash + in let level = Raw_level.of_int32_exn head.level in let* previous_commitment_hash = if level = node_ctxt.genesis_info.Sc_rollup.Commitment.level then (* Previous commitment for rollup genesis is itself. *) - return node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash + return + (Sc_rollup_proto_types.Commitment_hash.to_octez + node_ctxt.genesis_info.Sc_rollup.Commitment.commitment_hash) else let+ pred = Node_context.get_l2_block node_ctxt predecessor.hash in Sc_rollup_block.most_recent_commitment pred.header @@ -680,7 +716,7 @@ module Internal_for_tests = struct Sc_rollup_block. { block_hash = head.hash; - level; + level = head.level; predecessor = predecessor.hash; commitment_hash; previous_commitment_hash; @@ -690,7 +726,13 @@ module Internal_for_tests = struct } in let l2_block = - Sc_rollup_block.{header; content = (); num_ticks; initial_tick} + Sc_rollup_block. + { + header; + content = (); + num_ticks; + initial_tick = Sc_rollup.Tick.to_z initial_tick; + } in let* () = Node_context.save_l2_head node_ctxt l2_block in return l2_block diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/daemon_event.ml b/src/proto_018_Proxford/lib_sc_rollup_node/daemon_event.ml index 700fb8e63867917938aca6f66ebfbd4260f60a3c..2969126bcaabe2c9bf31d2d9030529bb9a2c8081 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/daemon_event.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/daemon_event.ml @@ -149,7 +149,7 @@ let new_heads_processed = new_heads_iteration Simple.new_heads_processed let included_operation (type kind) (operation : kind Protocol.Alpha_context.manager_operation) (result : kind Protocol.Apply_results.manager_operation_result) = - match L1_operation.of_manager_operation operation with + match Sc_rollup_injector.injector_operation_of_manager operation with | None -> Lwt.return_unit | Some operation -> ( match result with diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/dal_slots_tracker.ml b/src/proto_018_Proxford/lib_sc_rollup_node/dal_slots_tracker.ml index 0c9ea3315dc4d66be467c3b2d47fc832219b65fb..2def15b77f98c583af61f088af7d62d471e78973 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/dal_slots_tracker.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/dal_slots_tracker.ml @@ -84,7 +84,7 @@ let slots_info node_ctxt (Layer1.{hash; _} as head) = return None | Some published_block_hash -> let* {metadata; _} = - Layer1.fetch_tezos_block node_ctxt.Node_context.l1_ctxt hash + Layer1_helpers.fetch_tezos_block node_ctxt.Node_context.l1_ctxt hash in let*? metadata = Option.to_result diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/inbox.ml b/src/proto_018_Proxford/lib_sc_rollup_node/inbox.ml index ff490d6cb7d9425011ff664137936241e5a50114..d711228ed16683fefcb1fd7f450fbcd2e9b2eb44 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/inbox.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/inbox.ml @@ -33,7 +33,7 @@ let lift promise = Lwt.map Environment.wrap_tzresult promise let get_messages Node_context.{l1_ctxt; _} head = let open Lwt_result_syntax in - let* block = Layer1.fetch_tezos_block l1_ctxt head in + let* block = Layer1_helpers.fetch_tezos_block l1_ctxt head in let apply (type kind) accu ~source:_ (operation : kind manager_operation) _result = let open Result_syntax in diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/injector.mli b/src/proto_018_Proxford/lib_sc_rollup_node/injector.mli deleted file mode 100644 index 0f3db24e434eeded77d995b2d9125bb5dfab40b5..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/injector.mli +++ /dev/null @@ -1,30 +0,0 @@ -(*****************************************************************************) -(* *) -(* 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. *) -(* *) -(*****************************************************************************) - -include - Injector_sigs.S - with type state := Node_context.ro - and type tag := Configuration.purpose - and type operation := L1_operation.t diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/interpreter.ml b/src/proto_018_Proxford/lib_sc_rollup_node/interpreter.ml index 9cb8baaa7fac68eff29f52397c24cc333056efe1..77143300570d37e02ae8c5f3acd219e5d964a4de 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/interpreter.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/interpreter.ml @@ -33,7 +33,7 @@ open Alpha_context let get_boot_sector block_hash (node_ctxt : _ Node_context.t) = let open Lwt_result_syntax in let exception Found_boot_sector of string in - let* block = Layer1.fetch_tezos_block node_ctxt.l1_ctxt block_hash in + let* block = Layer1_helpers.fetch_tezos_block node_ctxt.l1_ctxt block_hash in let missing_boot_sector () = failwith "Boot sector not found in Tezos block %a" Block_hash.pp block_hash in @@ -168,7 +168,7 @@ let process_head (node_ctxt : _ Node_context.t) ctxt the messages the block ([remaining_messages]). *) let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = let open Lwt_result_syntax in - let pred_level = Raw_level.to_int32 block.header.level |> Int32.pred in + let pred_level = Int32.pred block.header.level in let* ctxt = Node_context.checkout_context node_ctxt block.header.predecessor in @@ -178,9 +178,16 @@ let start_state_of_block node_ctxt (block : Sc_rollup_block.t) = ctxt Layer1.{hash = block.header.predecessor; level = pred_level} in - let* inbox = Node_context.get_inbox node_ctxt block.header.inbox_hash in + let* inbox = + Node_context.get_inbox + node_ctxt + (Sc_rollup_proto_types.Inbox_hash.of_octez block.header.inbox_hash) + in let* {is_first_block; predecessor; predecessor_timestamp; messages} = - Node_context.get_messages node_ctxt block.header.inbox_witness + Node_context.get_messages + node_ctxt + (Sc_rollup_proto_types.Merkelized_payload_hashes_hash.of_octez + block.header.inbox_witness) in let inbox_level = Sc_rollup.Inbox.inbox_level inbox in let module PVM = (val node_ctxt.pvm) in @@ -233,9 +240,8 @@ let state_of_tick_aux node_ctxt ~start_state (event : Sc_rollup_block.t) tick = let* start_state = match start_state with | Some start_state - when Raw_level.( - start_state.Fueled_pvm.Accounted.inbox_level = event.header.level) - -> + when Raw_level.to_int32 start_state.Fueled_pvm.Accounted.inbox_level + = event.header.level -> return start_state | _ -> (* Recompute start state on level change or if we don't have a @@ -284,7 +290,7 @@ let state_of_tick node_ctxt ?start_state tick level = match event with | None -> return_none | Some event -> - assert (Raw_level.(event.header.level <= level)) ; + assert (event.header.level <= Raw_level.to_int32 level) ; let* result_state = if Node_context.is_loser node_ctxt then (* TODO: https://gitlab.com/tezos/tezos/-/issues/5253 diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/layer1.ml b/src/proto_018_Proxford/lib_sc_rollup_node/layer1.ml deleted file mode 100644 index ec67b468980861cffff52594c78bb699803ed56f..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/layer1.ml +++ /dev/null @@ -1,275 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Nomadic Labs, *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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_client_context - -(** - - Errors - ====== - -*) - -type error += Cannot_find_block of Block_hash.t - -let () = - Sc_rollup_node_errors.register_error_kind - ~id:"sc_rollup.node.cannot_find_block" - ~title:"Cannot find block from L1" - ~description:"A block couldn't be found from the L1 node" - ~pp:(fun ppf hash -> - Format.fprintf - ppf - "Block with hash %a was not found on the L1 node." - Block_hash.pp - hash) - `Temporary - Data_encoding.(obj1 (req "hash" Block_hash.encoding)) - (function Cannot_find_block hash -> Some hash | _ -> None) - (fun hash -> Cannot_find_block hash) - -(** - - State - ===== - -*) - -type header = { - hash : Block_hash.t; - level : int32; - header : Block_header.shell_header; -} - -let header_encoding = - let open Data_encoding in - conv - (fun {hash; level = _; header} -> (hash, header)) - (fun (hash, header) -> {hash; level = header.level; header}) - (merge_objs - (obj1 (req "hash" Block_hash.encoding)) - Block_header.shell_header_encoding) - -type head = {hash : Block_hash.t; level : int32} - -let head_encoding = - let open Data_encoding in - conv - (fun {hash; level} -> (hash, level)) - (fun (hash, level) -> {hash; level}) - (obj2 (req "hash" Block_hash.encoding) (req "level" Data_encoding.int32)) - -let head_of_header {hash; level; header = _} = {hash; level} - -module Blocks_cache = - Aches_lwt.Lache.Make_option - (Aches.Rache.Transfer (Aches.Rache.LRU) (Block_hash)) - -type blocks_cache = Alpha_block_services.block_info Blocks_cache.t - -type headers_cache = Block_header.shell_header Blocks_cache.t - -open Octez_crawler.Layer_1 - -type nonrec t = { - l1 : t; - cctxt : Client_context.full; - blocks_cache : blocks_cache; - (** Global blocks cache for the smart rollup node. *) - headers_cache : headers_cache; - (** Global block headers cache for the smart rollup node. *) - prefetch_blocks : int; (** Number of blocks to prefetch by default. *) -} - -let start ~name ~reconnection_delay ~l1_blocks_cache_size ?protocols - ?(prefetch_blocks = l1_blocks_cache_size) cctxt = - let open Lwt_result_syntax in - let*? () = - if prefetch_blocks > l1_blocks_cache_size then - error_with - "Blocks to prefetch must be less than the cache size: %d" - l1_blocks_cache_size - else Ok () - in - let*! l1 = start ~name ~reconnection_delay ?protocols cctxt in - let blocks_cache = Blocks_cache.create l1_blocks_cache_size in - let headers_cache = Blocks_cache.create l1_blocks_cache_size in - let cctxt = (cctxt :> Client_context.full) in - return {l1; cctxt; blocks_cache; headers_cache; prefetch_blocks} - -let shutdown {l1; _} = shutdown l1 - -let cache_shell_header {headers_cache; _} hash header = - Blocks_cache.put headers_cache hash (Lwt.return_some header) - -let iter_heads l1_ctxt f = - iter_heads l1_ctxt.l1 @@ fun (hash, {shell = {level; _} as header; _}) -> - cache_shell_header l1_ctxt hash header ; - f {hash; level; header} - -let wait_first l1_ctxt = - let open Lwt_syntax in - let+ hash, {shell = {level; _} as header; _} = wait_first l1_ctxt.l1 in - {hash; level; header} - -let get_predecessor_opt ?max_read {l1; _} = get_predecessor_opt ?max_read l1 - -let get_predecessor ?max_read {l1; _} = get_predecessor ?max_read l1 - -let get_tezos_reorg_for_new_head {l1; _} ?get_old_predecessor old_head new_head - = - get_tezos_reorg_for_new_head l1 ?get_old_predecessor old_head new_head - -module Internal_for_tests = struct - let dummy cctxt = - { - l1 = Internal_for_tests.dummy cctxt; - cctxt = (cctxt :> Client_context.full); - blocks_cache = Blocks_cache.create 1; - headers_cache = Blocks_cache.create 1; - prefetch_blocks = 0; - } -end - -(** - - Helpers - ======= - -*) - -(** [fetch_tezos_block cctxt hash] returns a block shell header of - [hash]. Looks for the block in the blocks cache first, and fetches it from - the L1 node otherwise. *) -let fetch_tezos_shell_header {cctxt; blocks_cache; headers_cache; _} hash = - let open Lwt_syntax in - trace (Cannot_find_block hash) - @@ - let errors = ref None in - let fetch hash = - let* shell_header = - Tezos_shell_services.Shell_services.Blocks.Header.shell_header - cctxt - ~chain:`Main - ~block:(`Hash (hash, 0)) - () - in - match shell_header with - | Error errs -> - errors := Some errs ; - return_none - | Ok shell_header -> return_some shell_header - in - let+ shell_header = - let do_cached_header_fetch () = - Blocks_cache.bind_or_put headers_cache hash fetch Lwt.return - in - match Blocks_cache.bind blocks_cache hash Lwt.return with - | None -> do_cached_header_fetch () - | Some block -> ( - (* There is already a full block being fetched. *) - let* block in - match block with - | None -> - (* Fetching full block failed. *) - do_cached_header_fetch () - | Some block -> - (* The full block is already in the cache. *) - return_some block.header.shell) - in - match (shell_header, !errors) with - | None, None -> - (* This should not happen if {!find_in_cache} behaves correctly, - i.e. calls {!fetch} for cache misses. *) - error_with - "Fetching Tezos block %a failed unexpectedly" - Block_hash.pp - hash - | None, Some errs -> Error errs - | Some shell_header, _ -> Ok shell_header - -(** [fetch_tezos_block cctxt hash] returns a block info given a block - hash. Looks for the block in the blocks cache first, and fetches it from the - L1 node otherwise. *) -let fetch_tezos_block {cctxt; blocks_cache; headers_cache; _} hash = - let open Lwt_syntax in - trace (Cannot_find_block hash) - @@ - let errors = ref None in - let fetch hash = - let* block = - Alpha_block_services.info - cctxt - ~chain:`Main - ~block:(`Hash (hash, 0)) - ~metadata:`Always - () - in - match block with - | Error errs -> - errors := Some errs ; - return_none - | Ok block -> return_some block - in - let+ block = Blocks_cache.bind_or_put blocks_cache hash fetch Lwt.return in - match (block, !errors) with - | None, None -> - (* This should not happen if {!find_in_cache} behaves correctly, - i.e. calls {!fetch} for cache misses. *) - error_with - "Fetching Tezos block %a failed unexpectedly" - Block_hash.pp - hash - | None, Some errs -> Error errs - | Some block, _ -> - Blocks_cache.put headers_cache hash (Lwt.return_some block.header.shell) ; - Ok block - -let make_prefetching_schedule {prefetch_blocks; _} blocks = - let blocks_with_prefetching, _, first_prefetch = - List.fold_left - (fun (acc, nb_prefetch, prefetch) b -> - let nb_prefetch = nb_prefetch + 1 in - let prefetch = b :: prefetch in - if nb_prefetch >= prefetch_blocks then ((b, prefetch) :: acc, 0, []) - else ((b, []) :: acc, nb_prefetch, prefetch)) - ([], 0, []) - (List.rev blocks) - in - match (blocks_with_prefetching, first_prefetch) with - | [], _ | _, [] -> blocks_with_prefetching - | (first, _) :: rest, _ -> (first, first_prefetch) :: rest - -let prefetch_tezos_blocks l1_ctxt = function - | [] -> () - | blocks -> - Lwt.async @@ fun () -> - List.iter_p - (fun {hash; _} -> - let open Lwt_syntax in - let+ _maybe_block = fetch_tezos_block l1_ctxt hash in - ()) - blocks diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/layer1.mli b/src/proto_018_Proxford/lib_sc_rollup_node/layer1.mli deleted file mode 100644 index 2b00c462c563872c8899d77425bde1b19fa8dba3..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/layer1.mli +++ /dev/null @@ -1,136 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Nomadic Labs, *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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 maintains information about the layer 1 chain. - - This module follows the evolution of the layer 1 chain by - subscribing to the head monitoring RPC offered by the Tezos node. -*) - -type header = { - hash : Block_hash.t; - level : int32; - header : Block_header.shell_header; -} - -type head = {hash : Block_hash.t; level : int32} - -val header_encoding : header Data_encoding.t - -val head_encoding : head Data_encoding.t - -val head_of_header : header -> head - -type t - -(** [start ~name ~reconnection_delay ~l1_blocks_cache_size ?protocols cctxt] - connects to a Tezos node and starts monitoring new heads. One can iterate on - the heads by calling {!iter_heads} on its result. [reconnection_delay] gives - an initial delay for the reconnection which is used in an exponential - backoff. The [name] is used to differentiate events. [l1_blocks_cache_size] - is the size of the caches for the blocks and headers. If [protocols] is - provided, only heads of these protocols will be monitored. *) -val start : - name:string -> - reconnection_delay:float -> - l1_blocks_cache_size:int -> - ?protocols:Protocol_hash.t list -> - ?prefetch_blocks:int -> - #Client_context.full -> - t tzresult Lwt.t - -(** [shutdown t] properly shuts the layer 1 down. *) -val shutdown : t -> unit Lwt.t - -(* TODO: https://gitlab.com/tezos/tezos/-/issues/3311 - Allow to retrieve L1 blocks through Tezos node storage locally. *) - -(** [iter_heads t f] calls [f] on all new heads appearing in the layer 1 - chain. In case of a disconnection with the layer 1 node, it reconnects - automatically. If [f] returns an error (other than a disconnection) it, - [iter_heads] terminates and returns the error. *) -val iter_heads : t -> (header -> unit tzresult Lwt.t) -> unit tzresult Lwt.t - -(** [wait_first t] waits for the first head to appear in the stream and - returns it. *) -val wait_first : t -> header Lwt.t - -val get_predecessor_opt : - ?max_read:int -> - t -> - Block_hash.t * int32 -> - (Block_hash.t * int32) option tzresult Lwt.t - -val get_predecessor : - ?max_read:int -> - t -> - Block_hash.t * int32 -> - (Block_hash.t * int32) tzresult Lwt.t - -val get_tezos_reorg_for_new_head : - t -> - ?get_old_predecessor: - (Block_hash.t * int32 -> (Block_hash.t * int32) tzresult Lwt.t) -> - [`Head of Block_hash.t * int32 | `Level of int32] -> - Block_hash.t * int32 -> - (Block_hash.t * int32) Reorg.t tzresult Lwt.t - -(** {2 Helpers } *) - -(** [fetch_tezos_shell_header cctxt hash] returns the block shell header of - [hash]. Looks for the block in the blocks cache first, and fetches it from - the L1 node otherwise. *) -val fetch_tezos_shell_header : - t -> Block_hash.t -> Block_header.shell_header tzresult Lwt.t - -(** [fetch_tezos_block cctxt hash] returns a block info given a block hash. - Looks for the block in the blocks cache first, and fetches it from the L1 - node otherwise. *) -val fetch_tezos_block : - t -> - Block_hash.t -> - Protocol_client_context.Alpha_block_services.block_info tzresult Lwt.t - -(** [make_prefetching_schedule l1_ctxt blocks] returns the list [blocks] with - each element associated to a list of blocks to prefetch of at most - [l1_ctxt.prefetch_blocks]. If [blocks = [b1; ...; bn]] and [prefetch_blocks - = 3] then the result will be [(b1, [b1;b2;b3]); (b2, []); (b3, []); (b4, - [b4;b5;b6]); ...]. *) -val make_prefetching_schedule : t -> 'block trace -> ('block * 'block list) list - -(** [prefetch_tezos_blocks l1_ctxt blocks] prefetches the blocks - asynchronously. NOTE: the number of blocks to prefetch must not be greater - than the size of the blocks cache otherwise they will be lost. *) -val prefetch_tezos_blocks : t -> head list -> unit - -(**/**) - -module Internal_for_tests : sig - (** Create a dummy Layer 1 object that does not follow any L1 chain. This - function is only to be used as a placeholder for unit tests (that do not - exercise the Layer 1 connection). *) - val dummy : #Client_context.full -> t -end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store_version.mli b/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.ml similarity index 67% rename from src/proto_018_Proxford/lib_sc_rollup_node/store_version.mli rename to src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.ml index 1f2f8b4a26cc96d70357839ccee9be8f7a91acfb..8312c25843735023a287a1287b424eb69e6e2757 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store_version.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.ml @@ -1,6 +1,7 @@ (*****************************************************************************) (* *) (* Open Source License *) +(* Copyright (c) 2023 Nomadic Labs, *) (* Copyright (c) 2023 Functori, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) @@ -23,13 +24,31 @@ (* *) (*****************************************************************************) -type t = V0 | V1 | V2 +open Protocol_client_context -(** Pretty-printer for store versions *) -val pp : Format.formatter -> t -> unit +type Layer1.block += Block of Alpha_block_services.block_info -(** Read the version file from [dir]. *) -val read_version_file : dir:string -> t option tzresult Lwt.t +let fetch cctxt ?metadata ?chain ?block () = + let open Lwt_result_syntax in + let+ block = Alpha_block_services.info cctxt ?metadata ?chain ?block () in + Block block -(** Write a version to the version file in [dir]. *) -val write_version_file : dir:string -> t -> unit tzresult Lwt.t +let extract_header = function + | Block block -> block.header.shell + | _ -> + invalid_arg ("Internal error: Block is not of protocol " ^ Protocol.name) + +let fetch_tezos_block l1_ctxt hash = + let open Lwt_result_syntax in + let+ block = Layer1.fetch_tezos_block fetch extract_header l1_ctxt hash in + match block with + | Block block -> block + | _ -> + Format.kasprintf + invalid_arg + "Internal error: Block %a is not of protocol %s" + Block_hash.pp + hash + Protocol.name + +let prefetch_tezos_blocks = Layer1.prefetch_tezos_blocks fetch extract_header diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store.ml b/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.mli similarity index 74% rename from src/proto_018_Proxford/lib_sc_rollup_node/store.ml rename to src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.mli index f89bd6e8cfb551522c566991a8cede8bb4e94e69..3b6fc64abf0ad9e4548664e3a949b88e3e2551b2 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/layer1_helpers.mli @@ -1,7 +1,7 @@ (*****************************************************************************) (* *) (* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) +(* Copyright (c) 2023 Nomadic Labs, *) (* Copyright (c) 2023 Functori, *) (* *) (* Permission is hereby granted, free of charge, to any person obtaining a *) @@ -24,4 +24,17 @@ (* *) (*****************************************************************************) -include Store_v2 +open Octez_smart_rollup_node.Layer1 + +(** [fetch_tezos_block cctxt hash] returns a block info given a block hash. + Looks for the block in the blocks cache first, and fetches it from the L1 + node otherwise. *) +val fetch_tezos_block : + t -> + Block_hash.t -> + Protocol_client_context.Alpha_block_services.block_info tzresult Lwt.t + +(** [prefetch_tezos_blocks l1_ctxt blocks] prefetches the blocks + asynchronously. NOTE: the number of blocks to prefetch must not be greater + than the size of the blocks cache otherwise they will be lost. *) +val prefetch_tezos_blocks : t -> head list -> unit diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/node_context.ml b/src/proto_018_Proxford/lib_sc_rollup_node/node_context.ml index 2f5d3b6b141062b90f4ad12baf6d033683b08ebf..cf10bbfed4858b6f0b5636bd3098c95e932a2e11 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/node_context.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/node_context.ml @@ -464,7 +464,7 @@ let level_of_hash {l1_ctxt; store; _} hash = let open Lwt_result_syntax in let* l2_header = Store.L2_blocks.header store.l2_blocks hash in match l2_header with - | Some {level; _} -> return (Raw_level.to_int32 level) + | Some {level; _} -> return level | None -> let+ {level; _} = Layer1.fetch_tezos_shell_header l1_ctxt hash in level @@ -540,7 +540,7 @@ let get_l2_block_predecessor node_ctxt hash = let+ header = Store.L2_blocks.header node_ctxt.store.l2_blocks hash in Option.map (fun {Sc_rollup_block.predecessor; level; _} -> - (predecessor, Int32.pred (Raw_level.to_int32 level))) + (predecessor, Int32.pred level)) header let get_predecessor_opt node_ctxt (hash, level) = @@ -612,8 +612,8 @@ let get_predecessor_header node_ctxt head = first look for a block before the [tick] *) let tick_search ~big_step_blocks node_ctxt head tick = let open Lwt_result_syntax in - if Sc_rollup.Tick.(head.Sc_rollup_block.initial_tick <= tick) then - if Sc_rollup.Tick.(Sc_rollup_block.final_tick head < tick) then + if Z.Compare.(head.Sc_rollup_block.initial_tick <= tick) then + if Z.Compare.(Sc_rollup_block.final_tick head < tick) then (* The head block does not contain the tick *) return_none else @@ -623,20 +623,18 @@ let tick_search ~big_step_blocks node_ctxt head tick = let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in let rec find_big_step (end_block : Sc_rollup_block.t) = let start_level = - Int32.sub - (Raw_level.to_int32 end_block.header.level) - (Int32.of_int big_step_blocks) + Int32.sub end_block.header.level (Int32.of_int big_step_blocks) in let start_level = if start_level < genesis_level then genesis_level else start_level in let* start_block = get_l2_block_by_level node_ctxt start_level in - if Sc_rollup.Tick.(start_block.initial_tick <= tick) then + if Z.Compare.(start_block.initial_tick <= tick) then return (start_block, end_block) else find_big_step start_block in let block_level Sc_rollup_block.{header = {level; _}; _} = - Raw_level.to_int32 level |> Int32.to_int + Int32.to_int level in let rec dicho start_block end_block = (* Precondition: @@ -652,7 +650,7 @@ let tick_search ~big_step_blocks node_ctxt head tick = let* block_middle = get_l2_block_by_level node_ctxt (Int32.of_int middle_level) in - if Sc_rollup.Tick.(block_middle.initial_tick <= tick) then + if Z.Compare.(block_middle.initial_tick <= tick) then dicho block_middle end_block else dicho start_block block_middle in @@ -675,51 +673,80 @@ let block_with_tick ({store; _} as node_ctxt) ~max_level tick = the refutation period as the big_step_blocks to do a dichotomy on the full space but we anticipate refutation to happen most of the time close to the head. *) + let max_level = Raw_level.to_int32 max_level in let** head = - if Raw_level.(head.header.level <= max_level) then return_some head - else find_l2_block_by_level node_ctxt (Raw_level.to_int32 max_level) + if head.header.level <= max_level then return_some head + else find_l2_block_by_level node_ctxt max_level in - tick_search ~big_step_blocks:4096 node_ctxt head tick + tick_search ~big_step_blocks:4096 node_ctxt head (Sc_rollup.Tick.to_z tick) -let get_commitment {store; _} commitment_hash = +let find_octez_commitment {store; _} commitment_hash = let open Lwt_result_syntax in - let* commitment = Store.Commitments.read store.commitments commitment_hash in + let+ commitment = Store.Commitments.read store.commitments commitment_hash in + Option.map fst commitment + +let find_commitment node_ctxt commitment_hash = + let open Lwt_result_syntax in + let commitment_hash = + Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash + in + let+ commitment = find_octez_commitment node_ctxt commitment_hash in + Option.map Sc_rollup_proto_types.Commitment.of_octez commitment + +let get_octez_commitment node_ctxt commitment_hash = + let open Lwt_result_syntax in + let* commitment = find_octez_commitment node_ctxt commitment_hash in match commitment with | None -> failwith "Could not retrieve commitment %a" - Sc_rollup.Commitment.Hash.pp + Octez_smart_rollup.Commitment.Hash.pp commitment_hash - | Some (c, ()) -> return c + | Some i -> return i -let find_commitment {store; _} hash = +let get_commitment node_ctxt commitment_hash = let open Lwt_result_syntax in - let+ commitment = Store.Commitments.read store.commitments hash in - Option.map fst commitment + let* commitment = find_commitment node_ctxt commitment_hash in + match commitment with + | None -> + failwith + "Could not retrieve commitment %a" + Sc_rollup.Commitment.Hash.pp + commitment_hash + | Some i -> return i let commitment_exists {store; _} hash = + let hash = Sc_rollup_proto_types.Commitment_hash.to_octez hash in Store.Commitments.mem store.commitments hash let save_commitment {store; _} commitment = let open Lwt_result_syntax in - let hash = Sc_rollup.Commitment.hash_uncarbonated commitment in + let commitment = Sc_rollup_proto_types.Commitment.to_octez commitment in + let hash = Octez_smart_rollup.Commitment.hash commitment in let+ () = Store.Commitments.append store.commitments ~key:hash ~value:commitment in - hash + Sc_rollup_proto_types.Commitment_hash.of_octez hash let commitment_published_at_level {store; _} commitment = + let commitment = Sc_rollup_proto_types.Commitment_hash.to_octez commitment in Store.Commitments_published_at_level.find store.commitments_published_at_level commitment -let set_commitment_published_at_level {store; _} = - Store.Commitments_published_at_level.add store.commitments_published_at_level +let set_commitment_published_at_level {store; _} hash = + let hash = Sc_rollup_proto_types.Commitment_hash.to_octez hash in + Store.Commitments_published_at_level.add + store.commitments_published_at_level + hash type commitment_source = Anyone | Us let commitment_was_published {store; _} ~source commitment_hash = let open Lwt_result_syntax in + let commitment_hash = + Sc_rollup_proto_types.Commitment_hash.to_octez commitment_hash + in match source with | Anyone -> Store.Commitments_published_at_level.mem @@ -735,31 +762,52 @@ let commitment_was_published {store; _} ~source commitment_hash = | Some {published_at_level = Some _; _} -> true | _ -> false) -let get_inbox {store; _} inbox_hash = +let find_octez_inbox {store; _} inbox_hash = let open Lwt_result_syntax in - let* inbox = Store.Inboxes.read store.inboxes inbox_hash in + let+ inbox = Store.Inboxes.read store.inboxes inbox_hash in + Option.map fst inbox + +let find_inbox node_ctxt inbox_hash = + let open Lwt_result_syntax in + let inbox_hash = Sc_rollup_proto_types.Inbox_hash.to_octez inbox_hash in + let+ inbox = find_octez_inbox node_ctxt inbox_hash in + Option.map Sc_rollup_proto_types.Inbox.of_octez inbox + +let get_octez_inbox node_ctxt inbox_hash = + let open Lwt_result_syntax in + let* inbox = find_octez_inbox node_ctxt inbox_hash in match inbox with | None -> - failwith "Could not retrieve inbox %a" Sc_rollup.Inbox.Hash.pp inbox_hash - | Some (i, ()) -> return i + failwith + "Could not retrieve inbox %a" + Octez_smart_rollup.Inbox.Hash.pp + inbox_hash + | Some i -> return i -let find_inbox {store; _} hash = +let get_inbox node_ctxt inbox_hash = let open Lwt_result_syntax in - let+ inbox = Store.Inboxes.read store.inboxes hash in - Option.map fst inbox + let* inbox = find_inbox node_ctxt inbox_hash in + match inbox with + | None -> + failwith "Could not retrieve inbox %a" Sc_rollup.Inbox.Hash.pp inbox_hash + | Some i -> return i let save_inbox {store; _} inbox = let open Lwt_result_syntax in - let hash = Sc_rollup.Inbox.hash inbox in + let inbox = Sc_rollup_proto_types.Inbox.to_octez inbox in + let hash = Octez_smart_rollup.Inbox.hash inbox in let+ () = Store.Inboxes.append store.inboxes ~key:hash ~value:inbox in - hash + Sc_rollup_proto_types.Inbox_hash.of_octez hash let find_inbox_by_block_hash ({store; _} as node_ctxt) block_hash = let open Lwt_result_syntax in let* header = Store.L2_blocks.header store.l2_blocks block_hash in match header with | None -> return_none - | Some {inbox_hash; _} -> find_inbox node_ctxt inbox_hash + | Some {inbox_hash; _} -> + find_inbox + node_ctxt + (Sc_rollup_proto_types.Inbox_hash.of_octez inbox_hash) let genesis_inbox node_ctxt = let genesis_level = Raw_level.to_int32 node_ctxt.genesis_info.level in @@ -809,6 +857,9 @@ type messages_info = { let find_messages node_ctxt messages_hash = let open Lwt_result_syntax in + let messages_hash = + Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez messages_hash + in let* msg = Store.Messages.read node_ctxt.store.messages messages_hash in match msg with | None -> return_none @@ -821,6 +872,13 @@ let find_messages node_ctxt messages_hash = let is_first_block = pred_header.header.proto_level <> grand_parent_header.header.proto_level in + let*? messages = + Environment.wrap_tzresult + @@ List.map_e + (fun m -> + Sc_rollup.Inbox_message.(deserialize @@ unsafe_of_string m)) + messages + in return_some { is_first_block; @@ -829,18 +887,22 @@ let find_messages node_ctxt messages_hash = messages; } -let get_messages_aux find node_ctxt hash = +let get_messages_aux find pp node_ctxt hash = let open Lwt_result_syntax in let* res = find node_ctxt hash in match res with | None -> failwith "Could not retrieve messages with payloads merkelized hash %a" - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.pp + pp hash | Some res -> return res -let get_messages node_ctxt = get_messages_aux find_messages node_ctxt +let get_messages node_ctxt = + get_messages_aux + find_messages + Sc_rollup.Inbox_merkelized_payload_hashes.Hash.pp + node_ctxt let get_messages_without_proto_messages node_ctxt = get_messages_aux @@ -850,30 +912,44 @@ let get_messages_without_proto_messages node_ctxt = match msg with | None -> return_none | Some (messages, _block_hash) -> return_some messages) + Tezos_crypto.Hashed.Smart_rollup_merkelized_payload_hashes_hash.pp node_ctxt let get_num_messages {store; _} hash = let open Lwt_result_syntax in + let hash = + Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez hash + in let* msg = Store.Messages.read store.messages hash in match msg with | None -> failwith "Could not retrieve number of messages for inbox witness %a" - Sc_rollup.Inbox_merkelized_payload_hashes.Hash.pp + Tezos_crypto.Hashed.Smart_rollup_merkelized_payload_hashes_hash.pp hash | Some (messages, _block_hash) -> return (List.length messages) let save_messages {store; _} key ~block_hash messages = - Store.Messages.append store.messages ~key ~header:block_hash ~value:messages + let open Lwt_result_syntax in + let key = Sc_rollup_proto_types.Merkelized_payload_hashes_hash.to_octez key in + let*? messages = + Environment.wrap_tzresult + @@ List.map_e Sc_rollup.Inbox_message.serialize messages + in + Store.Messages.append + store.messages + ~key + ~header:block_hash + ~value:(messages :> string list) let get_full_l2_block node_ctxt block_hash = let open Lwt_result_syntax in let* block = get_l2_block node_ctxt block_hash in - let* inbox = get_inbox node_ctxt block.header.inbox_hash + let* inbox = get_octez_inbox node_ctxt block.header.inbox_hash and* messages = get_messages_without_proto_messages node_ctxt block.header.inbox_witness and* commitment = - Option.map_es (get_commitment node_ctxt) block.header.commitment_hash + Option.map_es (get_octez_commitment node_ctxt) block.header.commitment_hash in return {block with content = {Sc_rollup_block.inbox; messages; commitment}} @@ -1032,58 +1108,91 @@ let get_slot_header {store; _} ~published_in_block_hash slot_index = slot_index Block_hash.pp published_in_block_hash - @@ Store.Dal_slots_headers.get - store.irmin_store - ~primary_key:published_in_block_hash - ~secondary_key:slot_index + @@ + let open Lwt_result_syntax in + let+ header = + Store.Dal_slots_headers.get + store.irmin_store + ~primary_key:published_in_block_hash + ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) + in + Sc_rollup_proto_types.Dal.Slot_header.of_octez header let get_all_slot_headers {store; _} ~published_in_block_hash = - Store.Dal_slots_headers.list_values - store.irmin_store - ~primary_key:published_in_block_hash + let open Lwt_result_syntax in + let+ headers = + Store.Dal_slots_headers.list_values + store.irmin_store + ~primary_key:published_in_block_hash + in + List.rev_map Sc_rollup_proto_types.Dal.Slot_header.of_octez headers + |> List.rev let get_slot_indexes {store; _} ~published_in_block_hash = - Store.Dal_slots_headers.list_secondary_keys - store.irmin_store - ~primary_key:published_in_block_hash + let open Lwt_result_syntax in + let+ indexes = + Store.Dal_slots_headers.list_secondary_keys + store.irmin_store + ~primary_key:published_in_block_hash + in + List.rev_map Sc_rollup_proto_types.Dal.Slot_index.of_octez indexes |> List.rev let save_slot_header {store; _} ~published_in_block_hash (slot_header : Dal.Slot.Header.t) = Store.Dal_slots_headers.add store.irmin_store ~primary_key:published_in_block_hash - ~secondary_key:slot_header.id.index - slot_header + ~secondary_key: + (Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_header.id.index) + (Sc_rollup_proto_types.Dal.Slot_header.to_octez slot_header) let find_slot_status {store; _} ~confirmed_in_block_hash slot_index = Store.Dal_slots_statuses.find store.irmin_store ~primary_key:confirmed_in_block_hash - ~secondary_key:slot_index + ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) let list_slots_statuses {store; _} ~confirmed_in_block_hash = - Store.Dal_slots_statuses.list_secondary_keys_with_values - store.irmin_store - ~primary_key:confirmed_in_block_hash + let open Lwt_result_syntax in + let+ statuses = + Store.Dal_slots_statuses.list_secondary_keys_with_values + store.irmin_store + ~primary_key:confirmed_in_block_hash + in + List.rev_map + (fun (index, status) -> + (Sc_rollup_proto_types.Dal.Slot_index.of_octez index, status)) + statuses + |> List.rev let save_slot_status {store; _} current_block_hash slot_index status = Store.Dal_slots_statuses.add store.irmin_store ~primary_key:current_block_hash - ~secondary_key:slot_index + ~secondary_key:(Sc_rollup_proto_types.Dal.Slot_index.to_octez slot_index) status -let find_confirmed_slots_history {store; _} = - Store.Dal_confirmed_slots_history.find store.irmin_store +let find_confirmed_slots_history {store; _} block = + let open Lwt_result_syntax in + let+ res = Store.Dal_confirmed_slots_history.find store.irmin_store block in + Option.map Sc_rollup_proto_types.Dal.Slot_history.of_octez res -let save_confirmed_slots_history {store; _} = - Store.Dal_confirmed_slots_history.add store.irmin_store +let save_confirmed_slots_history {store; _} block hist = + Store.Dal_confirmed_slots_history.add + store.irmin_store + block + (Sc_rollup_proto_types.Dal.Slot_history.to_octez hist) -let find_confirmed_slots_histories {store; _} = - Store.Dal_confirmed_slots_histories.find store.irmin_store +let find_confirmed_slots_histories {store; _} block = + let open Lwt_result_syntax in + let+ res = Store.Dal_confirmed_slots_histories.find store.irmin_store block in + Option.map Sc_rollup_proto_types.Dal.Slot_history_cache.of_octez res -let save_confirmed_slots_histories {store; _} = - Store.Dal_confirmed_slots_histories.add store.irmin_store +let save_confirmed_slots_histories {store; _} block hist = + Store.Dal_confirmed_slots_histories.add + store.irmin_store + block + (Sc_rollup_proto_types.Dal.Slot_history_cache.to_octez hist) module Internal_for_tests = struct let create_node_context cctxt diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/publisher.ml b/src/proto_018_Proxford/lib_sc_rollup_node/publisher.ml index f7b0cc4b168f8770073e60cf4870cb03520ca3e9..d2ad6afc0248e57c179dcd3b1188b1401b246de5 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/publisher.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/publisher.ml @@ -110,9 +110,9 @@ let build_commitment (node_ctxt : _ Node_context.t) let*! compressed_state = PVM.state_hash pvm_state in let*! tick = PVM.get_tick pvm_state in let* prev_commitment_tick = tick_of_level node_ctxt prev_commitment_level in + let distance = Z.sub (Sc_rollup.Tick.to_z tick) prev_commitment_tick in let number_of_ticks = - Sc_rollup.Tick.distance tick prev_commitment_tick - |> Z.to_int64 |> Sc_rollup.Number_of_ticks.of_value + distance |> Z.to_int64 |> Sc_rollup.Number_of_ticks.of_value in let*? number_of_ticks = match number_of_ticks with @@ -177,6 +177,7 @@ let create_commitment_if_necessary (node_ctxt : _ Node_context.t) ~predecessor let* last_commitment_hash = let+ pred = Node_context.get_l2_block node_ctxt predecessor in Sc_rollup_block.most_recent_commitment pred.header + |> Sc_rollup_proto_types.Commitment_hash.of_octez in let* last_commitment = Node_context.get_commitment node_ctxt last_commitment_hash @@ -221,9 +222,7 @@ let missing_commitments (node_ctxt : _ Node_context.t) = in let* head = Node_context.last_processed_head_opt node_ctxt in let next_head_level = - Option.map - (fun (b : Sc_rollup_block.t) -> Raw_level.succ b.header.level) - head + Option.map (fun (b : Sc_rollup_block.t) -> Int32.succ b.header.level) head in let sc_rollup_challenge_window_int32 = sc_rollup_challenge_window node_ctxt |> Int32.of_int @@ -249,7 +248,7 @@ let missing_commitments (node_ctxt : _ Node_context.t) = match (published_info, next_head_level) with | None, _ | _, None -> false | Some {first_published_at_level; _}, Some next_head_level -> - Raw_level.diff next_head_level first_published_at_level + Int32.sub next_head_level first_published_at_level > sc_rollup_challenge_window_int32 in let acc = if past_curfew then acc else commitment :: acc in @@ -264,6 +263,7 @@ let missing_commitments (node_ctxt : _ Node_context.t) = commitments that are missing. *) let commitment = Sc_rollup_block.most_recent_commitment finalized.header + |> Sc_rollup_proto_types.Commitment_hash.of_octez in gather [] commitment @@ -271,7 +271,11 @@ let publish_commitment (node_ctxt : _ Node_context.t) ~source (commitment : Sc_rollup.Commitment.t) = let open Lwt_result_syntax in let publish_operation = - L1_operation.Publish {rollup = node_ctxt.rollup_address; commitment} + L1_operation.Publish + { + rollup = node_ctxt.rollup_address; + commitment = Sc_rollup_proto_types.Commitment.to_octez commitment; + } in let*! () = Commitment_event.publish_commitment @@ -316,7 +320,9 @@ let earliest_cementing_level node_ctxt commitment_hash = Node_context.commitment_published_at_level node_ctxt commitment_hash in return_some - @@ add_level first_published_at_level (sc_rollup_challenge_window node_ctxt) + @@ Int32.add + first_published_at_level + (sc_rollup_challenge_window node_ctxt |> Int32.of_int) (** [latest_cementable_commitment node_ctxt head] is the most recent commitment hash that could be cemented in [head]'s successor if: @@ -329,7 +335,10 @@ let earliest_cementing_level node_ctxt commitment_hash = let latest_cementable_commitment (node_ctxt : _ Node_context.t) (head : Sc_rollup_block.t) = let open Lwt_result_option_syntax in - let commitment_hash = Sc_rollup_block.most_recent_commitment head.header in + let commitment_hash = + Sc_rollup_block.most_recent_commitment head.header + |> Sc_rollup_proto_types.Commitment_hash.of_octez + in let** commitment = Node_context.find_commitment node_ctxt commitment_hash in let** cementable_level_bound = return @@ -345,6 +354,7 @@ let latest_cementable_commitment (node_ctxt : _ Node_context.t) in let cementable_commitment = Sc_rollup_block.most_recent_commitment cementable_bound_block.header + |> Sc_rollup_proto_types.Commitment_hash.of_octez in return_some cementable_commitment @@ -370,7 +380,7 @@ let cementable_commitments (node_ctxt : _ Node_context.t) = match earliest_cementing_level with | None -> acc | Some earliest_cementing_level -> - if Raw_level.(earliest_cementing_level > head_level) then + if earliest_cementing_level > head_level then (* Commitments whose cementing level are after the head's successor won't be cementable in the next block. *) acc @@ -400,10 +410,11 @@ let cementable_commitments (node_ctxt : _ Node_context.t) = in if green_light then return cementable else return_nil -let cement_commitment (node_ctxt : _ Node_context.t) ~source = +let cement_commitment (node_ctxt : _ Node_context.t) ~source commitment = let open Lwt_result_syntax in + let commitment = Sc_rollup_proto_types.Commitment_hash.to_octez commitment in let cement_operation = - L1_operation.Cement {rollup = node_ctxt.rollup_address} + L1_operation.Cement {rollup = node_ctxt.rollup_address; commitment} in let* _hash = Injector.add_pending_operation ~source cement_operation in return_unit @@ -417,9 +428,7 @@ let on_cement_commitments (node_ctxt : state) = return_unit | Some source -> let* cementable_commitments = cementable_commitments node_ctxt in - List.iter_es - (fun _cementable_commitment -> cement_commitment node_ctxt ~source) - cementable_commitments + List.iter_es (cement_commitment node_ctxt ~source) cementable_commitments module Types = struct type nonrec state = state diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game.ml b/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game.ml index da0ffe65803214ee11ee4ad8667009b8ad17432e..fdd814a08990b1e95b996d53b7f16621d84c9198 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/refutation_game.ml @@ -70,7 +70,11 @@ let inject_next_move node_ctxt source ~refutation ~opponent = let open Lwt_result_syntax in let refute_operation = L1_operation.Refute - {rollup = node_ctxt.Node_context.rollup_address; refutation; opponent} + { + rollup = node_ctxt.Node_context.rollup_address; + refutation = Sc_rollup_proto_types.Game.refutation_to_octez refutation; + opponent; + } in let* _hash = Injector.add_pending_operation ~source refute_operation in return_unit @@ -448,7 +452,11 @@ let play_next_move node_ctxt game self opponent = let play_timeout (node_ctxt : _ Node_context.t) self stakers = let open Lwt_result_syntax in let timeout_operation = - L1_operation.Timeout {rollup = node_ctxt.rollup_address; stakers} + L1_operation.Timeout + { + rollup = node_ctxt.rollup_address; + stakers = Sc_rollup_proto_types.Game.index_to_octez stakers; + } in let source = Node_context.get_operator node_ctxt Timeout |> Option.value ~default:self diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/injector.ml b/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_injector.ml similarity index 76% rename from src/proto_018_Proxford/lib_sc_rollup_node/injector.ml rename to src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_injector.ml index 9f128729bb9ffd30a6d0592f6d85499eaed8d140..15950e96c941fa9fb87e7dcbe77d5a56ee7f3651 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/injector.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_injector.ml @@ -31,103 +31,59 @@ module Block_cache = Aches_lwt.Lache.Make_result (Aches.Rache.Transfer (Aches.Rache.LRU) (Block_hash)) -module Parameters : - PARAMETERS - with type state = Node_context.ro - and type Tag.t = Configuration.purpose - and type Operation.t = L1_operation.t = struct - type state = Node_context.ro - - let events_section = [Protocol.name; "sc_rollup_node"] - - module Tag : TAG with type t = Configuration.purpose = struct - type t = Configuration.purpose - - let compare = Stdlib.compare - - let equal = Stdlib.( = ) - - let hash = Hashtbl.hash - - let string_of_tag = Configuration.string_of_purpose - - let pp ppf t = Format.pp_print_string ppf (string_of_tag t) - - let encoding : t Data_encoding.t = - let open Data_encoding in - string_enum - (List.map (fun t -> (string_of_tag t, t)) Configuration.purposes) - end - - module Operation = L1_operation - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3459 - Very coarse approximation for the number of operation we - expect for each block *) - let table_estimated_size : Tag.t -> int = function - | Publish -> 1 - | Add_messages -> 100 - | Cement -> 1 - | Timeout -> 1 - | Refute -> 1 - - let operation_tag : Operation.t -> Tag.t = function - | Add_messages _ -> Add_messages - | Cement _ -> Cement - | Publish _ -> Publish - | Timeout _ -> Timeout - | Refute _ -> Refute - - let fee_parameter node_ctxt operation = - Node_context.get_fee_parameter node_ctxt (operation_tag operation) - - (* TODO: https://gitlab.com/tezos/tezos/-/issues/3459 - Decide if some batches must have all the operations succeed. See - {!Injector_sigs.Parameter.batch_must_succeed}. *) - let batch_must_succeed _ = `At_least_one - - let retry_unsuccessful_operation _node_ctxt (_op : Operation.t) status = - let open Lwt_syntax in - match status with - | Backtracked | Skipped | Other_branch -> - (* Always retry backtracked or skipped operations, or operations that - are on another branch because of a reorg: - - - Commitments are always produced on finalized blocks. They don't - need to be recomputed, and as such are valid in another branch. - - - The cementation operations should be re-injected because the node - only keeps track of the last cemented level and the last published - commitment, without rollbacks. - - - Messages posted to an inbox should be re-emitted (i.e. re-queued) - in case of a fork. - - - Timeout should be re-submitted as the timeout may be reached as well - on the other branch. - - - Refutation should be re-submitted in case of fork. - TODO: https://gitlab.com/tezos/tezos/-/issues/3459 - maybe check if game exists on other branch as well. - *) - return Retry - | Failed error -> ( - (* TODO: https://gitlab.com/tezos/tezos/-/issues/4071 - Think about which operations should be retried and when. *) - match classify_trace error with - | Permanent | Outdated -> return Forget - | Branch | Temporary -> return Retry) - | Never_included -> - (* Forget operations that are never included *) - return Forget -end +let injector_operation_to_manager : + L1_operation.t -> Protocol.Alpha_context.packed_manager_operation = function + | Add_messages {messages} -> Manager (Sc_rollup_add_messages {messages}) + | Cement {rollup; commitment = _} -> + let rollup = Sc_rollup_proto_types.Address.of_octez rollup in + Manager (Sc_rollup_cement {rollup}) + | Publish {rollup; commitment} -> + let rollup = Sc_rollup_proto_types.Address.of_octez rollup in + let commitment = Sc_rollup_proto_types.Commitment.of_octez commitment in + Manager (Sc_rollup_publish {rollup; commitment}) + | Refute {rollup; opponent; refutation} -> + let rollup = Sc_rollup_proto_types.Address.of_octez rollup in + let refutation = + Sc_rollup_proto_types.Game.refutation_of_octez refutation + in + Manager (Sc_rollup_refute {rollup; opponent; refutation}) + | Timeout {rollup; stakers} -> + let rollup = Sc_rollup_proto_types.Address.of_octez rollup in + let stakers = Sc_rollup_proto_types.Game.index_of_octez stakers in + Manager (Sc_rollup_timeout {rollup; stakers}) + +let injector_operation_of_manager : + type kind. + kind Protocol.Alpha_context.manager_operation -> L1_operation.t option = + function + | Sc_rollup_add_messages {messages} -> Some (Add_messages {messages}) + | Sc_rollup_cement {rollup} -> + let rollup = Sc_rollup_proto_types.Address.to_octez rollup in + let commitment = Octez_smart_rollup.Commitment.Hash.zero in + (* Just for printing *) + Some (Cement {rollup; commitment}) + | Sc_rollup_publish {rollup; commitment} -> + let rollup = Sc_rollup_proto_types.Address.to_octez rollup in + let commitment = Sc_rollup_proto_types.Commitment.to_octez commitment in + Some (Publish {rollup; commitment}) + | Sc_rollup_refute {rollup; opponent; refutation} -> + let rollup = Sc_rollup_proto_types.Address.to_octez rollup in + let refutation = + Sc_rollup_proto_types.Game.refutation_to_octez refutation + in + Some (Refute {rollup; opponent; refutation}) + | Sc_rollup_timeout {rollup; stakers} -> + let rollup = Sc_rollup_proto_types.Address.to_octez rollup in + let stakers = Sc_rollup_proto_types.Game.index_to_octez stakers in + Some (Timeout {rollup; stakers}) + | _ -> None module Proto_client = struct open Protocol_client_context - type operation = Parameters.Operation.t + type operation = L1_operation.t - type state = Parameters.state + type state = Injector.state type unsigned_operation = Tezos_base.Operation.shell_header * packed_contents_list @@ -153,7 +109,7 @@ module Proto_client = struct (Contents contents) let operation_size op = - manager_operation_size (L1_operation.to_manager_operation op) + manager_operation_size (injector_operation_to_manager op) (* The operation size overhead is an upper bound (in practice) of the overhead that will be added to a manager operation. To compute it we can use any @@ -261,10 +217,9 @@ module Proto_client = struct operations) Lwt.return - let operation_status (node_ctxt : Node_context.ro) block_hash operation_hash - ~index = + let operation_status {Injector.cctxt; _} block_hash operation_hash ~index = let open Lwt_result_syntax in - let* operations = get_block_operations node_ctxt.cctxt block_hash in + let* operations = get_block_operations cctxt block_hash in match Operation_hash.Map.find_opt operation_hash operations with | None -> return_none | Some operation -> ( @@ -302,9 +257,7 @@ module Proto_client = struct let annotated_operations = List.map (fun operation -> - let (Manager operation) = - L1_operation.to_manager_operation operation - in + let (Manager operation) = injector_operation_to_manager operation in Annotated_manager_operation (Injection.prepare_manager_operation ~fee:Limit.unknown @@ -403,18 +356,17 @@ module Proto_client = struct Operation.encoding_with_legacy_attestation_name op - let time_until_next_block (node_ctxt : Node_context.ro) + let time_until_next_block + {Injector.minimal_block_delay; delay_increment_per_round; _} (header : Tezos_base.Block_header.shell_header option) = let open Result_syntax in - let Constants.Parametric.{minimal_block_delay; delay_increment_per_round; _} - = - node_ctxt.protocol_constants.Constants.parametric - in match header with - | None -> - minimal_block_delay |> Period.to_seconds |> Int64.to_int - |> Ptime.Span.of_int_s + | None -> minimal_block_delay |> Int64.to_int |> Ptime.Span.of_int_s | Some header -> + let minimal_block_delay = Period.of_seconds_exn minimal_block_delay in + let delay_increment_per_round = + Period.of_seconds_exn delay_increment_per_round + in let next_level_timestamp = let* durations = Round.Durations.create @@ -441,6 +393,4 @@ module Proto_client = struct (Time.System.now ()) end -include Injector_functor.Make (Parameters) - -let () = register_proto_client Protocol.hash (module Proto_client) +let () = Injector.register_proto_client Protocol.hash (module Proto_client) diff --git a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_context_hash.mli b/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_injector.mli similarity index 85% rename from src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_context_hash.mli rename to src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_injector.mli index d7acec7ff0ea7c661607780ead88138dc5f2de91..ca4112313ef6449d4ec20d700049ae0d28263944 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_layer2/sc_rollup_context_hash.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_injector.mli @@ -23,4 +23,10 @@ (* *) (*****************************************************************************) -include Tezos_crypto.Intfs.HASH +(** Manager operation for a given L1 operation. *) +val injector_operation_to_manager : + L1_operation.t -> Protocol.Alpha_context.packed_manager_operation + +(** L1 operation corresponding to a manager operation if any. *) +val injector_operation_of_manager : + 'a Protocol.Alpha_context.manager_operation -> L1_operation.t option diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_node_errors.ml b/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_node_errors.ml index 6f88c4fb3f80c919a8955b1cef30b1d131a106a4..2949749abd34e12b06f4322e5f4299a3a402720c 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_node_errors.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/sc_rollup_node_errors.ml @@ -46,12 +46,8 @@ type error += layer1_inbox : Sc_rollup.Inbox.t; inbox : Sc_rollup.Inbox.t; } - | Unexpected_rollup of { - rollup_address : Sc_rollup.Address.t; - saved_address : Sc_rollup.Address.t; - } | Missing_PVM_state of Block_hash.t * Int32.t - | Cannot_checkout_context of Block_hash.t * Sc_rollup_context_hash.t option + | Cannot_checkout_context of Block_hash.t * Smart_rollup_context_hash.t option | No_batcher | No_publisher | Refutation_player_failed_to_start @@ -192,31 +188,6 @@ let () = | _ -> None) (fun (layer1_inbox, inbox) -> Inconsistent_inbox {layer1_inbox; inbox}) ; - register_error_kind - ~id:"sc_rollup.node.unexpected_rollup" - ~title:"Unexpected rollup for rollup node" - ~description:"This rollup node is already set up for another rollup." - ~pp:(fun ppf (rollup_address, saved_address) -> - Format.fprintf - ppf - "This rollup node was already set up for rollup %a, it cannot be run \ - for a different rollup %a." - Sc_rollup.Address.pp - saved_address - Sc_rollup.Address.pp - rollup_address) - `Permanent - Data_encoding.( - obj2 - (req "rollup_address" Sc_rollup.Address.encoding) - (req "saved_address" Sc_rollup.Address.encoding)) - (function - | Unexpected_rollup {rollup_address; saved_address} -> - Some (rollup_address, saved_address) - | _ -> None) - (fun (rollup_address, saved_address) -> - Unexpected_rollup {rollup_address; saved_address}) ; - register_error_kind `Permanent ~id:"internal.missing_pvm_state" @@ -246,14 +217,14 @@ let () = "The context %sfor block %a cannot be checkouted" (Option.fold ~none:"" - ~some:Sc_rollup_context_hash.to_b58check + ~some:Smart_rollup_context_hash.to_b58check context_hash) Block_hash.pp block) Data_encoding.( obj2 (req "block" Block_hash.encoding) - (opt "context" Sc_rollup_context_hash.encoding)) + (opt "context" Smart_rollup_context_hash.encoding)) (function | Cannot_checkout_context (block, context) -> Some (block, context) | _ -> None) diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/simulation.ml b/src/proto_018_Proxford/lib_sc_rollup_node/simulation.ml index b7177b4885ef847f1d83a7ec2afa082082d82a42..a13a580a5e13fc4b64f146066ec77d784688b77b 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/simulation.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/simulation.ml @@ -46,7 +46,9 @@ type t = { let simulate_info_per_level (node_ctxt : [`Read] Node_context.t) predecessor = let open Lwt_result_syntax in - let* block_info = Layer1.fetch_tezos_block node_ctxt.l1_ctxt predecessor in + let* block_info = + Layer1_helpers.fetch_tezos_block node_ctxt.l1_ctxt predecessor + in let predecessor_timestamp = block_info.header.shell.timestamp in return {predecessor_timestamp; predecessor} diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store_migration.ml b/src/proto_018_Proxford/lib_sc_rollup_node/store_migration.ml deleted file mode 100644 index a10d8043c46d84973ed7fea31701575d8fea9876..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store_migration.ml +++ /dev/null @@ -1,438 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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 Store_version - -type version_result = Version_known | Unintialized_version - -let messages_store_location ~storage_dir = - let open Filename.Infix in - storage_dir // "messages" - -let version_of_unversioned_store ~storage_dir = - let open Lwt_syntax in - let path = messages_store_location ~storage_dir in - let* messages_store_v0 = Store_v0.Messages.load ~path ~cache_size:1 Read_only - and* messages_store_v1 = - Store_v1.Messages.load ~path ~cache_size:1 Read_only - in - let cleanup () = - let open Lwt_syntax in - let* (_ : unit tzresult) = - match messages_store_v0 with - | Error _ -> Lwt.return_ok () - | Ok s -> Store_v0.Messages.close s - and* (_ : unit tzresult) = - match messages_store_v1 with - | Error _ -> Lwt.return_ok () - | Ok s -> Store_v1.Messages.close s - in - return_unit - in - let guess_version () = - let open Lwt_result_syntax in - match (messages_store_v0, messages_store_v1) with - | Ok _, Error _ -> return_some V0 - | Error _, Ok _ -> return_some V1 - | Ok _, Ok _ -> - (* Empty store, both loads succeed *) - return_none - | Error _, Error _ -> - failwith - "Cannot determine unversioned store version (no messages decodable)" - in - Lwt.finalize guess_version cleanup - -let version_of_store ~storage_dir = - let open Lwt_result_syntax in - let* version = Store_version.read_version_file ~dir:storage_dir in - match version with - | Some v -> return_some (v, Version_known) - | None -> - let+ v = version_of_unversioned_store ~storage_dir in - Option.map (fun v -> (v, Unintialized_version)) v - -module type MIGRATION_ACTIONS = sig - type from_store - - type dest_store - - val migrate_block_action : - from_store -> dest_store -> Sc_rollup_block.t -> unit tzresult Lwt.t - - val final_actions : - storage_dir:string -> - tmp_dir:string -> - from_store -> - dest_store -> - unit tzresult Lwt.t -end - -module type S = sig - val migrate : storage_dir:string -> unit tzresult Lwt.t -end - -let migrations = Stdlib.Hashtbl.create 7 - -module Make - (S_from : Store_sig.S) - (S_dest : Store_sig.S) - (Actions : MIGRATION_ACTIONS - with type from_store := Store_sigs.ro S_from.t - and type dest_store := Store_sigs.rw S_dest.t) : S = struct - let tmp_dir ~storage_dir = - Filename.concat (Configuration.default_storage_dir storage_dir) - @@ Format.asprintf - "migration_%a_%a" - Store_version.pp - S_from.version - Store_version.pp - S_dest.version - - let migrate ~storage_dir = - let open Lwt_result_syntax in - let* source_store = - S_from.load Read_only ~l2_blocks_cache_size:1 storage_dir - in - let tmp_dir = tmp_dir ~storage_dir in - let*! tmp_dir_exists = Lwt_utils_unix.dir_exists tmp_dir in - let*? () = - if tmp_dir_exists then - error_with - "Store migration (from %a to %a) is already ongoing. Wait for it to \ - finish or remove %S and restart." - Store_version.pp - S_from.version - Store_version.pp - S_dest.version - tmp_dir - else Ok () - in - let*! () = Lwt_utils_unix.create_dir tmp_dir in - let* dest_store = S_dest.load Read_write ~l2_blocks_cache_size:1 tmp_dir in - let cleanup () = - let open Lwt_syntax in - let* (_ : unit tzresult) = S_from.close source_store - and* (_ : unit tzresult) = S_dest.close dest_store in - (* Don't remove migration dir to allow for later resume. *) - return_unit - in - let run_migration () = - let* () = - S_from.iter_l2_blocks - source_store - (Actions.migrate_block_action source_store dest_store) - in - let* () = - Actions.final_actions ~storage_dir ~tmp_dir source_store dest_store - in - let*! () = Lwt_utils_unix.remove_dir tmp_dir in - Store_version.write_version_file ~dir:storage_dir S_dest.version - in - Lwt.finalize run_migration cleanup - - let () = Stdlib.Hashtbl.add migrations S_from.version (S_dest.version, migrate) -end - -let migration_path ~from ~dest = - let rec path acc from dest = - if from = dest then Some (List.rev acc) - else - let first_steps = - Stdlib.Hashtbl.find_all migrations from - |> List.stable_sort (fun (va, _) (vb, _) -> - (* Try biggest jumps first that don't go beyond the - destination *) - if va > dest && vb > dest then Stdlib.compare va vb - else if va > dest then 1 - else if vb > dest then -1 - else Stdlib.compare vb va) - in - (* Recursively look for migration sub-paths *) - let paths = - List.filter_map - (fun (step, migration) -> - path ((from, step, migration) :: acc) step dest) - first_steps - in - (* Choose shortest migration path *) - List.stable_sort List.compare_lengths paths |> List.hd - in - path [] from dest - -let maybe_run_migration ~storage_dir = - let open Lwt_result_syntax in - let* current_version = version_of_store ~storage_dir in - let last_version = Store.version in - match (current_version, last_version) with - | None, _ -> - (* Store not initialized, write last version *) - Store_version.write_version_file ~dir:storage_dir last_version - | Some (current, versioned), last when last = current -> ( - match versioned with - | Unintialized_version -> - Store_version.write_version_file ~dir:storage_dir last_version - | Version_known -> - (* Up to date, nothing to do *) - return_unit) - | Some (current, _), last -> ( - let migrations = migration_path ~from:current ~dest:last in - match migrations with - | None -> - failwith - "Store version %a is not supported by this rollup node because \ - there is no migration path from it to %a." - Store_version.pp - current - Store_version.pp - last - | Some migrations -> - Format.printf "Starting store migration@." ; - let+ () = - List.iter_es - (fun (vx, vy, migrate) -> - Format.printf - "- Migrating store from %a to %a@." - Store_version.pp - vx - Store_version.pp - vy ; - migrate ~storage_dir) - migrations - in - Format.printf "Store migration completed@.") - -module V1_migrations = struct - let convert_store_messages - (messages, (block_hash, timestamp, number_of_messages)) = - ( messages, - (false (* is migration block *), block_hash, timestamp, number_of_messages) - ) - - let migrate_messages (v0_store : _ Store_v0.t) (v1_store : _ Store_v1.t) - (l2_block : Sc_rollup_block.t) = - let open Lwt_result_syntax in - let* v0_messages = - Store_v0.Messages.read v0_store.messages l2_block.header.inbox_witness - in - match v0_messages with - | None -> return_unit - | Some v0_messages -> - let value, header = convert_store_messages v0_messages in - Store_v1.Messages.append - v1_store.messages - ~key:l2_block.header.inbox_witness - ~header - ~value - - (* In place migration of processed slots under new key name by hand *) - let migrate_dal_processed_slots_irmin (v1_store : _ Store_v1.t) = - let open Lwt_syntax in - let open Store_v1 in - let info () = - let date = - Tezos_base.Time.( - System.now () |> System.to_protocol |> Protocol.to_seconds) - in - let author = - Format.asprintf - "Rollup node %a" - Tezos_version_parser.pp - Tezos_version_value.Current_git_info.version - in - let message = "Migration store from v0 to v1" in - Irmin_store.Raw_irmin.Info.v ~author ~message date - in - let store = Irmin_store.Raw_irmin.unsafe v1_store.irmin_store in - let old_root = Store_v0.Dal_processed_slots.path in - let new_root = Dal_slots_statuses.path in - let* old_tree = Irmin_store.Raw_irmin.find_tree store old_root in - match old_tree with - | None -> return_unit - | Some _ -> - (* Move the tree in the new key *) - Irmin_store.Raw_irmin.with_tree_exn - ~info - store - new_root - (fun _new_tree -> return old_tree) - - let final_actions ~storage_dir ~tmp_dir (_v0_store : _ Store_v0.t) - (v1_store : _ Store_v1.t) = - let open Lwt_result_syntax in - let*! () = - Lwt_utils_unix.remove_dir (messages_store_location ~storage_dir) - in - let*! () = - Lwt_unix.rename - (messages_store_location ~storage_dir:tmp_dir) - (messages_store_location ~storage_dir) - in - let*! () = migrate_dal_processed_slots_irmin v1_store in - return_unit - - module From_v0 = - Make (Store_v0) (Store_v1) - (struct - let migrate_block_action = migrate_messages - - let final_actions = final_actions - end) -end - -module V2_migrations = struct - let messages_store_location ~storage_dir = - let open Filename.Infix in - storage_dir // "messages" - - let commitments_store_location ~storage_dir = - let open Filename.Infix in - storage_dir // "commitments" - - let inboxes_store_location ~storage_dir = - let open Filename.Infix in - storage_dir // "inboxes" - - let migrate_messages read_messages (v2_store : _ Store_v2.t) - (l2_block : Sc_rollup_block.t) = - let open Lwt_result_syntax in - let* v1_messages = read_messages l2_block.header.inbox_witness in - match v1_messages with - | None -> return_unit - | Some (messages, _v1_header) -> - let header = l2_block.header.block_hash in - Store_v2.Messages.append - v2_store.messages - ~key:l2_block.header.inbox_witness - ~header - ~value:messages - - let migrate_commitment read_commitment (v2_store : _ Store_v2.t) - (l2_block : Sc_rollup_block.t) = - let open Lwt_result_syntax in - match l2_block.header.commitment_hash with - | None -> return_unit - | Some commitment_hash -> ( - let* v1_commitment = read_commitment commitment_hash in - match v1_commitment with - | None -> return_unit - | Some commitment -> - Store_v2.Commitments.append - v2_store.commitments - ~key:commitment_hash - ~value:commitment) - - let migrate_inbox read_inbox (v2_store : _ Store_v2.t) - (l2_block : Sc_rollup_block.t) = - let open Lwt_result_syntax in - let* v1_inbox = read_inbox l2_block.header.inbox_hash in - match v1_inbox with - | None -> return_unit - | Some (inbox, ()) -> - Store_v2.Inboxes.append - v2_store.inboxes - ~key:l2_block.header.inbox_hash - ~value:inbox - - let final_actions ~storage_dir ~tmp_dir _ _ = - let open Lwt_result_syntax in - let*! () = - Lwt_utils_unix.remove_dir (messages_store_location ~storage_dir) - in - let*! () = - Lwt_utils_unix.remove_dir (commitments_store_location ~storage_dir) - in - let*! () = - Lwt_utils_unix.remove_dir (inboxes_store_location ~storage_dir) - in - let*! () = - Lwt_unix.rename - (messages_store_location ~storage_dir:tmp_dir) - (messages_store_location ~storage_dir) - in - let*! () = - Lwt_unix.rename - (commitments_store_location ~storage_dir:tmp_dir) - (commitments_store_location ~storage_dir) - in - let*! () = - Lwt_unix.rename - (inboxes_store_location ~storage_dir:tmp_dir) - (inboxes_store_location ~storage_dir) - in - return_unit - - module From_v1 = - Make (Store_v1) (Store_v2) - (struct - let migrate_block_action v1_store v2_store l2_block = - let open Lwt_result_syntax in - let* () = - migrate_messages - Store_v1.(Messages.read v1_store.messages) - v2_store - l2_block - and* () = - migrate_commitment - Store_v1.(Commitments.find v1_store.commitments) - v2_store - l2_block - and* () = - migrate_inbox - Store_v1.(Inboxes.read v1_store.inboxes) - v2_store - l2_block - in - return_unit - - let final_actions = final_actions - end) - - module From_v0 = - Make (Store_v0) (Store_v2) - (struct - let migrate_block_action v0_store v2_store l2_block = - let open Lwt_result_syntax in - let* () = - migrate_messages - Store_v0.(Messages.read v0_store.messages) - v2_store - l2_block - and* () = - migrate_commitment - Store_v0.(Commitments.find v0_store.commitments) - v2_store - l2_block - and* () = - migrate_inbox - Store_v0.(Inboxes.read v0_store.inboxes) - v2_store - l2_block - in - return_unit - - let final_actions = final_actions - end) -end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store_migration.mli b/src/proto_018_Proxford/lib_sc_rollup_node/store_migration.mli deleted file mode 100644 index 0b99202ca76815cb77f3cb7151c21e3aa5b9f7dd..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store_migration.mli +++ /dev/null @@ -1,67 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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 of parameter for migration functor {!Make}. *) -module type MIGRATION_ACTIONS = sig - (** Type of store from which data is migrated. *) - type from_store - - (** Type of store to which the data is migrated. *) - type dest_store - - (** Action or actions to migrate data associated to a block. NOTE: - [dest_store] is an empty R/W store initialized in a temporary location. *) - val migrate_block_action : - from_store -> dest_store -> Sc_rollup_block.t -> unit tzresult Lwt.t - - (** The final actions to be performed in the migration. In particular, this is - where data from the temporary store in [dest_store] in [tmp_dir] should be - reported in the actual [storage_dir]. *) - val final_actions : - storage_dir:string -> - tmp_dir:string -> - from_store -> - dest_store -> - unit tzresult Lwt.t -end - -module type S = sig - (** Migration function for the store located in [storage_dir]. *) - val migrate : storage_dir:string -> unit tzresult Lwt.t -end - -(** Functor to create and {e register} a migration. *) -module Make - (S_from : Store_sig.S) - (S_dest : Store_sig.S) - (Actions : MIGRATION_ACTIONS - with type from_store := Store_sigs.ro S_from.t - and type dest_store := Store_sigs.rw S_dest.t) : S - -(** Migrate store located in rollup node {e store} directory [storage_dir] if - needed. If there is no possible migration path registered to go from the - current version to the last {!Store.version}, this function resolves with an - error. *) -val maybe_run_migration : storage_dir:string -> unit tzresult Lwt.t diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store_sig.ml b/src/proto_018_Proxford/lib_sc_rollup_node/store_sig.ml deleted file mode 100644 index ffac28ff0409d1304131464a80fdd11701499e9d..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store_sig.ml +++ /dev/null @@ -1,65 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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. *) -(* *) -(*****************************************************************************) - -module type S = sig - type +'a store - - (** Type of store. The parameter indicates if the store can be written or only - read. *) - type 'a t = ([< `Read | `Write > `Read] as 'a) store - - (** Read/write store {!t}. *) - type rw = Store_sigs.rw t - - (** Read only store {!t}. *) - type ro = Store_sigs.ro t - - (** Version supported by this code. *) - val version : Store_version.t - - (** [close store] closes the store. *) - val close : _ t -> unit tzresult Lwt.t - - (** [load mode ~l2_blocks_cache_size directory] loads a store from the data - persisted in [directory]. If [mode] is {!Store_sigs.Read_only}, then the - indexes and irmin store will be opened in readonly mode and only read - operations will be permitted. This allows to open a store for read access - that is already opened in {!Store_sigs.Read_write} mode in another - process. [l2_blocks_cache_size] is the number of L2 blocks the rollup node - will keep in memory. *) - val load : - 'a Store_sigs.mode -> - l2_blocks_cache_size:int -> - string -> - 'a store tzresult Lwt.t - - (** [readonly store] returns a read-only version of [store]. *) - val readonly : _ t -> ro - - (** [iter_l2_blocks store f] iterates [f] on all L2 blocks reachable from the - head, from newest to oldest. *) - val iter_l2_blocks : - _ t -> (Sc_rollup_block.t -> unit tzresult Lwt.t) -> unit tzresult Lwt.t -end diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store_v0.ml b/src/proto_018_Proxford/lib_sc_rollup_node/store_v0.ml deleted file mode 100644 index 066a37f739fb3ba9037c31a4a8789ee09936bad4..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store_v0.ml +++ /dev/null @@ -1,506 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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 copy of - [src/proto_016_PtMumbai/lib_sc_rollup_node/store.ml], which contains the - store for the Mumbai rollup node. *) - -open Protocol -include Store_sigs -include Store_utils - -(** Aggregated collection of messages from the L1 inbox *) -open Alpha_context - -let version = Store_version.V0 - -module Irmin_store = struct - module IStore = Irmin_store.Make (struct - let name = "Tezos smart rollup node" - end) - - include IStore - include Store_utils.Make (IStore) -end - -module Empty_header = struct - type t = unit - - let name = "empty" - - let encoding = Data_encoding.unit - - let fixed_size = 0 -end - -module Add_empty_header = struct - module Header = Empty_header - - let header _ = () -end - -module Make_hash_index_key (H : Environment.S.HASH) = -Indexed_store.Make_index_key (struct - include Indexed_store.Make_fixed_encodable (H) - - let equal = H.equal -end) - -(** L2 blocks *) -module L2_blocks = - Indexed_store.Make_indexed_file - (struct - let name = "l2_blocks" - end) - (Tezos_store_shared.Block_key) - (struct - type t = (unit, unit) Sc_rollup_block.block - - let name = "sc_rollup_block_info" - - let encoding = - Sc_rollup_block.block_encoding Data_encoding.unit Data_encoding.unit - - module Header = struct - type t = Sc_rollup_block.header - - let name = "sc_rollup_block_header" - - let encoding = Sc_rollup_block.header_encoding - - let fixed_size = Sc_rollup_block.header_size - end - end) - -(** Unaggregated messages per block *) -module Messages = - Indexed_store.Make_indexed_file - (struct - let name = "messages" - end) - (Make_hash_index_key (Sc_rollup.Inbox_merkelized_payload_hashes.Hash)) - (struct - type t = Sc_rollup.Inbox_message.t list - - let name = "messages_list" - - let encoding = - Data_encoding.(list @@ dynamic_size Sc_rollup.Inbox_message.encoding) - - module Header = struct - type t = Block_hash.t * Timestamp.t * int - - let name = "messages_inbox_info" - - let encoding = - let open Data_encoding in - obj3 - (req "predecessor" Block_hash.encoding) - (req "predecessor_timestamp" Timestamp.encoding) - (req "num_messages" int31) - - let fixed_size = - WithExceptions.Option.get ~loc:__LOC__ - @@ Data_encoding.Binary.fixed_length encoding - end - end) - -(** Inbox state for each block *) -module Inboxes = - Indexed_store.Make_simple_indexed_file - (struct - let name = "inboxes" - end) - (Make_hash_index_key (Sc_rollup.Inbox.Hash)) - (struct - type t = Sc_rollup.Inbox.t - - let name = "inbox" - - let encoding = Sc_rollup.Inbox.encoding - - include Add_empty_header - end) - -module Commitments = - Indexed_store.Make_indexable - (struct - let name = "commitments" - end) - (Make_hash_index_key (Sc_rollup.Commitment.Hash)) - (Indexed_store.Make_index_value (Indexed_store.Make_fixed_encodable (struct - include Sc_rollup.Commitment - - let name = "commitment" - end))) - -module Commitments_published_at_level = struct - type element = { - first_published_at_level : Raw_level.t; - published_at_level : Raw_level.t option; - } - - let element_encoding = - let open Data_encoding in - let opt_level_encoding = - conv - (function None -> -1l | Some l -> Raw_level.to_int32 l) - (fun l -> if l = -1l then None else Some (Raw_level.of_int32_exn l)) - Data_encoding.int32 - in - conv - (fun {first_published_at_level; published_at_level} -> - (first_published_at_level, published_at_level)) - (fun (first_published_at_level, published_at_level) -> - {first_published_at_level; published_at_level}) - @@ obj2 - (req "first_published_at_level" Raw_level.encoding) - (req "published_at_level" opt_level_encoding) - - include - Indexed_store.Make_indexable - (struct - let name = "commitments" - end) - (Make_hash_index_key (Sc_rollup.Commitment.Hash)) - (Indexed_store.Make_index_value (Indexed_store.Make_fixed_encodable (struct - type t = element - - let name = "published_levels" - - let encoding = element_encoding - end))) -end - -module L2_head = Indexed_store.Make_singleton (struct - type t = Sc_rollup_block.t - - let name = "l2_head" - - let encoding = Sc_rollup_block.encoding -end) - -module Last_finalized_level = Indexed_store.Make_singleton (struct - type t = int32 - - let name = "finalized_level" - - let encoding = Data_encoding.int32 -end) - -(** Table from L1 levels to blocks hashes. *) -module Levels_to_hashes = - Indexed_store.Make_indexable - (struct - let name = "tezos_levels" - end) - (Indexed_store.Make_index_key (struct - type t = int32 - - let encoding = Data_encoding.int32 - - let name = "level" - - let fixed_size = 4 - - let equal = Int32.equal - end)) - (Tezos_store_shared.Block_key) - -(* Published slot headers per block hash, - stored as a list of bindings from `Dal_slot_index.t` - to `Dal.Slot.t`. The encoding function converts this - list into a `Dal.Slot_index.t`-indexed map. *) -module Dal_slot_pages = - Irmin_store.Make_nested_map - (struct - let path = ["dal"; "slot_pages"] - end) - (struct - type key = Block_hash.t - - let to_path_representation = Block_hash.to_b58check - end) - (struct - type key = Dal.Slot_index.t * Dal.Page.Index.t - - let encoding = - Data_encoding.(tup2 Dal.Slot_index.encoding Dal.Page.Index.encoding) - - let compare (i1, p1) (i2, p2) = - Compare.or_else (Dal.Slot_index.compare i1 i2) (fun () -> - Dal.Page.Index.compare p1 p2) - - let name = "slot_index" - end) - (struct - type value = Dal.Page.content - - let encoding = Dal.Page.content_encoding - - let name = "slot_pages" - end) - -(** stores slots whose data have been considered and pages stored to disk (if - they are confirmed). *) -module Dal_processed_slots = - Irmin_store.Make_nested_map - (struct - let path = ["dal"; "processed_slots"] - end) - (struct - type key = Block_hash.t - - let to_path_representation = Block_hash.to_b58check - end) - (struct - type key = Dal.Slot_index.t - - let encoding = Dal.Slot_index.encoding - - let compare = Dal.Slot_index.compare - - let name = "slot_index" - end) - (struct - type value = [`Confirmed | `Unconfirmed] - - let name = "slot_processing_status" - - let encoding = - let open Data_encoding in - let mk_case constr ~tag ~title = - case - ~title - (Tag tag) - (obj1 (req "kind" (constant title))) - (fun x -> if x = constr then Some () else None) - (fun () -> constr) - in - union - ~tag_size:`Uint8 - [ - mk_case `Confirmed ~tag:0 ~title:"Confirmed"; - mk_case `Unconfirmed ~tag:1 ~title:"Unconfirmed"; - ] - end) - -module Dal_slots_headers = - Irmin_store.Make_nested_map - (struct - let path = ["dal"; "slot_headers"] - end) - (struct - type key = Block_hash.t - - let to_path_representation = Block_hash.to_b58check - end) - (struct - type key = Dal.Slot_index.t - - let encoding = Dal.Slot_index.encoding - - let compare = Dal.Slot_index.compare - - let name = "slot_index" - end) - (struct - type value = Dal.Slot.Header.t - - let name = "slot_header" - - let encoding = Dal.Slot.Header.encoding - end) - -(* Published slot headers per block hash, stored as a list of bindings from - `Dal_slot_index.t` to `Dal.Slot.t`. The encoding function converts this - list into a `Dal.Slot_index.t`-indexed map. Note that the block_hash - refers to the block where slots headers have been confirmed, not - the block where they have been published. -*) - -(** Confirmed DAL slots history. See documentation of - {!Dal_slot_repr.Slots_history} for more details. *) -module Dal_confirmed_slots_history = - Irmin_store.Make_append_only_map - (struct - let path = ["dal"; "confirmed_slots_history"] - end) - (struct - type key = Block_hash.t - - let to_path_representation = Block_hash.to_b58check - end) - (struct - type value = Dal.Slots_history.t - - let name = "dal_slot_histories" - - let encoding = Dal.Slots_history.encoding - end) - -(** Confirmed DAL slots histories cache. See documentation of - {!Dal_slot_repr.Slots_history} for more details. *) -module Dal_confirmed_slots_histories = - (* TODO: https://gitlab.com/tezos/tezos/-/issues/4390 - Store single history points in map instead of whole history. *) - Irmin_store.Make_append_only_map - (struct - let path = ["dal"; "confirmed_slots_histories_cache"] - end) - (struct - type key = Block_hash.t - - let to_path_representation = Block_hash.to_b58check - end) - (struct - type value = Dal.Slots_history.History_cache.t - - let name = "dal_slot_history_cache" - - let encoding = Dal.Slots_history.History_cache.encoding - end) - -type 'a store = { - l2_blocks : 'a L2_blocks.t; - messages : 'a Messages.t; - inboxes : 'a Inboxes.t; - commitments : 'a Commitments.t; - commitments_published_at_level : 'a Commitments_published_at_level.t; - l2_head : 'a L2_head.t; - last_finalized_level : 'a Last_finalized_level.t; - levels_to_hashes : 'a Levels_to_hashes.t; - irmin_store : 'a Irmin_store.t; -} - -type 'a t = ([< `Read | `Write > `Read] as 'a) store - -type rw = Store_sigs.rw t - -type ro = Store_sigs.ro t - -let readonly - ({ - l2_blocks; - messages; - inboxes; - commitments; - commitments_published_at_level; - l2_head; - last_finalized_level; - levels_to_hashes; - irmin_store; - } : - _ t) : ro = - { - l2_blocks = L2_blocks.readonly l2_blocks; - messages = Messages.readonly messages; - inboxes = Inboxes.readonly inboxes; - commitments = Commitments.readonly commitments; - commitments_published_at_level = - Commitments_published_at_level.readonly commitments_published_at_level; - l2_head = L2_head.readonly l2_head; - last_finalized_level = Last_finalized_level.readonly last_finalized_level; - levels_to_hashes = Levels_to_hashes.readonly levels_to_hashes; - irmin_store = Irmin_store.readonly irmin_store; - } - -let close - ({ - l2_blocks; - messages; - inboxes; - commitments; - commitments_published_at_level; - l2_head = _; - last_finalized_level = _; - levels_to_hashes; - irmin_store; - } : - _ t) = - let open Lwt_result_syntax in - let+ () = L2_blocks.close l2_blocks - and+ () = Messages.close messages - and+ () = Inboxes.close inboxes - and+ () = Commitments.close commitments - and+ () = Commitments_published_at_level.close commitments_published_at_level - and+ () = Levels_to_hashes.close levels_to_hashes - and+ () = Irmin_store.close irmin_store in - () - -let load (type a) (mode : a mode) ~l2_blocks_cache_size data_dir : - a store tzresult Lwt.t = - let open Lwt_result_syntax in - let path name = Filename.concat data_dir name in - let cache_size = l2_blocks_cache_size in - let* l2_blocks = L2_blocks.load mode ~path:(path "l2_blocks") ~cache_size in - let* messages = Messages.load mode ~path:(path "messages") ~cache_size in - let* inboxes = Inboxes.load mode ~path:(path "inboxes") ~cache_size in - let* commitments = Commitments.load mode ~path:(path "commitments") in - let* commitments_published_at_level = - Commitments_published_at_level.load - mode - ~path:(path "commitments_published_at_level") - in - let* l2_head = L2_head.load mode ~path:(path "l2_head") in - let* last_finalized_level = - Last_finalized_level.load mode ~path:(path "last_finalized_level") - in - let* levels_to_hashes = - Levels_to_hashes.load mode ~path:(path "levels_to_hashes") - in - let+ irmin_store = Irmin_store.load mode (path "irmin_store") in - { - l2_blocks; - messages; - inboxes; - commitments; - commitments_published_at_level; - l2_head; - last_finalized_level; - levels_to_hashes; - irmin_store; - } - -let iter_l2_blocks ({l2_blocks; l2_head; _} : _ t) f = - let open Lwt_result_syntax in - let* head = L2_head.read l2_head in - match head with - | None -> - (* No reachable head, nothing to do *) - return_unit - | Some head -> - let rec loop hash = - let* block = L2_blocks.read l2_blocks hash in - match block with - | None -> - (* The block does not exist, the known chain stops here, so do we. *) - return_unit - | Some (block, header) -> - let* () = f {block with header} in - loop header.predecessor - in - loop head.header.block_hash diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store_v0.mli b/src/proto_018_Proxford/lib_sc_rollup_node/store_v0.mli deleted file mode 100644 index f2d9a002d6c1d6bf8000a7e5eb4ead8a11bf9894..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store_v0.mli +++ /dev/null @@ -1,164 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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 version of the store is used for the rollup nodes for protocol Mumbai, - i.e. = 16. - - This interface is a copy of - [src/proto_016_PtMumbai/lib_sc_rollup_node/store.mli], which contains the - layout for the Mumbai rollup node. -*) - -open Protocol -open Alpha_context -open Indexed_store - -module Irmin_store : sig - include module type of Irmin_store.Make (struct - let name = "Tezos smart rollup node" - end) - - include Store_sigs.Store with type 'a t := 'a t -end - -module L2_blocks : - INDEXED_FILE - with type key := Block_hash.t - and type value := (unit, unit) Sc_rollup_block.block - and type header := Sc_rollup_block.header - -(** Storage for persisting messages downloaded from the L1 node. *) -module Messages : - INDEXED_FILE - with type key := Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t - and type value := Sc_rollup.Inbox_message.t list - and type header := Block_hash.t * Timestamp.t * int - -(** Aggregated collection of messages from the L1 inbox *) -module Inboxes : - SIMPLE_INDEXED_FILE - with type key := Sc_rollup.Inbox.Hash.t - and type value := Sc_rollup.Inbox.t - and type header := unit - -(** Storage containing commitments and corresponding commitment hashes that the - rollup node has knowledge of. *) -module Commitments : - INDEXABLE_STORE - with type key := Sc_rollup.Commitment.Hash.t - and type value := Sc_rollup.Commitment.t - -(** Storage mapping commitment hashes to the level when they were published by - the rollup node. It only contains hashes of commitments published by this - rollup node. *) -module Commitments_published_at_level : sig - type element = { - first_published_at_level : Raw_level.t; - (** The level at which this commitment was first published. *) - published_at_level : Raw_level.t option; - (** The level at which we published this commitment. If - [first_published_at_level <> published_at_level] it means that the - commitment is republished. *) - } - - include - INDEXABLE_STORE - with type key := Sc_rollup.Commitment.Hash.t - and type value := element -end - -module L2_head : SINGLETON_STORE with type value := Sc_rollup_block.t - -module Last_finalized_level : SINGLETON_STORE with type value := int32 - -module Levels_to_hashes : - INDEXABLE_STORE with type key := int32 and type value := Block_hash.t - -(** Published slot headers per block hash, - stored as a list of bindings from [Dal_slot_index.t] - to [Dal.Slot.t]. The encoding function converts this - list into a [Dal.Slot_index.t]-indexed map. *) -module Dal_slots_headers : - Store_sigs.Nested_map - with type primary_key := Block_hash.t - and type secondary_key := Dal.Slot_index.t - and type value := Dal.Slot.Header.t - and type 'a store := 'a Irmin_store.t - -module Dal_confirmed_slots_history : - Store_sigs.Append_only_map - with type key := Block_hash.t - and type value := Dal.Slots_history.t - and type 'a store := 'a Irmin_store.t - -(** Confirmed DAL slots histories cache. See documentation of - {!Dal_slot_repr.Slots_history} for more details. *) -module Dal_confirmed_slots_histories : - Store_sigs.Append_only_map - with type key := Block_hash.t - and type value := Dal.Slots_history.History_cache.t - and type 'a store := 'a Irmin_store.t - -(** [Dal_slot_pages] is a [Store_utils.Nested_map] used to store the contents - of dal slots fetched by the rollup node, as a list of pages. The values of - this storage module have type `string list`. A value of the form - [page_contents] refers to a page of a slot that has been confirmed, and - whose contents are [page_contents]. -*) -module Dal_slot_pages : - Store_sigs.Nested_map - with type primary_key := Block_hash.t - and type secondary_key := Dal.Slot_index.t * Dal.Page.Index.t - and type value := Dal.Page.content - and type 'a store := 'a Irmin_store.t - -(** [Dal_processed_slots] is a [Store_utils.Nested_map] used to store the processing - status of dal slots content fetched by the rollup node. The values of - this storage module have type `[`Confirmed | `Unconfirmed]`, depending on - whether the content of the slot has been confirmed or not. If an entry is - not present for a [(block_hash, slot_index)], this either means that it's - not processed yet. -*) -module Dal_processed_slots : - Store_sigs.Nested_map - with type primary_key := Block_hash.t - and type secondary_key := Dal.Slot_index.t - and type value := [`Confirmed | `Unconfirmed] - and type 'a store := 'a Irmin_store.t - -type +'a store = { - l2_blocks : 'a L2_blocks.t; - messages : 'a Messages.t; - inboxes : 'a Inboxes.t; - commitments : 'a Commitments.t; - commitments_published_at_level : 'a Commitments_published_at_level.t; - l2_head : 'a L2_head.t; - last_finalized_level : 'a Last_finalized_level.t; - levels_to_hashes : 'a Levels_to_hashes.t; - irmin_store : 'a Irmin_store.t; -} - -include Store_sig.S with type 'a store := 'a store diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store_v1.ml b/src/proto_018_Proxford/lib_sc_rollup_node/store_v1.ml deleted file mode 100644 index adecbb8a2b5b62a821ecfa369413cf481e2e5348..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store_v1.ml +++ /dev/null @@ -1,253 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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 -open Alpha_context -include Store_sigs -include Store_utils -include Store_v0 - -let version = Store_version.V1 - -module Make_hash_index_key (H : Environment.S.HASH) = -Indexed_store.Make_index_key (struct - include Indexed_store.Make_fixed_encodable (H) - - let equal = H.equal -end) - -(** Unaggregated messages per block *) -module Messages = - Indexed_store.Make_indexed_file - (struct - let name = "messages" - end) - (Make_hash_index_key (Sc_rollup.Inbox_merkelized_payload_hashes.Hash)) - (struct - type t = Sc_rollup.Inbox_message.t list - - let name = "messages_list" - - let encoding = - Data_encoding.(list @@ dynamic_size Sc_rollup.Inbox_message.encoding) - - module Header = struct - type t = bool * Block_hash.t * Timestamp.t * int - - let name = "messages_inbox_info" - - let encoding = - let open Data_encoding in - obj4 - (req "is_first_block" bool) - (req "predecessor" Block_hash.encoding) - (req "predecessor_timestamp" Timestamp.encoding) - (req "num_messages" int31) - - let fixed_size = - WithExceptions.Option.get ~loc:__LOC__ - @@ Data_encoding.Binary.fixed_length encoding - end - end) - -module Dal_pages = struct - type removed_in_v1 -end - -module Dal_processed_slots = struct - type removed_in_v1 -end - -(** Store attestation statuses for DAL slots on L1. *) -module Dal_slots_statuses = - Irmin_store.Make_nested_map - (struct - let path = ["dal"; "slots_statuses"] - end) - (struct - type key = Block_hash.t - - let to_path_representation = Block_hash.to_b58check - end) - (struct - type key = Dal.Slot_index.t - - let encoding = Dal.Slot_index.encoding - - let compare = Dal.Slot_index.compare - - let name = "slot_index" - end) - (struct - (* TODO: https://gitlab.com/tezos/tezos/-/issues/4780. - - Rename Confirm-ed/ation to Attest-ed/ation in the rollup node. *) - type value = [`Confirmed | `Unconfirmed] - - let name = "slot_status" - - let encoding = - (* We don't use - Data_encoding.string_enum because a union is more storage-efficient. *) - let open Data_encoding in - union - ~tag_size:`Uint8 - [ - case - ~title:"Confirmed" - (Tag 0) - (obj1 (req "kind" (constant "Confirmed"))) - (function `Confirmed -> Some () | `Unconfirmed -> None) - (fun () -> `Confirmed); - case - ~title:"Unconfirmed" - (Tag 1) - (obj1 (req "kind" (constant "Unconfirmed"))) - (function `Unconfirmed -> Some () | `Confirmed -> None) - (fun () -> `Unconfirmed); - ] - end) - -type nonrec 'a store = { - l2_blocks : 'a L2_blocks.t; - messages : 'a Messages.t; - inboxes : 'a Inboxes.t; - commitments : 'a Commitments.t; - commitments_published_at_level : 'a Commitments_published_at_level.t; - l2_head : 'a L2_head.t; - last_finalized_level : 'a Last_finalized_level.t; - levels_to_hashes : 'a Levels_to_hashes.t; - irmin_store : 'a Irmin_store.t; -} - -type 'a t = ([< `Read | `Write > `Read] as 'a) store - -type rw = Store_sigs.rw t - -type ro = Store_sigs.ro t - -let readonly - ({ - l2_blocks; - messages; - inboxes; - commitments; - commitments_published_at_level; - l2_head; - last_finalized_level; - levels_to_hashes; - irmin_store; - } : - _ t) : ro = - { - l2_blocks = L2_blocks.readonly l2_blocks; - messages = Messages.readonly messages; - inboxes = Inboxes.readonly inboxes; - commitments = Commitments.readonly commitments; - commitments_published_at_level = - Commitments_published_at_level.readonly commitments_published_at_level; - l2_head = L2_head.readonly l2_head; - last_finalized_level = Last_finalized_level.readonly last_finalized_level; - levels_to_hashes = Levels_to_hashes.readonly levels_to_hashes; - irmin_store = Irmin_store.readonly irmin_store; - } - -let close - ({ - l2_blocks; - messages; - inboxes; - commitments; - commitments_published_at_level; - l2_head = _; - last_finalized_level = _; - levels_to_hashes; - irmin_store; - } : - _ t) = - let open Lwt_result_syntax in - let+ () = L2_blocks.close l2_blocks - and+ () = Messages.close messages - and+ () = Inboxes.close inboxes - and+ () = Commitments.close commitments - and+ () = Commitments_published_at_level.close commitments_published_at_level - and+ () = Levels_to_hashes.close levels_to_hashes - and+ () = Irmin_store.close irmin_store in - () - -let load (type a) (mode : a mode) ~l2_blocks_cache_size data_dir : - a store tzresult Lwt.t = - let open Lwt_result_syntax in - let path name = Filename.concat data_dir name in - let cache_size = l2_blocks_cache_size in - let* l2_blocks = L2_blocks.load mode ~path:(path "l2_blocks") ~cache_size in - let* messages = Messages.load mode ~path:(path "messages") ~cache_size in - let* inboxes = Inboxes.load mode ~path:(path "inboxes") ~cache_size in - let* commitments = Commitments.load mode ~path:(path "commitments") in - let* commitments_published_at_level = - Commitments_published_at_level.load - mode - ~path:(path "commitments_published_at_level") - in - let* l2_head = L2_head.load mode ~path:(path "l2_head") in - let* last_finalized_level = - Last_finalized_level.load mode ~path:(path "last_finalized_level") - in - let* levels_to_hashes = - Levels_to_hashes.load mode ~path:(path "levels_to_hashes") - in - let+ irmin_store = Irmin_store.load mode (path "irmin_store") in - { - l2_blocks; - messages; - inboxes; - commitments; - commitments_published_at_level; - l2_head; - last_finalized_level; - levels_to_hashes; - irmin_store; - } - -let iter_l2_blocks ({l2_blocks; l2_head; _} : _ t) f = - let open Lwt_result_syntax in - let* head = L2_head.read l2_head in - match head with - | None -> - (* No reachable head, nothing to do *) - return_unit - | Some head -> - let rec loop hash = - let* block = L2_blocks.read l2_blocks hash in - match block with - | None -> - (* The block does not exist, the known chain stops here, so do we. *) - return_unit - | Some (block, header) -> - let* () = f {block with header} in - loop header.predecessor - in - loop head.header.block_hash diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store_v1.mli b/src/proto_018_Proxford/lib_sc_rollup_node/store_v1.mli deleted file mode 100644 index 7662907121003367f4bdf443fb185008a1db33cc..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store_v1.mli +++ /dev/null @@ -1,79 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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 version of the store is used for the rollup nodes for protocols for and - after Nairobi, i.e. >= 17. *) - -open Protocol -open Alpha_context -open Indexed_store - -include module type of struct - include Store_v0 -end - -(** Storage for persisting messages downloaded from the L1 node. *) -module Messages : - INDEXED_FILE - with type key := Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t - and type value := Sc_rollup.Inbox_message.t list - and type header := bool * Block_hash.t * Timestamp.t * int - -module Dal_pages : sig - type removed_in_v1 -end - -module Dal_processed_slots : sig - type removed_in_v1 -end - -(** [Dal_slots_statuses] is a [Store_utils.Nested_map] used to store the - attestation status of DAL slots. The values of this storage module have type - `[`Confirmed | `Unconfirmed]`, depending on whether the content of the slot - has been attested on L1 or not. If an entry is not present for a - [(block_hash, slot_index)], this means that the corresponding block is not - processed yet. -*) -module Dal_slots_statuses : - Store_sigs.Nested_map - with type primary_key := Block_hash.t - and type secondary_key := Dal.Slot_index.t - and type value := [`Confirmed | `Unconfirmed] - and type 'a store := 'a Irmin_store.t - -type +'a store = { - l2_blocks : 'a L2_blocks.t; - messages : 'a Messages.t; - inboxes : 'a Inboxes.t; - commitments : 'a Commitments.t; - commitments_published_at_level : 'a Commitments_published_at_level.t; - l2_head : 'a L2_head.t; - last_finalized_level : 'a Last_finalized_level.t; - levels_to_hashes : 'a Levels_to_hashes.t; - irmin_store : 'a Irmin_store.t; -} - -include Store_sig.S with type 'a store := 'a store diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store_v2.ml b/src/proto_018_Proxford/lib_sc_rollup_node/store_v2.ml deleted file mode 100644 index 18b77336aa55753bbe7453796b9182a5bda1fec2..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store_v2.ml +++ /dev/null @@ -1,330 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2021 Nomadic Labs, *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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 -open Alpha_context -include Store_sigs -include Store_utils -include Store_v1 - -let version = Store_version.V2 - -module Make_hash_index_key (H : Environment.S.HASH) = -Indexed_store.Make_index_key (struct - include Indexed_store.Make_fixed_encodable (H) - - let equal = H.equal -end) - -(** Unaggregated messages per block *) -module Messages = - Indexed_store.Make_indexed_file - (struct - let name = "messages" - end) - (Make_hash_index_key (Sc_rollup.Inbox_merkelized_payload_hashes.Hash)) - (struct - type t = Sc_rollup.Inbox_message.t list - - let name = "messages_list" - - let encoding = - Data_encoding.(list @@ dynamic_size Sc_rollup.Inbox_message.encoding) - - module Header = struct - type t = Block_hash.t - - let name = "messages_block" - - let encoding = Block_hash.encoding - - let fixed_size = - WithExceptions.Option.get ~loc:__LOC__ - @@ Data_encoding.Binary.fixed_length encoding - end - end) - -module Empty_header = struct - type t = unit - - let name = "empty" - - let encoding = Data_encoding.unit - - let fixed_size = 0 -end - -module Add_empty_header = struct - module Header = Empty_header - - let header _ = () -end - -(** Versioned inboxes *) -module Inboxes = - Indexed_store.Make_simple_indexed_file - (struct - let name = "inboxes" - end) - (Make_hash_index_key (Sc_rollup.Inbox.Hash)) - (struct - type t = Sc_rollup.Inbox.t - - let to_repr inbox = - inbox - |> Data_encoding.Binary.to_string_exn Sc_rollup.Inbox.encoding - |> Data_encoding.Binary.of_string_exn Sc_rollup_inbox_repr.encoding - - let of_repr inbox = - inbox - |> Data_encoding.Binary.to_string_exn Sc_rollup_inbox_repr.encoding - |> Data_encoding.Binary.of_string_exn Sc_rollup.Inbox.encoding - - let encoding = - Data_encoding.conv - (fun x -> to_repr x |> Sc_rollup_inbox_repr.to_versioned) - (fun x -> Sc_rollup_inbox_repr.of_versioned x |> of_repr) - Sc_rollup_inbox_repr.versioned_encoding - - let name = "inbox" - - include Add_empty_header - end) - -(** Versioned commitments *) -module Commitments = - Indexed_store.Make_simple_indexed_file - (struct - let name = "commitments" - end) - (Make_hash_index_key (Sc_rollup.Commitment.Hash)) - (struct - type t = Sc_rollup.Commitment.t - - let to_repr commitment = - commitment - |> Data_encoding.Binary.to_string_exn Sc_rollup.Commitment.encoding - |> Data_encoding.Binary.of_string_exn Sc_rollup_commitment_repr.encoding - - let of_repr commitment = - commitment - |> Data_encoding.Binary.to_string_exn Sc_rollup_commitment_repr.encoding - |> Data_encoding.Binary.of_string_exn Sc_rollup.Commitment.encoding - - let encoding = - Data_encoding.conv - (fun x -> to_repr x |> Sc_rollup_commitment_repr.to_versioned) - (fun x -> Sc_rollup_commitment_repr.of_versioned x |> of_repr) - Sc_rollup_commitment_repr.versioned_encoding - - let name = "commitment" - - include Add_empty_header - end) - -module Protocols = struct - type level = First_known of int32 | Activation_level of int32 - - type proto_info = { - level : level; - proto_level : int; - protocol : Protocol_hash.t; - } - - type value = proto_info list - - let level_encoding = - let open Data_encoding in - conv - (function First_known l -> (l, false) | Activation_level l -> (l, true)) - (function l, false -> First_known l | l, true -> Activation_level l) - @@ obj2 (req "level" int32) (req "activates" bool) - - let proto_info_encoding = - let open Data_encoding in - conv - (fun {level; proto_level; protocol} -> (level, proto_level, protocol)) - (fun (level, proto_level, protocol) -> {level; proto_level; protocol}) - @@ obj3 - (req "level" level_encoding) - (req "proto_level" int31) - (req "protocol" Protocol_hash.encoding) - - include Indexed_store.Make_singleton (struct - type t = value - - let name = "protocols" - - let level_encoding = - let open Data_encoding in - conv - (function - | First_known l -> (l, false) | Activation_level l -> (l, true)) - (function l, false -> First_known l | l, true -> Activation_level l) - @@ obj2 (req "level" int32) (req "activates" bool) - - let proto_info_encoding = - let open Data_encoding in - conv - (fun {level; proto_level; protocol} -> (level, proto_level, protocol)) - (fun (level, proto_level, protocol) -> {level; proto_level; protocol}) - @@ obj3 - (req "level" level_encoding) - (req "proto_level" int31) - (req "protocol" Protocol_hash.encoding) - - let encoding = Data_encoding.list proto_info_encoding - end) -end - -type 'a store = { - l2_blocks : 'a L2_blocks.t; - messages : 'a Messages.t; - inboxes : 'a Inboxes.t; - commitments : 'a Commitments.t; - commitments_published_at_level : 'a Commitments_published_at_level.t; - l2_head : 'a L2_head.t; - last_finalized_level : 'a Last_finalized_level.t; - levels_to_hashes : 'a Levels_to_hashes.t; - protocols : 'a Protocols.t; - irmin_store : 'a Irmin_store.t; -} - -type 'a t = ([< `Read | `Write > `Read] as 'a) store - -type rw = Store_sigs.rw t - -type ro = Store_sigs.ro t - -let readonly - ({ - l2_blocks; - messages; - inboxes; - commitments; - commitments_published_at_level; - l2_head; - last_finalized_level; - levels_to_hashes; - protocols; - irmin_store; - } : - _ t) : ro = - { - l2_blocks = L2_blocks.readonly l2_blocks; - messages = Messages.readonly messages; - inboxes = Inboxes.readonly inboxes; - commitments = Commitments.readonly commitments; - commitments_published_at_level = - Commitments_published_at_level.readonly commitments_published_at_level; - l2_head = L2_head.readonly l2_head; - last_finalized_level = Last_finalized_level.readonly last_finalized_level; - levels_to_hashes = Levels_to_hashes.readonly levels_to_hashes; - protocols = Protocols.readonly protocols; - irmin_store = Irmin_store.readonly irmin_store; - } - -let close - ({ - l2_blocks; - messages; - inboxes; - commitments; - commitments_published_at_level; - l2_head = _; - last_finalized_level = _; - levels_to_hashes; - protocols = _; - irmin_store; - } : - _ t) = - let open Lwt_result_syntax in - let+ () = L2_blocks.close l2_blocks - and+ () = Messages.close messages - and+ () = Inboxes.close inboxes - and+ () = Commitments.close commitments - and+ () = Commitments_published_at_level.close commitments_published_at_level - and+ () = Levels_to_hashes.close levels_to_hashes - and+ () = Irmin_store.close irmin_store in - () - -let load (type a) (mode : a mode) ~l2_blocks_cache_size data_dir : - a store tzresult Lwt.t = - let open Lwt_result_syntax in - let path name = Filename.concat data_dir name in - let cache_size = l2_blocks_cache_size in - let* l2_blocks = L2_blocks.load mode ~path:(path "l2_blocks") ~cache_size in - let* messages = Messages.load mode ~path:(path "messages") ~cache_size in - let* inboxes = Inboxes.load mode ~path:(path "inboxes") ~cache_size in - let* commitments = - Commitments.load mode ~path:(path "commitments") ~cache_size - in - let* commitments_published_at_level = - Commitments_published_at_level.load - mode - ~path:(path "commitments_published_at_level") - in - let* l2_head = L2_head.load mode ~path:(path "l2_head") in - let* last_finalized_level = - Last_finalized_level.load mode ~path:(path "last_finalized_level") - in - let* levels_to_hashes = - Levels_to_hashes.load mode ~path:(path "levels_to_hashes") - in - let* protocols = Protocols.load mode ~path:(path "protocols") in - let+ irmin_store = Irmin_store.load mode (path "irmin_store") in - { - l2_blocks; - messages; - inboxes; - commitments; - commitments_published_at_level; - l2_head; - last_finalized_level; - levels_to_hashes; - protocols; - irmin_store; - } - -let iter_l2_blocks ({l2_blocks; l2_head; _} : _ t) f = - let open Lwt_result_syntax in - let* head = L2_head.read l2_head in - match head with - | None -> - (* No reachable head, nothing to do *) - return_unit - | Some head -> - let rec loop hash = - let* block = L2_blocks.read l2_blocks hash in - match block with - | None -> - (* The block does not exist, the known chain stops here, so do we. *) - return_unit - | Some (block, header) -> - let* () = f {block with header} in - loop header.predecessor - in - loop head.header.block_hash diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store_v2.mli b/src/proto_018_Proxford/lib_sc_rollup_node/store_v2.mli deleted file mode 100644 index fb8e1bc4313f3031b7e63f1e50bb4bced2439170..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store_v2.mli +++ /dev/null @@ -1,94 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2022 Nomadic Labs, *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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 version of the store is used for the rollup nodes for protocols for and - after Nairobi, i.e. >= 17. *) - -open Protocol -open Alpha_context -open Indexed_store - -include module type of struct - include Store_v1 -end - -(** Storage for persisting messages downloaded from the L1 node. *) -module Messages : - INDEXED_FILE - with type key := Sc_rollup.Inbox_merkelized_payload_hashes.Hash.t - and type value := Sc_rollup.Inbox_message.t list - and type header := Block_hash.t - -(** Storage for persisting inboxes. *) -module Inboxes : - SIMPLE_INDEXED_FILE - with type key := Sc_rollup.Inbox.Hash.t - and type value := Sc_rollup.Inbox.t - and type header := unit - -(** Storage containing commitments and corresponding commitment hashes that the - rollup node has knowledge of. *) -module Commitments : - SIMPLE_INDEXED_FILE - with type key := Sc_rollup.Commitment.Hash.t - and type value := Sc_rollup.Commitment.t - and type header := unit - -module Protocols : sig - type level = First_known of int32 | Activation_level of int32 - - (** Each element of this type represents information we have about a Tezos - protocol regarding its activation. *) - type proto_info = { - level : level; - (** The level at which we have seen the protocol for the first time, - either because we saw its activation or because the first block we - saw (at the origination of the rollup) was from this protocol. *) - proto_level : int; - (** The protocol level, i.e. its number in the sequence of protocol - activations on the chain. *) - protocol : Protocol_hash.t; (** The protocol this information concerns. *) - } - - val proto_info_encoding : proto_info Data_encoding.t - - include SINGLETON_STORE with type value = proto_info list -end - -type +'a store = { - l2_blocks : 'a L2_blocks.t; - messages : 'a Messages.t; - inboxes : 'a Inboxes.t; - commitments : 'a Commitments.t; - commitments_published_at_level : 'a Commitments_published_at_level.t; - l2_head : 'a L2_head.t; - last_finalized_level : 'a Last_finalized_level.t; - levels_to_hashes : 'a Levels_to_hashes.t; - protocols : 'a Protocols.t; - irmin_store : 'a Irmin_store.t; -} - -include Store_sig.S with type 'a store := 'a store diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/store_version.ml b/src/proto_018_Proxford/lib_sc_rollup_node/store_version.ml deleted file mode 100644 index db71f628911302ba849e2d0fdec8895320b2db1b..0000000000000000000000000000000000000000 --- a/src/proto_018_Proxford/lib_sc_rollup_node/store_version.ml +++ /dev/null @@ -1,61 +0,0 @@ -(*****************************************************************************) -(* *) -(* Open Source License *) -(* Copyright (c) 2023 Functori, *) -(* *) -(* 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 = V0 | V1 | V2 - -let pp ppf v = - Format.pp_print_string ppf - @@ match v with V0 -> "v0" | V1 -> "v1" | V2 -> "v2" - -let encoding = - let open Data_encoding in - conv - (function V0 -> 0 | V1 -> 1 | V2 -> 2) - (function - | 0 -> V0 - | 1 -> V1 - | 2 -> V2 - | v -> Format.ksprintf Stdlib.failwith "Unsupported store version %d" v) - (obj1 (req "store_version" int31)) - -let path ~dir = Filename.concat dir "version" - -let read_version_file ~dir = - let open Lwt_result_syntax in - protect @@ fun () -> - let filename = path ~dir in - let*! exists = Lwt_unix.file_exists filename in - if not exists then return_none - else - let* json = Lwt_utils_unix.Json.read_file filename in - return_some (Data_encoding.Json.destruct encoding json) - -let write_version_file ~dir version = - let open Lwt_result_syntax in - protect @@ fun () -> - let filename = path ~dir in - let*! () = Lwt_utils_unix.create_dir dir in - let json = Data_encoding.Json.construct encoding version in - Lwt_utils_unix.Json.write_file filename json diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/test/canary.ml b/src/proto_018_Proxford/lib_sc_rollup_node/test/canary.ml index 4fc059c6aeabc013c0e3a212e53e5ec36b69e1df..66b9d6ef3a9cbeac214cd1ff19d35137fe43fb56 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/test/canary.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/test/canary.ml @@ -31,6 +31,7 @@ Subject: Canary unit tests to make sure the test helpers work as intended *) +open Octez_smart_rollup open Protocol.Alpha_context let build_chain node_ctxt ~genesis ~length = @@ -55,9 +56,7 @@ let canary_test node_ctxt ~genesis = Node_context.get_l2_block node_ctxt block.header.block_hash in let* store_block_by_level = - Node_context.get_l2_block_by_level - node_ctxt - (Raw_level.to_int32 block.header.level) + Node_context.get_l2_block_by_level node_ctxt block.header.level in Helpers.Assert.L2_block.equal ~loc:__LOC__ diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.ml b/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.ml index e4e10ac2334469df8a139f5463d9fd4092d50764..e888c6b40313f6e550b8a8b8c8698e0d9a9c3501 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.ml +++ b/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.ml @@ -23,8 +23,10 @@ (* *) (*****************************************************************************) +open Octez_smart_rollup open Protocol open Alpha_context +open Octez_smart_rollup_node let uid = ref 0 @@ -68,7 +70,7 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = in let* inbox_hash = Node_context.save_inbox node_ctxt inbox in let inbox_witness = Sc_rollup.Inbox.current_witness inbox in - let ctxt = Context.empty node_ctxt.context in + let ctxt = Octez_smart_rollup_node.Context.empty node_ctxt.context in let num_ticks = 0L in let module PVM = (val node_ctxt.pvm) in let initial_tick = Sc_rollup.Tick.initial in @@ -76,7 +78,7 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = let*! state = PVM.install_boot_sector initial_state boot_sector in let*! genesis_state_hash = PVM.state_hash state in let*! ctxt = PVM.State.set ctxt state in - let*! context_hash = Context.commit ctxt in + let*! context_hash = Octez_smart_rollup_node.Context.commit ctxt in let commitment = Sc_rollup.Commitment.genesis_commitment ~origination_level:node_ctxt.genesis_info.level @@ -88,7 +90,7 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = Sc_rollup_block. { block_hash = head.hash; - level = node_ctxt.genesis_info.level; + level = Raw_level.to_int32 node_ctxt.genesis_info.level; predecessor = predecessor.hash; commitment_hash = Some commitment_hash; previous_commitment_hash; @@ -98,7 +100,13 @@ let add_l2_genesis_block (node_ctxt : _ Node_context.t) ~boot_sector = } in let l2_block = - Sc_rollup_block.{header; content = (); num_ticks; initial_tick} + Sc_rollup_block. + { + header; + content = (); + num_ticks; + initial_tick = Sc_rollup.Tick.to_z initial_tick; + } in let* () = Node_context.save_l2_head node_ctxt l2_block in return l2_block @@ -182,7 +190,7 @@ let append_l2_block (node_ctxt : _ Node_context.t) ?(is_first_block = false) | None -> failwith "No genesis block, please add one with add_l2_genesis_block" in - let pred_level = Raw_level.to_int32 predecessor_l2_block.header.level in + let pred_level = predecessor_l2_block.header.level in let predecessor = head_of_level ~predecessor:predecessor_l2_block.header.predecessor @@ -205,9 +213,7 @@ let append_dummy_l2_chain node_ctxt ~length = let open Lwt_result_syntax in let* head = Node_context.last_processed_head_opt node_ctxt in let head_level = - match head with - | None -> 0 - | Some h -> h.header.level |> Raw_level.to_int32 |> Int32.to_int + match head with None -> 0 | Some h -> h.header.level |> Int32.to_int in let batches = Stdlib.List.init length (fun i -> diff --git a/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.mli b/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.mli index 6f2035aefe24db787122872a049e94c679c67f76..b6571220f74a7fe518c03d6ed1c25b4fb7d98451 100644 --- a/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.mli +++ b/src/proto_018_Proxford/lib_sc_rollup_node/test/helpers/helpers.mli @@ -23,6 +23,7 @@ (* *) (*****************************************************************************) +open Octez_smart_rollup open Protocol open Alpha_context diff --git a/tezt/tests/expected/sc_rollup.ml/Oxford- arith - RPC API should work and be stable.out b/tezt/tests/expected/sc_rollup.ml/Oxford- arith - RPC API should work and be stable.out index 0385a3db079cc174c329dba59f41f042250962a5..b1686186e99dffa882b7debf32c8d968d36e3073 100644 --- a/tezt/tests/expected/sc_rollup.ml/Oxford- arith - RPC API should work and be stable.out +++ b/tezt/tests/expected/sc_rollup.ml/Oxford- arith - RPC API should work and be stable.out @@ -294,5 +294,6 @@ Error [ "[SC_ROLLUP_INBOX_HASH]", "[SC_ROLLUP_INBOX_HASH]", "[SC_ROLLUP_INBOX_HASH]" ] } }, - "messages": [ "31352d31", "31352d32", "31352d33", "31352d34", "31352d35" ], + "messages": + [ "0131352d31", "0131352d32", "0131352d33", "0131352d34", "0131352d35" ], "initial_tick": "352", "num_ticks": "28" } diff --git a/tezt/tests/expected/sc_rollup.ml/Oxford- wasm_2_0_0 - RPC API should work and be stable.out b/tezt/tests/expected/sc_rollup.ml/Oxford- wasm_2_0_0 - RPC API should work and be stable.out index bf95d9d8459a881ebce051a33e7f06bbbbdc6a94..48616972b8a330e536965328bfb45640d7ad80ee 100644 --- a/tezt/tests/expected/sc_rollup.ml/Oxford- wasm_2_0_0 - RPC API should work and be stable.out +++ b/tezt/tests/expected/sc_rollup.ml/Oxford- wasm_2_0_0 - RPC API should work and be stable.out @@ -299,5 +299,6 @@ null [ "[SC_ROLLUP_INBOX_HASH]", "[SC_ROLLUP_INBOX_HASH]", "[SC_ROLLUP_INBOX_HASH]" ] } }, - "messages": [ "31352d31", "31352d32", "31352d33", "31352d34", "31352d35" ], + "messages": + [ "0131352d31", "0131352d32", "0131352d33", "0131352d34", "0131352d35" ], "initial_tick": "1430000000000", "num_ticks": "99000000000" }