From 947d298d5c15fdbe00f43df17a0f1faa842d69b6 Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Tue, 19 Nov 2024 11:03:49 +0100 Subject: [PATCH 1/2] Proto: use round ownership functions --- src/proto_alpha/lib_delegate/baking_scheduling.ml | 2 ++ src/proto_alpha/lib_delegate/baking_state.ml | 11 +++++++++-- src/proto_alpha/lib_delegate/baking_state.mli | 5 +++++ src/proto_alpha/lib_protocol/apply.ml | 6 +++--- src/proto_alpha/lib_protocol/delegate_sampler.ml | 9 ++++----- src/proto_alpha/lib_protocol/validate.ml | 11 ++++------- 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/proto_alpha/lib_delegate/baking_scheduling.ml b/src/proto_alpha/lib_delegate/baking_scheduling.ml index 803e35d1c65c..6428ce68c120 100644 --- a/src/proto_alpha/lib_delegate/baking_scheduling.ml +++ b/src/proto_alpha/lib_delegate/baking_scheduling.ml @@ -299,6 +299,8 @@ let first_potential_round_at_next_level state ~earliest_round = within the range [0 ... committee_size], look for the first subsequent slot we own, and finally translate it back to a round by restoring the original offset. *) + (* TODO https://gitlab.com/tezos/tezos/-/issues/7931 + The use of Round.to_slot should be avoided *) let*? earliest_slot = Round.to_slot ~committee_size earliest_round in let*? earliest_round = Round.to_int earliest_round in let period_offset = earliest_round / committee_size in diff --git a/src/proto_alpha/lib_delegate/baking_state.ml b/src/proto_alpha/lib_delegate/baking_state.ml index 5a10844ea61a..0bfb143c3f11 100644 --- a/src/proto_alpha/lib_delegate/baking_state.ml +++ b/src/proto_alpha/lib_delegate/baking_state.ml @@ -284,6 +284,13 @@ module Delegate_slots = struct let min_slot slots = SlotMap.min_binding slots.own_delegate_slots + let own_round_owner slots ~committee_size ~round = + let open Result_syntax in + let* slot = + Round.to_slot ~committee_size round |> Environment.wrap_tzresult + in + return @@ SlotMap.find slot slots.own_delegate_slots + let voting_power slots ~slot = SlotMap.find slot slots.all_delegate_voting_power end @@ -1168,9 +1175,9 @@ let round_proposer state ~level round = let committee_size = state.global_state.constants.parametric.consensus_committee_size in - Round.to_slot round ~committee_size |> function + match Delegate_slots.own_round_owner slots ~round ~committee_size with | Error _ -> None - | Ok slot -> Delegate_slots.own_slot_owner slots ~slot + | Ok owner -> owner let cache_size_limit = 100 diff --git a/src/proto_alpha/lib_delegate/baking_state.mli b/src/proto_alpha/lib_delegate/baking_state.mli index e38bb6b53847..aaed47d00de0 100644 --- a/src/proto_alpha/lib_delegate/baking_state.mli +++ b/src/proto_alpha/lib_delegate/baking_state.mli @@ -125,6 +125,11 @@ module Delegate_slots : sig given slot is not the delegate's first slot). *) val own_slot_owner : t -> slot:Slot.t -> delegate_slot option + (** Returns, among our *own* delegates, the delegate (together with its + first attesting slot) that owns the given round, if any. *) + val own_round_owner : + t -> committee_size:int -> round:Round.t -> delegate_slot option tzresult + (** Returns the voting power of the delegate whose first slot is the given slot. Returns [None] if the slot is not the first slot of any delegate. *) val voting_power : t -> slot:Slot.t -> int option diff --git a/src/proto_alpha/lib_protocol/apply.ml b/src/proto_alpha/lib_protocol/apply.ml index f6f304c13a1b..d416828b1be9 100644 --- a/src/proto_alpha/lib_protocol/apply.ml +++ b/src/proto_alpha/lib_protocol/apply.ml @@ -2522,9 +2522,9 @@ let punish_double_baking ctxt ~operation_hash (bh1 : Block_header.t) let round1 = Fitness.round bh1_fitness in let*? raw_level = Raw_level.of_int32 bh1.shell.level in let level = Level.from_raw ctxt raw_level in - let committee_size = Constants.consensus_committee_size ctxt in - let*? slot1 = Round.to_slot round1 ~committee_size in - let* ctxt, consensus_pk1 = Stake_distribution.slot_owner ctxt level slot1 in + let* ctxt, _, consensus_pk1 = + Stake_distribution.baking_rights_owner ctxt level ~round:round1 + in punish_delegate ctxt ~operation_hash diff --git a/src/proto_alpha/lib_protocol/delegate_sampler.ml b/src/proto_alpha/lib_protocol/delegate_sampler.ml index 32e4fa07c4eb..44999a2f58cb 100644 --- a/src/proto_alpha/lib_protocol/delegate_sampler.ml +++ b/src/proto_alpha/lib_protocol/delegate_sampler.ml @@ -150,11 +150,10 @@ 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 - let*? round = Round_repr.to_int round in - let consensus_committee_size = Constants_storage.consensus_committee_size c in - let*? slot = Slot_repr.of_int (round mod consensus_committee_size) in - let+ ctxt, pk = slot_owner c level slot in - (ctxt, slot, pk) + let committee_size = Constants_storage.consensus_committee_size c in + let*? slot = Round_repr.to_slot ~committee_size round in + let* ctxt, pk = slot_owner c level slot in + return (ctxt, slot, pk) let load_sampler_for_cycle ctxt cycle = let open Lwt_result_syntax in diff --git a/src/proto_alpha/lib_protocol/validate.ml b/src/proto_alpha/lib_protocol/validate.ml index 0c2f8be7e326..3c12292d9152 100644 --- a/src/proto_alpha/lib_protocol/validate.ml +++ b/src/proto_alpha/lib_protocol/validate.ml @@ -1780,14 +1780,11 @@ module Anonymous = struct level1 in let level = Level.from_raw vi.ctxt level1 in - let committee_size = Constants.consensus_committee_size vi.ctxt in - let*? slot1 = Round.to_slot round1 ~committee_size in - let* ctxt, consensus_key1 = - Stake_distribution.slot_owner vi.ctxt level slot1 + let* ctxt, _, consensus_key1 = + Stake_distribution.baking_rights_owner vi.ctxt level ~round:round1 in - let*? slot2 = Round.to_slot round2 ~committee_size in - let* ctxt, consensus_key2 = - Stake_distribution.slot_owner ctxt level slot2 + let* ctxt, _, consensus_key2 = + Stake_distribution.baking_rights_owner ctxt level ~round:round2 in let delegate1, delegate2 = (consensus_key1.delegate, consensus_key2.delegate) -- GitLab From 3801b74c2f3d5752fd2417cc01e5aeac55350474 Mon Sep 17 00:00:00 2001 From: Lucas Randazzo Date: Wed, 27 Nov 2024 11:40:11 +0100 Subject: [PATCH 2/2] Proto: Inline slot_owner in baking_rights_owner The `Round.to_slot` step is still necessary, because it uses the committee size. This is to only have a controllably limited number of bakers that can potentially propose at a given level. This is necessary (for now) in the baker. Since everyone will be able to attest, this also means that it will be technically the only relevant use of `committee_size`, changing its definition to `number of unique rounds before looping bakers` or something. --- src/proto_alpha/lib_protocol/delegate_sampler.ml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/proto_alpha/lib_protocol/delegate_sampler.ml b/src/proto_alpha/lib_protocol/delegate_sampler.ml index 44999a2f58cb..b73a69e6768b 100644 --- a/src/proto_alpha/lib_protocol/delegate_sampler.ml +++ b/src/proto_alpha/lib_protocol/delegate_sampler.ml @@ -151,8 +151,10 @@ 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 let committee_size = Constants_storage.consensus_committee_size c in + (* We use [Round.to_slot] to have a limited number of unique rounds + (it should loop after some time) *) let*? slot = Round_repr.to_slot ~committee_size round in - let* ctxt, pk = slot_owner c level slot in + let* ctxt, pk = Random.owner c level (Slot_repr.to_int slot) in return (ctxt, slot, pk) let load_sampler_for_cycle ctxt cycle = -- GitLab