diff --git a/substrate/bin/node-template/runtime/src/lib.rs b/substrate/bin/node-template/runtime/src/lib.rs index 63d79e6047..eae40e1ab3 100644 --- a/substrate/bin/node-template/runtime/src/lib.rs +++ b/substrate/bin/node-template/runtime/src/lib.rs @@ -195,9 +195,14 @@ impl frame_system::Config for Runtime { impl pallet_randomness_collective_flip::Config for Runtime {} +parameter_types! { + pub const MaxAuthorities: u32 = 32; +} + impl pallet_aura::Config for Runtime { type AuthorityId = AuraId; type DisabledValidators = (); + type MaxAuthorities = MaxAuthorities; } impl pallet_grandpa::Config for Runtime { @@ -382,7 +387,7 @@ impl_runtime_apis! { } fn authorities() -> Vec { - Aura::authorities() + Aura::authorities().into_inner() } } diff --git a/substrate/frame/aura/Cargo.toml b/substrate/frame/aura/Cargo.toml index f6aa4fac2f..ee7b15f91e 100644 --- a/substrate/frame/aura/Cargo.toml +++ b/substrate/frame/aura/Cargo.toml @@ -14,9 +14,7 @@ targets = ["x86_64-unknown-linux-gnu"] [dependencies] sp-application-crypto = { version = "4.0.0-dev", default-features = false, path = "../../primitives/application-crypto" } -codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = [ - "derive", -] } +codec = { package = "parity-scale-codec", version = "2.2.0", default-features = false, features = ["derive", "max-encoded-len"] } sp-std = { version = "4.0.0-dev", default-features = false, path = "../../primitives/std" } sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../primitives/runtime" } frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" } diff --git a/substrate/frame/aura/src/lib.rs b/substrate/frame/aura/src/lib.rs index 1138a3e850..e8b68f928e 100644 --- a/substrate/frame/aura/src/lib.rs +++ b/substrate/frame/aura/src/lib.rs @@ -38,10 +38,10 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Decode, Encode}; +use codec::{Decode, Encode, MaxEncodedLen}; use frame_support::{ traits::{DisabledValidators, FindAuthor, Get, OnTimestampSet, OneSessionHandler}, - ConsensusEngineId, Parameter, + BoundedSlice, ConsensusEngineId, Parameter, WeakBoundedVec, }; use sp_consensus_aura::{AuthorityIndex, ConsensusLog, Slot, AURA_ENGINE_ID}; use sp_runtime::{ @@ -49,7 +49,7 @@ use sp_runtime::{ traits::{IsMember, Member, SaturatedConversion, Saturating, Zero}, RuntimeAppPublic, }; -use sp_std::prelude::*; +use sp_std::{convert::TryFrom, vec::Vec}; pub mod migrations; mod mock; @@ -70,7 +70,10 @@ pub mod pallet { + Parameter + RuntimeAppPublic + Default - + MaybeSerializeDeserialize; + + MaybeSerializeDeserialize + + MaxEncodedLen; + /// The maximum number of authorities that the pallet can hold. + type MaxAuthorities: Get; /// A way to check whether a given validator is disabled and should not be authoring blocks. /// Blocks authored by a disabled validator will lead to a panic as part of this module's @@ -79,6 +82,7 @@ pub mod pallet { } #[pallet::pallet] + #[pallet::generate_storage_info] pub struct Pallet(sp_std::marker::PhantomData); #[pallet::hooks] @@ -113,7 +117,8 @@ pub mod pallet { /// The current authority set. #[pallet::storage] #[pallet::getter(fn authorities)] - pub(super) type Authorities = StorageValue<_, Vec, ValueQuery>; + pub(super) type Authorities = + StorageValue<_, WeakBoundedVec, ValueQuery>; /// The current slot of this block. /// @@ -143,18 +148,22 @@ pub mod pallet { } impl Pallet { - fn change_authorities(new: Vec) { + fn change_authorities(new: WeakBoundedVec) { >::put(&new); - let log: DigestItem = - DigestItem::Consensus(AURA_ENGINE_ID, ConsensusLog::AuthoritiesChange(new).encode()); + let log: DigestItem = DigestItem::Consensus( + AURA_ENGINE_ID, + ConsensusLog::AuthoritiesChange(new.into_inner()).encode(), + ); >::deposit_log(log.into()); } fn initialize_authorities(authorities: &[T::AuthorityId]) { if !authorities.is_empty() { assert!(>::get().is_empty(), "Authorities are already initialized!"); - >::put(authorities); + let bounded = >::try_from(authorities) + .expect("Initial authority set must be less than T::MaxAuthorities"); + >::put(bounded); } } @@ -202,8 +211,12 @@ impl OneSessionHandler for Pallet { if changed { let next_authorities = validators.map(|(_, k)| k).collect::>(); let last_authorities = Self::authorities(); - if next_authorities != last_authorities { - Self::change_authorities(next_authorities); + if last_authorities != next_authorities { + let bounded = >::force_from( + next_authorities, + Some("AuRa new session"), + ); + Self::change_authorities(bounded); } } } diff --git a/substrate/frame/aura/src/mock.rs b/substrate/frame/aura/src/mock.rs index 0e258fb9a6..4418d9e85a 100644 --- a/substrate/frame/aura/src/mock.rs +++ b/substrate/frame/aura/src/mock.rs @@ -87,6 +87,10 @@ impl pallet_timestamp::Config for Test { type WeightInfo = (); } +parameter_types! { + pub const MaxAuthorities: u32 = 10; +} + thread_local! { static DISABLED_VALIDATORS: RefCell> = RefCell::new(Default::default()); } @@ -113,6 +117,7 @@ impl DisabledValidators for MockDisabledValidators { impl pallet_aura::Config for Test { type AuthorityId = AuthorityId; type DisabledValidators = MockDisabledValidators; + type MaxAuthorities = MaxAuthorities; } pub fn new_test_ext(authorities: Vec) -> sp_io::TestExternalities { diff --git a/substrate/frame/support/src/storage/bounded_vec.rs b/substrate/frame/support/src/storage/bounded_vec.rs index 6d25e058c0..0f56511e6e 100644 --- a/substrate/frame/support/src/storage/bounded_vec.rs +++ b/substrate/frame/support/src/storage/bounded_vec.rs @@ -21,6 +21,7 @@ use crate::{ storage::{StorageDecodeLength, StorageTryAppend}, traits::Get, + WeakBoundedVec, }; use codec::{Decode, Encode, EncodeLike, MaxEncodedLen}; use core::{ @@ -45,8 +46,13 @@ pub struct BoundedVec(Vec, PhantomData); #[derive(Encode)] pub struct BoundedSlice<'a, T, S>(&'a [T], PhantomData); -// `BoundedSlice`s encode to something which will always decode into a `BoundedVec` or a `Vec`. +// `BoundedSlice`s encode to something which will always decode into a `BoundedVec`, +// `WeakBoundedVec`, or a `Vec`. impl<'a, T: Encode + Decode, S: Get> EncodeLike> for BoundedSlice<'a, T, S> {} +impl<'a, T: Encode + Decode, S: Get> EncodeLike> + for BoundedSlice<'a, T, S> +{ +} impl<'a, T: Encode + Decode, S: Get> EncodeLike> for BoundedSlice<'a, T, S> {} impl<'a, T, S: Get> TryFrom<&'a [T]> for BoundedSlice<'a, T, S> { diff --git a/substrate/primitives/consensus/slots/Cargo.toml b/substrate/primitives/consensus/slots/Cargo.toml index 9619f627a0..2718158cfb 100644 --- a/substrate/primitives/consensus/slots/Cargo.toml +++ b/substrate/primitives/consensus/slots/Cargo.toml @@ -13,7 +13,7 @@ readme = "README.md" targets = ["x86_64-unknown-linux-gnu"] [dependencies] -codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] } +codec = { package = "parity-scale-codec", version = "2.2.0", default-features = false, features = ["derive", "max-encoded-len"] } sp-runtime = { version = "4.0.0-dev", default-features = false, path = "../../runtime" } sp-arithmetic = { version = "4.0.0-dev", default-features = false, path = "../../arithmetic" }