diff --git a/frame/babe/src/benchmarking.rs b/frame/babe/src/benchmarking.rs index 087cac2ed6cc6..145a82c4f8049 100644 --- a/frame/babe/src/benchmarking.rs +++ b/frame/babe/src/benchmarking.rs @@ -91,7 +91,7 @@ mod tests { let equivocation_proof = generate_equivocation_proof( offending_authority_index, offending_authority_pair, - CurrentSlot::get() + 1, + CurrentSlot::::get() + 1, ); println!("equivocation_proof: {:?}", equivocation_proof); diff --git a/frame/babe/src/equivocation.rs b/frame/babe/src/equivocation.rs index 30fbaf31371bf..154faa49f0b26 100644 --- a/frame/babe/src/equivocation.rs +++ b/frame/babe/src/equivocation.rs @@ -48,7 +48,7 @@ use sp_staking::{ }; use sp_std::prelude::*; -use crate::{Call, Module, Config}; +use crate::{Call, Pallet, Config}; /// A trait with utility methods for handling equivocation reports in BABE. /// The trait provides methods for reporting an offence triggered by a valid @@ -182,7 +182,7 @@ where /// A `ValidateUnsigned` implementation that restricts calls to `report_equivocation_unsigned` /// to local calls (i.e. extrinsics generated on this node) or that already in a block. This /// guarantees that only block authors can include unsigned equivocation reports. -impl frame_support::unsigned::ValidateUnsigned for Module { +impl frame_support::unsigned::ValidateUnsigned for Pallet { type Call = Call; fn validate_unsigned(source: TransactionSource, call: &Self::Call) -> TransactionValidity { if let Call::report_equivocation_unsigned(equivocation_proof, key_owner_proof) = call { diff --git a/frame/babe/src/lib.rs b/frame/babe/src/lib.rs index c259b60c6a7ce..5c8b8bb0a7ca4 100644 --- a/frame/babe/src/lib.rs +++ b/frame/babe/src/lib.rs @@ -23,13 +23,10 @@ use codec::{Decode, Encode}; use frame_support::{ - decl_error, decl_module, decl_storage, dispatch::DispatchResultWithPostInfo, traits::{FindAuthor, Get, KeyOwnerProofSystem, OneSessionHandler, OnTimestampSet}, weights::{Pays, Weight}, - Parameter, }; -use frame_system::{ensure_none, ensure_root, ensure_signed}; use sp_application_crypto::Public; use sp_runtime::{ generic::DigestItem, @@ -64,52 +61,7 @@ pub use randomness::{ CurrentBlockRandomness, RandomnessFromOneEpochAgo, RandomnessFromTwoEpochsAgo, }; -pub trait Config: pallet_timestamp::Config { - /// The amount of time, in slots, that each epoch should last. - /// NOTE: Currently it is not possible to change the epoch duration after - /// the chain has started. Attempting to do so will brick block production. - type EpochDuration: Get; - - /// The expected average block time at which BABE should be creating - /// blocks. Since BABE is probabilistic it is not trivial to figure out - /// what the expected average block time should be based on the slot - /// duration and the security parameter `c` (where `1 - c` represents - /// the probability of a slot being empty). - type ExpectedBlockTime: Get; - - /// BABE requires some logic to be triggered on every block to query for whether an epoch - /// has ended and to perform the transition to the next epoch. - /// - /// Typically, the `ExternalTrigger` type should be used. An internal trigger should only be used - /// when no other module is responsible for changing authority set. - type EpochChangeTrigger: EpochChangeTrigger; - - /// The proof of key ownership, used for validating equivocation reports. - /// The proof must include the session index and validator count of the - /// session at which the equivocation occurred. - type KeyOwnerProof: Parameter + GetSessionNumber + GetValidatorCount; - - /// The identification of a key owner, used when reporting equivocations. - type KeyOwnerIdentification: Parameter; - - /// A system for proving ownership of keys, i.e. that a given key was part - /// of a validator set, needed for validating equivocation reports. - type KeyOwnerProofSystem: KeyOwnerProofSystem< - (KeyTypeId, AuthorityId), - Proof = Self::KeyOwnerProof, - IdentificationTuple = Self::KeyOwnerIdentification, - >; - - /// The equivocation handling subsystem, defines methods to report an - /// offence (after the equivocation has been validated) and for submitting a - /// transaction to report an equivocation (from an offchain context). - /// NOTE: when enabling equivocation handling (i.e. this type isn't set to - /// `()`) you must use this pallet's `ValidateUnsigned` in the runtime - /// definition. - type HandleEquivocation: HandleEquivocation; - - type WeightInfo: WeightInfo; -} +pub use pallet::*; pub trait WeightInfo { fn plan_config_change() -> Weight; @@ -137,11 +89,11 @@ pub struct SameAuthoritiesForever; impl EpochChangeTrigger for SameAuthoritiesForever { fn trigger(now: T::BlockNumber) { - if >::should_epoch_change(now) { - let authorities = >::authorities(); + if >::should_epoch_change(now) { + let authorities = >::authorities(); let next_authorities = authorities.clone(); - >::enact_epoch_change(authorities, next_authorities); + >::enact_epoch_change(authorities, next_authorities); } } } @@ -150,8 +102,70 @@ const UNDER_CONSTRUCTION_SEGMENT_LENGTH: usize = 256; type MaybeRandomness = Option; -decl_error! { - pub enum Error for Module { +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use super::*; + + /// The BABE Pallet + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + #[pallet::config] + #[pallet::disable_frame_system_supertrait_check] + pub trait Config: pallet_timestamp::Config { + /// The amount of time, in slots, that each epoch should last. + /// NOTE: Currently it is not possible to change the epoch duration after + /// the chain has started. Attempting to do so will brick block production. + #[pallet::constant] + type EpochDuration: Get; + + /// The expected average block time at which BABE should be creating + /// blocks. Since BABE is probabilistic it is not trivial to figure out + /// what the expected average block time should be based on the slot + /// duration and the security parameter `c` (where `1 - c` represents + /// the probability of a slot being empty). + #[pallet::constant] + type ExpectedBlockTime: Get; + + /// BABE requires some logic to be triggered on every block to query for whether an epoch + /// has ended and to perform the transition to the next epoch. + /// + /// Typically, the `ExternalTrigger` type should be used. An internal trigger should only be used + /// when no other module is responsible for changing authority set. + type EpochChangeTrigger: EpochChangeTrigger; + + /// The proof of key ownership, used for validating equivocation reports. + /// The proof must include the session index and validator count of the + /// session at which the equivocation occurred. + type KeyOwnerProof: Parameter + GetSessionNumber + GetValidatorCount; + + /// The identification of a key owner, used when reporting equivocations. + type KeyOwnerIdentification: Parameter; + + /// A system for proving ownership of keys, i.e. that a given key was part + /// of a validator set, needed for validating equivocation reports. + type KeyOwnerProofSystem: KeyOwnerProofSystem< + (KeyTypeId, AuthorityId), + Proof = Self::KeyOwnerProof, + IdentificationTuple = Self::KeyOwnerIdentification, + >; + + /// The equivocation handling subsystem, defines methods to report an + /// offence (after the equivocation has been validated) and for submitting a + /// transaction to report an equivocation (from an offchain context). + /// NOTE: when enabling equivocation handling (i.e. this type isn't set to + /// `()`) you must use this pallet's `ValidateUnsigned` in the runtime + /// definition. + type HandleEquivocation: HandleEquivocation; + + type WeightInfo: WeightInfo; + } + + #[pallet::error] + pub enum Error { /// An equivocation proof provided as part of an equivocation report is invalid. InvalidEquivocationProof, /// A key ownership proof provided as part of an equivocation report is invalid. @@ -159,150 +173,189 @@ decl_error! { /// A given equivocation report is valid but already previously reported. DuplicateOffenceReport, } -} -decl_storage! { - trait Store for Module as Babe { - /// Current epoch index. - pub EpochIndex get(fn epoch_index): u64; + /// Current epoch index. + #[pallet::storage] + #[pallet::getter(fn epoch_index)] + pub type EpochIndex = StorageValue<_, u64, ValueQuery>; - /// Current epoch authorities. - pub Authorities get(fn authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; + /// Current epoch authorities. + #[pallet::storage] + #[pallet::getter(fn authorities)] + pub type Authorities = StorageValue<_, Vec<(AuthorityId, BabeAuthorityWeight)>, ValueQuery>; - /// The slot at which the first epoch actually started. This is 0 - /// until the first block of the chain. - pub GenesisSlot get(fn genesis_slot): Slot; + /// The slot at which the first epoch actually started. This is 0 + /// until the first block of the chain. + #[pallet::storage] + #[pallet::getter(fn genesis_slot)] + pub type GenesisSlot = StorageValue<_, Slot, ValueQuery>; - /// Current slot number. - pub CurrentSlot get(fn current_slot): Slot; + /// Current slot number. + #[pallet::storage] + #[pallet::getter(fn current_slot)] + pub type CurrentSlot = StorageValue<_, Slot, ValueQuery>; - /// The epoch randomness for the *current* epoch. - /// - /// # Security - /// - /// This MUST NOT be used for gambling, as it can be influenced by a - /// malicious validator in the short term. It MAY be used in many - /// cryptographic protocols, however, so long as one remembers that this - /// (like everything else on-chain) it is public. For example, it can be - /// used where a number is needed that cannot have been chosen by an - /// adversary, for purposes such as public-coin zero-knowledge proofs. - // NOTE: the following fields don't use the constants to define the - // array size because the metadata API currently doesn't resolve the - // variable to its underlying value. - pub Randomness get(fn randomness): schnorrkel::Randomness; - - /// Pending epoch configuration change that will be applied when the next epoch is enacted. - PendingEpochConfigChange: Option; - - /// Next epoch randomness. - NextRandomness: schnorrkel::Randomness; - - /// Next epoch authorities. - NextAuthorities: Vec<(AuthorityId, BabeAuthorityWeight)>; - - /// Randomness under construction. - /// - /// We make a tradeoff between storage accesses and list length. - /// We store the under-construction randomness in segments of up to - /// `UNDER_CONSTRUCTION_SEGMENT_LENGTH`. - /// - /// Once a segment reaches this length, we begin the next one. - /// We reset all segments and return to `0` at the beginning of every - /// epoch. - SegmentIndex build(|_| 0): u32; - - /// TWOX-NOTE: `SegmentIndex` is an increasing integer, so this is okay. - UnderConstruction: map hasher(twox_64_concat) u32 => Vec; - - /// Temporary value (cleared at block finalization) which is `Some` - /// if per-block initialization has already been called for current block. - Initialized get(fn initialized): Option; - - /// Temporary value (cleared at block finalization) that includes the VRF output generated - /// at this block. This field should always be populated during block processing unless - /// secondary plain slots are enabled (which don't contain a VRF output). - AuthorVrfRandomness get(fn author_vrf_randomness): MaybeRandomness; - - /// The block numbers when the last and current epoch have started, respectively `N-1` and - /// `N`. - /// NOTE: We track this is in order to annotate the block number when a given pool of - /// entropy was fixed (i.e. it was known to chain observers). Since epochs are defined in - /// slots, which may be skipped, the block numbers may not line up with the slot numbers. - EpochStart: (T::BlockNumber, T::BlockNumber); - - /// How late the current block is compared to its parent. - /// - /// This entry is populated as part of block execution and is cleaned up - /// on block finalization. Querying this storage entry outside of block - /// execution context should always yield zero. - Lateness get(fn lateness): T::BlockNumber; - - /// The configuration for the current epoch. Should never be `None` as it is initialized in genesis. - EpochConfig: Option; - - /// The configuration for the next epoch, `None` if the config will not change - /// (you can fallback to `EpochConfig` instead in that case). - NextEpochConfig: Option; - } - add_extra_genesis { - config(authorities): Vec<(AuthorityId, BabeAuthorityWeight)>; - config(epoch_config): Option; - build(|config| { - Module::::initialize_authorities(&config.authorities); - EpochConfig::put(config.epoch_config.clone().expect("epoch_config must not be None")); - }) - } -} + /// The epoch randomness for the *current* epoch. + /// + /// # Security + /// + /// This MUST NOT be used for gambling, as it can be influenced by a + /// malicious validator in the short term. It MAY be used in many + /// cryptographic protocols, however, so long as one remembers that this + /// (like everything else on-chain) it is public. For example, it can be + /// used where a number is needed that cannot have been chosen by an + /// adversary, for purposes such as public-coin zero-knowledge proofs. + // NOTE: the following fields don't use the constants to define the + // array size because the metadata API currently doesn't resolve the + // variable to its underlying value. + #[pallet::storage] + #[pallet::getter(fn randomness)] + pub type Randomness = StorageValue<_, schnorrkel::Randomness, ValueQuery>; + + /// Pending epoch configuration change that will be applied when the next epoch is enacted. + #[pallet::storage] + pub(super) type PendingEpochConfigChange = StorageValue<_, NextConfigDescriptor>; + + /// Next epoch randomness. + #[pallet::storage] + pub(super) type NextRandomness = StorageValue<_, schnorrkel::Randomness, ValueQuery>; + + /// Next epoch authorities. + #[pallet::storage] + pub(super) type NextAuthorities = StorageValue< + _, + Vec<(AuthorityId, BabeAuthorityWeight)>, + ValueQuery, + >; -decl_module! { - /// The BABE Pallet - pub struct Module for enum Call where origin: T::Origin { - /// The number of **slots** that an epoch takes. We couple sessions to - /// epochs, i.e. we start a new session once the new epoch begins. - /// NOTE: Currently it is not possible to change the epoch duration - /// after the chain has started. Attempting to do so will brick block - /// production. - const EpochDuration: u64 = T::EpochDuration::get(); + /// Randomness under construction. + /// + /// We make a tradeoff between storage accesses and list length. + /// We store the under-construction randomness in segments of up to + /// `UNDER_CONSTRUCTION_SEGMENT_LENGTH`. + /// + /// Once a segment reaches this length, we begin the next one. + /// We reset all segments and return to `0` at the beginning of every + /// epoch. + #[pallet::storage] + pub(super) type SegmentIndex = StorageValue<_, u32, ValueQuery>; + + /// TWOX-NOTE: `SegmentIndex` is an increasing integer, so this is okay. + #[pallet::storage] + pub(super) type UnderConstruction = StorageMap< + _, + Twox64Concat, + u32, + Vec, + ValueQuery, + >; - /// The expected average block time at which BABE should be creating - /// blocks. Since BABE is probabilistic it is not trivial to figure out - /// what the expected average block time should be based on the slot - /// duration and the security parameter `c` (where `1 - c` represents - /// the probability of a slot being empty). - const ExpectedBlockTime: T::Moment = T::ExpectedBlockTime::get(); + /// Temporary value (cleared at block finalization) which is `Some` + /// if per-block initialization has already been called for current block. + #[pallet::storage] + #[pallet::getter(fn initialized)] + pub(super) type Initialized = StorageValue<_, MaybeRandomness>; + + /// Temporary value (cleared at block finalization) that includes the VRF output generated + /// at this block. This field should always be populated during block processing unless + /// secondary plain slots are enabled (which don't contain a VRF output). + #[pallet::storage] + #[pallet::getter(fn author_vrf_randomness)] + pub(super) type AuthorVrfRandomness = StorageValue<_, MaybeRandomness, ValueQuery>; + + /// The block numbers when the last and current epoch have started, respectively `N-1` and + /// `N`. + /// NOTE: We track this is in order to annotate the block number when a given pool of + /// entropy was fixed (i.e. it was known to chain observers). Since epochs are defined in + /// slots, which may be skipped, the block numbers may not line up with the slot numbers. + #[pallet::storage] + pub(super) type EpochStart = StorageValue< + _, + (T::BlockNumber, T::BlockNumber), + ValueQuery, + >; + + /// How late the current block is compared to its parent. + /// + /// This entry is populated as part of block execution and is cleaned up + /// on block finalization. Querying this storage entry outside of block + /// execution context should always yield zero. + #[pallet::storage] + #[pallet::getter(fn lateness)] + pub(super) type Lateness = StorageValue<_, T::BlockNumber, ValueQuery>; + + /// The configuration for the current epoch. Should never be `None` as it is initialized in genesis. + #[pallet::storage] + pub(super) type EpochConfig = StorageValue<_, BabeEpochConfiguration>; + + /// The configuration for the next epoch, `None` if the config will not change + /// (you can fallback to `EpochConfig` instead in that case). + #[pallet::storage] + pub(super) type NextEpochConfig = StorageValue<_, BabeEpochConfiguration>; + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>, + pub epoch_config: Option, + } + + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + authorities: Default::default(), + epoch_config: Default::default(), + } + } + } + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { + SegmentIndex::::put(0); + Pallet::::initialize_authorities(&self.authorities); + EpochConfig::::put(self.epoch_config.clone().expect("epoch_config must not be None")); + } + } + + #[pallet::hooks] + impl Hooks> for Pallet { /// Initialization - fn on_initialize(now: T::BlockNumber) -> Weight { + fn on_initialize(now: BlockNumberFor) -> Weight { Self::do_initialize(now); - 0 } /// Block finalization - fn on_finalize() { + fn on_finalize(_n: BlockNumberFor) { // at the end of the block, we can safely include the new VRF output // from this block into the under-construction randomness. If we've determined // that this block was the first in a new epoch, the changeover logic has // already occurred at this point, so the under-construction randomness // will only contain outputs from the right epoch. - if let Some(Some(randomness)) = Initialized::take() { + if let Some(Some(randomness)) = Initialized::::take() { Self::deposit_randomness(&randomness); } // The stored author generated VRF output is ephemeral. - AuthorVrfRandomness::kill(); + AuthorVrfRandomness::::kill(); // remove temporary "environment" entry from storage Lateness::::kill(); } + } + #[pallet::call] + impl Pallet { /// Report authority equivocation/misbehavior. This method will verify /// the equivocation proof and validate the given key ownership proof /// against the extracted offender. If both are valid, the offence will /// be reported. - #[weight = ::WeightInfo::report_equivocation(key_owner_proof.validator_count())] - fn report_equivocation( - origin, + #[pallet::weight(::WeightInfo::report_equivocation( + key_owner_proof.validator_count(), + ))] + pub fn report_equivocation( + origin: OriginFor, equivocation_proof: EquivocationProof, key_owner_proof: T::KeyOwnerProof, ) -> DispatchResultWithPostInfo { @@ -323,9 +376,11 @@ decl_module! { /// block authors will call it (validated in `ValidateUnsigned`), as such /// if the block author is defined it will be defined as the equivocation /// reporter. - #[weight = ::WeightInfo::report_equivocation(key_owner_proof.validator_count())] - fn report_equivocation_unsigned( - origin, + #[pallet::weight(::WeightInfo::report_equivocation( + key_owner_proof.validator_count(), + ))] + pub fn report_equivocation_unsigned( + origin: OriginFor, equivocation_proof: EquivocationProof, key_owner_proof: T::KeyOwnerProof, ) -> DispatchResultWithPostInfo { @@ -342,13 +397,14 @@ decl_module! { /// the next call to `enact_epoch_change`. The config will be activated one epoch after. /// Multiple calls to this method will replace any existing planned config change that had /// not been enacted yet. - #[weight = ::WeightInfo::plan_config_change()] - fn plan_config_change( - origin, + #[pallet::weight(::WeightInfo::plan_config_change())] + pub fn plan_config_change( + origin: OriginFor, config: NextConfigDescriptor, - ) { + ) -> DispatchResultWithPostInfo { ensure_root(origin)?; - PendingEpochConfigChange::put(config); + PendingEpochConfigChange::::put(config); + Ok(().into()) } } } @@ -356,7 +412,7 @@ decl_module! { /// A BABE public key pub type BabeKey = [u8; PUBLIC_KEY_LENGTH]; -impl FindAuthor for Module { +impl FindAuthor for Pallet { fn find_author<'a, I>(digests: I) -> Option where I: 'a + IntoIterator { @@ -371,15 +427,15 @@ impl FindAuthor for Module { } } -impl IsMember for Module { +impl IsMember for Pallet { fn is_member(authority_id: &AuthorityId) -> bool { - >::authorities() + >::authorities() .iter() .any(|id| &id.0 == authority_id) } } -impl pallet_session::ShouldEndSession for Module { +impl pallet_session::ShouldEndSession for Pallet { fn should_end_session(now: T::BlockNumber) -> bool { // it might be (and it is in current implementation) that session module is calling // should_end_session() from it's own on_initialize() handler @@ -391,7 +447,7 @@ impl pallet_session::ShouldEndSession for Module { } } -impl Module { +impl Pallet { /// Determine the BABE slot duration based on the Timestamp module configuration. pub fn slot_duration() -> T::Moment { // we double the minimum block-period so each author can always propose within @@ -411,7 +467,7 @@ impl Module { // the same randomness and validator set as signalled in the genesis, // so we don't rotate the epoch. now != One::one() && { - let diff = CurrentSlot::get().saturating_sub(Self::current_epoch_start()); + let diff = CurrentSlot::::get().saturating_sub(Self::current_epoch_start()); *diff >= T::EpochDuration::get() } } @@ -435,7 +491,7 @@ impl Module { pub fn next_expected_epoch_change(now: T::BlockNumber) -> Option { let next_slot = Self::current_epoch_start().saturating_add(T::EpochDuration::get()); next_slot - .checked_sub(*CurrentSlot::get()) + .checked_sub(*CurrentSlot::::get()) .map(|slots_remaining| { // This is a best effort guess. Drifts in the slot/block ratio will cause errors here. let blocks_remaining: T::BlockNumber = slots_remaining.saturated_into(); @@ -457,12 +513,12 @@ impl Module { debug_assert!(Self::initialized().is_some()); // Update epoch index - let epoch_index = EpochIndex::get() + let epoch_index = EpochIndex::::get() .checked_add(1) .expect("epoch indices will never reach 2^64 before the death of the universe; qed"); - EpochIndex::put(epoch_index); - Authorities::put(authorities); + EpochIndex::::put(epoch_index); + Authorities::::put(authorities); // Update epoch randomness. let next_epoch_index = epoch_index @@ -472,10 +528,10 @@ impl Module { // Returns randomness for the current epoch and computes the *next* // epoch randomness. let randomness = Self::randomness_change_epoch(next_epoch_index); - Randomness::put(randomness); + Randomness::::put(randomness); // Update the next epoch authorities. - NextAuthorities::put(&next_authorities); + NextAuthorities::::put(&next_authorities); // Update the start blocks of the previous and new current epoch. >::mutate(|(previous_epoch_start_block, current_epoch_start_block)| { @@ -485,7 +541,7 @@ impl Module { // After we update the current epoch, we signal the *next* epoch change // so that nodes can track changes. - let next_randomness = NextRandomness::get(); + let next_randomness = NextRandomness::::get(); let next_epoch = NextEpochDescriptor { authorities: next_authorities, @@ -493,14 +549,14 @@ impl Module { }; Self::deposit_consensus(ConsensusLog::NextEpochData(next_epoch)); - if let Some(next_config) = NextEpochConfig::get() { - EpochConfig::put(next_config); + if let Some(next_config) = NextEpochConfig::::get() { + EpochConfig::::put(next_config); } - if let Some(pending_epoch_config_change) = PendingEpochConfigChange::take() { + if let Some(pending_epoch_config_change) = PendingEpochConfigChange::::take() { let next_epoch_config: BabeEpochConfiguration = pending_epoch_config_change.clone().into(); - NextEpochConfig::put(next_epoch_config); + NextEpochConfig::::put(next_epoch_config); Self::deposit_consensus(ConsensusLog::NextConfigData(pending_epoch_config_change)); } @@ -510,25 +566,25 @@ impl Module { /// give correct results after `do_initialize` of the first block /// in the chain (as its result is based off of `GenesisSlot`). pub fn current_epoch_start() -> Slot { - Self::epoch_start(EpochIndex::get()) + Self::epoch_start(EpochIndex::::get()) } /// Produces information about the current epoch. pub fn current_epoch() -> Epoch { Epoch { - epoch_index: EpochIndex::get(), + epoch_index: EpochIndex::::get(), start_slot: Self::current_epoch_start(), duration: T::EpochDuration::get(), authorities: Self::authorities(), randomness: Self::randomness(), - config: EpochConfig::get().expect("EpochConfig is initialized in genesis; we never `take` or `kill` it; qed"), + config: EpochConfig::::get().expect("EpochConfig is initialized in genesis; we never `take` or `kill` it; qed"), } } /// Produces information about the next epoch (which was already previously /// announced). pub fn next_epoch() -> Epoch { - let next_epoch_index = EpochIndex::get().checked_add(1).expect( + let next_epoch_index = EpochIndex::::get().checked_add(1).expect( "epoch index is u64; it is always only incremented by one; \ if u64 is not enough we should crash for safety; qed.", ); @@ -537,10 +593,10 @@ impl Module { epoch_index: next_epoch_index, start_slot: Self::epoch_start(next_epoch_index), duration: T::EpochDuration::get(), - authorities: NextAuthorities::get(), - randomness: NextRandomness::get(), - config: NextEpochConfig::get().unwrap_or_else(|| { - EpochConfig::get().expect("EpochConfig is initialized in genesis; we never `take` or `kill` it; qed") + authorities: NextAuthorities::::get(), + randomness: NextRandomness::::get(), + config: NextEpochConfig::::get().unwrap_or_else(|| { + EpochConfig::::get().expect("EpochConfig is initialized in genesis; we never `take` or `kill` it; qed") }), } } @@ -555,26 +611,26 @@ impl Module { .checked_mul(T::EpochDuration::get()) .expect(PROOF); - epoch_start.checked_add(*GenesisSlot::get()).expect(PROOF).into() + epoch_start.checked_add(*GenesisSlot::::get()).expect(PROOF).into() } fn deposit_consensus(new: U) { let log: DigestItem = DigestItem::Consensus(BABE_ENGINE_ID, new.encode()); - >::deposit_log(log.into()) + >::deposit_log(log.into()) } fn deposit_randomness(randomness: &schnorrkel::Randomness) { - let segment_idx = ::get(); - let mut segment = ::get(&segment_idx); + let segment_idx = SegmentIndex::::get(); + let mut segment = UnderConstruction::::get(&segment_idx); if segment.len() < UNDER_CONSTRUCTION_SEGMENT_LENGTH { // push onto current segment: not full. segment.push(*randomness); - ::insert(&segment_idx, &segment); + UnderConstruction::::insert(&segment_idx, &segment); } else { // move onto the next segment and update the index. let segment_idx = segment_idx + 1; - ::insert(&segment_idx, &vec![randomness.clone()]); - ::put(&segment_idx); + UnderConstruction::::insert(&segment_idx, &vec![randomness.clone()]); + SegmentIndex::::put(&segment_idx); } } @@ -586,7 +642,7 @@ impl Module { return; } - let maybe_pre_digest: Option = >::digest() + let maybe_pre_digest: Option = >::digest() .logs .iter() .filter_map(|s| s.as_pre_runtime()) @@ -603,9 +659,9 @@ impl Module { // on the first non-zero block (i.e. block #1) // this is where the first epoch (epoch #0) actually starts. // we need to adjust internal storage accordingly. - if *GenesisSlot::get() == 0 { - GenesisSlot::put(digest.slot()); - debug_assert_ne!(*GenesisSlot::get(), 0); + if *GenesisSlot::::get() == 0 { + GenesisSlot::::put(digest.slot()); + debug_assert_ne!(*GenesisSlot::::get(), 0); // deposit a log because this is the first block in epoch #0 // we use the same values as genesis because we haven't collected any @@ -622,11 +678,11 @@ impl Module { let current_slot = digest.slot(); // how many slots were skipped between current and last block - let lateness = current_slot.saturating_sub(CurrentSlot::get() + 1); + let lateness = current_slot.saturating_sub(CurrentSlot::::get() + 1); let lateness = T::BlockNumber::from(*lateness as u32); Lateness::::put(lateness); - CurrentSlot::put(current_slot); + CurrentSlot::::put(current_slot); let authority_index = digest.authority_index(); @@ -635,7 +691,7 @@ impl Module { .vrf_output() .and_then(|vrf_output| { // Reconstruct the bytes of VRFInOut using the authority id. - Authorities::get() + Authorities::::get() .get(authority_index as usize) .and_then(|author| { schnorrkel::PublicKey::from_bytes(author.0.as_slice()).ok() @@ -644,7 +700,7 @@ impl Module { let transcript = sp_consensus_babe::make_transcript( &Self::randomness(), current_slot, - EpochIndex::get(), + EpochIndex::::get(), ); vrf_output.0.attach_input_hash( @@ -661,11 +717,11 @@ impl Module { // For primary VRF output we place it in the `Initialized` storage // item and it'll be put onto the under-construction randomness later, // once we've decided which epoch this block is in. - Initialized::put(if is_primary { maybe_randomness } else { None }); + Initialized::::put(if is_primary { maybe_randomness } else { None }); // Place either the primary or secondary VRF output into the // `AuthorVrfRandomness` storage item. - AuthorVrfRandomness::put(maybe_randomness); + AuthorVrfRandomness::::put(maybe_randomness); // enact epoch change, if necessary. T::EpochChangeTrigger::trigger::(now) @@ -674,8 +730,8 @@ impl Module { /// Call this function exactly once when an epoch changes, to update the /// randomness. Returns the new randomness. fn randomness_change_epoch(next_epoch_index: u64) -> schnorrkel::Randomness { - let this_randomness = NextRandomness::get(); - let segment_idx: u32 = ::mutate(|s| sp_std::mem::replace(s, 0)); + let this_randomness = NextRandomness::::get(); + let segment_idx: u32 = SegmentIndex::::mutate(|s| sp_std::mem::replace(s, 0)); // overestimate to the segment being full. let rho_size = segment_idx.saturating_add(1) as usize * UNDER_CONSTRUCTION_SEGMENT_LENGTH; @@ -683,18 +739,18 @@ impl Module { let next_randomness = compute_randomness( this_randomness, next_epoch_index, - (0..segment_idx).flat_map(|i| ::take(&i)), + (0..segment_idx).flat_map(|i| UnderConstruction::::take(&i)), Some(rho_size), ); - NextRandomness::put(&next_randomness); + NextRandomness::::put(&next_randomness); this_randomness } fn initialize_authorities(authorities: &[(AuthorityId, BabeAuthorityWeight)]) { if !authorities.is_empty() { - assert!(Authorities::get().is_empty(), "Authorities are already initialized!"); - Authorities::put(authorities); - NextAuthorities::put(authorities); + assert!(Authorities::::get().is_empty(), "Authorities are already initialized!"); + Authorities::::put(authorities); + NextAuthorities::::put(authorities); } } @@ -714,7 +770,7 @@ impl Module { let validator_set_count = key_owner_proof.validator_count(); let session_index = key_owner_proof.session(); - let epoch_index = (*slot.saturating_sub(GenesisSlot::get()) / T::EpochDuration::get()) + let epoch_index = (*slot.saturating_sub(GenesisSlot::::get()) / T::EpochDuration::get()) .saturated_into::(); // check that the slot number is consistent with the session index @@ -763,7 +819,7 @@ impl Module { } } -impl OnTimestampSet for Module { +impl OnTimestampSet for Pallet { fn on_timestamp_set(moment: T::Moment) { let slot_duration = Self::slot_duration(); assert!(!slot_duration.is_zero(), "Babe slot duration cannot be zero."); @@ -771,17 +827,17 @@ impl OnTimestampSet for Module { let timestamp_slot = moment / slot_duration; let timestamp_slot = Slot::from(timestamp_slot.saturated_into::()); - assert!(CurrentSlot::get() == timestamp_slot, "Timestamp slot must match `CurrentSlot`"); + assert!(CurrentSlot::::get() == timestamp_slot, "Timestamp slot must match `CurrentSlot`"); } } -impl frame_support::traits::EstimateNextSessionRotation for Module { +impl frame_support::traits::EstimateNextSessionRotation for Pallet { fn average_session_length() -> T::BlockNumber { T::EpochDuration::get().saturated_into() } fn estimate_current_session_progress(_now: T::BlockNumber) -> (Option, Weight) { - let elapsed = CurrentSlot::get().saturating_sub(Self::current_epoch_start()) + 1; + let elapsed = CurrentSlot::::get().saturating_sub(Self::current_epoch_start()) + 1; ( Some(Percent::from_rational( @@ -802,17 +858,17 @@ impl frame_support::traits::EstimateNextSessionRotation frame_support::traits::Lateness for Module { +impl frame_support::traits::Lateness for Pallet { fn lateness(&self) -> T::BlockNumber { Self::lateness() } } -impl sp_runtime::BoundToRuntimeAppPublic for Module { +impl sp_runtime::BoundToRuntimeAppPublic for Pallet { type Public = AuthorityId; } -impl OneSessionHandler for Module { +impl OneSessionHandler for Pallet { type Key = AuthorityId; fn on_genesis_session<'a, I: 'a>(validators: I) @@ -890,7 +946,7 @@ pub mod migrations { let mut reads = 0; if let Some(pending_change) = OldNextEpochConfig::::get() { - PendingEpochConfigChange::put(pending_change); + PendingEpochConfigChange::::put(pending_change); writes += 1; } @@ -899,8 +955,8 @@ pub mod migrations { OldNextEpochConfig::::kill(); - EpochConfig::put(epoch_config.clone()); - NextEpochConfig::put(epoch_config); + EpochConfig::::put(epoch_config.clone()); + NextEpochConfig::::put(epoch_config); writes += 3; diff --git a/frame/babe/src/mock.rs b/frame/babe/src/mock.rs index 487535121ff1e..4a59321327818 100644 --- a/frame/babe/src/mock.rs +++ b/frame/babe/src/mock.rs @@ -27,7 +27,7 @@ use sp_runtime::{ }; use frame_system::InitKind; use frame_support::{ - parameter_types, StorageValue, + parameter_types, traits::{KeyOwnerProofSystem, OnInitialize}, weights::Weight, }; @@ -451,7 +451,7 @@ pub fn generate_equivocation_proof( use sp_consensus_babe::digests::CompatibleDigestItem; let current_block = System::block_number(); - let current_slot = CurrentSlot::get(); + let current_slot = CurrentSlot::::get(); let make_header = || { let parent_hash = System::parent_hash(); diff --git a/frame/babe/src/randomness.rs b/frame/babe/src/randomness.rs index 71412a962becf..16846c4559860 100644 --- a/frame/babe/src/randomness.rs +++ b/frame/babe/src/randomness.rs @@ -21,7 +21,7 @@ use super::{ AuthorVrfRandomness, Config, EpochStart, NextRandomness, Randomness, VRF_OUTPUT_LENGTH, }; -use frame_support::{traits::Randomness as RandomnessT, StorageValue}; +use frame_support::{traits::Randomness as RandomnessT}; use sp_runtime::traits::Hash; /// Randomness usable by consensus protocols that **depend** upon finality and take action @@ -117,7 +117,7 @@ impl RandomnessT for RandomnessFromTwoEpochs fn random(subject: &[u8]) -> (T::Hash, T::BlockNumber) { let mut subject = subject.to_vec(); subject.reserve(VRF_OUTPUT_LENGTH); - subject.extend_from_slice(&Randomness::get()[..]); + subject.extend_from_slice(&Randomness::::get()[..]); (T::Hashing::hash(&subject[..]), EpochStart::::get().0) } @@ -127,7 +127,7 @@ impl RandomnessT for RandomnessFromOneEpochA fn random(subject: &[u8]) -> (T::Hash, T::BlockNumber) { let mut subject = subject.to_vec(); subject.reserve(VRF_OUTPUT_LENGTH); - subject.extend_from_slice(&NextRandomness::get()[..]); + subject.extend_from_slice(&NextRandomness::::get()[..]); (T::Hashing::hash(&subject[..]), EpochStart::::get().1) } @@ -135,7 +135,7 @@ impl RandomnessT for RandomnessFromOneEpochA impl RandomnessT, T::BlockNumber> for CurrentBlockRandomness { fn random(subject: &[u8]) -> (Option, T::BlockNumber) { - let random = AuthorVrfRandomness::get().map(|random| { + let random = AuthorVrfRandomness::::get().map(|random| { let mut subject = subject.to_vec(); subject.reserve(VRF_OUTPUT_LENGTH); subject.extend_from_slice(&random); diff --git a/frame/babe/src/tests.rs b/frame/babe/src/tests.rs index 0ccc3db4df0b0..e9966ddb75dd0 100644 --- a/frame/babe/src/tests.rs +++ b/frame/babe/src/tests.rs @@ -19,7 +19,7 @@ use super::{Call, *}; use frame_support::{ - assert_err, assert_ok, + assert_err, assert_ok, assert_noop, traits::{Currency, EstimateNextSessionRotation, OnFinalize}, weights::{GetDispatchInfo, Pays}, }; @@ -92,11 +92,11 @@ fn first_block_epoch_zero_start() { Babe::on_finalize(1); let header = System::finalize(); - assert_eq!(SegmentIndex::get(), 0); - assert_eq!(UnderConstruction::get(0), vec![vrf_randomness]); + assert_eq!(SegmentIndex::::get(), 0); + assert_eq!(UnderConstruction::::get(0), vec![vrf_randomness]); assert_eq!(Babe::randomness(), [0; 32]); assert_eq!(Babe::author_vrf_randomness(), None); - assert_eq!(NextRandomness::get(), [0; 32]); + assert_eq!(NextRandomness::::get(), [0; 32]); assert_eq!(header.digest.logs.len(), 2); assert_eq!(pre_digest.logs.len(), 1); @@ -278,10 +278,10 @@ fn can_enact_next_config() { allowed_slots: sp_consensus_babe::AllowedSlots::PrimarySlots, }; - EpochConfig::put(current_config); - NextEpochConfig::put(next_config.clone()); + EpochConfig::::put(current_config); + NextEpochConfig::::put(next_config.clone()); - assert_eq!(NextEpochConfig::get(), Some(next_config.clone())); + assert_eq!(NextEpochConfig::::get(), Some(next_config.clone())); Babe::plan_config_change( Origin::root(), @@ -295,8 +295,8 @@ fn can_enact_next_config() { Babe::on_finalize(9); let header = System::finalize(); - assert_eq!(EpochConfig::get(), Some(next_config)); - assert_eq!(NextEpochConfig::get(), Some(next_next_config.clone())); + assert_eq!(EpochConfig::::get(), Some(next_config)); + assert_eq!(NextEpochConfig::::get(), Some(next_next_config.clone())); let consensus_log = sp_consensus_babe::ConsensusLog::NextConfigData( NextConfigDescriptor::V1 { @@ -325,14 +325,14 @@ fn only_root_can_enact_config_change() { next_config.clone(), ); - assert_eq!(res, Err(DispatchError::BadOrigin)); + assert_noop!(res, DispatchError::BadOrigin); let res = Babe::plan_config_change( Origin::signed(1), next_config.clone(), ); - assert_eq!(res, Err(DispatchError::BadOrigin)); + assert_noop!(res, DispatchError::BadOrigin); let res = Babe::plan_config_change( Origin::root(), @@ -346,7 +346,7 @@ fn only_root_can_enact_config_change() { #[test] fn can_fetch_current_and_next_epoch_data() { new_test_ext(5).execute_with(|| { - EpochConfig::put(BabeEpochConfiguration { + EpochConfig::::put(BabeEpochConfiguration { c: (1, 4), allowed_slots: sp_consensus_babe::AllowedSlots::PrimarySlots, }); @@ -444,7 +444,7 @@ fn report_equivocation_current_session_works() { let equivocation_proof = generate_equivocation_proof( offending_validator_index as u32, &offending_authority_pair, - CurrentSlot::get(), + CurrentSlot::::get(), ); // create the key ownership proof @@ -518,7 +518,7 @@ fn report_equivocation_old_session_works() { let equivocation_proof = generate_equivocation_proof( offending_validator_index as u32, &offending_authority_pair, - CurrentSlot::get(), + CurrentSlot::::get(), ); // create the key ownership proof @@ -584,7 +584,7 @@ fn report_equivocation_invalid_key_owner_proof() { let equivocation_proof = generate_equivocation_proof( offending_validator_index as u32, &offending_authority_pair, - CurrentSlot::get(), + CurrentSlot::::get(), ); // create the key ownership proof @@ -664,7 +664,7 @@ fn report_equivocation_invalid_equivocation_proof() { let mut equivocation_proof = generate_equivocation_proof( offending_validator_index as u32, &offending_authority_pair, - CurrentSlot::get(), + CurrentSlot::::get(), ); equivocation_proof.second_header = equivocation_proof.first_header.clone(); assert_invalid_equivocation(equivocation_proof); @@ -673,7 +673,7 @@ fn report_equivocation_invalid_equivocation_proof() { let mut equivocation_proof = generate_equivocation_proof( offending_validator_index as u32, &offending_authority_pair, - CurrentSlot::get(), + CurrentSlot::::get(), ); equivocation_proof.first_header.digest_mut().logs.remove(0); assert_invalid_equivocation(equivocation_proof); @@ -682,7 +682,7 @@ fn report_equivocation_invalid_equivocation_proof() { let mut equivocation_proof = generate_equivocation_proof( offending_validator_index as u32, &offending_authority_pair, - CurrentSlot::get(), + CurrentSlot::::get(), ); equivocation_proof.first_header.digest_mut().logs.remove(1); assert_invalid_equivocation(equivocation_proof); @@ -691,7 +691,7 @@ fn report_equivocation_invalid_equivocation_proof() { let mut equivocation_proof = generate_equivocation_proof( offending_validator_index as u32, &offending_authority_pair, - CurrentSlot::get(), + CurrentSlot::::get(), ); equivocation_proof.slot = Slot::from(0); assert_invalid_equivocation(equivocation_proof.clone()); @@ -701,7 +701,7 @@ fn report_equivocation_invalid_equivocation_proof() { let mut equivocation_proof = generate_equivocation_proof( offending_validator_index as u32, &offending_authority_pair, - CurrentSlot::get() + 1, + CurrentSlot::::get() + 1, ); // use the header from the previous equivocation generated @@ -714,7 +714,7 @@ fn report_equivocation_invalid_equivocation_proof() { let mut equivocation_proof = generate_equivocation_proof( offending_validator_index as u32, &offending_authority_pair, - CurrentSlot::get() + 1, + CurrentSlot::::get() + 1, ); // replace the seal digest with the digest from the @@ -753,7 +753,7 @@ fn report_equivocation_validate_unsigned_prevents_duplicates() { let equivocation_proof = generate_equivocation_proof( offending_validator_index as u32, &offending_authority_pair, - CurrentSlot::get(), + CurrentSlot::::get(), ); let key = ( @@ -775,7 +775,7 @@ fn report_equivocation_validate_unsigned_prevents_duplicates() { ); // the transaction is valid when passed as local - let tx_tag = (offending_authority_pair.public(), CurrentSlot::get()); + let tx_tag = (offending_authority_pair.public(), CurrentSlot::::get()); assert_eq!( ::validate_unsigned( TransactionSource::Local, @@ -848,7 +848,7 @@ fn valid_equivocation_reports_dont_pay_fees() { // generate an equivocation proof. let equivocation_proof = - generate_equivocation_proof(0, &offending_authority_pair, CurrentSlot::get()); + generate_equivocation_proof(0, &offending_authority_pair, CurrentSlot::::get()); // create the key ownership proof. let key_owner_proof = Historical::prove(( @@ -941,7 +941,7 @@ fn add_epoch_configurations_migration_works() { &[], ).is_none()); - assert_eq!(EpochConfig::get(), Some(current_epoch)); - assert_eq!(PendingEpochConfigChange::get(), Some(next_config_descriptor)); + assert_eq!(EpochConfig::::get(), Some(current_epoch)); + assert_eq!(PendingEpochConfigChange::::get(), Some(next_config_descriptor)); }); }