Raw File
(*****************************************************************************)
(*                                                                           *)
(* Open Source License                                                       *)
(* Copyright (c) 2022-2023 TriliTech <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.                                                 *)
(*                                                                           *)
(*****************************************************************************)

(** [t] allows a [wrapped_tree] to be manipulated as a tree of
    [chunked_byte_vector] *)
type t

(** [key] was too long, or contained invalid steps. *)
exception Invalid_key of string

(** Invalid index for a subkey *)
exception Index_too_large of int

(** A value was not found in the durable store. *)
exception Value_not_found

(** A tree does not exists under key in the durable store. *)
exception Tree_not_found

(** Attempted to write/read to/from a value at [offset],
    beyond the [limit]. *)
exception Out_of_bounds of (int64 * int64)

(** [Durable_storage.t] was empty. *)
exception Durable_empty

(** Cannot modify a readonly value. *)
exception Readonly_value

(** Cannot read from or write to more than 2,048 bytes *)
exception IO_too_large

(** [encoding] is a [Tezos_tree_encoding] for [t]. *)
val encoding : t Tezos_tree_encoding.t

val of_storage :
  default:t -> Tezos_webassembly_interpreter.Durable_storage.t -> t

(** @raise Durable_empty *)
val of_storage_exn : Tezos_webassembly_interpreter.Durable_storage.t -> t

val to_storage : t -> Tezos_webassembly_interpreter.Durable_storage.t

(** Type describing the behavior of generic functions:
    - [Value] indicates the operation should work on the value only
    - [Directory] indicates the operation should work on the value and all
    subkeys under the given key.

    See [hash], for example.
*)
type kind = Value | Directory

(** [key] is the type that indexes [t]. It enforces several constraints:
    - a key's length is bounded.
    - a key is a series of non-empty steps, where
    - a step is preceded by '/'
    - a step only contains alphanumeric ascii, or dots ('.') *)
type key

(** [max_key_length] is the maximum length of a key in bytes. *)
val max_key_length : int

(** @raise Invalid_key *)
val key_of_string_exn : string -> key

val key_of_string_opt : string -> key option

(** [find_value durable key] optionally looks for the value encoded at [key]
    in [durable]. *)
val find_value :
  t -> key -> Tezos_lazy_containers.Chunked_byte_vector.t option Lwt.t

(** @raise Value_not_found *)
val find_value_exn :
  t -> key -> Tezos_lazy_containers.Chunked_byte_vector.t Lwt.t

(** [copy_tree_exn tree ?edit_readonly from_key to_key] produces a new tree in which a copy of
    the entire subtree at from_key is copied to to_key.

    [~edit_readonly:true] allows a a tree to be copied into a readonly location.

    @raise Readonly_value
*)
val copy_tree_exn : t -> ?edit_readonly:bool -> key -> key -> t Lwt.t

(** [move_tree_exn tree from_key to_key] produces a new tree in which
    the entire subtree at from_key is moved to to_key.

    @raise Readonly_value
*)
val move_tree_exn : t -> key -> key -> t Lwt.t

(** [list durable key] returns the subkeys under [key]. *)
val list : t -> key -> string list Lwt.t

(** [count_subtrees durable key] returns the number of subtrees under [key]. *)
val count_subtrees : t -> key -> int Lwt.t

(** [subtree_name_at durable key n] returns the name of the n_th subtree
    under [key]. *)
val subtree_name_at : t -> key -> int -> string Lwt.t

(** [delete ?edit_readonly ~kind durable key] deletes the value of [key] if
    [kind = `Value], and subtrees and/or values of [key] if [kind = `All].

    @raise Readonly_value when [edit_readonly] is not set while trying
    to edit the readonly section.
*)
val delete : ?edit_readonly:bool -> kind:kind -> t -> key -> t Lwt.t

(** [hash ~kind durable key] retrieves the tree hash of the value (if [kind =
    Value]) or the complete directory ([kind = Directory]) at the given [key].
    This is not the same as the hash of the value. *)
val hash : kind:kind -> t -> key -> Context_hash.t option Lwt.t

(** [hash_exn ~kind durable key] retrieves the tree hash of the value (if [kind
    = Value]) or the complete directory ([kind = Directory]) at the given [key].
    This is not the same as the hash of the value.

    @raise Value_not_found when [key] is not found and [kind = Value]
    @raise Tree_not_found when [key] is not found and [kind = Directory]. *)
val hash_exn : kind:kind -> t -> key -> Context_hash.t Lwt.t

(** [set_value_exn durable key str] installs the value [str] in
    [durable] under [key], replacing any previous contents under this
    key without fetching it. *)
val set_value_exn : t -> ?edit_readonly:bool -> key -> string -> t Lwt.t

(** [create_value_exn ?edit_readonly durable key size] allocates a new value of
    [size] at the given [key]. Returns [Some durable] if the value didn't exist,
    and [None] if there was already a value at the given [key]

    @raise Invalid_key if the key is invalid.
    @raise Readonly_value iff [edit_readonly] is not set to [true]
    when attempting to write in the [readonly] section.
*)
val create_value_exn :
  t -> ?edit_readonly:bool -> key -> int64 -> t option Lwt.t

(** [write_value_exn ?edit_readonly durable key offset bytes] writes
    [bytes] to [key], starting at the given [offset].

    If no value at [key] exists, it is created.

    [~edit_readonly:true] allows a value to be written into a readonly location.

    @raise Out_of_bounds
    @raise Readonly_value iff [edit_readonly] is not set to [true]
    when attempting to write in the [readonly] section.
*)
val write_value_exn :
  t -> ?edit_readonly:bool -> key -> int64 -> string -> t Lwt.t

(** [read_value durable key offset max_bytes] reads up to [max_bytes]
    bytes from the value at [key], starting at the given [offset].

    @raise Value_not_found when [key] is not found.
    @raise Out_of_bounds when [offset] is larger than the value.
*)
val read_value_exn : t -> key -> int64 -> int64 -> string Lwt.t

module Internal_for_tests : sig
  val key_is_readonly : key -> bool

  val key_to_list : key -> string list
end
back to top