mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-21 02:45:43 +00:00
Decouple the session validators from im-online (#7127)
* Decouple the session validators from im-online * . * Add SessionInterface trait in im-online Add ValidatorId in im-online Trait Make im-online compile Make substrate binary compile * Fix merging issue * Make all compile * Fix tests * Avoid using frame dep in primitives via pallet-session-common * Merge ValidatorSet into SessionInterface trait Wrap a few too long lines Add some docs * Move pallet-sesion-common into pallet-session * Move SessionInterface to sp-session and impl it in session pallet Ref https://github.com/paritytech/substrate/pull/7127#discussion_r494892472 * Split put historical::FullValidatorIdentification trait * Fix line width * Fix staking mock * Fix session doc test * Simplify <T as ValidatorIdentification<AccountId>>::ValidatorId as ValidatorId<T> * Nits * Clean up. * Make it compile by commenting out report_offence_im_online bench * Tests * Nits * Move OneSessionHandler to sp-session * Fix tests * Add some docs * . * Fix typo * Rename to ValidatorSet::session_index() * Add some more docs * . * Remove extra empty line * Fix line width check . * Apply suggestions from code review * Cleaup Cargo.toml * Aura has migrated to Pallet now Co-authored-by: Tomasz Drwięga <tomasz@parity.io>
This commit is contained in:
Generated
+1
@@ -1628,6 +1628,7 @@ dependencies = [
|
|||||||
"sp-inherents",
|
"sp-inherents",
|
||||||
"sp-io",
|
"sp-io",
|
||||||
"sp-runtime",
|
"sp-runtime",
|
||||||
|
"sp-staking",
|
||||||
"sp-state-machine",
|
"sp-state-machine",
|
||||||
"sp-std",
|
"sp-std",
|
||||||
"sp-tracing",
|
"sp-tracing",
|
||||||
|
|||||||
@@ -830,6 +830,7 @@ impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime where
|
|||||||
impl pallet_im_online::Config for Runtime {
|
impl pallet_im_online::Config for Runtime {
|
||||||
type AuthorityId = ImOnlineId;
|
type AuthorityId = ImOnlineId;
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
|
type ValidatorSet = Historical;
|
||||||
type SessionDuration = SessionDuration;
|
type SessionDuration = SessionDuration;
|
||||||
type ReportUnresponsiveness = Offences;
|
type ReportUnresponsiveness = Offences;
|
||||||
type UnsignedPriority = ImOnlineUnsignedPriority;
|
type UnsignedPriority = ImOnlineUnsignedPriority;
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
use sp_std::{result, prelude::*};
|
use sp_std::{result, prelude::*};
|
||||||
use codec::{Encode, Decode};
|
use codec::{Encode, Decode};
|
||||||
use frame_support::{Parameter, traits::{Get, FindAuthor}, ConsensusEngineId};
|
use frame_support::{Parameter, traits::{Get, FindAuthor, OneSessionHandler}, ConsensusEngineId};
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
RuntimeAppPublic,
|
RuntimeAppPublic,
|
||||||
traits::{SaturatedConversion, Saturating, Zero, Member, IsMember}, generic::DigestItem,
|
traits::{SaturatedConversion, Saturating, Zero, Member, IsMember}, generic::DigestItem,
|
||||||
@@ -144,7 +144,7 @@ impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Pallet<T> {
|
|||||||
type Public = T::AuthorityId;
|
type Public = T::AuthorityId;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> pallet_session::OneSessionHandler<T::AccountId> for Pallet<T> {
|
impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
|
||||||
type Key = T::AuthorityId;
|
type Key = T::AuthorityId;
|
||||||
|
|
||||||
fn on_genesis_session<'a, I: 'a>(validators: I)
|
fn on_genesis_session<'a, I: 'a>(validators: I)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
use frame_support::{decl_module, decl_storage};
|
use frame_support::{decl_module, decl_storage, traits::OneSessionHandler};
|
||||||
use sp_authority_discovery::AuthorityId;
|
use sp_authority_discovery::AuthorityId;
|
||||||
|
|
||||||
/// The module's config trait.
|
/// The module's config trait.
|
||||||
@@ -85,7 +85,7 @@ impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Module<T> {
|
|||||||
type Public = AuthorityId;
|
type Public = AuthorityId;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> pallet_session::OneSessionHandler<T::AccountId> for Module<T> {
|
impl<T: Config> OneSessionHandler<T::AccountId> for Module<T> {
|
||||||
type Key = AuthorityId;
|
type Key = AuthorityId;
|
||||||
|
|
||||||
fn on_genesis_session<'a, I: 'a>(authorities: I)
|
fn on_genesis_session<'a, I: 'a>(authorities: I)
|
||||||
@@ -265,7 +265,7 @@ mod tests {
|
|||||||
let mut externalities = TestExternalities::new(t);
|
let mut externalities = TestExternalities::new(t);
|
||||||
|
|
||||||
externalities.execute_with(|| {
|
externalities.execute_with(|| {
|
||||||
use pallet_session::OneSessionHandler;
|
use frame_support::traits::OneSessionHandler;
|
||||||
|
|
||||||
AuthorityDiscovery::on_genesis_session(
|
AuthorityDiscovery::on_genesis_session(
|
||||||
first_authorities.iter().map(|id| (id, id.clone()))
|
first_authorities.iter().map(|id| (id, id.clone()))
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use codec::{Decode, Encode};
|
|||||||
use frame_support::{
|
use frame_support::{
|
||||||
decl_error, decl_module, decl_storage,
|
decl_error, decl_module, decl_storage,
|
||||||
dispatch::DispatchResultWithPostInfo,
|
dispatch::DispatchResultWithPostInfo,
|
||||||
traits::{FindAuthor, Get, KeyOwnerProofSystem, Randomness as RandomnessT},
|
traits::{FindAuthor, Get, KeyOwnerProofSystem, OneSessionHandler, Randomness as RandomnessT},
|
||||||
weights::{Pays, Weight},
|
weights::{Pays, Weight},
|
||||||
Parameter,
|
Parameter,
|
||||||
};
|
};
|
||||||
@@ -769,7 +769,7 @@ impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Module<T> {
|
|||||||
type Public = AuthorityId;
|
type Public = AuthorityId;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> pallet_session::OneSessionHandler<T::AccountId> for Module<T> {
|
impl<T: Config> OneSessionHandler<T::AccountId> for Module<T> {
|
||||||
type Key = AuthorityId;
|
type Key = AuthorityId;
|
||||||
|
|
||||||
fn on_genesis_session<'a, I: 'a>(validators: I)
|
fn on_genesis_session<'a, I: 'a>(validators: I)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ use fg_primitives::{
|
|||||||
};
|
};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
decl_error, decl_event, decl_module, decl_storage, dispatch::DispatchResultWithPostInfo,
|
decl_error, decl_event, decl_module, decl_storage, dispatch::DispatchResultWithPostInfo,
|
||||||
storage, traits::KeyOwnerProofSystem, weights::{Pays, Weight}, Parameter,
|
storage, traits::{OneSessionHandler, KeyOwnerProofSystem}, weights::{Pays, Weight}, Parameter,
|
||||||
};
|
};
|
||||||
use frame_system::{ensure_none, ensure_root, ensure_signed};
|
use frame_system::{ensure_none, ensure_root, ensure_signed};
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
@@ -587,7 +587,7 @@ impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Module<T> {
|
|||||||
type Public = AuthorityId;
|
type Public = AuthorityId;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> pallet_session::OneSessionHandler<T::AccountId> for Module<T>
|
impl<T: Config> OneSessionHandler<T::AccountId> for Module<T>
|
||||||
where T: pallet_session::Config
|
where T: pallet_session::Config
|
||||||
{
|
{
|
||||||
type Key = AuthorityId;
|
type Key = AuthorityId;
|
||||||
|
|||||||
@@ -25,11 +25,10 @@ use codec::{Decode, Encode};
|
|||||||
use fg_primitives::ScheduledChange;
|
use fg_primitives::ScheduledChange;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_err, assert_ok,
|
assert_err, assert_ok,
|
||||||
traits::{Currency, OnFinalize},
|
traits::{Currency, OnFinalize, OneSessionHandler},
|
||||||
weights::{GetDispatchInfo, Pays},
|
weights::{GetDispatchInfo, Pays},
|
||||||
};
|
};
|
||||||
use frame_system::{EventRecord, Phase};
|
use frame_system::{EventRecord, Phase};
|
||||||
use pallet_session::OneSessionHandler;
|
|
||||||
use sp_core::H256;
|
use sp_core::H256;
|
||||||
use sp_keyring::Ed25519Keyring;
|
use sp_keyring::Ed25519Keyring;
|
||||||
use sp_runtime::testing::Digest;
|
use sp_runtime::testing::Digest;
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ codec = { package = "parity-scale-codec", version = "2.0.0", default-features =
|
|||||||
sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" }
|
sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" }
|
||||||
sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" }
|
sp-std = { version = "2.0.0", default-features = false, path = "../../primitives/std" }
|
||||||
serde = { version = "1.0.101", optional = true }
|
serde = { version = "1.0.101", optional = true }
|
||||||
pallet-session = { version = "2.0.0", default-features = false, path = "../session" }
|
|
||||||
sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" }
|
sp-io = { version = "2.0.0", default-features = false, path = "../../primitives/io" }
|
||||||
sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" }
|
sp-runtime = { version = "2.0.0", default-features = false, path = "../../primitives/runtime" }
|
||||||
sp-staking = { version = "2.0.0", default-features = false, path = "../../primitives/staking" }
|
sp-staking = { version = "2.0.0", default-features = false, path = "../../primitives/staking" }
|
||||||
@@ -28,8 +27,11 @@ frame-system = { version = "2.0.0", default-features = false, path = "../system"
|
|||||||
|
|
||||||
frame-benchmarking = { version = "2.0.0", default-features = false, path = "../benchmarking", optional = true }
|
frame-benchmarking = { version = "2.0.0", default-features = false, path = "../benchmarking", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
pallet-session = { version = "2.0.0", path = "../session" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "pallet-session/historical"]
|
default = ["std"]
|
||||||
std = [
|
std = [
|
||||||
"sp-application-crypto/std",
|
"sp-application-crypto/std",
|
||||||
"pallet-authorship/std",
|
"pallet-authorship/std",
|
||||||
@@ -37,7 +39,6 @@ std = [
|
|||||||
"sp-core/std",
|
"sp-core/std",
|
||||||
"sp-std/std",
|
"sp-std/std",
|
||||||
"serde",
|
"serde",
|
||||||
"pallet-session/std",
|
|
||||||
"sp-io/std",
|
"sp-io/std",
|
||||||
"sp-runtime/std",
|
"sp-runtime/std",
|
||||||
"sp-staking/std",
|
"sp-staking/std",
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ use codec::{Encode, Decode};
|
|||||||
use sp_core::offchain::OpaqueNetworkState;
|
use sp_core::offchain::OpaqueNetworkState;
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
use sp_std::convert::TryInto;
|
use sp_std::convert::TryInto;
|
||||||
use pallet_session::historical::IdentificationTuple;
|
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
offchain::storage::StorageValueRef,
|
offchain::storage::StorageValueRef,
|
||||||
RuntimeDebug,
|
RuntimeDebug,
|
||||||
@@ -95,7 +94,7 @@ use sp_staking::{
|
|||||||
};
|
};
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
decl_module, decl_event, decl_storage, Parameter, debug, decl_error,
|
decl_module, decl_event, decl_storage, Parameter, debug, decl_error,
|
||||||
traits::Get,
|
traits::{Get, ValidatorSet, ValidatorSetWithIdentification, OneSessionHandler},
|
||||||
};
|
};
|
||||||
use frame_system::ensure_none;
|
use frame_system::ensure_none;
|
||||||
use frame_system::offchain::{
|
use frame_system::offchain::{
|
||||||
@@ -227,7 +226,19 @@ pub struct Heartbeat<BlockNumber>
|
|||||||
pub validators_len: u32,
|
pub validators_len: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Config: SendTransactionTypes<Call<Self>> + pallet_session::historical::Config {
|
/// A type for representing the validator id in a session.
|
||||||
|
pub type ValidatorId<T> = <
|
||||||
|
<T as Config>::ValidatorSet as ValidatorSet<<T as frame_system::Config>::AccountId>
|
||||||
|
>::ValidatorId;
|
||||||
|
|
||||||
|
/// A tuple of (ValidatorId, Identification) where `Identification` is the full identification of `ValidatorId`.
|
||||||
|
pub type IdentificationTuple<T> = (
|
||||||
|
ValidatorId<T>,
|
||||||
|
<<T as Config>::ValidatorSet as
|
||||||
|
ValidatorSetWithIdentification<<T as frame_system::Config>::AccountId>>::Identification,
|
||||||
|
);
|
||||||
|
|
||||||
|
pub trait Config: SendTransactionTypes<Call<Self>> + frame_system::Config {
|
||||||
/// The identifier type for an authority.
|
/// The identifier type for an authority.
|
||||||
type AuthorityId: Member + Parameter + RuntimeAppPublic + Default + Ord;
|
type AuthorityId: Member + Parameter + RuntimeAppPublic + Default + Ord;
|
||||||
|
|
||||||
@@ -242,6 +253,9 @@ pub trait Config: SendTransactionTypes<Call<Self>> + pallet_session::historical:
|
|||||||
/// there is a chance the authority will produce a block and they won't be necessary.
|
/// there is a chance the authority will produce a block and they won't be necessary.
|
||||||
type SessionDuration: Get<Self::BlockNumber>;
|
type SessionDuration: Get<Self::BlockNumber>;
|
||||||
|
|
||||||
|
/// A type for retrieving the validators supposed to be online in a session.
|
||||||
|
type ValidatorSet: ValidatorSetWithIdentification<Self::AccountId>;
|
||||||
|
|
||||||
/// A type that gives us the ability to submit unresponsiveness offence reports.
|
/// A type that gives us the ability to submit unresponsiveness offence reports.
|
||||||
type ReportUnresponsiveness:
|
type ReportUnresponsiveness:
|
||||||
ReportOffence<
|
ReportOffence<
|
||||||
@@ -293,10 +307,10 @@ decl_storage! {
|
|||||||
double_map hasher(twox_64_concat) SessionIndex, hasher(twox_64_concat) AuthIndex
|
double_map hasher(twox_64_concat) SessionIndex, hasher(twox_64_concat) AuthIndex
|
||||||
=> Option<Vec<u8>>;
|
=> Option<Vec<u8>>;
|
||||||
|
|
||||||
/// For each session index, we keep a mapping of `T::ValidatorId` to the
|
/// For each session index, we keep a mapping of `ValidatorId<T>` to the
|
||||||
/// number of blocks authored by the given authority.
|
/// number of blocks authored by the given authority.
|
||||||
AuthoredBlocks get(fn authored_blocks):
|
AuthoredBlocks get(fn authored_blocks):
|
||||||
double_map hasher(twox_64_concat) SessionIndex, hasher(twox_64_concat) T::ValidatorId
|
double_map hasher(twox_64_concat) SessionIndex, hasher(twox_64_concat) ValidatorId<T>
|
||||||
=> u32;
|
=> u32;
|
||||||
}
|
}
|
||||||
add_extra_genesis {
|
add_extra_genesis {
|
||||||
@@ -345,7 +359,7 @@ decl_module! {
|
|||||||
) {
|
) {
|
||||||
ensure_none(origin)?;
|
ensure_none(origin)?;
|
||||||
|
|
||||||
let current_session = <pallet_session::Module<T>>::current_index();
|
let current_session = T::ValidatorSet::session_index();
|
||||||
let exists = <ReceivedHeartbeats>::contains_key(
|
let exists = <ReceivedHeartbeats>::contains_key(
|
||||||
¤t_session,
|
¤t_session,
|
||||||
&heartbeat.authority_index
|
&heartbeat.authority_index
|
||||||
@@ -397,12 +411,15 @@ type OffchainResult<T, A> = Result<A, OffchainErr<<T as frame_system::Config>::B
|
|||||||
|
|
||||||
/// Keep track of number of authored blocks per authority, uncles are counted as
|
/// Keep track of number of authored blocks per authority, uncles are counted as
|
||||||
/// well since they're a valid proof of being online.
|
/// well since they're a valid proof of being online.
|
||||||
impl<T: Config + pallet_authorship::Config> pallet_authorship::EventHandler<T::ValidatorId, T::BlockNumber> for Module<T> {
|
impl<
|
||||||
fn note_author(author: T::ValidatorId) {
|
T: Config + pallet_authorship::Config,
|
||||||
|
> pallet_authorship::EventHandler<ValidatorId<T>, T::BlockNumber> for Module<T>
|
||||||
|
{
|
||||||
|
fn note_author(author: ValidatorId<T>) {
|
||||||
Self::note_authorship(author);
|
Self::note_authorship(author);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn note_uncle(author: T::ValidatorId, _age: T::BlockNumber) {
|
fn note_uncle(author: ValidatorId<T>, _age: T::BlockNumber) {
|
||||||
Self::note_authorship(author);
|
Self::note_authorship(author);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -413,7 +430,7 @@ impl<T: Config> Module<T> {
|
|||||||
/// authored at least one block, during the current session. Otherwise
|
/// authored at least one block, during the current session. Otherwise
|
||||||
/// `false`.
|
/// `false`.
|
||||||
pub fn is_online(authority_index: AuthIndex) -> bool {
|
pub fn is_online(authority_index: AuthIndex) -> bool {
|
||||||
let current_validators = <pallet_session::Module<T>>::validators();
|
let current_validators = T::ValidatorSet::validators();
|
||||||
|
|
||||||
if authority_index >= current_validators.len() as u32 {
|
if authority_index >= current_validators.len() as u32 {
|
||||||
return false;
|
return false;
|
||||||
@@ -424,8 +441,8 @@ impl<T: Config> Module<T> {
|
|||||||
Self::is_online_aux(authority_index, authority)
|
Self::is_online_aux(authority_index, authority)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_online_aux(authority_index: AuthIndex, authority: &T::ValidatorId) -> bool {
|
fn is_online_aux(authority_index: AuthIndex, authority: &ValidatorId<T>) -> bool {
|
||||||
let current_session = <pallet_session::Module<T>>::current_index();
|
let current_session = T::ValidatorSet::session_index();
|
||||||
|
|
||||||
<ReceivedHeartbeats>::contains_key(¤t_session, &authority_index) ||
|
<ReceivedHeartbeats>::contains_key(¤t_session, &authority_index) ||
|
||||||
<AuthoredBlocks<T>>::get(
|
<AuthoredBlocks<T>>::get(
|
||||||
@@ -437,13 +454,13 @@ impl<T: Config> Module<T> {
|
|||||||
/// Returns `true` if a heartbeat has been received for the authority at `authority_index` in
|
/// Returns `true` if a heartbeat has been received for the authority at `authority_index` in
|
||||||
/// the authorities series, during the current session. Otherwise `false`.
|
/// the authorities series, during the current session. Otherwise `false`.
|
||||||
pub fn received_heartbeat_in_current_session(authority_index: AuthIndex) -> bool {
|
pub fn received_heartbeat_in_current_session(authority_index: AuthIndex) -> bool {
|
||||||
let current_session = <pallet_session::Module<T>>::current_index();
|
let current_session = T::ValidatorSet::session_index();
|
||||||
<ReceivedHeartbeats>::contains_key(¤t_session, &authority_index)
|
<ReceivedHeartbeats>::contains_key(¤t_session, &authority_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Note that the given authority has authored a block in the current session.
|
/// Note that the given authority has authored a block in the current session.
|
||||||
fn note_authorship(author: T::ValidatorId) {
|
fn note_authorship(author: ValidatorId<T>) {
|
||||||
let current_session = <pallet_session::Module<T>>::current_index();
|
let current_session = T::ValidatorSet::session_index();
|
||||||
|
|
||||||
<AuthoredBlocks<T>>::mutate(
|
<AuthoredBlocks<T>>::mutate(
|
||||||
¤t_session,
|
¤t_session,
|
||||||
@@ -460,8 +477,8 @@ impl<T: Config> Module<T> {
|
|||||||
return Err(OffchainErr::TooEarly(heartbeat_after))
|
return Err(OffchainErr::TooEarly(heartbeat_after))
|
||||||
}
|
}
|
||||||
|
|
||||||
let session_index = <pallet_session::Module<T>>::current_index();
|
let session_index = T::ValidatorSet::session_index();
|
||||||
let validators_len = <pallet_session::Module<T>>::validators().len() as u32;
|
let validators_len = Keys::<T>::decode_len().unwrap_or_default() as u32;
|
||||||
|
|
||||||
Ok(Self::local_authority_keys()
|
Ok(Self::local_authority_keys()
|
||||||
.map(move |(authority_index, key)|
|
.map(move |(authority_index, key)|
|
||||||
@@ -614,7 +631,7 @@ impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Module<T> {
|
|||||||
type Public = T::AuthorityId;
|
type Public = T::AuthorityId;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> pallet_session::OneSessionHandler<T::AccountId> for Module<T> {
|
impl<T: Config> OneSessionHandler<T::AccountId> for Module<T> {
|
||||||
type Key = T::AuthorityId;
|
type Key = T::AuthorityId;
|
||||||
|
|
||||||
fn on_genesis_session<'a, I: 'a>(validators: I)
|
fn on_genesis_session<'a, I: 'a>(validators: I)
|
||||||
@@ -639,22 +656,24 @@ impl<T: Config> pallet_session::OneSessionHandler<T::AccountId> for Module<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn on_before_session_ending() {
|
fn on_before_session_ending() {
|
||||||
let session_index = <pallet_session::Module<T>>::current_index();
|
let session_index = T::ValidatorSet::session_index();
|
||||||
let keys = Keys::<T>::get();
|
let keys = Keys::<T>::get();
|
||||||
let current_validators = <pallet_session::Module<T>>::validators();
|
let current_validators = T::ValidatorSet::validators();
|
||||||
|
|
||||||
let offenders = current_validators.into_iter().enumerate()
|
let offenders = current_validators.into_iter().enumerate()
|
||||||
.filter(|(index, id)|
|
.filter(|(index, id)|
|
||||||
!Self::is_online_aux(*index as u32, id)
|
!Self::is_online_aux(*index as u32, id)
|
||||||
).filter_map(|(_, id)|
|
).filter_map(|(_, id)|
|
||||||
T::FullIdentificationOf::convert(id.clone()).map(|full_id| (id, full_id))
|
<T::ValidatorSet as ValidatorSetWithIdentification<T::AccountId>>::IdentificationOf::convert(
|
||||||
|
id.clone()
|
||||||
|
).map(|full_id| (id, full_id))
|
||||||
).collect::<Vec<IdentificationTuple<T>>>();
|
).collect::<Vec<IdentificationTuple<T>>>();
|
||||||
|
|
||||||
// Remove all received heartbeats and number of authored blocks from the
|
// Remove all received heartbeats and number of authored blocks from the
|
||||||
// current session, they have already been processed and won't be needed
|
// current session, they have already been processed and won't be needed
|
||||||
// anymore.
|
// anymore.
|
||||||
<ReceivedHeartbeats>::remove_prefix(&<pallet_session::Module<T>>::current_index());
|
<ReceivedHeartbeats>::remove_prefix(&T::ValidatorSet::session_index());
|
||||||
<AuthoredBlocks<T>>::remove_prefix(&<pallet_session::Module<T>>::current_index());
|
<AuthoredBlocks<T>>::remove_prefix(&T::ValidatorSet::session_index());
|
||||||
|
|
||||||
if offenders.is_empty() {
|
if offenders.is_empty() {
|
||||||
Self::deposit_event(RawEvent::AllGood);
|
Self::deposit_event(RawEvent::AllGood);
|
||||||
@@ -691,7 +710,7 @@ impl<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if session index from heartbeat is recent
|
// check if session index from heartbeat is recent
|
||||||
let current_session = <pallet_session::Module<T>>::current_index();
|
let current_session = T::ValidatorSet::session_index();
|
||||||
if heartbeat.session_index != current_session {
|
if heartbeat.session_index != current_session {
|
||||||
return InvalidTransaction::Stale.into();
|
return InvalidTransaction::Stale.into();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ impl Config for Runtime {
|
|||||||
type AuthorityId = UintAuthorityId;
|
type AuthorityId = UintAuthorityId;
|
||||||
type Event = ();
|
type Event = ();
|
||||||
type ReportUnresponsiveness = OffenceHandler;
|
type ReportUnresponsiveness = OffenceHandler;
|
||||||
|
type ValidatorSet = Historical;
|
||||||
type SessionDuration = Period;
|
type SessionDuration = Period;
|
||||||
type UnsignedPriority = UnsignedPriority;
|
type UnsignedPriority = UnsignedPriority;
|
||||||
type WeightInfo = ();
|
type WeightInfo = ();
|
||||||
@@ -195,6 +196,7 @@ impl<LocalCall> frame_system::offchain::SendTransactionTypes<LocalCall> for Runt
|
|||||||
pub type ImOnline = Module<Runtime>;
|
pub type ImOnline = Module<Runtime>;
|
||||||
pub type System = frame_system::Module<Runtime>;
|
pub type System = frame_system::Module<Runtime>;
|
||||||
pub type Session = pallet_session::Module<Runtime>;
|
pub type Session = pallet_session::Module<Runtime>;
|
||||||
|
pub type Historical = pallet_session::historical::Module<Runtime>;
|
||||||
|
|
||||||
pub fn advance_session() {
|
pub fn advance_session() {
|
||||||
let now = System::block_number().max(1);
|
let now = System::block_number().max(1);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ use sp_std::vec;
|
|||||||
|
|
||||||
use frame_system::{RawOrigin, Module as System, Config as SystemConfig};
|
use frame_system::{RawOrigin, Module as System, Config as SystemConfig};
|
||||||
use frame_benchmarking::{benchmarks, account};
|
use frame_benchmarking::{benchmarks, account};
|
||||||
use frame_support::traits::{Currency, OnInitialize};
|
use frame_support::traits::{Currency, OnInitialize, ValidatorSet, ValidatorSetWithIdentification};
|
||||||
|
|
||||||
use sp_runtime::{Perbill, traits::{Convert, StaticLookup, Saturating, UniqueSaturatedInto}};
|
use sp_runtime::{Perbill, traits::{Convert, StaticLookup, Saturating, UniqueSaturatedInto}};
|
||||||
use sp_staking::offence::{ReportOffence, Offence, OffenceDetails};
|
use sp_staking::offence::{ReportOffence, Offence, OffenceDetails};
|
||||||
@@ -176,6 +176,34 @@ fn make_offenders<T: Config>(num_offenders: u32, num_nominators: u32) -> Result<
|
|||||||
Ok((id_tuples, offenders))
|
Ok((id_tuples, offenders))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_offenders_im_online<T: Config>(num_offenders: u32, num_nominators: u32) -> Result<
|
||||||
|
(Vec<pallet_im_online::IdentificationTuple<T>>, Vec<Offender<T>>),
|
||||||
|
&'static str
|
||||||
|
> {
|
||||||
|
Staking::<T>::new_session(0);
|
||||||
|
|
||||||
|
let mut offenders = vec![];
|
||||||
|
for i in 0 .. num_offenders {
|
||||||
|
let offender = create_offender::<T>(i + 1, num_nominators)?;
|
||||||
|
offenders.push(offender);
|
||||||
|
}
|
||||||
|
|
||||||
|
Staking::<T>::start_session(0);
|
||||||
|
|
||||||
|
let id_tuples = offenders.iter()
|
||||||
|
.map(|offender| <
|
||||||
|
<T as ImOnlineConfig>::ValidatorSet as ValidatorSet<T::AccountId>
|
||||||
|
>::ValidatorIdOf::convert(offender.controller.clone())
|
||||||
|
.expect("failed to get validator id from account id"))
|
||||||
|
.map(|validator_id| <
|
||||||
|
<T as ImOnlineConfig>::ValidatorSet as ValidatorSetWithIdentification<T::AccountId>
|
||||||
|
>::IdentificationOf::convert(validator_id.clone())
|
||||||
|
.map(|full_id| (validator_id, full_id))
|
||||||
|
.expect("failed to convert validator id to full identification"))
|
||||||
|
.collect::<Vec<pallet_im_online::IdentificationTuple<T>>>();
|
||||||
|
Ok((id_tuples, offenders))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn check_events<T: Config, I: Iterator<Item = <T as SystemConfig>::Event>>(expected: I) {
|
fn check_events<T: Config, I: Iterator<Item = <T as SystemConfig>::Event>>(expected: I) {
|
||||||
let events = System::<T>::events() .into_iter()
|
let events = System::<T>::events() .into_iter()
|
||||||
@@ -220,7 +248,7 @@ benchmarks! {
|
|||||||
// make sure reporters actually get rewarded
|
// make sure reporters actually get rewarded
|
||||||
Staking::<T>::set_slash_reward_fraction(Perbill::one());
|
Staking::<T>::set_slash_reward_fraction(Perbill::one());
|
||||||
|
|
||||||
let (offenders, raw_offenders) = make_offenders::<T>(o, n)?;
|
let (offenders, raw_offenders) = make_offenders_im_online::<T>(o, n)?;
|
||||||
let keys = ImOnline::<T>::keys();
|
let keys = ImOnline::<T>::keys();
|
||||||
let validator_set_count = keys.len() as u32;
|
let validator_set_count = keys.len() as u32;
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ use sp_runtime::{
|
|||||||
traits::IdentityLookup,
|
traits::IdentityLookup,
|
||||||
testing::{Header, UintAuthorityId},
|
testing::{Header, UintAuthorityId},
|
||||||
};
|
};
|
||||||
|
use pallet_session::historical as pallet_session_historical;
|
||||||
|
|
||||||
type AccountId = u64;
|
type AccountId = u64;
|
||||||
type AccountIndex = u32;
|
type AccountIndex = u32;
|
||||||
@@ -130,6 +130,7 @@ impl pallet_session::Config for Test {
|
|||||||
type DisabledValidatorsThreshold = ();
|
type DisabledValidatorsThreshold = ();
|
||||||
type WeightInfo = ();
|
type WeightInfo = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
pallet_staking_reward_curve::build! {
|
pallet_staking_reward_curve::build! {
|
||||||
const I_NPOS: sp_runtime::curve::PiecewiseLinear<'static> = curve!(
|
const I_NPOS: sp_runtime::curve::PiecewiseLinear<'static> = curve!(
|
||||||
min_inflation: 0_025_000,
|
min_inflation: 0_025_000,
|
||||||
@@ -175,6 +176,7 @@ impl pallet_staking::Config for Test {
|
|||||||
impl pallet_im_online::Config for Test {
|
impl pallet_im_online::Config for Test {
|
||||||
type AuthorityId = UintAuthorityId;
|
type AuthorityId = UintAuthorityId;
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
|
type ValidatorSet = Historical;
|
||||||
type SessionDuration = Period;
|
type SessionDuration = Period;
|
||||||
type ReportUnresponsiveness = Offences;
|
type ReportUnresponsiveness = Offences;
|
||||||
type UnsignedPriority = ();
|
type UnsignedPriority = ();
|
||||||
@@ -214,6 +216,7 @@ frame_support::construct_runtime!(
|
|||||||
Session: pallet_session::{Module, Call, Storage, Event, Config<T>},
|
Session: pallet_session::{Module, Call, Storage, Event, Config<T>},
|
||||||
ImOnline: pallet_im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
|
ImOnline: pallet_im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
|
||||||
Offences: pallet_offences::{Module, Call, Storage, Event},
|
Offences: pallet_offences::{Module, Call, Storage, Event},
|
||||||
|
Historical: pallet_session_historical::{Module},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,10 @@ use codec::{Encode, Decode};
|
|||||||
use sp_runtime::KeyTypeId;
|
use sp_runtime::KeyTypeId;
|
||||||
use sp_runtime::traits::{Convert, OpaqueKeys};
|
use sp_runtime::traits::{Convert, OpaqueKeys};
|
||||||
use sp_session::{MembershipProof, ValidatorCount};
|
use sp_session::{MembershipProof, ValidatorCount};
|
||||||
use frame_support::{decl_module, decl_storage};
|
use frame_support::{
|
||||||
use frame_support::{Parameter, print};
|
decl_module, decl_storage, Parameter, print,
|
||||||
|
traits::{ValidatorSet, ValidatorSetWithIdentification},
|
||||||
|
};
|
||||||
use sp_trie::{MemoryDB, Trie, TrieMut, Recorder, EMPTY_PREFIX};
|
use sp_trie::{MemoryDB, Trie, TrieMut, Recorder, EMPTY_PREFIX};
|
||||||
use sp_trie::trie_types::{TrieDBMut, TrieDB};
|
use sp_trie::trie_types::{TrieDBMut, TrieDB};
|
||||||
use super::{SessionIndex, Module as SessionModule};
|
use super::{SessionIndex, Module as SessionModule};
|
||||||
@@ -102,6 +104,24 @@ impl<T: Config> Module<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Config> ValidatorSet<T::AccountId> for Module<T> {
|
||||||
|
type ValidatorId = T::ValidatorId;
|
||||||
|
type ValidatorIdOf = T::ValidatorIdOf;
|
||||||
|
|
||||||
|
fn session_index() -> sp_staking::SessionIndex {
|
||||||
|
super::Module::<T>::current_index()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validators() -> Vec<Self::ValidatorId> {
|
||||||
|
super::Module::<T>::validators()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Config> ValidatorSetWithIdentification<T::AccountId> for Module<T> {
|
||||||
|
type Identification = T::FullIdentification;
|
||||||
|
type IdentificationOf = T::FullIdentificationOf;
|
||||||
|
}
|
||||||
|
|
||||||
/// Specialization of the crate-level `SessionManager` which returns the set of full identification
|
/// Specialization of the crate-level `SessionManager` which returns the set of full identification
|
||||||
/// when creating a new session.
|
/// when creating a new session.
|
||||||
pub trait SessionManager<ValidatorId, FullIdentification>: crate::SessionManager<ValidatorId> {
|
pub trait SessionManager<ValidatorId, FullIdentification>: crate::SessionManager<ValidatorId> {
|
||||||
|
|||||||
@@ -116,13 +116,14 @@ pub mod weights;
|
|||||||
|
|
||||||
use sp_std::{prelude::*, marker::PhantomData, ops::{Sub, Rem}};
|
use sp_std::{prelude::*, marker::PhantomData, ops::{Sub, Rem}};
|
||||||
use codec::Decode;
|
use codec::Decode;
|
||||||
use sp_runtime::{KeyTypeId, Perbill, RuntimeAppPublic, BoundToRuntimeAppPublic};
|
use sp_runtime::{KeyTypeId, Perbill, RuntimeAppPublic};
|
||||||
use sp_runtime::traits::{Convert, Zero, Member, OpaqueKeys, Saturating};
|
use sp_runtime::traits::{Convert, Zero, Member, OpaqueKeys, Saturating};
|
||||||
use sp_staking::SessionIndex;
|
use sp_staking::SessionIndex;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
ensure, decl_module, decl_event, decl_storage, decl_error, ConsensusEngineId, Parameter,
|
ensure, decl_module, decl_event, decl_storage, decl_error, ConsensusEngineId, Parameter,
|
||||||
traits::{
|
traits::{
|
||||||
Get, FindAuthor, ValidatorRegistration, EstimateNextSessionRotation, EstimateNextNewSession,
|
Get, FindAuthor, ValidatorRegistration, EstimateNextSessionRotation, EstimateNextNewSession,
|
||||||
|
OneSessionHandler, ValidatorSet,
|
||||||
},
|
},
|
||||||
dispatch::{self, DispatchResult, DispatchError},
|
dispatch::{self, DispatchResult, DispatchError},
|
||||||
weights::Weight,
|
weights::Weight,
|
||||||
@@ -256,40 +257,6 @@ pub trait SessionHandler<ValidatorId> {
|
|||||||
fn on_disabled(validator_index: usize);
|
fn on_disabled(validator_index: usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A session handler for specific key type.
|
|
||||||
pub trait OneSessionHandler<ValidatorId>: BoundToRuntimeAppPublic {
|
|
||||||
/// The key type expected.
|
|
||||||
type Key: Decode + Default + RuntimeAppPublic;
|
|
||||||
|
|
||||||
fn on_genesis_session<'a, I: 'a>(validators: I)
|
|
||||||
where I: Iterator<Item=(&'a ValidatorId, Self::Key)>, ValidatorId: 'a;
|
|
||||||
|
|
||||||
/// Session set has changed; act appropriately. Note that this can be called
|
|
||||||
/// before initialization of your module.
|
|
||||||
///
|
|
||||||
/// `changed` is true when at least one of the session keys
|
|
||||||
/// or the underlying economic identities/distribution behind one the
|
|
||||||
/// session keys has changed, false otherwise.
|
|
||||||
///
|
|
||||||
/// The `validators` are the validators of the incoming session, and `queued_validators`
|
|
||||||
/// will follow.
|
|
||||||
fn on_new_session<'a, I: 'a>(
|
|
||||||
changed: bool,
|
|
||||||
validators: I,
|
|
||||||
queued_validators: I,
|
|
||||||
) where I: Iterator<Item=(&'a ValidatorId, Self::Key)>, ValidatorId: 'a;
|
|
||||||
|
|
||||||
|
|
||||||
/// A notification for end of the session.
|
|
||||||
///
|
|
||||||
/// Note it is triggered before any `SessionManager::end_session` handlers,
|
|
||||||
/// so we can still affect the validator set.
|
|
||||||
fn on_before_session_ending() {}
|
|
||||||
|
|
||||||
/// A validator got disabled. Act accordingly until a new session begins.
|
|
||||||
fn on_disabled(_validator_index: usize);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[impl_trait_for_tuples::impl_for_tuples(1, 30)]
|
#[impl_trait_for_tuples::impl_for_tuples(1, 30)]
|
||||||
#[tuple_types_no_default_trait_bound]
|
#[tuple_types_no_default_trait_bound]
|
||||||
impl<AId> SessionHandler<AId> for Tuple {
|
impl<AId> SessionHandler<AId> for Tuple {
|
||||||
@@ -830,6 +797,19 @@ impl<T: Config> Module<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Config> ValidatorSet<T::AccountId> for Module<T> {
|
||||||
|
type ValidatorId = T::ValidatorId;
|
||||||
|
type ValidatorIdOf = T::ValidatorIdOf;
|
||||||
|
|
||||||
|
fn session_index() -> sp_staking::SessionIndex {
|
||||||
|
Module::<T>::current_index()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validators() -> Vec<Self::ValidatorId> {
|
||||||
|
Module::<T>::validators()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Wraps the author-scraping logic for consensus engines that can recover
|
/// Wraps the author-scraping logic for consensus engines that can recover
|
||||||
/// the canonical index of an author. This then transforms it into the
|
/// the canonical index of an author. This then transforms it into the
|
||||||
/// registering account-ID of that session key index.
|
/// registering account-ID of that session key index.
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
// Tests for the Session Pallet
|
// Tests for the Session Pallet
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use codec::Decode;
|
||||||
use frame_support::{traits::OnInitialize, assert_ok};
|
use frame_support::{traits::OnInitialize, assert_ok};
|
||||||
use sp_core::crypto::key_types::DUMMY;
|
use sp_core::crypto::key_types::DUMMY;
|
||||||
use sp_runtime::testing::UintAuthorityId;
|
use sp_runtime::testing::UintAuthorityId;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ use crate::*;
|
|||||||
use crate as staking;
|
use crate as staking;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_ok, parameter_types,
|
assert_ok, parameter_types,
|
||||||
traits::{Currency, FindAuthor, Get, OnFinalize, OnInitialize},
|
traits::{Currency, FindAuthor, Get, OnFinalize, OnInitialize, OneSessionHandler},
|
||||||
weights::{constants::RocksDbWeight, Weight},
|
weights::{constants::RocksDbWeight, Weight},
|
||||||
IterableStorageMap, StorageDoubleMap, StorageMap, StorageValue,
|
IterableStorageMap, StorageDoubleMap, StorageMap, StorageValue,
|
||||||
};
|
};
|
||||||
@@ -53,7 +53,7 @@ thread_local! {
|
|||||||
|
|
||||||
/// Another session handler struct to test on_disabled.
|
/// Another session handler struct to test on_disabled.
|
||||||
pub struct OtherSessionHandler;
|
pub struct OtherSessionHandler;
|
||||||
impl pallet_session::OneSessionHandler<AccountId> for OtherSessionHandler {
|
impl OneSessionHandler<AccountId> for OtherSessionHandler {
|
||||||
type Key = UintAuthorityId;
|
type Key = UintAuthorityId;
|
||||||
|
|
||||||
fn on_genesis_session<'a, I: 'a>(_: I)
|
fn on_genesis_session<'a, I: 'a>(_: I)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ sp-tracing = { version = "2.0.0", default-features = false, path = "../../primit
|
|||||||
sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" }
|
sp-core = { version = "2.0.0", default-features = false, path = "../../primitives/core" }
|
||||||
sp-arithmetic = { version = "2.0.0", default-features = false, path = "../../primitives/arithmetic" }
|
sp-arithmetic = { version = "2.0.0", default-features = false, path = "../../primitives/arithmetic" }
|
||||||
sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" }
|
sp-inherents = { version = "2.0.0", default-features = false, path = "../../primitives/inherents" }
|
||||||
|
sp-staking = { version = "2.0.0", default-features = false, path = "../../primitives/staking" }
|
||||||
frame-support-procedural = { version = "2.0.1", default-features = false, path = "./procedural" }
|
frame-support-procedural = { version = "2.0.1", default-features = false, path = "./procedural" }
|
||||||
paste = "0.1.6"
|
paste = "0.1.6"
|
||||||
once_cell = { version = "1", default-features = false, optional = true }
|
once_cell = { version = "1", default-features = false, optional = true }
|
||||||
@@ -52,6 +53,7 @@ std = [
|
|||||||
"sp-arithmetic/std",
|
"sp-arithmetic/std",
|
||||||
"frame-metadata/std",
|
"frame-metadata/std",
|
||||||
"sp-inherents/std",
|
"sp-inherents/std",
|
||||||
|
"sp-staking/std",
|
||||||
"sp-state-machine",
|
"sp-state-machine",
|
||||||
"frame-support-procedural/std",
|
"frame-support-procedural/std",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -23,13 +23,15 @@ use sp_std::{prelude::*, result, marker::PhantomData, ops::Div, fmt::Debug};
|
|||||||
use codec::{FullCodec, Codec, Encode, Decode, EncodeLike};
|
use codec::{FullCodec, Codec, Encode, Decode, EncodeLike};
|
||||||
use sp_core::u32_trait::Value as U32;
|
use sp_core::u32_trait::Value as U32;
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
RuntimeDebug, ConsensusEngineId, DispatchResult, DispatchError,
|
RuntimeAppPublic, RuntimeDebug, BoundToRuntimeAppPublic,
|
||||||
|
ConsensusEngineId, DispatchResult, DispatchError,
|
||||||
traits::{
|
traits::{
|
||||||
MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput, Bounded, Zero,
|
MaybeSerializeDeserialize, AtLeast32Bit, Saturating, TrailingZeroInput, Bounded, Zero,
|
||||||
BadOrigin, AtLeast32BitUnsigned, UniqueSaturatedFrom, UniqueSaturatedInto,
|
BadOrigin, AtLeast32BitUnsigned, Convert, UniqueSaturatedFrom, UniqueSaturatedInto,
|
||||||
SaturatedConversion, StoredMapError,
|
SaturatedConversion, StoredMapError,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use sp_staking::SessionIndex;
|
||||||
use crate::dispatch::Parameter;
|
use crate::dispatch::Parameter;
|
||||||
use crate::storage::StorageMap;
|
use crate::storage::StorageMap;
|
||||||
use crate::weights::Weight;
|
use crate::weights::Weight;
|
||||||
@@ -40,6 +42,67 @@ use impl_trait_for_tuples::impl_for_tuples;
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub use sp_std::{mem::{swap, take}, cell::RefCell, vec::Vec, boxed::Box};
|
pub use sp_std::{mem::{swap, take}, cell::RefCell, vec::Vec, boxed::Box};
|
||||||
|
|
||||||
|
/// A trait for online node inspection in a session.
|
||||||
|
///
|
||||||
|
/// Something that can give information about the current validator set.
|
||||||
|
pub trait ValidatorSet<AccountId> {
|
||||||
|
/// Type for representing validator id in a session.
|
||||||
|
type ValidatorId: Parameter;
|
||||||
|
/// A type for converting `AccountId` to `ValidatorId`.
|
||||||
|
type ValidatorIdOf: Convert<AccountId, Option<Self::ValidatorId>>;
|
||||||
|
|
||||||
|
/// Returns current session index.
|
||||||
|
fn session_index() -> SessionIndex;
|
||||||
|
|
||||||
|
/// Returns the active set of validators.
|
||||||
|
fn validators() -> Vec<Self::ValidatorId>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [`ValidatorSet`] combined with an identification.
|
||||||
|
pub trait ValidatorSetWithIdentification<AccountId>: ValidatorSet<AccountId> {
|
||||||
|
/// Full identification of `ValidatorId`.
|
||||||
|
type Identification: Parameter;
|
||||||
|
/// A type for converting `ValidatorId` to `Identification`.
|
||||||
|
type IdentificationOf: Convert<Self::ValidatorId, Option<Self::Identification>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A session handler for specific key type.
|
||||||
|
pub trait OneSessionHandler<ValidatorId>: BoundToRuntimeAppPublic {
|
||||||
|
/// The key type expected.
|
||||||
|
type Key: Decode + Default + RuntimeAppPublic;
|
||||||
|
|
||||||
|
/// The given validator set will be used for the genesis session.
|
||||||
|
/// It is guaranteed that the given validator set will also be used
|
||||||
|
/// for the second session, therefore the first call to `on_new_session`
|
||||||
|
/// should provide the same validator set.
|
||||||
|
fn on_genesis_session<'a, I: 'a>(validators: I)
|
||||||
|
where I: Iterator<Item=(&'a ValidatorId, Self::Key)>, ValidatorId: 'a;
|
||||||
|
|
||||||
|
/// Session set has changed; act appropriately. Note that this can be called
|
||||||
|
/// before initialization of your module.
|
||||||
|
///
|
||||||
|
/// `changed` is true when at least one of the session keys
|
||||||
|
/// or the underlying economic identities/distribution behind one the
|
||||||
|
/// session keys has changed, false otherwise.
|
||||||
|
///
|
||||||
|
/// The `validators` are the validators of the incoming session, and `queued_validators`
|
||||||
|
/// will follow.
|
||||||
|
fn on_new_session<'a, I: 'a>(
|
||||||
|
changed: bool,
|
||||||
|
validators: I,
|
||||||
|
queued_validators: I,
|
||||||
|
) where I: Iterator<Item=(&'a ValidatorId, Self::Key)>, ValidatorId: 'a;
|
||||||
|
|
||||||
|
/// A notification for end of the session.
|
||||||
|
///
|
||||||
|
/// Note it is triggered before any `SessionManager::end_session` handlers,
|
||||||
|
/// so we can still affect the validator set.
|
||||||
|
fn on_before_session_ending() {}
|
||||||
|
|
||||||
|
/// A validator got disabled. Act accordingly until a new session begins.
|
||||||
|
fn on_disabled(_validator_index: usize);
|
||||||
|
}
|
||||||
|
|
||||||
/// Simple trait for providing a filter over a reference to some type.
|
/// Simple trait for providing a filter over a reference to some type.
|
||||||
pub trait Filter<T> {
|
pub trait Filter<T> {
|
||||||
/// Determine if a given value should be allowed through the filter (returns `true`) or not.
|
/// Determine if a given value should be allowed through the filter (returns `true`) or not.
|
||||||
|
|||||||
Reference in New Issue
Block a user