diff --git a/src/proto_alpha/lib_plugin/dal_services.ml b/src/proto_alpha/lib_plugin/dal_services.ml index dd880a694adb589b119dcf94dad95a9efc101f14..cdabdd422e180c481ec18b20fbceb340a86ecb9b 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 3b7a898aa71b18424d5ec7405bed2bf1508d3c55..903a0668e1d2654118417940acee4e791bd3c0eb 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 54d8c00fc8ae2d0d6040ac0d9788e825bb1ac7ef..dcefa6a73362604c5559cc6955fc241396b1c2b9 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 10318b27470c583adaa20d87cd5af81f559a2b5f..c9e9a404e6c665271c4c1ba4107565d3334c1303 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 a394f7dff8c25f7bd1707b3fc8db1afba0d57748..0078267eca661b43b3635abb4dc42e6ebabd6eb7 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 8964820680f3979af41d3acf363d81cf535fa479..1388bc3ea7285251071bba5e16f011b9e5d45fb4 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 ab273c4fa65ff1c226d5308a0bcf24c88ee8de60..1626234482b82dbbd493842caca2198d976c8272 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 @@ -146,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 *) @@ -188,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 = @@ -201,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 = @@ -330,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 4783dd1fc60f7d3d72e0c33a5ce4ee1c248fee55..56c4edf8e34a93674b62b7f241e4f4cd257eb538 100644 --- a/src/proto_alpha/lib_protocol/delegate_sampler.mli +++ b/src/proto_alpha/lib_protocol/delegate_sampler.mli @@ -34,13 +34,16 @@ 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 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 be66508f753233856f890d6fda89a476b9c037f8..d72c6e86ac0ee60823cf355093582b0ea9a22ad6 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 cafac1daf2387852fff364f3f88105ff8539780d..1b20a4502e5250a172a1b36c453bd39f3fb77c9c 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 diff --git a/src/proto_alpha/lib_protocol/validate_errors.ml b/src/proto_alpha/lib_protocol/validate_errors.ml index 97dc42a0ce9600683db935b64be4127b17da92d1..7ffcbedca7cae663ab5e8e155d59f8506201d64b 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 c89c5329b1d288a3e0ceb57c584e58017f9868df..db8cd730d9f737455a5b09863b6139d328a37f87 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. *)