diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index b4b791877439bc9cc7e5dcde8de00a62e30cbdc8..988d6ad409905fe30f89e87bb5320c27e669e39d 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2833,6 +2833,15 @@ module Dal : sig val genesis : t val equal : t -> t -> bool + + val encoding : t Data_encoding.t + + module History_cache : Bounded_history_repr.S + + val add_confirmed_slots_no_cache : t -> Slot.t list -> t tzresult + + val add_confirmed_slots : + t -> History_cache.t -> Slot.t list -> (t * History_cache.t) tzresult end end diff --git a/src/proto_alpha/lib_protocol/dal_slot_repr.ml b/src/proto_alpha/lib_protocol/dal_slot_repr.ml index d21abd25886bd91758c4345285d7549db610e5c6..58ece202ea6eb287c1f7917f7e9897a12922e179 100644 --- a/src/proto_alpha/lib_protocol/dal_slot_repr.ml +++ b/src/proto_alpha/lib_protocol/dal_slot_repr.ml @@ -71,7 +71,7 @@ type slot = t type slot_index = Index.t -let equal ({published_level; index; header} : t) s2 = +let slot_equal ({published_level; index; header} : t) s2 = Raw_level_repr.equal published_level s2.published_level && Index.equal index s2.index && Header.equal header s2.header @@ -120,7 +120,7 @@ module Page = struct page_index end -let encoding = +let slot_encoding = let open Data_encoding in conv (fun {published_level; index; header} -> (published_level, index, header)) @@ -130,7 +130,7 @@ let encoding = (req "index" Data_encoding.uint8) (req "header" Header.encoding)) -let pp fmt {published_level; index; header} = +let pp_slot fmt {published_level; index; header} = Format.fprintf fmt "published_level: %a index: %a header: %a" @@ -186,7 +186,7 @@ module Slots_history = struct module Leaf = struct type t = slot - let to_bytes = Data_encoding.Binary.to_bytes_exn encoding + let to_bytes = Data_encoding.Binary.to_bytes_exn slot_encoding end module Content_prefix = struct @@ -239,12 +239,19 @@ module Slots_history = struct pointers. *) type ptr = Pointer_hash.t - type t = (content, ptr) Skip_list.cell option + type history = (content, ptr) Skip_list.cell - let slot_encoding = encoding + type t = history option - let encoding = - Skip_list.encoding Pointer_hash.encoding encoding |> Data_encoding.option + let history_encoding = + Skip_list.encoding Pointer_hash.encoding slot_encoding + + let equal_history : history -> history -> bool = + Skip_list.equal Pointer_hash.equal slot_equal + + let encoding = Data_encoding.option history_encoding + + let equal : t -> t -> bool = Option.equal equal_history let genesis : t = None @@ -255,18 +262,58 @@ module Slots_history = struct :: List.map Pointer_hash.to_bytes back_pointers_hashes |> Pointer_hash.hash_bytes - let add_confirmed_slot t slot = + let pp_history fmt (history : history) = + let history_hash = hash_skip_list_cell history in + Format.fprintf + fmt + "@[hash : %a@;%a@]" + Pointer_hash.pp + history_hash + (Skip_list.pp ~pp_content:pp_slot ~pp_ptr:Pointer_hash.pp) + history + + module History_cache = + Bounded_history_repr.Make + (struct + let name = "dal_slots_cache" + end) + (Pointer_hash) + (struct + type t = history + + let encoding = history_encoding + + let pp = pp_history + + let equal = equal_history + end) + + let add_confirmed_slot (t, cache) slot = + let open Tzresult_syntax in match t with - | None -> Some (Skip_list.genesis slot) + | None -> return (Some (Skip_list.genesis slot), cache) | Some t -> let content = slot in let prev_cell_ptr = hash_skip_list_cell t in - Skip_list.next ~prev_cell:t ~prev_cell_ptr content |> Option.some - - let add_confirmed_slots t slots = List.fold_left add_confirmed_slot t slots - - let equal = Option.equal @@ Skip_list.equal Pointer_hash.equal equal + let* cache = History_cache.remember prev_cell_ptr t cache in + return + ( Skip_list.next ~prev_cell:t ~prev_cell_ptr content |> Option.some, + cache ) + + let add_confirmed_slots t cache slots = + List.fold_left_e add_confirmed_slot (t, cache) slots + + let add_confirmed_slots_no_cache = + let no_cache = History_cache.empty ~capacity:0L in + fun t slots -> + List.fold_left_e add_confirmed_slot (t, no_cache) slots >|? fst end include V1 end + +let encoding = slot_encoding + +let pp = pp_slot + +let equal = slot_equal diff --git a/src/proto_alpha/lib_protocol/dal_slot_repr.mli b/src/proto_alpha/lib_protocol/dal_slot_repr.mli index 9c483bc8ddbefbf7ccba27f1ac25438223e826f7..18ded1f945b557df98ea573d68cf1ea9faedf888 100644 --- a/src/proto_alpha/lib_protocol/dal_slot_repr.mli +++ b/src/proto_alpha/lib_protocol/dal_slot_repr.mli @@ -177,9 +177,24 @@ module Slots_history : sig (** First cell of this skip list. *) val genesis : t - (** [add_confirmed_slots cell slots] updates the given structure - [cell] with the list of [slots]. *) - val add_confirmed_slots : t -> slot list -> t + (** The [History_cache.t] structure is basically a bounded lookup table of + {!t} skip lists. (See {!Bounded_history_repr.S}). In the L1 layer, the + capacity (bound) is set to zero (nothing is remembered). By contrast, + the rollup node uses a history cache with a (sufficiently) large capacity + to participate in all potential refutation games occurring during the + challenge period. Indeed, the successive recent skip-lists stored in + the cache are needed to produce proofs involving slots' pages. *) + module History_cache : Bounded_history_repr.S + + (** [add_confirmed_slots hist cache slots] updates the given structure + [hist] with the list of [slots]. The given [cache] is also updated to + add successive values of [cell] to it. *) + val add_confirmed_slots : + t -> History_cache.t -> slot list -> (t * History_cache.t) tzresult + + (** [add_confirmed_slots_no_cache cell slots] same as {!add_confirmed_slots}, + but no cache is updated. *) + val add_confirmed_slots_no_cache : t -> slot list -> t tzresult (** [equal a b] returns true iff a is equal to b. *) val equal : t -> t -> bool diff --git a/src/proto_alpha/lib_protocol/dal_slot_storage.ml b/src/proto_alpha/lib_protocol/dal_slot_storage.ml index 937d2d6359a27733f538970a9b8b2b8237eca189..e34d6a94191d34a407d4a91c6cfe9e1d23b15839 100644 --- a/src/proto_alpha/lib_protocol/dal_slot_storage.ml +++ b/src/proto_alpha/lib_protocol/dal_slot_storage.ml @@ -51,9 +51,12 @@ let get_slots_history ctxt = let update_skip_list ctxt ~confirmed_slots = get_slots_history ctxt >>=? fun slots_history -> - Dal_slot_repr.Slots_history.add_confirmed_slots slots_history confirmed_slots - |> Storage.Dal.Slots_history.add ctxt - >>= fun ctxt -> return ctxt + Lwt.return + @@ Dal_slot_repr.Slots_history.add_confirmed_slots_no_cache + slots_history + confirmed_slots + >>=? fun slots_history -> + Storage.Dal.Slots_history.add ctxt slots_history >|= ok let finalize_pending_slots ctxt = let {Level_repr.level = raw_level; _} = Raw_context.current_level ctxt in