From 472ed2634f83cfb219d3681d3fcbfc5c40819e9f Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Tue, 30 Sep 2025 15:49:52 +0200 Subject: [PATCH 1/3] Proto/abaab: remove obsolete error --- src/proto_alpha/lib_protocol/validate_errors.ml | 13 +------------ src/proto_alpha/lib_protocol/validate_errors.mli | 1 - 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/src/proto_alpha/lib_protocol/validate_errors.ml b/src/proto_alpha/lib_protocol/validate_errors.ml index 97dc42a0ce96..7ffcbedca7ca 100644 --- a/src/proto_alpha/lib_protocol/validate_errors.ml +++ b/src/proto_alpha/lib_protocol/validate_errors.ml @@ -144,7 +144,6 @@ module Consensus = struct hash : Operation_hash.t; } | Empty_aggregation_committee - | All_bakers_attest_not_implemented let () = register_error_kind @@ -465,17 +464,7 @@ module Consensus = struct Format.fprintf ppf "The aggregation committee is empty.") Data_encoding.empty (function Empty_aggregation_committee -> Some () | _ -> None) - (fun () -> Empty_aggregation_committee) ; - register_error_kind - `Permanent - ~id:"validate.all_bakers_attest_not_implemented" - ~title:"All bakers attest not implemented" - ~description:"All bakers attest is not implemented yet" - ~pp:(fun ppf () -> - Format.fprintf ppf "All bakers attest is not implemented yet") - Data_encoding.empty - (function All_bakers_attest_not_implemented -> Some () | _ -> None) - (fun () -> All_bakers_attest_not_implemented) + (fun () -> Empty_aggregation_committee) end module Voting = struct diff --git a/src/proto_alpha/lib_protocol/validate_errors.mli b/src/proto_alpha/lib_protocol/validate_errors.mli index c89c5329b1d2..db8cd730d9f7 100644 --- a/src/proto_alpha/lib_protocol/validate_errors.mli +++ b/src/proto_alpha/lib_protocol/validate_errors.mli @@ -94,7 +94,6 @@ module Consensus : sig hash : Operation_hash.t; } | Empty_aggregation_committee - | All_bakers_attest_not_implemented end (** Errors that may arise while validating a voting operation. *) -- GitLab From ee863e7cd98afb2a4bf4b65cce7f36a17e7d796a Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Tue, 30 Sep 2025 15:57:54 +0200 Subject: [PATCH 2/3] Proto/abaab: add invalid slot error --- .../lib_protocol/delegate_sampler.ml | 21 +++++++++++++++++++ .../lib_protocol/delegate_sampler.mli | 2 ++ 2 files changed, 23 insertions(+) diff --git a/src/proto_alpha/lib_protocol/delegate_sampler.ml b/src/proto_alpha/lib_protocol/delegate_sampler.ml index ab273c4fa65f..43b112ff6ba4 100644 --- a/src/proto_alpha/lib_protocol/delegate_sampler.ml +++ b/src/proto_alpha/lib_protocol/delegate_sampler.ml @@ -25,6 +25,27 @@ (* *) (*****************************************************************************) +type error += Invalid_slot of {level : Level_repr.t; slot : Slot_repr.t} + +let () = + register_error_kind + `Permanent + ~id:"validate.invalid_slot" + ~title:"Invalid slot" + ~description:"The provided slot is not valid." + ~pp:(fun ppf (level, slot) -> + Format.fprintf + ppf + "Cannot provide the delegate for slot %a at level %a." + Slot_repr.pp + slot + Level_repr.pp + level) + Data_encoding.( + obj2 (req "level" Level_repr.encoding) (req "slot" Slot_repr.encoding)) + (function Invalid_slot {level; slot} -> Some (level, slot) | _ -> None) + (fun (level, slot) -> Invalid_slot {level; slot}) + module Delegate_sampler_state = struct module Cache_client = struct type cached_value = Delegate_consensus_key.pk Sampler.t diff --git a/src/proto_alpha/lib_protocol/delegate_sampler.mli b/src/proto_alpha/lib_protocol/delegate_sampler.mli index 4783dd1fc60f..0d83f28b17d7 100644 --- a/src/proto_alpha/lib_protocol/delegate_sampler.mli +++ b/src/proto_alpha/lib_protocol/delegate_sampler.mli @@ -34,6 +34,8 @@ This module is responsible for maintaining the table {!Storage.Delegate_sampler_state}. *) +type error += Invalid_slot of {level : Level_repr.t; slot : Slot_repr.t} + (** Participation slots potentially associated to accounts. The accounts that didn't place a deposit will be excluded from this list. This function should only be used to compute the deposits to -- GitLab From 02a729f6189dcb08b88f8b005272ed3d13cac492 Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Tue, 30 Sep 2025 15:59:14 +0200 Subject: [PATCH 3/3] Proto/abaab: update slot owner --- src/proto_alpha/lib_plugin/dal_services.ml | 5 ++++- src/proto_alpha/lib_plugin/mempool.ml | 2 +- src/proto_alpha/lib_protocol/alpha_context.ml | 10 +++++++++- src/proto_alpha/lib_protocol/alpha_context.mli | 2 +- src/proto_alpha/lib_protocol/apply.ml | 10 ++++++---- src/proto_alpha/lib_protocol/baking.ml | 9 +++++---- .../lib_protocol/delegate_sampler.ml | 18 +++++++++++++++--- .../lib_protocol/delegate_sampler.mli | 3 ++- src/proto_alpha/lib_protocol/raw_context.mli | 3 ++- src/proto_alpha/lib_protocol/validate.ml | 14 +++++++------- 10 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/proto_alpha/lib_plugin/dal_services.ml b/src/proto_alpha/lib_plugin/dal_services.ml index dd880a694adb..cdabdd422e18 100644 --- a/src/proto_alpha/lib_plugin/dal_services.ml +++ b/src/proto_alpha/lib_plugin/dal_services.ml @@ -37,7 +37,10 @@ let shards ctxt ~level = let*? slots = Slot.Range.create ~min:0 ~count:number_of_shards in Slot.Range.rev_fold_es (fun (ctxt, map) slot -> - let* ctxt, consensus_pk = Stake_distribution.slot_owner ctxt level slot in + let*? round = Round.of_slot slot in + let* ctxt, _, consensus_pk = + Stake_distribution.baking_rights_owner ctxt level ~round + in let slot = Slot.to_int slot in let map = Signature.Public_key_hash.Map.update diff --git a/src/proto_alpha/lib_plugin/mempool.ml b/src/proto_alpha/lib_plugin/mempool.ml index 3b7a898aa71b..903a0668e1d2 100644 --- a/src/proto_alpha/lib_plugin/mempool.ml +++ b/src/proto_alpha/lib_plugin/mempool.ml @@ -824,7 +824,7 @@ let get_context context ~(head : Tezos_base.Block_header.shell_header) = let sources_from_level_and_slot ctxt level slot = let open Lwt_syntax in - let* slot_owner = Stake_distribution.slot_owner ctxt level slot in + let* slot_owner = Stake_distribution.attestation_slot_owner ctxt level slot in match slot_owner with | Ok ( _ctxt, diff --git a/src/proto_alpha/lib_protocol/alpha_context.ml b/src/proto_alpha/lib_protocol/alpha_context.ml index 54d8c00fc8ae..dcefa6a73362 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.ml +++ b/src/proto_alpha/lib_protocol/alpha_context.ml @@ -652,7 +652,15 @@ end module Stake_distribution = struct let baking_rights_owner = Delegate_sampler.baking_rights_owner - let slot_owner = Delegate_sampler.slot_owner + let attestation_slot_owner ctxt level slot = + let all_bakers_attest_enabled = + Consensus_parameters_storage.check_all_bakers_attest_at_level ctxt level + in + Delegate_sampler.attestation_slot_owner + ~all_bakers_attest_enabled + ctxt + level + slot let stake_info_for_cycle = Delegate_sampler.stake_info_for_cycle diff --git a/src/proto_alpha/lib_protocol/alpha_context.mli b/src/proto_alpha/lib_protocol/alpha_context.mli index 10318b27470c..c9e9a404e6c6 100644 --- a/src/proto_alpha/lib_protocol/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/alpha_context.mli @@ -5288,7 +5288,7 @@ module Stake_distribution : sig round:Round.t -> (context * Slot.t * Consensus_key.pk) tzresult Lwt.t - val slot_owner : + val attestation_slot_owner : context -> Level.t -> Slot.t -> (context * Consensus_key.pk) tzresult Lwt.t val stake_info_for_cycle : diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index a394f7dff8c2..0078267eca66 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -2308,7 +2308,7 @@ let record_preattestation ctxt (mode : mode) (content : consensus_content) : to finalize anyway in this mode. *) let* ctxt, consensus_key = let level = Level.from_raw ctxt content.level in - Stake_distribution.slot_owner ctxt level content.slot + Stake_distribution.attestation_slot_owner ctxt level content.slot in return ( ctxt, @@ -2363,7 +2363,7 @@ let record_attestation ctxt (mode : mode) (consensus : consensus_content) to finalize anyway in this mode. *) let* ctxt, consensus_key = let level = Level.from_raw ctxt consensus.level in - Stake_distribution.slot_owner ctxt level consensus.slot + Stake_distribution.attestation_slot_owner ctxt level consensus.slot in return ( ctxt, @@ -2549,7 +2549,9 @@ let punish_double_consensus_operation ctxt ~operation_hash ~payload_producer Misbehaviour.{level; round; kind = Double_attesting} in let level = Level.from_raw ctxt misbehaviour.level in - let* ctxt, {delegate; _} = Stake_distribution.slot_owner ctxt level slot in + let* ctxt, {delegate; _} = + Stake_distribution.attestation_slot_owner ctxt level slot + in let* ctxt, contents_result = punish_double_signing ctxt @@ -2662,7 +2664,7 @@ let apply_contents_list (type kind) ctxt chain_id (mode : mode) in let level = Level.from_raw ctxt level in let* ctxt, consensus_pk = - Stake_distribution.slot_owner ctxt level consensus_slot + Stake_distribution.attestation_slot_owner ctxt level consensus_slot in let delegate = consensus_pk.delegate in let*! ctxt, _already_denounced = diff --git a/src/proto_alpha/lib_protocol/baking.ml b/src/proto_alpha/lib_protocol/baking.ml index 8964820680f3..1388bc3ea728 100644 --- a/src/proto_alpha/lib_protocol/baking.ml +++ b/src/proto_alpha/lib_protocol/baking.ml @@ -135,8 +135,8 @@ let attesting_rights (ctxt : t) level = Slot.Range.rev_fold_es (fun (ctxt, map) slot -> let*? round = Round.of_slot slot in - let* ctxt, consensus_pk = - Stake_distribution.slot_owner ctxt level slot + let* ctxt, _, consensus_pk = + Stake_distribution.baking_rights_owner ctxt level ~round in let map = Signature.Public_key_hash.Map.update @@ -226,8 +226,9 @@ let attesting_rights_by_first_slot ctxt level : let* ctxt, (delegates_map, slots_map) = Slot.Range.fold_es (fun (ctxt, (delegates_map, slots_map)) slot -> - let+ ctxt, consensus_key = - Stake_distribution.slot_owner ctxt level slot + let*? round = Round.of_slot slot in + let+ ctxt, _, consensus_key = + Stake_distribution.baking_rights_owner ctxt level ~round in let initial_slot, delegates_map = match diff --git a/src/proto_alpha/lib_protocol/delegate_sampler.ml b/src/proto_alpha/lib_protocol/delegate_sampler.ml index 43b112ff6ba4..1626234482b8 100644 --- a/src/proto_alpha/lib_protocol/delegate_sampler.ml +++ b/src/proto_alpha/lib_protocol/delegate_sampler.ml @@ -167,8 +167,6 @@ module Random = struct return (c, pk) end -let slot_owner c level slot = Random.owner c level (Slot_repr.to_int slot) - let baking_rights_owner c (level : Level_repr.t) ~round = let open Lwt_result_syntax in (* This committee is used for rounds *) @@ -209,6 +207,7 @@ let stake_info_for_cycle ctxt cycle = in return (ctxt, total_stake, stakes_pk) in + (* The returned list of delegates is already sorted *) Raw_context.stake_info_for_cycle ~read ctxt cycle let stake_info ctxt level = @@ -222,6 +221,16 @@ let load_stake_info_for_cycle ctxt cycle = in return ctxt +let attestation_slot_owner ~all_bakers_attest_enabled ctxt level slot = + let open Lwt_result_syntax in + if all_bakers_attest_enabled then + let* ctxt, _, info = stake_info ctxt level in + let i = Slot_repr.to_int slot in + match List.nth info i with + | None -> tzfail (Invalid_slot {level; slot}) + | Some (owner, _) -> return (ctxt, owner) + else Random.owner ctxt level (Slot_repr.to_int slot) + let get_delegate_stake_from_staking_balance ctxt delegate staking_balance = let open Lwt_result_syntax in let* staking_parameters = @@ -351,7 +360,10 @@ let attesting_power ~all_bakers_attest_enabled ctxt level = in Slot_repr.Range.fold_es (fun (ctxt, map) slot -> - let* ctxt, consensus_pk = slot_owner ctxt level slot in + let* ctxt, consensus_pk = + (* all_bakers_attest_enabled = false *) + attestation_slot_owner ~all_bakers_attest_enabled ctxt level slot + in let map = Signature.Public_key_hash.Map.update consensus_pk.delegate diff --git a/src/proto_alpha/lib_protocol/delegate_sampler.mli b/src/proto_alpha/lib_protocol/delegate_sampler.mli index 0d83f28b17d7..56c4edf8e34a 100644 --- a/src/proto_alpha/lib_protocol/delegate_sampler.mli +++ b/src/proto_alpha/lib_protocol/delegate_sampler.mli @@ -42,7 +42,8 @@ type error += Invalid_slot of {level : Level_repr.t; slot : Slot_repr.t} freeze or initialize the protocol while stitching. RPCs can use this function to predict an approximation of long term future slot allocations. It shouldn't be used in the baker. *) -val slot_owner : +val attestation_slot_owner : + all_bakers_attest_enabled:bool -> Raw_context.t -> Level_repr.t -> Slot_repr.t -> diff --git a/src/proto_alpha/lib_protocol/raw_context.mli b/src/proto_alpha/lib_protocol/raw_context.mli index be66508f7532..d72c6e86ac0e 100644 --- a/src/proto_alpha/lib_protocol/raw_context.mli +++ b/src/proto_alpha/lib_protocol/raw_context.mli @@ -313,7 +313,8 @@ val init_stake_info_for_cycle : [init_stake_info_for_cycle] or [stake_info_for_cycle] was previously called for the same [cycle]. Otherwise, it is read "on-disk" with the [read] function and then cached in [ctxt] like - [init_stake_info_for_cycle]. *) + [init_stake_info_for_cycle]. + The list follows a lexicographical order on the delegate pkh. *) val stake_info_for_cycle : read:(t -> (t * Int64.t * (consensus_pk * int64) list) tzresult Lwt.t) -> t -> diff --git a/src/proto_alpha/lib_protocol/validate.ml b/src/proto_alpha/lib_protocol/validate.ml index cafac1daf238..1b20a4502e52 100644 --- a/src/proto_alpha/lib_protocol/validate.ml +++ b/src/proto_alpha/lib_protocol/validate.ml @@ -1964,7 +1964,7 @@ module Anonymous = struct List.fold_left_es (fun (ctxt, public_keys) slot -> let* ctxt, consensus_key = - Stake_distribution.slot_owner ctxt level slot + Stake_distribution.attestation_slot_owner ctxt level slot in match consensus_key.consensus_pk with | Bls pk -> return (ctxt, pk :: public_keys) @@ -1998,7 +1998,7 @@ module Anonymous = struct List.fold_left_es (fun (ctxt, pks, weighted_pks) (slot, dal) -> let* ctxt, consensus_key = - Stake_distribution.slot_owner ctxt level slot + Stake_distribution.attestation_slot_owner ctxt level slot in match consensus_key.consensus_pk with | Bls consensus_pk -> ( @@ -2166,7 +2166,7 @@ module Anonymous = struct check_denunciation_age vi (`Consensus_denounciation kind) level.level in let* ctxt, consensus_key = - Stake_distribution.slot_owner vi.ctxt level slot + Stake_distribution.attestation_slot_owner vi.ctxt level slot in let delegate = consensus_key.delegate in let* already_slashed = @@ -2442,7 +2442,7 @@ module Anonymous = struct let*? () = check_denunciation_age vi `Dal_denounciation level in let level = Level.from_raw vi.ctxt level in let* ctxt, consensus_key = - Stake_distribution.slot_owner vi.ctxt level consensus_slot + Stake_distribution.attestation_slot_owner vi.ctxt level consensus_slot in let delegate = consensus_key.delegate in let*! already_denounced = @@ -2471,9 +2471,9 @@ module Anonymous = struct shard_index = shard_with_proof.shard.index; }) in - let* _ctxt, shard_owner = - let*? tb_slot = Slot.of_int shard_index in - Stake_distribution.slot_owner vi.ctxt level tb_slot + let* _ctxt, _, shard_owner = + let*? tb_round = Round.of_int shard_index in + Stake_distribution.baking_rights_owner vi.ctxt level ~round:tb_round in let*? () = error_unless -- GitLab