diff --git a/src/proto_alpha/lib_delegate/baking_scheduling.ml b/src/proto_alpha/lib_delegate/baking_scheduling.ml index 803e35d1c65ca800454c7213b346f9c8466caf80..6428ce68c120b0d0d3c883865852146d20c2a13d 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 5a10844ea61aee30eb02205e5894d655f1539a67..0bfb143c3f11d1a9e554270947c9bdd61fc2cc70 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 e38bb6b5384779ed08e33628ec808ccbd23f8e84..aaed47d00de05628b1be6015f032252da5f2e93e 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 f6f304c13a1b001b9cdf9c685a7e5a9d4d429a90..d416828b1be9976edb16803a4fba576e5c80bd2e 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 32e4fa07c4ebd3e440253ba7066f78021b1dc867..b73a69e6768bc8c8e71fe359a37da5bfb4b2741e 100644 --- a/src/proto_alpha/lib_protocol/delegate_sampler.ml +++ b/src/proto_alpha/lib_protocol/delegate_sampler.ml @@ -150,11 +150,12 @@ 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 + (* 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 = Random.owner c level (Slot_repr.to_int 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 0c2f8be7e326d9069d90e83f064345df52a03003..3c12292d915243fee9fcdf1efaf3502d6b91afef 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)