From 1fb6d98882aecaefa85ca80e8738c753bfc5464c Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 1 Dec 2022 15:46:09 +0100 Subject: [PATCH 01/10] Proto/Dal: make minor doc-string edits --- src/proto_alpha/lib_protocol/raw_context.ml | 6 ++--- src/proto_alpha/lib_protocol/raw_context.mli | 23 ++++++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index 77d3cf56ab1c..759e5cdf5b4f 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -1702,13 +1702,13 @@ module Dal = struct let slot_index = Slot_repr.to_int slot in (* An optimisation could be to return only [pkh_to_shards] map because the second one is not used. This can be done later - on if it is a good optimisation. *) + on, if it is a good optimisation. *) let committee = update_committee committee pkh ~slot_index ~power:1 in compute_power (index - 1) committee in (* This committee is an intermediate to compute the final DAL - commitee. This one only projects the Tenderbake committee into - the DAL committee. The next one reorder the slots so that they + committee. This one only projects the Tenderbake committee into + the DAL committee. The next one reorders the slots so that they are grouped by public key hash. *) compute_power (number_of_shards - 1) empty_dal_committee >>=? fun unordered_committee -> diff --git a/src/proto_alpha/lib_protocol/raw_context.mli b/src/proto_alpha/lib_protocol/raw_context.mli index c181e1cf1296..74998fff5b8b 100644 --- a/src/proto_alpha/lib_protocol/raw_context.mli +++ b/src/proto_alpha/lib_protocol/raw_context.mli @@ -427,25 +427,26 @@ module Dal : sig (** The DAL committee is a subset of the Tenderbake committee. A shard from [0;number_of_shards] is associated to a public key - hash. For efficiency reasons, the committee is two-folds: a - mapping public key hash to shards and shards to public key - hashes. The DAL committee ensures the shards associated to the + hash. For efficiency reasons, the committee is both: + a mapping from public key hashes to shards and + a mapping from shards to public key hashes. + The DAL committee ensures the shards associated to the same public key hash are contiguous. The list of shards is represented as two natural numbers [(initial, power)] which encodes the list of shards: - [initial;initial + 1;...;initial + power - 1]. + [initial; initial + 1; ... ; initial + power - 1]. This data-type ensures the following invariants: - \forall pkh shard, find pkh_to_shards pkh = Some (start,n) -> - \forall i, i \in [start; start + n -1] -> find shard_to_pkh shard + \forall i, i \in [start; start + n - 1] -> find shard_to_pkh i = Some pkh - forall pkh shard, find shard_to_pkh shard = Some pkh -> \exists (start,n), find pkh_to_shards pkh = Some (start,n) /\ - start <= shard <= start + n -1 + start <= shard <= start + n - 1 - - Given an attestor, all its shards assignement are contiguous + - Given an attestor, all its shard assignments are contiguous *) type committee = { pkh_to_shards : @@ -456,12 +457,12 @@ module Dal : sig (** [compute_committee ctxt pkh_from_tenderbake_slot] computes the DAL committee using the [pkh_from_tenderbake_slot] function. This functions takes into account the fact that the DAL committee and - the Tenderbake committee may have different size. If the DAL + the Tenderbake committee may have different sizes. If the DAL committee is smaller, then we simply take a projection of the Tenderbake committee for the first [n] slots. If the DAL - committee is larger, shards are computed moduloe the Tenderbake - committee. Slots assignements are reordered for a given a public - key hash, to ensure all the slots (or shards in the context of + committee is larger, shards are computed modulo the Tenderbake + committee. Slots assignments are reordered for a given a public + key hash to ensure all the slots (or shards in the context of DAL) shards are contiguous (see {!type:committee}). *) val compute_committee : t -> -- GitLab From 092423b24fce3eaab33207820d93ee7bcc421d13 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 1 Dec 2022 16:02:16 +0100 Subject: [PATCH 02/10] Proto/Dal: rename functions for clarity --- src/proto_alpha/lib_protocol/alpha_context.mli | 2 +- src/proto_alpha/lib_protocol/dal_apply.ml | 2 +- src/proto_alpha/lib_protocol/raw_context.ml | 4 ++-- src/proto_alpha/lib_protocol/raw_context.mli | 12 ++++++------ 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 073242aeef40..0f5a2ee5c2d7 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -2956,7 +2956,7 @@ module Dal : sig val shards_of_attestor : context -> attestor:public_key_hash -> shard_index list option - val record_available_shards : context -> t -> int list -> context + val record_attested_shards : context -> t -> int list -> context type committee = { pkh_to_shards : (shard_index * int) Signature.Public_key_hash.Map.t; diff --git a/src/proto_alpha/lib_protocol/dal_apply.ml b/src/proto_alpha/lib_protocol/dal_apply.ml index 25a71055138e..6ad45b9824b5 100644 --- a/src/proto_alpha/lib_protocol/dal_apply.ml +++ b/src/proto_alpha/lib_protocol/dal_apply.ml @@ -79,7 +79,7 @@ let apply_attestation ctxt op = let level = Level.current ctxt in error (Dal_data_availibility_attestor_not_in_committee {attestor; level}) | Some shards -> - Ok (Dal.Attestation.record_available_shards ctxt attestation shards) + Ok (Dal.Attestation.record_attested_shards ctxt attestation shards) let validate_publish_slot_header ctxt operation = assert_dal_feature_enabled ctxt >>? fun () -> diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index 759e5cdf5b4f..6bc603a251ae 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -1600,11 +1600,11 @@ module Dal = struct (fun (length, slot_header) -> Dal_register_invalid_slot_header {length; slot_header}) - let record_available_shards ctxt slots shards = + let record_attested_shards ctxt attestation shards = let dal_attestation_slot_accountability = Dal_attestation_repr.Accountability.record_shards_availability ctxt.back.dal_attestation_slot_accountability - slots + attestation shards in {ctxt with back = {ctxt.back with dal_attestation_slot_accountability}} diff --git a/src/proto_alpha/lib_protocol/raw_context.mli b/src/proto_alpha/lib_protocol/raw_context.mli index 74998fff5b8b..16ab92f48169 100644 --- a/src/proto_alpha/lib_protocol/raw_context.mli +++ b/src/proto_alpha/lib_protocol/raw_context.mli @@ -394,12 +394,12 @@ module Sc_rollup_in_memory_inbox : sig end module Dal : sig - (** [record_available_shards ctxt slots shards] records that the - list of shards [shards] were declared available. The function - assumes that a shard belongs to the interval [0; number_of_shards - - 1]. Otherwise, for each shard outside this interval, it is a - no-op. *) - val record_available_shards : t -> Dal_attestation_repr.t -> int list -> t + (** [record_attested_shards ctxt attestation shards] records that the + list of shards [shards] were attested (declared available by some + attestor). The function assumes that a shard belongs to the + interval [0; number_of_shards - 1]. Otherwise, for each shard + outside this interval, it is a no-op. *) + val record_attested_shards : t -> Dal_attestation_repr.t -> int list -> t (** [register_slot_header ctxt slot_header] returns a new context where the new candidate [slot] have been taken into -- GitLab From c9006774e6d8d59cb4ecdd980a3ca9840417c17c Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 1 Dec 2022 17:11:35 +0100 Subject: [PATCH 03/10] Proto/Dal: make minor edits for readability --- .../lib_protocol/dal_attestation_repr.ml | 16 ++++++++++------ .../lib_protocol/dal_attestation_repr.mli | 6 +++--- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/proto_alpha/lib_protocol/dal_attestation_repr.ml b/src/proto_alpha/lib_protocol/dal_attestation_repr.ml index a3b68922fada..afdd35ac4d8b 100644 --- a/src/proto_alpha/lib_protocol/dal_attestation_repr.ml +++ b/src/proto_alpha/lib_protocol/dal_attestation_repr.ml @@ -39,9 +39,9 @@ representation. Hence, if there are [256] slots, and [2] are not attested, this representation will be of size [32] bits + [16] bits = [48] bits which is better than [256] bits. *) -type t = Bitset.t -type attested_slots = t +(* A set of (attested) slot indexes. *) +type t = Bitset.t type operation = { attestor : Signature.Public_key_hash.t; @@ -96,11 +96,15 @@ module Shard_map = Map.Make (struct end) module Accountability = struct + type attested_slots = t + (* DAL/FIXME https://gitlab.com/tezos/tezos/-/issues/3109 Think hard about this data structure and whether it needs to be optimized. *) + + (* A list of set of shard indexes (a set of shards per slot) *) type t = Bitset.t list let init ~length = @@ -120,15 +124,15 @@ module Accountability = struct bitset shards - let record_shards_availability shard_bitset_per_slot slots shards = + let record_shards_availability shard_bitset_per_slot attested_slots shards = List.mapi (fun slot bitset -> - match Bitset.mem slots slot with + match Bitset.mem attested_slots slot with | Error _ -> (* slot index is above the length provided at initialisation *) bitset - | Ok slot_available -> - if slot_available then record_slot_shard_availability bitset shards + | Ok slot_attested -> + if slot_attested then record_slot_shard_availability bitset shards else bitset) shard_bitset_per_slot diff --git a/src/proto_alpha/lib_protocol/dal_attestation_repr.mli b/src/proto_alpha/lib_protocol/dal_attestation_repr.mli index 7d1ebed02e72..5975b03a730b 100644 --- a/src/proto_alpha/lib_protocol/dal_attestation_repr.mli +++ b/src/proto_alpha/lib_protocol/dal_attestation_repr.mli @@ -44,8 +44,6 @@ type t -type attested_slots = t - (** The shape of Dal attestation operations injected by delegates. *) type operation = { attestor : Signature.Public_key_hash.t; @@ -69,7 +67,7 @@ val empty : t val is_attested : t -> Dal_slot_repr.Index.t -> bool (** [commit slot_attestation index] commits into [slot_attestation] - that the [index] is available. *) + that the slot [index] is available. *) val commit : t -> Dal_slot_repr.Index.t -> t (** [occupied_size_in_bits slot_attestation] returns the size in bits of an attestation. *) @@ -95,6 +93,8 @@ module Shard_map : Map.S with type key = shard_index This information will be used at the end of block finalisation to have the protocol declaring whether the slot is available. *) module Accountability : sig + type attested_slots = t + (** The data-structure used to record the shards-slots availability. *) type t -- GitLab From f0c93b420db9eeb23ad751f7f8a1f586bd901b8b Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Tue, 6 Dec 2022 12:44:28 +0100 Subject: [PATCH 04/10] Proto/Plugin: default level for dal_shards RPC is current level --- src/proto_alpha/lib_plugin/RPC.ml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/proto_alpha/lib_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index 8302e417096d..b40051a5d75c 100644 --- a/src/proto_alpha/lib_plugin/RPC.ml +++ b/src/proto_alpha/lib_plugin/RPC.ml @@ -2411,7 +2411,9 @@ module Dal = struct let shards = RPC_service.get_service - ~description:"Get the shard assignements for a given level" + ~description: + "Get the shard assignements for a given level (the default is the \ + current level)" ~query:shards_query ~output: Data_encoding.( @@ -2433,7 +2435,7 @@ module Dal = struct let register_shards () = Registration.register0 ~chunked:true S.shards @@ fun ctxt level () -> - let level = Option.value level ~default:(Raw_level.of_int32_exn 0l) in + let level = Option.value level ~default:(Level.current ctxt).level in Dal_services.shards ctxt ~level let register () = -- GitLab From 15294124aa112e51e825d9e53dcc0723bff502b8 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Mon, 5 Dec 2022 15:00:24 +0100 Subject: [PATCH 05/10] Proto/Dal: refactor to eliminate duplicate code --- src/proto_alpha/lib_protocol/dal_apply.ml | 24 +++++++++---------- src/proto_alpha/lib_protocol/dal_apply.mli | 3 +++ src/proto_alpha/lib_protocol/dal_services.ml | 10 ++------ .../validate/generator_descriptors.ml | 10 +------- 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/proto_alpha/lib_protocol/dal_apply.ml b/src/proto_alpha/lib_protocol/dal_apply.ml index 6ad45b9824b5..b4e265918217 100644 --- a/src/proto_alpha/lib_protocol/dal_apply.ml +++ b/src/proto_alpha/lib_protocol/dal_apply.ml @@ -152,21 +152,21 @@ let finalisation ctxt = Dal.Slot.finalize_pending_slot_headers ctxt >|=? fun (ctxt, attestation) -> (ctxt, Some attestation)) +let compute_committee ctxt level = + assert_dal_feature_enabled ctxt >>?= fun () -> + let pkh_from_tenderbake_slot slot = + Stake_distribution.slot_owner ctxt level slot + >|=? fun (ctxt, consensus_pk1) -> (ctxt, consensus_pk1.delegate) + in + (* This committee is cached because it is the one we will use + for the validation of the DAL attestations. *) + Alpha_context.Dal.Attestation.compute_committee ctxt pkh_from_tenderbake_slot + let initialisation ctxt ~level = let open Lwt_result_syntax in only_if_dal_feature_enabled ctxt ~default:(fun ctxt -> return ctxt) (fun ctxt -> - let pkh_from_tenderbake_slot slot = - Stake_distribution.slot_owner ctxt level slot - >|=? fun (ctxt, consensus_pk1) -> (ctxt, consensus_pk1.delegate) - in - (* This committee is cached because it is the one we will use - for the validation of the DAL attestations. *) - let* committee = - Alpha_context.Dal.Attestation.compute_committee - ctxt - pkh_from_tenderbake_slot - in - return (Alpha_context.Dal.Attestation.init_committee ctxt committee)) + let+ committee = compute_committee ctxt level in + Alpha_context.Dal.Attestation.init_committee ctxt committee) diff --git a/src/proto_alpha/lib_protocol/dal_apply.mli b/src/proto_alpha/lib_protocol/dal_apply.mli index 28daea642838..5ff80c0a65dc 100644 --- a/src/proto_alpha/lib_protocol/dal_apply.mli +++ b/src/proto_alpha/lib_protocol/dal_apply.mli @@ -63,3 +63,6 @@ val finalisation : t -> (t * Dal.Attestation.t option) tzresult Lwt.t in memory so that every time we need to use this committee, there is no need to recompute it again. *) val initialisation : t -> level:Level.t -> t tzresult Lwt.t + +(** [compute_committee ctxt level] computes the DAL committee for [level]. *) +val compute_committee : t -> Level.t -> Dal.Attestation.committee tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/dal_services.ml b/src/proto_alpha/lib_protocol/dal_services.ml index 660f6783ec7f..67ec5d301834 100644 --- a/src/proto_alpha/lib_protocol/dal_services.ml +++ b/src/proto_alpha/lib_protocol/dal_services.ml @@ -37,13 +37,7 @@ let shards ctxt ~level = let open Dal.Attestation in assert_dal_feature_enabled ctxt >>?= fun () -> let level = Level.from_raw ctxt level in - let pkh_from_tenderbake_slot slot = - Stake_distribution.slot_owner ctxt level slot - >|=? fun (ctxt, consensus_key) -> (ctxt, consensus_key.delegate) - in (* We do not cache this committee. This function being used by RPCs to know the DAL committee at some particular level. *) - let* committee = - Dal.Attestation.compute_committee ctxt pkh_from_tenderbake_slot - in - Signature.Public_key_hash.Map.bindings committee.pkh_to_shards |> return + let+ committee = Dal_apply.compute_committee ctxt level in + Signature.Public_key_hash.Map.bindings committee.pkh_to_shards diff --git a/src/proto_alpha/lib_protocol/test/integration/validate/generator_descriptors.ml b/src/proto_alpha/lib_protocol/test/integration/validate/generator_descriptors.ml index 170f0435c8da..d79b6d0ea3a8 100644 --- a/src/proto_alpha/lib_protocol/test/integration/validate/generator_descriptors.ml +++ b/src/proto_alpha/lib_protocol/test/integration/validate/generator_descriptors.ml @@ -631,15 +631,7 @@ let endorsement_descriptor = let dal_slot_availibility ctxt delegate = let open Lwt_result_syntax in let level = Alpha_context.Level.current ctxt in - let pkh_from_tenderbake_slot slot = - Alpha_context.Stake_distribution.slot_owner ctxt level slot - >|=? fun (ctxt, consensus_pk1) -> (ctxt, consensus_pk1.delegate) - in - let* committee = - Alpha_context.Dal.Attestation.compute_committee - ctxt - pkh_from_tenderbake_slot - in + let* committee = Dal_apply.compute_committee ctxt level in match Environment.Signature.Public_key_hash.Map.find delegate -- GitLab From dddc532ff327dfc952cdfb53aa2218ef1235fc84 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Mon, 5 Dec 2022 11:45:38 +0100 Subject: [PATCH 06/10] Proto/Dal: introduce blocks_per_epoch --- .../lib_parameters/default_parameters.ml | 3 +++ src/proto_alpha/lib_protocol/alpha_context.mli | 1 + .../lib_protocol/constants_parametric_repr.ml | 14 ++++++++++---- .../lib_protocol/constants_parametric_repr.mli | 1 + src/proto_alpha/lib_protocol/constants_repr.ml | 10 ++++++++++ src/proto_alpha/lib_protocol/raw_context.ml | 1 + 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/proto_alpha/lib_parameters/default_parameters.ml b/src/proto_alpha/lib_parameters/default_parameters.ml index e6a7a7e83825..5a205a41c382 100644 --- a/src/proto_alpha/lib_parameters/default_parameters.ml +++ b/src/proto_alpha/lib_parameters/default_parameters.ml @@ -73,6 +73,7 @@ let default_dal = number_of_slots = 256; attestation_lag = 1; availability_threshold = 50; + blocks_per_epoch = 32l; cryptobox_parameters = default_cryptobox_parameters; } @@ -289,6 +290,7 @@ let constants_sandbox = { constants_mainnet.dal with number_of_slots = 16; + blocks_per_epoch = 2l; cryptobox_parameters = derive_cryptobox_parameters ~redundancy_factor:8 @@ -335,6 +337,7 @@ let constants_test = { constants_mainnet.dal with number_of_slots = 8; + blocks_per_epoch = 2l; cryptobox_parameters = derive_cryptobox_parameters ~redundancy_factor:4 diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 0f5a2ee5c2d7..62aaf873b52b 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -794,6 +794,7 @@ module Constants : sig number_of_slots : int; attestation_lag : int; availability_threshold : int; + blocks_per_epoch : int32; cryptobox_parameters : Dal.parameters; } diff --git a/src/proto_alpha/lib_protocol/constants_parametric_repr.ml b/src/proto_alpha/lib_protocol/constants_parametric_repr.ml index a95a8e78c031..358b0efbb35c 100644 --- a/src/proto_alpha/lib_protocol/constants_parametric_repr.ml +++ b/src/proto_alpha/lib_protocol/constants_parametric_repr.ml @@ -30,6 +30,7 @@ type dal = { number_of_slots : int; attestation_lag : int; availability_threshold : int; + blocks_per_epoch : int32; cryptobox_parameters : Dal.parameters; } @@ -42,30 +43,35 @@ let dal_encoding = attestation_lag; availability_threshold; cryptobox_parameters; + blocks_per_epoch; } -> ( ( feature_enable, number_of_slots, attestation_lag, - availability_threshold ), + availability_threshold, + blocks_per_epoch ), cryptobox_parameters )) (fun ( ( feature_enable, number_of_slots, attestation_lag, - availability_threshold ), + availability_threshold, + blocks_per_epoch ), cryptobox_parameters ) -> { feature_enable; number_of_slots; attestation_lag; availability_threshold; + blocks_per_epoch; cryptobox_parameters; }) (merge_objs - (obj4 + (obj5 (req "feature_enable" bool) (req "number_of_slots" int16) (req "attestation_lag" int16) - (req "availability_threshold" int16)) + (req "availability_threshold" int16) + (req "blocks_per_epoch" int32)) Dal.parameters_encoding) (* The encoded representation of this type is stored in the context as diff --git a/src/proto_alpha/lib_protocol/constants_parametric_repr.mli b/src/proto_alpha/lib_protocol/constants_parametric_repr.mli index 0ce06811885f..3033307a1ccd 100644 --- a/src/proto_alpha/lib_protocol/constants_parametric_repr.mli +++ b/src/proto_alpha/lib_protocol/constants_parametric_repr.mli @@ -30,6 +30,7 @@ type dal = { number_of_slots : int; attestation_lag : int; availability_threshold : int; + blocks_per_epoch : int32; cryptobox_parameters : Dal.parameters; } diff --git a/src/proto_alpha/lib_protocol/constants_repr.ml b/src/proto_alpha/lib_protocol/constants_repr.ml index 32d83c860752..ed78dff9ab00 100644 --- a/src/proto_alpha/lib_protocol/constants_repr.ml +++ b/src/proto_alpha/lib_protocol/constants_repr.ml @@ -326,6 +326,16 @@ let check_constants constants = (Invalid_protocol_constants "The number of data availability slot must be between 1 and 256") >>? fun () -> + error_unless + Compare.Int32.( + constants.dal.blocks_per_epoch > 0l + && constants.dal.blocks_per_epoch <= constants.blocks_per_cycle + && Int32.rem constants.blocks_per_cycle constants.dal.blocks_per_epoch + = 0l) + (Invalid_protocol_constants + "The epoch length must be between 1 and blocks_per_cycle, and \ + blocks_per_epoch must divide blocks_per_cycle.") + >>? fun () -> error_unless Compare.Int.( constants.sc_rollup.max_number_of_stored_cemented_commitments > 0) diff --git a/src/proto_alpha/lib_protocol/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index 6bc603a251ae..b1feb28eeb80 100644 --- a/src/proto_alpha/lib_protocol/raw_context.ml +++ b/src/proto_alpha/lib_protocol/raw_context.ml @@ -1016,6 +1016,7 @@ let prepare_first_block ~level ~timestamp ctxt = number_of_slots = c.dal.number_of_slots; attestation_lag = c.dal.endorsement_lag; availability_threshold = c.dal.availability_threshold; + blocks_per_epoch = 32l; cryptobox_parameters; } in -- GitLab From 7690f2ebbf361516d1e5db62e81b522925a7de5c Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Mon, 5 Dec 2022 13:41:50 +0100 Subject: [PATCH 07/10] Proto/Dal: have one DAL committee per epoch --- src/proto_alpha/lib_protocol/dal_apply.ml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/proto_alpha/lib_protocol/dal_apply.ml b/src/proto_alpha/lib_protocol/dal_apply.ml index b4e265918217..7942e74f788b 100644 --- a/src/proto_alpha/lib_protocol/dal_apply.ml +++ b/src/proto_alpha/lib_protocol/dal_apply.ml @@ -154,8 +154,22 @@ let finalisation ctxt = let compute_committee ctxt level = assert_dal_feature_enabled ctxt >>?= fun () -> + let blocks_per_epoch = (Constants.parametric ctxt).dal.blocks_per_epoch in + let first_level_in_epoch = + match + Level.sub + ctxt + level + (Int32.to_int @@ Int32.rem level.Level.cycle_position blocks_per_epoch) + with + | Some v -> v + | None -> + (* unreachable, because level.level >= level.cycle_position >= + (level.cycle_position mod blocks_per_epoch) *) + assert false + in let pkh_from_tenderbake_slot slot = - Stake_distribution.slot_owner ctxt level slot + Stake_distribution.slot_owner ctxt first_level_in_epoch slot >|=? fun (ctxt, consensus_pk1) -> (ctxt, consensus_pk1.delegate) in (* This committee is cached because it is the one we will use -- GitLab From 669aff9262611ad445b7981e9f99f699460d1d13 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Tue, 6 Dec 2022 12:42:27 +0100 Subject: [PATCH 08/10] Tezt/Dal: check that there's one committee per epoch --- tezt/lib_tezos/rollup.ml | 27 +++++++++++++++++++++++ tezt/lib_tezos/rollup.mli | 8 +++++++ tezt/tests/dal.ml | 46 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+) diff --git a/tezt/lib_tezos/rollup.ml b/tezt/lib_tezos/rollup.ml index d55761d62122..53ca0f88c854 100644 --- a/tezt/lib_tezos/rollup.ml +++ b/tezt/lib_tezos/rollup.ml @@ -533,6 +533,33 @@ module Dal = struct } end + module Committee = struct + type member = {attestor : string; first_shard_index : int; power : int} + + type t = member list + + let typ = + let open Check in + list + @@ convert + (fun {attestor; first_shard_index; power} -> + (attestor, first_shard_index, power)) + (tuple3 string int int) + + let at_level node ~level = + let* json = + RPC.(call node @@ get_chain_block_context_dal_shards ~level ()) + in + return + @@ List.map + (fun json -> + let pkh = JSON.(json |=> 0 |> as_string) in + let first_shard_index = JSON.(json |=> 1 |=> 0 |> as_int) in + let power = JSON.(json |=> 1 |=> 1 |> as_int) in + {attestor = pkh; first_shard_index; power}) + (JSON.as_list json) + end + let pad n message = let padding = String.make n '\000' in message ^ padding diff --git a/tezt/lib_tezos/rollup.mli b/tezt/lib_tezos/rollup.mli index eb79d21ba397..80000138ef51 100644 --- a/tezt/lib_tezos/rollup.mli +++ b/tezt/lib_tezos/rollup.mli @@ -328,4 +328,12 @@ module Dal : sig val to_string : Cryptobox.commitment -> string end + + module Committee : sig + type t + + val typ : t Check.typ + + val at_level : Node.t -> level:int -> t Lwt.t + end end diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index 2498c9435a12..98cfe26e78b4 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -310,6 +310,48 @@ let test_feature_flag _protocol _parameters _cryptobox node client Test.fail "Unexpected entry dal in the context when DAL is disabled" ; unit +let test_one_committee_per_epoch _protocol _parameters _cryptobox node _client + _bootstrap_key = + let* blocks_per_epoch = + let* json = RPC.(call node @@ get_chain_block_context_constants ()) in + return @@ JSON.(json |-> "dal_parametric" |-> "blocks_per_epoch" |> as_int) + in + let* current_level = + RPC.(call node @@ get_chain_block_helper_current_level ()) + in + (* The test assumes we are at a level when an epoch starts. And + that is indeed the case. *) + assert (current_level.cycle_position = 0) ; + let* first_committee = + Rollup.Dal.Committee.at_level node ~level:current_level.level + in + (* We iterate through (the committees at) levels [current_level + + offset], with [offset] from 1 to [blocks_per_epoch]. At offset 0 + we have the [first_committee] (first in the current epoch). The + committees at offsets 1 to [blocks_per_epoch - 1] should be the + same as the one at offset 0, the one at [blocks_per_epoch] (first + in the next epoch) should be different. *) + let rec iter offset = + if offset > blocks_per_epoch then unit + else + let level = current_level.level + offset in + let* committee = Rollup.Dal.Committee.at_level node ~level in + if offset < blocks_per_epoch then ( + Check.((first_committee = committee) Rollup.Dal.Committee.typ) + ~error_msg: + "Unexpected different DAL committees at first level: %L, versus \ + current level: %R" ; + unit) + else if offset = blocks_per_epoch then ( + Check.((first_committee = committee) Rollup.Dal.Committee.typ) + ~error_msg: + "Unexpected equal DAL committees at first levels in subsequent \ + epochs: %L and %R" ; + unit) + else iter (offset + 1) + in + iter 1 + let publish_slot ~source ?level ?fee ?error ~index ~commitment ~proof node client = let level = @@ -1628,6 +1670,10 @@ let register ~protocols = "feature_flag_is_disabled" test_feature_flag protocols ; + scenario_with_layer1_node + "one_committee_per_epoch" + test_one_committee_per_epoch + protocols ; (* Tests with layer1 and dal nodes *) test_dal_node_startup protocols ; -- GitLab From 6a5cb63d636b5e5d82112df36b86c16211cd6ad2 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 7 Dec 2022 15:28:27 +0100 Subject: [PATCH 09/10] Tezt/Dal: fetch more DAL parameters --- tezt/lib_tezos/rollup.ml | 6 ++++++ tezt/lib_tezos/rollup.mli | 2 ++ tezt/tests/dal.ml | 30 +++++++++--------------------- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/tezt/lib_tezos/rollup.ml b/tezt/lib_tezos/rollup.ml index 53ca0f88c854..5cb9d676d76a 100644 --- a/tezt/lib_tezos/rollup.ml +++ b/tezt/lib_tezos/rollup.ml @@ -503,9 +503,11 @@ module Dal = struct module Parameters = struct type t = { + feature_enabled : bool; cryptobox : Cryptobox.parameters; number_of_slots : int; attestation_lag : int; + blocks_per_epoch : int; } let parameter_file protocol = @@ -523,13 +525,17 @@ module Dal = struct let page_size = JSON.(json |-> "page_size" |> as_int) in let number_of_slots = JSON.(json |-> "number_of_slots" |> as_int) in let attestation_lag = JSON.(json |-> "attestation_lag" |> as_int) in + let blocks_per_epoch = JSON.(json |-> "blocks_per_epoch" |> as_int) in + let feature_enabled = JSON.(json |-> "feature_enable" |> as_bool) in return { + feature_enabled; cryptobox = Cryptobox.Verifier. {number_of_shards; redundancy_factor; slot_size; page_size}; number_of_slots; attestation_lag; + blocks_per_epoch; } end diff --git a/tezt/lib_tezos/rollup.mli b/tezt/lib_tezos/rollup.mli index 80000138ef51..32956bab670c 100644 --- a/tezt/lib_tezos/rollup.mli +++ b/tezt/lib_tezos/rollup.mli @@ -219,9 +219,11 @@ module Dal : sig module Parameters : sig type t = { + feature_enabled : bool; cryptobox : Cryptobox.parameters; number_of_slots : int; attestation_lag : int; + blocks_per_epoch : int; } val parameter_file : Protocol.t -> string Lwt.t diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index 98cfe26e78b4..482aa1c2c3de 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -250,25 +250,13 @@ let test_feature_flag _protocol _parameters _cryptobox node client - 2. It checks the new operations added by the feature flag cannot be propagated by checking their classification in the mempool. *) - let* protocol_parameters = - RPC.Client.call client @@ RPC.get_chain_block_context_constants () - in - let feature_flag = - JSON.( - protocol_parameters |-> "dal_parametric" |-> "feature_enable" |> as_bool) - in - let number_of_slots = - JSON.( - protocol_parameters |-> "dal_parametric" |-> "number_of_slots" |> as_int) - in - let* parameters = Rollup.Dal.Parameters.from_client client in - let cryptobox_params = parameters.cryptobox in - let cryptobox = Rollup.Dal.make cryptobox_params in + let* params = Rollup.Dal.Parameters.from_client client in + let cryptobox = Rollup.Dal.make params.cryptobox in let commitment, proof = Rollup.Dal.Commitment.dummy_commitment cryptobox "coucou" in Check.( - (feature_flag = false) + (params.feature_enabled = false) bool ~error_msg:"Feature flag for the DAL should be disabled") ; let*? process = @@ -285,7 +273,9 @@ let test_feature_flag _protocol _parameters _cryptobox node client inject ~force:true ~signer:Constant.bootstrap1 - (dal_attestation ~level ~attestation:(Array.make number_of_slots false)) + (dal_attestation + ~level + ~attestation:(Array.make params.number_of_slots false)) client) in let* (`OpHash oph2) = @@ -310,12 +300,10 @@ let test_feature_flag _protocol _parameters _cryptobox node client Test.fail "Unexpected entry dal in the context when DAL is disabled" ; unit -let test_one_committee_per_epoch _protocol _parameters _cryptobox node _client +let test_one_committee_per_epoch _protocol _parameters _cryptobox node client _bootstrap_key = - let* blocks_per_epoch = - let* json = RPC.(call node @@ get_chain_block_context_constants ()) in - return @@ JSON.(json |-> "dal_parametric" |-> "blocks_per_epoch" |> as_int) - in + let* params = Rollup.Dal.Parameters.from_client client in + let blocks_per_epoch = params.blocks_per_epoch in let* current_level = RPC.(call node @@ get_chain_block_helper_current_level ()) in -- GitLab From 0f71c0a6ab6fd0252df398597dcc2a9eebf5aaa1 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Mon, 12 Dec 2022 09:28:10 +0100 Subject: [PATCH 10/10] Tezt: update regression outputs --- ...- (mode client) RPC regression tests- misc_protocol.out | 7 ++++--- ...a- (mode light) RPC regression tests- misc_protocol.out | 7 ++++--- ...a- (mode proxy) RPC regression tests- misc_protocol.out | 7 ++++--- ...erver_data_dir) RPC regression tests- misc_protocol.out | 7 ++++--- ...oxy_server_rpc) RPC regression tests- misc_protocol.out | 7 ++++--- 5 files changed, 20 insertions(+), 15 deletions(-) diff --git a/tezt/tests/expected/RPC_test.ml/Alpha- (mode client) RPC regression tests- misc_protocol.out b/tezt/tests/expected/RPC_test.ml/Alpha- (mode client) RPC regression tests- misc_protocol.out index 9791c9158c85..7adb8d7f2532 100644 --- a/tezt/tests/expected/RPC_test.ml/Alpha- (mode client) RPC regression tests- misc_protocol.out +++ b/tezt/tests/expected/RPC_test.ml/Alpha- (mode client) RPC regression tests- misc_protocol.out @@ -46,9 +46,10 @@ "tx_rollup_sunset_level": 3473409, "dal_parametric": { "feature_enable": false, "number_of_slots": 16, "attestation_lag": 1, - "availability_threshold": 50, "redundancy_factor": 8, "page_size": 128, - "slot_size": 32768, "number_of_shards": 64 }, - "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, + "availability_threshold": 50, "blocks_per_epoch": 2, + "redundancy_factor": 8, "page_size": 128, "slot_size": 32768, + "number_of_shards": 64 }, "sc_rollup_enable": false, + "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160, "sc_rollup_stake_amount": "10000000000", "sc_rollup_commitment_period_in_blocks": 30, diff --git a/tezt/tests/expected/RPC_test.ml/Alpha- (mode light) RPC regression tests- misc_protocol.out b/tezt/tests/expected/RPC_test.ml/Alpha- (mode light) RPC regression tests- misc_protocol.out index 94771e38790e..798d70c46406 100644 --- a/tezt/tests/expected/RPC_test.ml/Alpha- (mode light) RPC regression tests- misc_protocol.out +++ b/tezt/tests/expected/RPC_test.ml/Alpha- (mode light) RPC regression tests- misc_protocol.out @@ -46,9 +46,10 @@ "tx_rollup_sunset_level": 3473409, "dal_parametric": { "feature_enable": false, "number_of_slots": 16, "attestation_lag": 1, - "availability_threshold": 50, "redundancy_factor": 8, "page_size": 128, - "slot_size": 32768, "number_of_shards": 64 }, - "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, + "availability_threshold": 50, "blocks_per_epoch": 2, + "redundancy_factor": 8, "page_size": 128, "slot_size": 32768, + "number_of_shards": 64 }, "sc_rollup_enable": false, + "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160, "sc_rollup_stake_amount": "10000000000", "sc_rollup_commitment_period_in_blocks": 30, diff --git a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy) RPC regression tests- misc_protocol.out b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy) RPC regression tests- misc_protocol.out index 9d57a015a373..e7a4dbb24319 100644 --- a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy) RPC regression tests- misc_protocol.out +++ b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy) RPC regression tests- misc_protocol.out @@ -46,9 +46,10 @@ "tx_rollup_sunset_level": 3473409, "dal_parametric": { "feature_enable": false, "number_of_slots": 16, "attestation_lag": 1, - "availability_threshold": 50, "redundancy_factor": 8, "page_size": 128, - "slot_size": 32768, "number_of_shards": 64 }, - "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, + "availability_threshold": 50, "blocks_per_epoch": 2, + "redundancy_factor": 8, "page_size": 128, "slot_size": 32768, + "number_of_shards": 64 }, "sc_rollup_enable": false, + "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160, "sc_rollup_stake_amount": "10000000000", "sc_rollup_commitment_period_in_blocks": 30, diff --git a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_data_dir) RPC regression tests- misc_protocol.out b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_data_dir) RPC regression tests- misc_protocol.out index 1b08b3512c50..07e0eb63f9bc 100644 --- a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_data_dir) RPC regression tests- misc_protocol.out +++ b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_data_dir) RPC regression tests- misc_protocol.out @@ -46,9 +46,10 @@ "tx_rollup_sunset_level": 3473409, "dal_parametric": { "feature_enable": false, "number_of_slots": 16, "attestation_lag": 1, - "availability_threshold": 50, "redundancy_factor": 8, "page_size": 128, - "slot_size": 32768, "number_of_shards": 64 }, - "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, + "availability_threshold": 50, "blocks_per_epoch": 2, + "redundancy_factor": 8, "page_size": 128, "slot_size": 32768, + "number_of_shards": 64 }, "sc_rollup_enable": false, + "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160, "sc_rollup_stake_amount": "10000000000", "sc_rollup_commitment_period_in_blocks": 30, diff --git a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_rpc) RPC regression tests- misc_protocol.out b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_rpc) RPC regression tests- misc_protocol.out index 1b08b3512c50..07e0eb63f9bc 100644 --- a/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_rpc) RPC regression tests- misc_protocol.out +++ b/tezt/tests/expected/RPC_test.ml/Alpha- (mode proxy_server_rpc) RPC regression tests- misc_protocol.out @@ -46,9 +46,10 @@ "tx_rollup_sunset_level": 3473409, "dal_parametric": { "feature_enable": false, "number_of_slots": 16, "attestation_lag": 1, - "availability_threshold": 50, "redundancy_factor": 8, "page_size": 128, - "slot_size": 32768, "number_of_shards": 64 }, - "sc_rollup_enable": false, "sc_rollup_origination_size": 6314, + "availability_threshold": 50, "blocks_per_epoch": 2, + "redundancy_factor": 8, "page_size": 128, "slot_size": 32768, + "number_of_shards": 64 }, "sc_rollup_enable": false, + "sc_rollup_origination_size": 6314, "sc_rollup_challenge_window_in_blocks": 20160, "sc_rollup_stake_amount": "10000000000", "sc_rollup_commitment_period_in_blocks": 30, -- GitLab