Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Generate storage info for pallet authority_discovery (#9428)
Browse files Browse the repository at this point in the history
* Migrate Aura pallet to BoundedVec

Implementing issue #8629

* Fixed aura tests after BoundedVec change

* Moved Vec to BoundedVec in authority-discovery

* Merging into the main branch

* Added MaxEncodedLen to crypto

Need this without full_crypto to be able to add generate_store_info

* Add generate_store_info for aura

* Adding changes to Slot to add MaxEncodedLen

* Adding generate_store_info to authority discovery

* fmt

* removing panics in runtime if vec size too large

* authority-discovery: Remove panics in runtime
Can happen if vec size is too large, so truncate the vec in that case

* Adding logging when I truncate Vecs

* Got the sign the other way around

* Reverting pallet_aura changes
This is already being addressed by PR #9371

* Change BoundedVec to WeakBoundedVec

More robust implementation following @thiolliere recommendation.

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
  • Loading branch information
Georges and shawntabrizi authored Aug 30, 2021
1 parent ecf32b9 commit d6847a7
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 21 deletions.
5 changes: 4 additions & 1 deletion bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,7 @@ parameter_types! {
pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
/// We prioritize im-online heartbeats over election solution submission.
pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
pub const MaxAuthorities: u32 = 100;
}

impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
Expand Down Expand Up @@ -955,7 +956,9 @@ impl pallet_offences::Config for Runtime {
type OnOffenceHandler = Staking;
}

impl pallet_authority_discovery::Config for Runtime {}
impl pallet_authority_discovery::Config for Runtime {
type MaxAuthorities = MaxAuthorities;
}

impl pallet_grandpa::Config for Runtime {
type Event = Event;
Expand Down
74 changes: 56 additions & 18 deletions frame/authority-discovery/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,15 @@
// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

use frame_support::traits::OneSessionHandler;
use frame_support::{
traits::{Get, OneSessionHandler},
WeakBoundedVec,
};
use sp_authority_discovery::AuthorityId;
use sp_std::prelude::*;

use core::convert::TryFrom;

pub use pallet::*;

#[frame_support::pallet]
Expand All @@ -36,21 +41,27 @@ pub mod pallet {

#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::generate_storage_info]
pub struct Pallet<T>(_);

#[pallet::config]
/// The pallet's config trait.
pub trait Config: frame_system::Config + pallet_session::Config {}
pub trait Config: frame_system::Config + pallet_session::Config {
/// The maximum number of authorities that can be added.
type MaxAuthorities: Get<u32>;
}

#[pallet::storage]
#[pallet::getter(fn keys)]
/// Keys of the current authority set.
pub(super) type Keys<T: Config> = StorageValue<_, Vec<AuthorityId>, ValueQuery>;
pub(super) type Keys<T: Config> =
StorageValue<_, WeakBoundedVec<AuthorityId, T::MaxAuthorities>, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn next_keys)]
/// Keys of the next authority set.
pub(super) type NextKeys<T: Config> = StorageValue<_, Vec<AuthorityId>, ValueQuery>;
pub(super) type NextKeys<T: Config> =
StorageValue<_, WeakBoundedVec<AuthorityId, T::MaxAuthorities>, ValueQuery>;

#[pallet::genesis_config]
pub struct GenesisConfig {
Expand All @@ -75,31 +86,36 @@ impl<T: Config> Pallet<T> {
/// Retrieve authority identifiers of the current and next authority set
/// sorted and deduplicated.
pub fn authorities() -> Vec<AuthorityId> {
let mut keys = Keys::<T>::get();
let next = NextKeys::<T>::get();
let mut keys = Keys::<T>::get().to_vec();
let next = NextKeys::<T>::get().to_vec();

keys.extend(next);
keys.sort();
keys.dedup();

keys
keys.to_vec()
}

/// Retrieve authority identifiers of the current authority set in the original order.
pub fn current_authorities() -> Vec<AuthorityId> {
pub fn current_authorities() -> WeakBoundedVec<AuthorityId, T::MaxAuthorities> {
Keys::<T>::get()
}

/// Retrieve authority identifiers of the next authority set in the original order.
pub fn next_authorities() -> Vec<AuthorityId> {
pub fn next_authorities() -> WeakBoundedVec<AuthorityId, T::MaxAuthorities> {
NextKeys::<T>::get()
}

fn initialize_keys(keys: &[AuthorityId]) {
fn initialize_keys(keys: &Vec<AuthorityId>) {
if !keys.is_empty() {
assert!(Keys::<T>::get().is_empty(), "Keys are already initialized!");
Keys::<T>::put(keys);
NextKeys::<T>::put(keys);

let bounded_keys =
WeakBoundedVec::<AuthorityId, T::MaxAuthorities>::try_from((*keys).clone())
.expect("Keys vec too big");

Keys::<T>::put(&bounded_keys);
NextKeys::<T>::put(&bounded_keys);
}
}
}
Expand All @@ -124,10 +140,29 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
{
// Remember who the authorities are for the new and next session.
if changed {
let keys = validators.map(|x| x.1);
Keys::<T>::put(keys.collect::<Vec<_>>());
let next_keys = queued_validators.map(|x| x.1);
NextKeys::<T>::put(next_keys.collect::<Vec<_>>());
let keys = validators.map(|x| x.1).collect::<Vec<_>>();

let bounded_keys = WeakBoundedVec::<_, T::MaxAuthorities>::force_from(
keys,
Some(
"Warning: The session has more validators than expected. \
A runtime configuration adjustment may be needed.",
),
);

Keys::<T>::put(bounded_keys);

let next_keys = queued_validators.map(|x| x.1).collect::<Vec<_>>();

let next_bounded_keys = WeakBoundedVec::<_, T::MaxAuthorities>::force_from(
next_keys,
Some(
"Warning: The session has more queued validators than expected. \
A runtime configuration adjustment may be needed.",
),
);

NextKeys::<T>::put(next_bounded_keys);
}
}

Expand Down Expand Up @@ -166,10 +201,13 @@ mod tests {
}
);

impl Config for Test {}

parameter_types! {
pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(33);
pub const MaxAuthorities: u32 = 100;
}

impl Config for Test {
type MaxAuthorities = MaxAuthorities;
}

impl pallet_session::Config for Test {
Expand Down
1 change: 1 addition & 0 deletions primitives/application-crypto/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ macro_rules! app_crypto_public_not_full_crypto {
$crate::codec::Encode,
$crate::codec::Decode,
$crate::RuntimeDebug,
$crate::codec::MaxEncodedLen,
)]
pub struct Public($public);
}
Expand Down
4 changes: 2 additions & 2 deletions primitives/consensus/slots/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@

#![cfg_attr(not(feature = "std"), no_std)]

use codec::{Decode, Encode};
use codec::{Decode, Encode, MaxEncodedLen};

/// Unit type wrapper that represents a slot.
#[derive(Debug, Encode, Decode, Eq, Clone, Copy, Default, Ord)]
#[derive(Debug, Encode, MaxEncodedLen, Decode, Eq, Clone, Copy, Default, Ord)]
pub struct Slot(u64);

impl core::ops::Deref for Slot {
Expand Down

0 comments on commit d6847a7

Please sign in to comment.