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

Generate storage info for pallet authority_discovery #9428

Merged
20 commits merged into from
Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
georgesdib marked this conversation as resolved.
Show resolved Hide resolved
}

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
88 changes: 70 additions & 18 deletions frame/authority-discovery/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@
// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]

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

use core::convert::TryFrom;

pub use pallet::*;

#[frame_support::pallet]
Expand All @@ -36,21 +42,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<_, BoundedVec<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<_, BoundedVec<AuthorityId, T::MaxAuthorities>, ValueQuery>;

#[pallet::genesis_config]
pub struct GenesisConfig {
Expand All @@ -75,31 +87,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() -> BoundedVec<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() -> BoundedVec<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 =
BoundedVec::<AuthorityId, T::MaxAuthorities>::try_from((*keys).clone())
.expect("Keys vec too big");
KiChjang marked this conversation as resolved.
Show resolved Hide resolved

Keys::<T>::put(bounded_keys.clone());
gui1117 marked this conversation as resolved.
Show resolved Hide resolved
NextKeys::<T>::put(bounded_keys);
}
}
}
Expand All @@ -124,10 +141,42 @@ 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 mut keys = validators.map(|x| x.1).collect::<Vec<_>>();

if keys.len() >= T::MaxAuthorities::get() as usize {
// Truncate to MaxAuthorities, to not fail the conversion
keys.truncate(T::MaxAuthorities::get() as usize);
gui1117 marked this conversation as resolved.
Show resolved Hide resolved

log::warn!(
"Provided validators vec size {} is too large (max size {})",
keys.len(),
T::MaxAuthorities::get()
);
}

let bounded_keys = BoundedVec::<AuthorityId, T::MaxAuthorities>::try_from(keys)
.expect("We truncated so this should never fail");

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

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

if next_keys.len() >= T::MaxAuthorities::get() as usize {
// Truncate to MaxAuthorities, to not fail the conversion
next_keys.truncate(T::MaxAuthorities::get() as usize);

log::warn!(
"Provided queued_validators vec size {} is too large (max size {})",
next_keys.len(),
T::MaxAuthorities::get()
);
}

let next_bounded_keys =
BoundedVec::<AuthorityId, T::MaxAuthorities>::try_from(next_keys)
.expect("We truncated so this should never fail");

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

Expand Down Expand Up @@ -166,10 +215,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