diff --git a/src/proto_alpha/lib_parameters/default_parameters.ml b/src/proto_alpha/lib_parameters/default_parameters.ml index e6a7a7e83825c24871b6f74eeecc4db2e6efae77..5a205a41c382ce520fe0856dd078ec4f829a47fe 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_plugin/RPC.ml b/src/proto_alpha/lib_plugin/RPC.ml index 8302e417096dece84c1cf8f7b1fa451c51e57279..b40051a5d75cf9b49440ba1a6c293446f36a12dc 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 () = diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 073242aeef40a2bb8a3ad2b4693c0633971078a3..62aaf873b52b71aaea3488bd0fce4e87db759811 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; } @@ -2956,7 +2957,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/constants_parametric_repr.ml b/src/proto_alpha/lib_protocol/constants_parametric_repr.ml index a95a8e78c031fd783732f7c0f6f80efb2149e0e9..358b0efbb35caf7534d4d6af38745234d82a8763 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 0ce06811885f5748aba2dcbf7a2eb948113adaf7..3033307a1ccd24b06b4bf8f8a3585484741cda14 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 32d83c860752c26bc230b92eab676df815b2530d..ed78dff9ab005cc65367e281c7a32bc44cdf3435 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/dal_apply.ml b/src/proto_alpha/lib_protocol/dal_apply.ml index 25a71055138ee92fec47c58d6b9d83c0aabfbbcf..7942e74f788b0a6d3af03358ffa4898d7838803b 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 () -> @@ -152,21 +152,35 @@ 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 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 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 + 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 28daea6428380a26ea46dc757941621c76b569b6..5ff80c0a65dc3debb23968ed9aaa9d0bc2cc6cf9 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_attestation_repr.ml b/src/proto_alpha/lib_protocol/dal_attestation_repr.ml index a3b68922fadaf9bc6f5bd7fe1d8e75c011d2f517..afdd35ac4d8b747332bfbd018db5e66f7f990d16 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 7d1ebed02e720c505b04c5ebfc2ed8a6c66419a1..5975b03a730b8630e022bd8cf986adef63670350 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 diff --git a/src/proto_alpha/lib_protocol/dal_services.ml b/src/proto_alpha/lib_protocol/dal_services.ml index 660f6783ec7ff63f6c971e8b014d948ee1c28d81..67ec5d3018349428a2446519889b258cd05acee0 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/raw_context.ml b/src/proto_alpha/lib_protocol/raw_context.ml index 77d3cf56ab1cb78ae8c9b1486bdd0f88a2b8f7dd..b1feb28eeb80ce17f762529db343c7d6c68eaadd 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 @@ -1600,11 +1601,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}} @@ -1702,13 +1703,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 c181e1cf1296db90407a5300540c1a401184d1ec..16ab92f48169c20cb69d6ca62f198f062d07ac3b 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 @@ -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 -> 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 170f0435c8da45468e937bacab956238f5ca8571..d79b6d0ea3a85bfa3c4c104f1af2049dbe7ebb44 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 diff --git a/tezt/lib_tezos/rollup.ml b/tezt/lib_tezos/rollup.ml index d55761d6212275e5ab5bc1d6fa8325ae35804a75..5cb9d676d76ac450c576b0429e2a2947ca816caa 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,16 +525,47 @@ 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 + 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 eb79d21ba39727c73e07d506c3b9d2f976bf0cff..32956bab670c7fad778bcc2d11c03b56dc753eb4 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 @@ -328,4 +330,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 2498c9435a126146e0403b8be11f9db73c078af3..482aa1c2c3def5344172437e10cd18255b6c640c 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,6 +300,46 @@ 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* 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 + (* 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 +1658,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 ; 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 9791c9158c851d31163525f4256e09ff434076f2..7adb8d7f2532bcbc8f1e602f11297a0f295c85ca 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 94771e38790eaca2e0306bffd06336aad618c5c7..798d70c46406ce3b15737da3671f021b6265c7b5 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 9d57a015a3737eaf30e6c56239a69d9d38f66820..e7a4dbb24319e219489318a935562e12ef5f26bc 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 1b08b3512c50b2c71265e7d02d886b8919f792e7..07e0eb63f9bc0e8479efa0f1ecd38f6a7163efe8 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 1b08b3512c50b2c71265e7d02d886b8919f792e7..07e0eb63f9bc0e8479efa0f1ecd38f6a7163efe8 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,