package octez-l2-libs
Octez layer2 libraries
Install
Dune Dependency
Authors
Maintainers
Sources
tezos-octez-v20.1.tag.bz2
sha256=ddfb5076eeb0b32ac21c1eed44e8fc86a6743ef18ab23fff02d36e365bb73d61
sha512=d22a827df5146e0aa274df48bc2150b098177ff7e5eab52c6109e867eb0a1f0ec63e6bfbb0e3645a6c2112de3877c91a17df32ccbff301891ce4ba630c997a65
doc/src/octez-l2-libs.scoru-wasm/durable.ml.html
Source file durable.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
(*****************************************************************************) (* *) (* 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. *) (* *) (*****************************************************************************) module T = Tezos_tree_encoding.Wrapped module Runner = Tezos_tree_encoding.Runner.Make (Tezos_tree_encoding.Wrapped) module E = Tezos_tree_encoding module Storage = Tezos_webassembly_interpreter.Durable_storage open Tezos_lazy_containers type t = T.tree (* The maximum size of bytes allowed to be read/written at once. *) let max_store_io_size = 2048L exception Invalid_key of string exception Index_too_large of int exception Value_not_found exception Tree_not_found exception Durable_empty = Storage.Durable_empty exception Out_of_bounds of (int64 * int64) exception IO_too_large exception Readonly_value let encoding = E.wrapped_tree let of_storage ~default s = match Storage.to_tree s with Some t -> t | None -> default let of_storage_exn s = Storage.to_tree_exn s let to_storage d = Storage.of_tree d type kind = Value | Directory type key = Writeable of string list | Readonly of string list (* A key is bounded to 250 bytes, including the implicit '/durable' prefix. Additionally, values are implicitly appended with '_'. **) let max_key_length = 250 - String.length "/durable" - String.length "/@" let key_of_string_exn s = if String.length s > max_key_length then raise (Invalid_key s) ; let key = match String.split '/' s with | "" :: tl -> tl (* Must start with '/' *) | _ -> raise (Invalid_key s) in let assert_valid_char = function | '.' | 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '-' | '_' -> () | _ -> raise (Invalid_key s) in let all_steps_valid = List.for_all (fun x -> x <> "" && (String.iter assert_valid_char x ; true)) in if all_steps_valid key then match key with "readonly" :: _ | [] -> Readonly key | _ -> Writeable key else raise (Invalid_key s) let key_of_string_opt s = try Some (key_of_string_exn s) with Invalid_key _ -> None (** We append all values with '@', which is an invalid key-character w.r.t. external use. This ensures that an external user is prevented from accidentally writing a value to a place which is part of another value (e.g. writing a chunked_byte_vector to "/a/length", where "/a/length" previously existed as part of another chunked_byte_vector encoding.) *) let value_marker = "@" let to_value_key k = List.append k [value_marker] let assert_key_writeable = function | Readonly _ -> raise Readonly_value | Writeable _ -> () let assert_max_bytes max_bytes = if max_store_io_size < max_bytes then raise IO_too_large let key_contents = function Readonly k | Writeable k -> k let exists tree key = let open Lwt.Syntax in let key = key_contents key in let+ opt = T.find_tree tree key in Option.is_some opt let find_value tree key = let open Lwt.Syntax in let key = key_contents key in let* opt = T.find_tree tree @@ to_value_key key in match opt with | None -> Lwt.return_none | Some subtree -> let+ value = Runner.decode Chunked_byte_vector.encoding subtree in Some value let find_value_exn tree key = let open Lwt.Syntax in let+ opt = find_value tree key in match opt with None -> raise Value_not_found | Some value -> value (** helper function used in the copy/move *) let find_tree_exn tree key = let open Lwt.Syntax in let key = key_contents key in let+ opt = T.find_tree tree key in match opt with None -> raise Tree_not_found | Some subtree -> subtree let copy_tree_exn tree ?(edit_readonly = false) from_key to_key = let open Lwt.Syntax in if not edit_readonly then assert_key_writeable to_key ; let* move_tree = find_tree_exn tree from_key in let to_key = key_contents to_key in T.add_tree tree to_key move_tree let count_subtrees tree key = T.length tree @@ key_contents key let list tree key = let open Lwt.Syntax in let+ subtrees = T.list tree @@ key_contents key in List.rev @@ List.rev_map (fun (name, _) -> if name = "@" then "" else name) subtrees let delete ?(edit_readonly = false) ~kind tree key = if not edit_readonly then assert_key_writeable key ; match kind with | Value -> T.remove tree @@ to_value_key (key_contents key) | Directory -> T.remove tree @@ key_contents key let subtree_name_at tree key index = let open Lwt.Syntax in let* subtree = find_tree_exn tree key in let* list = T.list ~offset:index ~length:1 subtree [] in let nth = List.nth list 0 in match nth with | Some (step, _) when Compare.String.(step = value_marker) -> Lwt.return "" | Some (step, _) -> Lwt.return step | None -> raise (Index_too_large index) let move_tree_exn tree from_key to_key = let open Lwt.Syntax in assert_key_writeable from_key ; assert_key_writeable to_key ; let* move_tree = find_tree_exn tree from_key in let* tree = delete ~kind:Directory tree from_key in T.add_tree tree (key_contents to_key) move_tree let hash ~kind tree key = let open Lwt.Syntax in let key = match kind with | Value -> to_value_key (key_contents key) | Directory -> key_contents key in let+ opt = T.find_tree tree key in Option.map (fun subtree -> T.hash subtree) opt let hash_exn ~kind tree key = let open Lwt.Syntax in let+ opt = hash ~kind tree key in match opt with | None -> let exn = match kind with Value -> Value_not_found | Directory -> Tree_not_found in raise exn | Some hash -> hash let set_value_exn tree ?(edit_readonly = false) key str = if not edit_readonly then assert_key_writeable key ; let key = to_value_key @@ key_contents key in let encoding = E.scope key Chunked_byte_vector.encoding in Runner.encode encoding (Tezos_lazy_containers.Chunked_byte_vector.of_string str) tree let create_value_exn tree ?(edit_readonly = false) key size = let open Lwt.Syntax in let open Tezos_lazy_containers in if not edit_readonly then assert_key_writeable key ; let key = to_value_key @@ key_contents key in let* opt = T.find_tree tree key in let encoding = E.scope key Chunked_byte_vector.encoding in match opt with | None -> let* durable = Runner.encode encoding (Chunked_byte_vector.allocate size) tree in Lwt.return_some durable | Some _subtree -> Lwt.return_none let write_value_exn tree ?(edit_readonly = false) key offset bytes = if not edit_readonly then assert_key_writeable key ; let open Lwt.Syntax in let open Tezos_lazy_containers in let num_bytes = Int64.of_int @@ String.length bytes in assert_max_bytes num_bytes ; let key = to_value_key @@ key_contents key in let* opt = T.find_tree tree key in let encoding = E.scope key Chunked_byte_vector.encoding in let* value = match opt with | None -> Lwt.return @@ Chunked_byte_vector.allocate 0L | Some _subtree -> Runner.decode encoding tree in let vec_len = Chunked_byte_vector.length value in if offset > vec_len then raise (Out_of_bounds (offset, vec_len)) ; let grow_by = Int64.(num_bytes |> add offset |> Fun.flip sub vec_len) in if Int64.compare grow_by 0L > 0 then Chunked_byte_vector.grow value grow_by ; let* () = Chunked_byte_vector.store_bytes value offset @@ Bytes.of_string bytes in Runner.encode encoding value tree let read_value_exn tree key offset num_bytes = let open Lwt.Syntax in let open Tezos_lazy_containers in assert_max_bytes num_bytes ; let* value = find_value_exn tree key in let vec_len = Chunked_byte_vector.length value in if offset < 0L || offset >= vec_len then raise (Out_of_bounds (offset, vec_len)) ; let num_bytes = Int64.(num_bytes |> add offset |> min vec_len |> Fun.flip sub offset) in let+ bytes = Chunked_byte_vector.load_bytes value offset num_bytes in Bytes.to_string bytes module Internal_for_tests = struct let key_is_readonly = function Readonly _ -> true | Writeable _ -> false let key_to_list = key_contents end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>