Skip to content
Snippets Groups Projects
Commit 92630df1 authored by ferrell-code's avatar ferrell-code Committed by GitHub
Browse files

Authority Discovery to FRAME v2 (#8620)


* migrate to new macro

* formatting

* Apply suggestions from code review

* Update frame/authority-discovery/src/lib.rs

Co-authored-by: default avatarGuillaume Thiolliere <gui.thiolliere@gmail.com>
parent bb343c7c
Branches
No related merge requests found
......@@ -15,45 +15,87 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//! # Authority discovery module.
//! # Authority discovery pallet.
//!
//! This module is used by the `client/authority-discovery` and by polkadot's parachain logic
//! This pallet is used by the `client/authority-discovery` and by polkadot's parachain logic
//! to retrieve the current and the next set of authorities.
// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]
use sp_std::prelude::*;
use frame_support::{decl_module, decl_storage, traits::OneSessionHandler};
use frame_support::traits::OneSessionHandler;
#[cfg(feature = "std")]
use frame_support::traits::GenesisBuild;
use sp_authority_discovery::AuthorityId;
/// The module's config trait.
pub trait Config: frame_system::Config + pallet_session::Config {}
pub use pallet::*;
decl_storage! {
trait Store for Module<T: Config> as AuthorityDiscovery {
/// Keys of the current authority set.
Keys get(fn keys): Vec<AuthorityId>;
/// Keys of the next authority set.
NextKeys get(fn next_keys): Vec<AuthorityId>;
}
add_extra_genesis {
config(keys): Vec<AuthorityId>;
build(|config| Module::<T>::initialize_keys(&config.keys))
#[frame_support::pallet]
pub mod pallet {
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use super::*;
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
#[pallet::config]
/// The pallet's config trait.
pub trait Config: frame_system::Config + pallet_session::Config {}
#[pallet::storage]
#[pallet::getter(fn keys)]
/// Keys of the current authority set.
pub(super) type Keys<T: Config> = StorageValue<
_,
Vec<AuthorityId>,
ValueQuery,
>;
#[pallet::storage]
#[pallet::getter(fn next_keys)]
/// Keys of the next authority set.
pub(super) type NextKeys<T: Config> = StorageValue<
_,
Vec<AuthorityId>,
ValueQuery,
>;
#[pallet::genesis_config]
pub struct GenesisConfig {
pub keys: Vec<AuthorityId>,
}
}
decl_module! {
pub struct Module<T: Config> for enum Call where origin: T::Origin {
#[cfg(feature = "std")]
impl Default for GenesisConfig {
fn default() -> Self {
Self {
keys: Default::default(),
}
}
}
#[pallet::genesis_build]
impl<T: Config> GenesisBuild<T> for GenesisConfig {
fn build(&self) {
Pallet::<T>::initialize_keys(&self.keys)
}
}
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
#[pallet::call]
impl<T: Config> Pallet<T> {}
}
impl<T: Config> Module<T> {
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::get();
let next = NextKeys::get();
let mut keys = Keys::<T>::get();
let next = NextKeys::<T>::get();
keys.extend(next);
keys.sort();
......@@ -64,28 +106,28 @@ impl<T: Config> Module<T> {
/// Retrieve authority identifiers of the current authority set in the original order.
pub fn current_authorities() -> Vec<AuthorityId> {
Keys::get()
Keys::<T>::get()
}
/// Retrieve authority identifiers of the next authority set in the original order.
pub fn next_authorities() -> Vec<AuthorityId> {
NextKeys::get()
NextKeys::<T>::get()
}
fn initialize_keys(keys: &[AuthorityId]) {
if !keys.is_empty() {
assert!(Keys::get().is_empty(), "Keys are already initialized!");
Keys::put(keys);
NextKeys::put(keys);
assert!(Keys::<T>::get().is_empty(), "Keys are already initialized!");
Keys::<T>::put(keys);
NextKeys::<T>::put(keys);
}
}
}
impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Module<T> {
impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Pallet<T> {
type Public = AuthorityId;
}
impl<T: Config> OneSessionHandler<T::AccountId> for Module<T> {
impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
type Key = AuthorityId;
fn on_genesis_session<'a, I: 'a>(authorities: I)
......@@ -102,9 +144,9 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Module<T> {
// Remember who the authorities are for the new and next session.
if changed {
let keys = validators.map(|x| x.1);
Keys::put(keys.collect::<Vec<_>>());
Keys::<T>::put(keys.collect::<Vec<_>>());
let next_keys = queued_validators.map(|x| x.1);
NextKeys::put(next_keys.collect::<Vec<_>>());
NextKeys::<T>::put(next_keys.collect::<Vec<_>>());
}
}
......@@ -113,6 +155,17 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Module<T> {
}
}
#[cfg(feature = "std")]
impl GenesisConfig {
/// Direct implementation of `GenesisBuild::assimilate_storage`.
pub fn assimilate_storage<T: Config>(
&self,
storage: &mut sp_runtime::Storage
) -> Result<(), String> {
<Self as GenesisBuild<T>>::assimilate_storage(self, storage)
}
}
#[cfg(test)]
mod tests {
use crate as pallet_authority_discovery;
......@@ -221,7 +274,7 @@ mod tests {
#[test]
fn authorities_returns_current_and_next_authority_set() {
// The whole authority discovery module ignores account ids, but we still need them for
// The whole authority discovery pallet ignores account ids, but we still need them for
// `pallet_session::OneSessionHandler::on_new_session`, thus its safe to use the same value
// everywhere.
let account_id = AuthorityPair::from_seed_slice(vec![10; 32].as_ref()).unwrap().public();
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment