package tezos-protocol-014-PtKathma
Tezos protocol 014-PtKathma package
Install
Dune Dependency
Authors
Maintainers
Sources
tezos-octez-v20.1.tag.bz2
sha256=ddfb5076eeb0b32ac21c1eed44e8fc86a6743ef18ab23fff02d36e365bb73d61
sha512=d22a827df5146e0aa274df48bc2150b098177ff7e5eab52c6109e867eb0a1f0ec63e6bfbb0e3645a6c2112de3877c91a17df32ccbff301891ce4ba630c997a65
doc/src/tezos_raw_protocol_014_PtKathma/ticket_lazy_storage_diff.ml.html
Source file ticket_lazy_storage_diff.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 275 276 277 278 279 280 281 282 283 284 285 286 287
(*****************************************************************************) (* *) (* Open Source License *) (* Copyright (c) 2021 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. *) (* *) (*****************************************************************************) open Alpha_context type error += Failed_to_load_big_map_value_type of Big_map.Id.t let () = let open Data_encoding in register_error_kind `Permanent ~id:"Failed_to_load_big_map_value_type" ~title:"Failed to load big-map value type" ~description: "Failed to load big-map value type when computing ticket diffs." ~pp:(fun ppf big_map_id -> Format.fprintf ppf "Failed to load big-map value type for big-map-id: '%a'" Z.pp_print (Big_map.Id.unparse_to_z big_map_id)) (obj1 (req "big_map_id" Big_map.Id.encoding)) (function | Failed_to_load_big_map_value_type big_map_id -> Some big_map_id | _ -> None) (fun big_map_id -> Failed_to_load_big_map_value_type big_map_id) (** Extracts the ticket-token and amount from an ex_ticket value. *) let token_and_amount ctxt ex_ticket = Gas.consume ctxt Ticket_costs.Constants.cost_collect_tickets_step >|? fun ctxt -> let token, amount = Ticket_token.token_and_amount_of_ex_ticket ex_ticket in ((token, Script_int.to_zint amount), ctxt) (** Extracts the ticket-token and amount from an ex_ticket value and returns the opposite of the amount. This is used to account for removal of tickets inside big maps when either a ticket is taken out of a big map or a whole big map is dropped. *) let neg_token_and_amount ctxt ex_ticket = token_and_amount ctxt ex_ticket >>? fun ((token, amount), ctxt) -> Gas.consume ctxt (Ticket_costs.negate_cost amount) >|? fun ctxt -> ((token, Z.neg amount), ctxt) let parse_value_type ctxt value_type = Script_ir_translator.parse_big_map_value_ty ctxt ~legacy:true (Micheline.root value_type) (** Collects all ticket-token balances contained in the given node and prepends them to the accumulator [acc]. The given [get_token_and_amount] function extracts the ticket-token and amount (either positive or negative) from an [ex_ticket] value, depending on whether the diff stems from adding or removing a value containing tickets. *) let collect_token_diffs_of_node ctxt has_tickets node ~get_token_and_amount acc = Ticket_scanner.tickets_of_node ctxt (* It's currently not possible to have nested lazy structures, but this is for future proofing. *) ~include_lazy:true ~allow_zero_amount_tickets:true has_tickets (Micheline.root node) >>=? fun (ex_tickets, ctxt) -> List.fold_left_e (fun (acc, ctxt) ticket -> get_token_and_amount ctxt ticket >|? fun (item, ctxt) -> (item :: acc, ctxt)) (acc, ctxt) ex_tickets >>?= return (** A module for keeping track of script-key-hashes. It's used for looking up keys for multiple big-map updates referencing the same key. *) module Key_hash_map = Carbonated_map.Make (struct type context = Alpha_context.context let consume = Alpha_context.Gas.consume end) (struct type t = Script_expr_hash.t let compare = Script_expr_hash.compare let compare_cost _ = Ticket_costs.Constants.cost_compare_ticket_hash end) (** Collects all ticket-token diffs from a big-map update and prepends them to the accumulator [acc]. *) let collect_token_diffs_of_big_map_update ctxt ~big_map_id has_tickets {Lazy_storage_kind.Big_map.key = _; key_hash; value} already_updated acc = let collect_token_diffs_of_node_option ctxt ~get_token_and_amount expr_opt acc = match expr_opt with | Some expr -> collect_token_diffs_of_node ctxt has_tickets expr ~get_token_and_amount acc | None -> return (acc, ctxt) in (* First check if the key-hash has already been updated, in that case pull the value from the [already_updated] map. Note that this should not happen with the current implementation of big-map overlays as it guarantees that keys are unique. The extra check is used for future proofing. *) ( Key_hash_map.find ctxt key_hash already_updated >>?= fun (val_opt, ctxt) -> match val_opt with | Some updated_value -> return (updated_value, ctxt) | None -> (* Load tickets from the old value that was removed. *) Big_map.get_opt ctxt big_map_id key_hash >|=? fun (ctxt, old_value) -> (old_value, ctxt) ) >>=? fun (old_value, ctxt) -> collect_token_diffs_of_node_option ctxt ~get_token_and_amount:neg_token_and_amount old_value acc >>=? fun (acc, ctxt) -> Key_hash_map.update ctxt key_hash (fun ctxt _ -> ok (Some value, ctxt)) already_updated >>?= fun (already_updated, ctxt) -> (* TODO: #2303 Avoid re-parsing the value. In order to find tickets from the new value, we need to parse it. It would be more efficient if the value was already present. *) collect_token_diffs_of_node_option ctxt ~get_token_and_amount:token_and_amount value acc >|=? fun (tickets, ctxt) -> (tickets, already_updated, ctxt) (** Collects all ticket-token diffs from a list of big-map updates and prepends them to the accumulator [acc]. *) let collect_token_diffs_of_big_map_updates ctxt big_map_id ~value_type updates acc = (* TODO: #2303 Avoid re-parsing the value type. We should have the non-serialized version of the value type. *) parse_value_type ctxt value_type >>?= fun (Script_ir_translator.Ex_ty value_type, ctxt) -> Ticket_scanner.type_has_tickets ctxt value_type >>?= fun (has_tickets, ctxt) -> List.fold_left_es (fun (acc, already_updated, ctxt) update -> collect_token_diffs_of_big_map_update ctxt ~big_map_id has_tickets update already_updated acc) (acc, Key_hash_map.empty, ctxt) updates >|=? fun (acc, _already_updated, ctxt) -> (acc, ctxt) (** Given a big-map id, this function collects ticket-token diffs and prepends them to the accumulator [acc]. *) let collect_token_diffs_of_big_map ctxt ~get_token_and_amount big_map_id acc = Gas.consume ctxt Ticket_costs.Constants.cost_collect_tickets_step >>?= fun ctxt -> Big_map.exists ctxt big_map_id >>=? fun (ctxt, key_val_tys) -> match key_val_tys with | Some (_key_ty, value_ty) -> (* TODO: #2303 Avoid re-parsing the value type. In order to find tickets from the value, we need to parse the value type. It would be more efficient if the value preserved. *) parse_value_type ctxt value_ty >>?= fun (Script_ir_translator.Ex_ty value_type, ctxt) -> Ticket_scanner.type_has_tickets ctxt value_type >>?= fun (has_tickets, ctxt) -> (* Iterate over big-map items. *) (* TODO: #2316 Verify gas-model for [Big_map.list_values]. This is to make sure that we pay sufficient gas for traversing the values. *) Big_map.list_values ctxt big_map_id >>=? fun (ctxt, exprs) -> List.fold_left_es (fun (acc, ctxt) node -> collect_token_diffs_of_node ctxt has_tickets node ~get_token_and_amount acc) (acc, ctxt) exprs | None -> fail (Failed_to_load_big_map_value_type big_map_id) (** Collects ticket-token diffs from a big-map and a list of updates, and prepends them to the given accumulator [acc]. *) let collect_token_diffs_of_big_map_and_updates ctxt big_map_id updates acc = Gas.consume ctxt Ticket_costs.Constants.cost_collect_tickets_step >>?= fun ctxt -> Big_map.exists ctxt big_map_id >>=? fun (ctxt, key_val_opt) -> match key_val_opt with | Some (_val, value_type) -> collect_token_diffs_of_big_map_updates ctxt big_map_id ~value_type updates acc | None -> fail (Failed_to_load_big_map_value_type big_map_id) (** Inspects the given [Lazy_storage.diffs_item] and prepends all ticket-token diffs, resulting from the updates, to the given accumulator [acc]. *) let collect_token_diffs_of_big_map_diff ctxt diff_item acc = Gas.consume ctxt Ticket_costs.Constants.cost_collect_tickets_step >>?= fun ctxt -> match diff_item with | Lazy_storage.Item (Lazy_storage_kind.Big_map, big_map_id, Remove) -> (* Collect all removed tokens from the big-map. *) collect_token_diffs_of_big_map ctxt ~get_token_and_amount:neg_token_and_amount big_map_id acc | Item (Lazy_storage_kind.Big_map, big_map_id, Update {init; updates}) -> ( match init with | Lazy_storage.Existing -> (* Collect token diffs from the updates to the big-map. *) collect_token_diffs_of_big_map_and_updates ctxt big_map_id updates acc | Copy {src} -> (* Collect tokens diffs from the source of the copied big-map. *) collect_token_diffs_of_big_map ctxt ~get_token_and_amount:token_and_amount src acc >>=? fun (acc, ctxt) -> (* Collect token diffs from the updates to the copied big-map. *) collect_token_diffs_of_big_map_and_updates ctxt src updates acc | Alloc {key_type = _; value_type} -> collect_token_diffs_of_big_map_updates ctxt big_map_id ~value_type updates acc) | Item (Sapling_state, _, _) -> return (acc, ctxt) let ticket_diffs_of_lazy_storage_diff ctxt diffs_items = List.fold_left_es (fun (acc, ctxt) diff_item -> collect_token_diffs_of_big_map_diff ctxt diff_item acc) ([], ctxt) diffs_items
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>