From fa5bef52ecdb0193f6a3b94e9a61fedb93058173 Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Tue, 7 Oct 2025 17:04:18 +0200 Subject: [PATCH 1/6] DAL/Proto: introduce a dynamic case in attestaion_lag_kind (1) The encoding will be handled in the next MR --- .../lib_protocol/alpha_context.mli | 2 +- src/proto_alpha/lib_protocol/dal_slot_repr.ml | 20 ++++++++++++++++--- .../lib_protocol/dal_slot_repr.mli | 15 +++++++++++--- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index e7eeb063325f..4aabbbfece08 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -3098,7 +3098,7 @@ module Dal : sig module Slots_history : sig type t - type attestation_lag_kind = Legacy + type attestation_lag_kind = Legacy | Dynamic of int val attestation_lag_value : attestation_lag_kind -> int diff --git a/src/proto_alpha/lib_protocol/dal_slot_repr.ml b/src/proto_alpha/lib_protocol/dal_slot_repr.ml index ccb8f536180a..f679c65703c0 100644 --- a/src/proto_alpha/lib_protocol/dal_slot_repr.ml +++ b/src/proto_alpha/lib_protocol/dal_slot_repr.ml @@ -335,18 +335,24 @@ module History = struct (* History is represented via a skip list. The content of the cell is the hash of a merkle proof. *) - type attestation_lag_kind = Legacy + type attestation_lag_kind = Legacy | Dynamic of int (** The legacy attestation lag used by mainnet, ghostnet and shadownet *) let legacy_attestation_lag = 8 - let attestation_lag_value = function Legacy -> legacy_attestation_lag + let attestation_lag_value = function + | Legacy -> legacy_attestation_lag + | Dynamic n -> n let attestation_lag_kind_equal lag1 lag2 = - match (lag1, lag2) with Legacy, Legacy -> true + match (lag1, lag2) with + | Legacy, Legacy -> true + | Dynamic n1, Dynamic n2 -> Compare.Int.equal n1 n2 + | Legacy, Dynamic _ | Dynamic _, Legacy -> false let pp_attestation_lag_kind fmt = function | Legacy -> Format.fprintf fmt "Legacy:%d" legacy_attestation_lag + | Dynamic n -> Format.fprintf fmt "Dynamic:%d" n type cell_id = {header_id : Header.id; attestation_lag : attestation_lag_kind} @@ -457,6 +463,10 @@ module History = struct (function | Unpublished {header_id; attestation_lag = Legacy} -> Some ((), header_id) + | Unpublished {attestation_lag = Dynamic _; _} -> + (* We'll use a different encoding for [Dynamic] to keep + encoding&hash retro-compatibility for [Legacy]. *) + None | Published _ -> None) (fun ((), header_id) -> Unpublished {header_id; attestation_lag = Legacy}) @@ -475,6 +485,10 @@ module History = struct Header.encoding) (function | Unpublished _ -> None + | Published {attestation_lag = Dynamic _; _} -> + (* We'll use a different encoding for [Dynamic] to keep + encoding&hash retro-compatibility for [Legacy]. *) + None | Published { header; diff --git a/src/proto_alpha/lib_protocol/dal_slot_repr.mli b/src/proto_alpha/lib_protocol/dal_slot_repr.mli index 8d92d2f4dd5e..3342b1cc6b4c 100644 --- a/src/proto_alpha/lib_protocol/dal_slot_repr.mli +++ b/src/proto_alpha/lib_protocol/dal_slot_repr.mli @@ -279,9 +279,18 @@ module History : sig confirmed slot headers. *) type t - (** Storing attestation lag in the cells of skip-lists in a retro-compatible - way. This first step is to introduce the needed code for the extension. *) - type attestation_lag_kind = Legacy + (** Starting with the first protocol (P) with this refactoring, the + attestation lag changes, and future protocols may even make it dynamic. We + want to store the attestation-lag information in skip-list cells without + breaking the hashes of cells produced before P. To do so, we use the type + below to either use the legacy (implicit) lag or an explicit value carried + by new cells. + + - [Legacy]: cell predates protocol P; the lag wasn't serialized, so we + infer it from history and DO NOT include it in the cell's encoding. + - [Dynamic n]: cell created at/after P; the lag is serialized and thus + committed in the cell's hash. *) + type attestation_lag_kind = Legacy | Dynamic of int (** Returns the value of attestation_lag parameter based on the given attestation_lag_kind. *) -- GitLab From 21cef7262303e6c464e7c14f1d7145c9f89a51b8 Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Wed, 8 Oct 2025 08:02:14 +0200 Subject: [PATCH 2/6] DAL/Proto: introduce a dynamic case in attestaion_lag_kind. adapt encoding --- src/proto_alpha/lib_protocol/dal_slot_repr.ml | 81 ++++++++++++++++++- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/src/proto_alpha/lib_protocol/dal_slot_repr.ml b/src/proto_alpha/lib_protocol/dal_slot_repr.ml index f679c65703c0..9cfdc9aa4c25 100644 --- a/src/proto_alpha/lib_protocol/dal_slot_repr.ml +++ b/src/proto_alpha/lib_protocol/dal_slot_repr.ml @@ -465,7 +465,7 @@ module History = struct Some ((), header_id) | Unpublished {attestation_lag = Dynamic _; _} -> (* We'll use a different encoding for [Dynamic] to keep - encoding&hash retro-compatibility for [Legacy]. *) + encoding and hash retro-compatibility for [Legacy]. *) None | Published _ -> None) (fun ((), header_id) -> @@ -487,7 +487,7 @@ module History = struct | Unpublished _ -> None | Published {attestation_lag = Dynamic _; _} -> (* We'll use a different encoding for [Dynamic] to keep - encoding&hash retro-compatibility for [Legacy]. *) + encoding and hash retro-compatibility for [Legacy]. *) None | Published { @@ -522,7 +522,82 @@ module History = struct total_shards; }) in - union ~tag_size:`Uint8 [legacy_unpublished_case; legacy_published_case] + let dynamic_unpublished_case = + case + ~title:"unpublished_dyn" + (Tag 4) + (merge_objs + (obj2 + (req "kind" (constant "unpublished")) + (req "attestation_lag" uint8)) + Header.id_encoding) + (function + | Unpublished {header_id; attestation_lag = Dynamic lag} -> + Some (((), lag), header_id) + | Unpublished {attestation_lag = Legacy; _} -> None + | Published _ -> None) + (fun (((), lag), header_id) -> + Unpublished {header_id; attestation_lag = Dynamic lag}) + in + let dynamic_published_case = + case + ~title:"published_dyn" + (Tag 5) + (merge_objs + (obj6 + (req "kind" (constant "published")) + (req "publisher" Contract_repr.encoding) + (req "is_proto_attested" bool) + (req "attested_shards" uint16) + (req "total_shards" uint16) + (req "attestation_lag" uint8)) + Header.encoding) + (function + | Unpublished _ -> None + | Published {attestation_lag = Legacy; _} -> None + | Published + { + header; + attestation_lag = Dynamic lag; + publisher; + is_proto_attested; + attested_shards; + total_shards; + } -> + Some + ( ( (), + publisher, + is_proto_attested, + attested_shards, + total_shards, + lag ), + header )) + (fun ( ( (), + publisher, + is_proto_attested, + attested_shards, + total_shards, + lag ), + header ) + -> + Published + { + header; + attestation_lag = Dynamic lag; + publisher; + is_proto_attested; + attested_shards; + total_shards; + }) + in + union + ~tag_size:`Uint8 + [ + legacy_unpublished_case; + legacy_published_case; + dynamic_unpublished_case; + dynamic_published_case; + ] let equal t1 t2 = match (t1, t2) with -- GitLab From aba62502390416d960b115ad349c7f8d8a77a46e Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Tue, 7 Oct 2025 17:36:40 +0200 Subject: [PATCH 3/6] DAL/Proto: extend update_skip_list to enable providing the attestation lag --- .../lib_protocol/alpha_context.mli | 2 ++ src/proto_alpha/lib_protocol/dal_slot_repr.ml | 12 ++++++--- .../lib_protocol/dal_slot_repr.mli | 2 ++ .../lib_protocol/dal_slot_storage.ml | 1 + .../test/pbt/test_dal_slot_proof.ml | 14 +++++----- .../test/pbt/test_sc_rollup_encoding.ml | 3 ++- .../test/unit/test_dal_slot_proof.ml | 26 +++++++++++-------- .../test/test_octez_conversions.ml | 26 +++++++++++-------- 8 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 4aabbbfece08..a233813c9ab4 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -3151,6 +3151,7 @@ module Dal : sig t -> published_level:Raw_level.t -> number_of_slots:int -> + attestation_lag:attestation_lag_kind -> (Slot.Header.t * Contract.t * Attestation.attestation_status) list -> t tzresult @@ -3159,6 +3160,7 @@ module Dal : sig History_cache.t -> published_level:Raw_level.t -> number_of_slots:int -> + attestation_lag:attestation_lag_kind -> (Slot.Header.t * Contract.t * Attestation.attestation_status) list -> (t * History_cache.t) tzresult diff --git a/src/proto_alpha/lib_protocol/dal_slot_repr.ml b/src/proto_alpha/lib_protocol/dal_slot_repr.ml index 9cfdc9aa4c25..4103c567e44b 100644 --- a/src/proto_alpha/lib_protocol/dal_slot_repr.ml +++ b/src/proto_alpha/lib_protocol/dal_slot_repr.ml @@ -912,7 +912,7 @@ module History = struct will simplify the shape of proofs and help bounding the history cache required for their generation. *) let update_skip_list (t : t) cache ~published_level ~number_of_slots - slot_headers_with_statuses = + ~attestation_lag slot_headers_with_statuses = let open Result_syntax in let* () = List.iter_e @@ -927,14 +927,19 @@ module History = struct fill_slot_headers ~number_of_slots ~published_level - ~attestation_lag:Legacy + ~attestation_lag slot_headers_with_statuses in List.fold_left_e (add_cell ~number_of_slots) (t, cache) slot_headers let update_skip_list_no_cache = let empty_cache = History_cache.empty ~capacity:0L in - fun t ~published_level ~number_of_slots slot_headers_with_statuses -> + fun t + ~published_level + ~number_of_slots + ~attestation_lag + slot_headers_with_statuses + -> let open Result_syntax in let+ cell, (_ : History_cache.t) = update_skip_list @@ -942,6 +947,7 @@ module History = struct empty_cache ~published_level ~number_of_slots + ~attestation_lag slot_headers_with_statuses in cell diff --git a/src/proto_alpha/lib_protocol/dal_slot_repr.mli b/src/proto_alpha/lib_protocol/dal_slot_repr.mli index 3342b1cc6b4c..6e9d30c457b2 100644 --- a/src/proto_alpha/lib_protocol/dal_slot_repr.mli +++ b/src/proto_alpha/lib_protocol/dal_slot_repr.mli @@ -399,6 +399,7 @@ module History : sig History_cache.t -> published_level:Raw_level_repr.t -> number_of_slots:int -> + attestation_lag:attestation_lag_kind -> (Header.t * Contract_repr.t * Dal_attestation_repr.Accountability.attestation_status) @@ -411,6 +412,7 @@ module History : sig t -> published_level:Raw_level_repr.t -> number_of_slots:int -> + attestation_lag:attestation_lag_kind -> (Header.t * Contract_repr.t * Dal_attestation_repr.Accountability.attestation_status) diff --git a/src/proto_alpha/lib_protocol/dal_slot_storage.ml b/src/proto_alpha/lib_protocol/dal_slot_storage.ml index d9eb597292e5..8f721c6afea6 100644 --- a/src/proto_alpha/lib_protocol/dal_slot_storage.ml +++ b/src/proto_alpha/lib_protocol/dal_slot_storage.ml @@ -82,6 +82,7 @@ let update_skip_list ctxt ~slot_headers_statuses ~published_level slots_history cache ~published_level + ~attestation_lag:Legacy slot_headers_statuses in let*! ctxt = Storage.Dal.Slot.History.add ctxt slots_history in diff --git a/src/proto_alpha/lib_protocol/test/pbt/test_dal_slot_proof.ml b/src/proto_alpha/lib_protocol/test/pbt/test_dal_slot_proof.ml index 8cd94e4ce89c..5d084c20795d 100644 --- a/src/proto_alpha/lib_protocol/test/pbt/test_dal_slot_proof.ml +++ b/src/proto_alpha/lib_protocol/test/pbt/test_dal_slot_proof.ml @@ -118,12 +118,14 @@ struct slots_headers in let*?@ cell, cache = - Dal_slot_repr.History.update_skip_list - ~number_of_slots:Parameters.dal_parameters.number_of_slots - cell - cache - ~published_level - slots_headers + Dal_slot_repr.History.( + update_skip_list + ~number_of_slots:Parameters.dal_parameters.number_of_slots + cell + cache + ~published_level + slots_headers + ~attestation_lag:Legacy) in let slots_info = List.fold_left diff --git a/src/proto_alpha/lib_protocol/test/pbt/test_sc_rollup_encoding.ml b/src/proto_alpha/lib_protocol/test/pbt/test_sc_rollup_encoding.ml index d5a3b4511700..9631c54a6351 100644 --- a/src/proto_alpha/lib_protocol/test/pbt/test_sc_rollup_encoding.ml +++ b/src/proto_alpha/lib_protocol/test/pbt/test_sc_rollup_encoding.ml @@ -222,7 +222,8 @@ let gen_dal_slots_history () = ~number_of_slots history ~published_level - slot_headers) + slot_headers + ~attestation_lag:Legacy) |> function | Ok history -> loop history llist | Error e -> diff --git a/src/proto_alpha/lib_protocol/test/unit/test_dal_slot_proof.ml b/src/proto_alpha/lib_protocol/test/unit/test_dal_slot_proof.ml index 9ace1c2e3fac..ea5b9da0c9a8 100644 --- a/src/proto_alpha/lib_protocol/test/unit/test_dal_slot_proof.ml +++ b/src/proto_alpha/lib_protocol/test/unit/test_dal_slot_proof.ml @@ -65,11 +65,13 @@ struct let index = mk_slot_index id in let* _data, _poly, slot = mk_slot ~level ~index () in let@ result = - Hist.update_skip_list_no_cache - skip_list - ~published_level:level - [(slot, Contract_repr.zero, mk_attested)] - ~number_of_slots:Parameters.dal_parameters.number_of_slots + Hist.( + update_skip_list_no_cache + skip_list + ~published_level:level + [(slot, Contract_repr.zero, mk_attested)] + ~number_of_slots:Parameters.dal_parameters.number_of_slots + ~attestation_lag:Legacy) in check_result result @@ -187,12 +189,14 @@ struct let open Lwt_result_wrap_syntax in let* _slot_data, polynomial, slot = mk_slot ~level ?index () in let*?@ skip_list, cache = - Hist.update_skip_list - ~number_of_slots:Parameters.dal_parameters.number_of_slots - genesis_history - genesis_history_cache - ~published_level:level - [(slot, Contract_repr.zero, mk_attested)] + Hist.( + update_skip_list + ~number_of_slots:Parameters.dal_parameters.number_of_slots + genesis_history + genesis_history_cache + ~published_level:level + [(slot, Contract_repr.zero, mk_attested)] + ~attestation_lag:Legacy) in let* page_info, page_id = mk_page_info slot polynomial in produce_and_verify_proof diff --git a/src/proto_alpha/lib_sc_rollup_node/test/test_octez_conversions.ml b/src/proto_alpha/lib_sc_rollup_node/test/test_octez_conversions.ml index 27512e7f58a1..cfe9dd17a1c7 100644 --- a/src/proto_alpha/lib_sc_rollup_node/test/test_octez_conversions.ml +++ b/src/proto_alpha/lib_sc_rollup_node/test/test_octez_conversions.ml @@ -281,11 +281,13 @@ let gen_slot_history = in List.fold_left_e (fun hist (published_level, attested_slots) -> - Dal.Slots_history.update_skip_list_no_cache - ~number_of_slots - hist - ~published_level - attested_slots) + Dal.Slots_history.( + update_skip_list_no_cache + ~number_of_slots + hist + ~published_level + attested_slots + ~attestation_lag:Legacy)) Dal.Slots_history.genesis l |> function @@ -315,12 +317,14 @@ let gen_slot_history_cache = in List.fold_left_e (fun (hist, cache) (published_level, attested_slots) -> - Dal.Slots_history.update_skip_list - ~number_of_slots - hist - cache - ~published_level - attested_slots) + Dal.Slots_history.( + update_skip_list + ~number_of_slots + hist + cache + ~published_level + attested_slots + ~attestation_lag:Legacy)) (Dal.Slots_history.genesis, cache) l |> function -- GitLab From 64d43d50c8c0a1e05ff12b3028304d30f42b7185 Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Tue, 7 Oct 2025 17:39:44 +0200 Subject: [PATCH 4/6] DAL/Proto: enable the use of (Dynamic attestation_lag) from dal_slot_storage Now, cells will be pushed with (Dynamic lag), even if lag = 8 --- src/proto_alpha/lib_protocol/dal_slot_storage.ml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/proto_alpha/lib_protocol/dal_slot_storage.ml b/src/proto_alpha/lib_protocol/dal_slot_storage.ml index 8f721c6afea6..0bcaf20a4732 100644 --- a/src/proto_alpha/lib_protocol/dal_slot_storage.ml +++ b/src/proto_alpha/lib_protocol/dal_slot_storage.ml @@ -65,7 +65,7 @@ let get_slot_headers_history ctxt = | Some slots_history -> slots_history let update_skip_list ctxt ~slot_headers_statuses ~published_level - ~number_of_slots = + ~number_of_slots ~attestation_lag = let open Lwt_result_syntax in let open Dal_slot_repr.History in let* slots_history = get_slot_headers_history ctxt in @@ -82,7 +82,7 @@ let update_skip_list ctxt ~slot_headers_statuses ~published_level slots_history cache ~published_level - ~attestation_lag:Legacy + ~attestation_lag:(Dynamic attestation_lag) slot_headers_statuses in let*! ctxt = Storage.Dal.Slot.History.add ctxt slots_history in @@ -115,7 +115,8 @@ let finalize_pending_slot_headers ctxt ~number_of_slots = let open Lwt_result_syntax in let {Level_repr.level = raw_level; _} = Raw_context.current_level ctxt in let Constants_parametric_repr.{dal; _} = Raw_context.constants ctxt in - match Raw_level_repr.(sub raw_level dal.attestation_lag) with + let attestation_lag = dal.attestation_lag in + match Raw_level_repr.(sub raw_level attestation_lag) with | None -> return (ctxt, Dal_attestation_repr.empty) | Some published_level -> let* published_slots = find_slot_headers ctxt published_level in @@ -140,5 +141,6 @@ let finalize_pending_slot_headers ctxt ~number_of_slots = ~slot_headers_statuses ~published_level ~number_of_slots + ~attestation_lag in return (ctxt, attestation) -- GitLab From 757f3ba9340eea4f0c2b9417d0f6b8256fb94ad5 Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Wed, 8 Oct 2025 07:57:44 +0200 Subject: [PATCH 5/6] DAL/Tezt: re-enable tests that use non legacy attestation lag This reverts commit 62300bb4da9de69c7f8d36f46f8d417c915d0e41. --- tezt/tests/dal.ml | 3 --- 1 file changed, 3 deletions(-) diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index 83a6ccc301d6..38b188552bf2 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -11488,7 +11488,6 @@ let register ~protocols = ~uses:(fun _protocol -> [Constant.octez_agnostic_baker]) ~attestation_threshold:100 ~attestation_lag:16 - ~tags:[Tag.ci_disabled] ~activation_timestamp:Now ~number_of_slots:8 ~operator_profiles:[0; 1; 2; 3; 4; 5; 6; 7] @@ -11734,7 +11733,6 @@ let register ~protocols = ~slot_size:(1 lsl 15) ~redundancy_factor:8 ~attestation_lag:4 - ~tags:[Tag.ci_disabled] ~page_size:128 test_reveal_dal_page_in_fast_exec_wasm_pvm protocols ; @@ -11749,7 +11747,6 @@ let register ~protocols = ~redundancy_factor:8 ~page_size:128 ~attestation_lag:4 - ~tags:[Tag.ci_disabled] Tx_kernel_e2e.test_tx_kernel_e2e protocols ; scenario_with_all_nodes -- GitLab From 51e0e0c4727ef4f1e29a1c83363ffac4146a4587 Mon Sep 17 00:00:00 2001 From: "iguerNL@Functori" Date: Wed, 15 Oct 2025 15:53:24 +0200 Subject: [PATCH 6/6] Tezt/DAL: reset regression traces for SC rollup refutation operation gas --- ...peration size and gas for SC rollup refutation operation.out | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tezt/tests/expected/operation_size_and_gas.ml/Alpha- operation size and gas for SC rollup refutation operation.out b/tezt/tests/expected/operation_size_and_gas.ml/Alpha- operation size and gas for SC rollup refutation operation.out index fbab433399c8..3a16dde7ba84 100644 --- a/tezt/tests/expected/operation_size_and_gas.ml/Alpha- operation size and gas for SC rollup refutation operation.out +++ b/tezt/tests/expected/operation_size_and_gas.ml/Alpha- operation size and gas for SC rollup refutation operation.out @@ -70,4 +70,4 @@ This sequence of operations was run: [PUBLIC_KEY_HASH] ...................................................... -ꜩ10000 Frozen_bonds([PUBLIC_KEY_HASH],[SMART_ROLLUP_HASH]) ... +ꜩ10000 -smart_rollup_refute, 231, 5149.837000 +smart_rollup_refute, 231, 5149.841000 -- GitLab