Revision 5fa6faa707c4eedc955a4f0562195703224a63fa authored by Thomas Letan on 14 August 2023, 09:49:56 UTC, committed by Thomas Letan on 14 August 2023, 09:55:15 UTC
Tztop was added at a time where the protocol couldn’t be loaded in utop.
This is no longer the case, and as a consequence, we can safely retire
tztop.
1 parent 5745a2e
Raw File
page_store.mli
(*****************************************************************************)
(*                                                                           *)
(* Open Source License                                                       *)
(* Copyright (c) 2023 Marigold <contact@marigold.dev>                        *)
(* Copyright (c) 2023 Trili Tech <contact@trili.tech>                        *)
(*                                                                           *)
(* 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 error +=
  | Reveal_data_path_not_a_directory of string
  | Cannot_create_reveal_data_dir of string
  | Cannot_write_page_to_page_storage of {hash : string; content : bytes}
  | Cannot_read_page_from_page_storage of string
  | Incorrect_page_hash of {
      expected : Dac_plugin.raw_hash;
      actual : Dac_plugin.raw_hash;
    }
  | Cannot_fetch_remote_page_with_flooding_strategy of {
      hash : Dac_plugin.raw_hash;
    }

(** [S] is the module type defining the backend required for
    persisting DAC pages data onto the page storage. *)
module type S = sig
  (** [t] represents an instance of a storage backened. *)
  type t

  (** [configuration] is the type of the configuration which can
      be used to initialize the store.*)
  type configuration

  (** [init configuration] initializes a page store using the information
      provided in [configuration]. *)
  val init : configuration -> t

  (** [save dac_plugin t ~hash ~content] writes [content] of page onto storage
      backend [t] under given [key].

      When writing fails it returns a [Cannot_write_page_to_page_storage]
      error.

      We require [save] to be atomic. *)
  val save :
    Dac_plugin.t ->
    t ->
    hash:Dac_plugin.hash ->
    content:bytes ->
    unit tzresult Lwt.t

  (** [mem dac_plugin t hash] Checks whether there is an entry for [hash] in
      the page storage.
      It can fail with error [Cannot_read_from_page_storage hash_as_string],
      if it was not possible to check that the page exists for any reason
      related to the page storage backend implementation. *)
  val mem : Dac_plugin.t -> t -> Dac_plugin.hash -> bool tzresult Lwt.t

  (** [load dac_plugin t hash] returns [content] of the storage backend [t]
      represented by a key. When reading fails it returns a
      [Cannot_read_page_from_page_storage] error. *)
  val load : Dac_plugin.t -> t -> Dac_plugin.hash -> bytes tzresult Lwt.t
end

(** [Filesystem] is an implementation of the page store backed up by
    the local filesystem. The configuration is a string denoting the
    path where files will be saved. A page is saved as a file whose
    name is the hex encoded hash of its content. *)
module Filesystem : S with type configuration = string

(** The configuration type for page stores that fetch pages remotely, when they
    are not available on the local page store. The parameter [cctxt]
    corresponds to the client context used to connect to the remote host for
    fetching pages. *)
type remote_configuration = {
  cctxt : Dac_node_client.cctxt;
  page_store : Filesystem.t;
}

(** A [Page_store] implementation backed by the local filesystem, which
   uses a connection to a Dac node to retrieve pages that are not
   saved locally. *)
module Remote : S with type configuration = remote_configuration

type remote_with_flooding_configuration = {
  timeout : float;
  cctxts : Dac_node_client.cctxt list;
  page_store : Filesystem.t;
}

(** A [Page_store] implementation backed by the local filesystem, which
   uses connections to a collection of Dac nodes to retrieve pages that are not
   saved locally. It retrieves pages by sending the same page request to each remote
   node and saves only 1 copy of the page locally. 
   
   It is typically used by the Observer node to retrieve missing pages from the DAC
   committee members.
   *)

(** TODO: https://gitlab.com/tezos/tezos/-/issues/5672
    Merge Remote_with_flooding into Remote *)
module Remote_with_flooding :
  S with type configuration = remote_with_flooding_configuration

(**/**)

module Internal_for_tests : sig
  (** [With_data_integrity_check] tweaks a module [P] of type [Page_store]
      so that the [content] of a page is verified against the [hash] supplied,
      before the page is saved in the underlying [Page_store]. If the
      verification of the hash fails, the
      page is not saved and the error [Hash_of_page_is_invalid] is returned. *)
  module With_data_integrity_check (P : S) :
    S with type configuration = P.configuration and type t = P.t

  (** [With_remote_context(R)(P)] tweaks a module [P] of type [Page_store]
      so that it will fetch pages using a function [R.fetch] to load pages
      remotely and saved them in the page store of type [P], when a page
      is not present in said store. *)
  module With_remote_fetch (R : sig
    type remote_context

    val fetch :
      Dac_plugin.t -> remote_context -> Dac_plugin.hash -> bytes tzresult Lwt.t
  end)
  (P : S) :
    S
      with type configuration = R.remote_context * P.t
       and type t = R.remote_context * P.t
end

(** [ensure_reveal_data_dir_exists reveal_data_dir] checks that the
      path at [reveal_data_dir] exists and is a directory. If
      the path does not exist, it is created as a directory.
      Parent directories are recursively created when they do not
      exist.

      This function may fail with
      {ul
        {li [Reveal_data_path_not_a_directory reveal_data_dir] if the
          path exists and is not a directory,}

        {li [Cannot_create_reveal_data_dir reveal_data_dir] If the
            creation of the directory fails.}
      }
  *)
val ensure_reveal_data_dir_exists : string -> unit tzresult Lwt.t
back to top