Generate storage info for pallet authority_discovery (#9428)

* 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>
This commit is contained in:
Georges
2021-08-30 07:11:59 +01:00
committed by GitHub
parent 03c7b11244
commit ac2468c47b
4 changed files with 63 additions and 21 deletions
+4 -1
View File
@@ -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
@@ -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;
+56 -18
View File
@@ -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]
@@ -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 {
@@ -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);
}
}
}
@@ -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);
}
}
@@ -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 {
@@ -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);
}
@@ -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 {