mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 03:17:56 +00:00
session: add handler for genesis session (#3413)
* session: add handler for genesis session * node: bump spec version * aura: handle on_genesis_session * srml: make sure we don't re-initialize genesis authorities * session: fix mock * node: remove genesis authorities from chain spec * staking: fix mock * srml: don't initialize genesis authorities twice * aura: don't reinitialize genesis authorities * aura: fix runtime_io dependency * Bump runtime
This commit is contained in:
committed by
Svyatoslav Nikolsky
parent
3590c9c33f
commit
d1dde7e087
@@ -166,13 +166,13 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
|
||||
key: endowed_accounts[0].clone(),
|
||||
}),
|
||||
babe: Some(BabeConfig {
|
||||
authorities: initial_authorities.iter().map(|x| (x.3.clone(), 1)).collect(),
|
||||
authorities: vec![],
|
||||
}),
|
||||
im_online: Some(ImOnlineConfig {
|
||||
keys: initial_authorities.iter().map(|x| x.4.clone()).collect(),
|
||||
keys: vec![],
|
||||
}),
|
||||
grandpa: Some(GrandpaConfig {
|
||||
authorities: initial_authorities.iter().map(|x| (x.2.clone(), 1)).collect(),
|
||||
authorities: vec![],
|
||||
}),
|
||||
membership_Instance1: Some(Default::default()),
|
||||
}
|
||||
@@ -298,13 +298,13 @@ pub fn testnet_genesis(
|
||||
key: root_key,
|
||||
}),
|
||||
babe: Some(BabeConfig {
|
||||
authorities: initial_authorities.iter().map(|x| (x.3.clone(), 1)).collect(),
|
||||
authorities: vec![],
|
||||
}),
|
||||
im_online: Some(ImOnlineConfig{
|
||||
keys: initial_authorities.iter().map(|x| x.4.clone()).collect(),
|
||||
keys: vec![],
|
||||
}),
|
||||
grandpa: Some(GrandpaConfig {
|
||||
authorities: initial_authorities.iter().map(|x| (x.2.clone(), 1)).collect(),
|
||||
authorities: vec![],
|
||||
}),
|
||||
membership_Instance1: Some(Default::default()),
|
||||
}
|
||||
|
||||
@@ -80,8 +80,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
// and set impl_version to equal spec_version. If only runtime
|
||||
// implementation changes and behavior does not, then leave spec_version as
|
||||
// is and increment impl_version.
|
||||
spec_version: 142,
|
||||
impl_version: 142,
|
||||
spec_version: 143,
|
||||
impl_version: 143,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ rstd = { package = "sr-std", path = "../../core/sr-std", default-features = fals
|
||||
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
|
||||
primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false }
|
||||
app-crypto = { package = "substrate-application-crypto", path = "../../core/application-crypto", default-features = false }
|
||||
runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] }
|
||||
srml-support = { path = "../support", default-features = false }
|
||||
system = { package = "srml-system", path = "../system", default-features = false }
|
||||
timestamp = { package = "srml-timestamp", path = "../timestamp", default-features = false }
|
||||
|
||||
@@ -165,7 +165,19 @@ decl_storage! {
|
||||
LastTimestamp get(last) build(|_| 0.into()): T::Moment;
|
||||
|
||||
/// The current authorities
|
||||
pub Authorities get(authorities) config(): Vec<T::AuthorityId>;
|
||||
pub Authorities get(authorities): Vec<T::AuthorityId>;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(authorities): Vec<T::AuthorityId>;
|
||||
build(|
|
||||
storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay),
|
||||
config: &GenesisConfig<T>
|
||||
| {
|
||||
runtime_io::with_storage(
|
||||
storage,
|
||||
|| Module::<T>::initialize_authorities(&config.authorities),
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,11 +195,25 @@ impl<T: Trait> Module<T> {
|
||||
);
|
||||
<system::Module<T>>::deposit_log(log.into());
|
||||
}
|
||||
|
||||
fn initialize_authorities(authorities: &[T::AuthorityId]) {
|
||||
if !authorities.is_empty() {
|
||||
assert!(<Authorities<T>>::get().is_empty(), "Authorities are already initialized!");
|
||||
<Authorities<T>>::put_ref(authorities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> session::OneSessionHandler<T::AccountId> for Module<T> {
|
||||
type Key = T::AuthorityId;
|
||||
|
||||
fn on_genesis_session<'a, I: 'a>(validators: I)
|
||||
where I: Iterator<Item=(&'a T::AccountId, T::AuthorityId)>
|
||||
{
|
||||
let authorities = validators.map(|(_, k)| k).collect::<Vec<_>>();
|
||||
Self::initialize_authorities(&authorities);
|
||||
}
|
||||
|
||||
fn on_new_session<'a, I: 'a>(changed: bool, validators: I, _queued_validators: I)
|
||||
where I: Iterator<Item=(&'a T::AccountId, T::AuthorityId)>
|
||||
{
|
||||
@@ -200,6 +226,7 @@ impl<T: Trait> session::OneSessionHandler<T::AccountId> for Module<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_disabled(i: usize) {
|
||||
let log: DigestItem<T::Hash> = DigestItem::Consensus(
|
||||
AURA_ENGINE_ID,
|
||||
|
||||
@@ -123,7 +123,7 @@ decl_storage! {
|
||||
pub EpochIndex get(epoch_index): u64;
|
||||
|
||||
/// Current epoch authorities.
|
||||
pub Authorities get(authorities) config(): Vec<(AuthorityId, BabeWeight)>;
|
||||
pub Authorities get(authorities): Vec<(AuthorityId, BabeWeight)>;
|
||||
|
||||
/// Slot at which the current epoch started. It is possible that no
|
||||
/// block was authored at the given slot and the epoch change was
|
||||
@@ -163,6 +163,18 @@ decl_storage! {
|
||||
SegmentIndex build(|_| 0): u32;
|
||||
UnderConstruction: map u32 => Vec<[u8; 32 /* VRF_OUTPUT_LENGTH */]>;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(authorities): Vec<(AuthorityId, BabeWeight)>;
|
||||
build(|
|
||||
storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay),
|
||||
config: &GenesisConfig
|
||||
| {
|
||||
runtime_io::with_storage(
|
||||
storage,
|
||||
|| Module::<T>::initialize_authorities(&config.authorities),
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
@@ -292,6 +304,12 @@ impl<T: Trait> Module<T> {
|
||||
this_randomness
|
||||
}
|
||||
|
||||
fn initialize_authorities(authorities: &[(AuthorityId, BabeWeight)]) {
|
||||
if !authorities.is_empty() {
|
||||
assert!(Authorities::get().is_empty(), "Authorities are already initialized!");
|
||||
Authorities::put_ref(authorities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> OnTimestampSet<T::Moment> for Module<T> {
|
||||
@@ -300,6 +318,14 @@ impl<T: Trait> OnTimestampSet<T::Moment> for Module<T> {
|
||||
|
||||
impl<T: Trait> session::OneSessionHandler<T::AccountId> for Module<T> {
|
||||
type Key = AuthorityId;
|
||||
|
||||
fn on_genesis_session<'a, I: 'a>(validators: I)
|
||||
where I: Iterator<Item=(&'a T::AccountId, AuthorityId)>
|
||||
{
|
||||
let authorities = validators.map(|(_, k)| (k, 1)).collect::<Vec<_>>();
|
||||
Self::initialize_authorities(&authorities);
|
||||
}
|
||||
|
||||
fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, queued_validators: I)
|
||||
where I: Iterator<Item=(&'a T::AccountId, AuthorityId)>
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@ codec = { package = "parity-scale-codec", version = "1.0.0", default-features =
|
||||
primitives = { package = "substrate-primitives", path = "../../core/primitives", default-features = false }
|
||||
substrate-finality-grandpa-primitives = { path = "../../core/finality-grandpa/primitives", default-features = false }
|
||||
rstd = { package = "sr-std", path = "../../core/sr-std", default-features = false }
|
||||
runtime_io = { package = "sr-io", path = "../../core/sr-io", default-features = false, features = [ "wasm-nice-panic-message" ] }
|
||||
sr-primitives = { path = "../../core/sr-primitives", default-features = false }
|
||||
srml-support = { path = "../support", default-features = false }
|
||||
system = { package = "srml-system", path = "../system", default-features = false }
|
||||
|
||||
@@ -133,7 +133,7 @@ decl_event!(
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Trait> as GrandpaFinality {
|
||||
/// The current authority set.
|
||||
Authorities get(authorities) config(): Vec<(AuthorityId, AuthorityWeight)>;
|
||||
Authorities get(authorities): Vec<(AuthorityId, AuthorityWeight)>;
|
||||
|
||||
/// State of the current authority set.
|
||||
State get(state): StoredState<T::BlockNumber> = StoredState::Live;
|
||||
@@ -147,6 +147,18 @@ decl_storage! {
|
||||
/// `true` if we are currently stalled.
|
||||
Stalled get(stalled): Option<(T::BlockNumber, T::BlockNumber)>;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(authorities): Vec<(AuthorityId, AuthorityWeight)>;
|
||||
build(|
|
||||
storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay),
|
||||
config: &GenesisConfig
|
||||
| {
|
||||
runtime_io::with_storage(
|
||||
storage,
|
||||
|| Module::<T>::initialize_authorities(&config.authorities),
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
@@ -310,6 +322,13 @@ impl<T: Trait> Module<T> {
|
||||
let log: DigestItem<T::Hash> = DigestItem::Consensus(GRANDPA_ENGINE_ID, log.encode());
|
||||
<system::Module<T>>::deposit_log(log.into());
|
||||
}
|
||||
|
||||
fn initialize_authorities(authorities: &[(AuthorityId, AuthorityWeight)]) {
|
||||
if !authorities.is_empty() {
|
||||
assert!(Authorities::get().is_empty(), "Authorities are already initialized!");
|
||||
Authorities::put_ref(authorities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
@@ -346,12 +365,19 @@ impl<T: Trait> Module<T> {
|
||||
impl<T: Trait> session::OneSessionHandler<T::AccountId> for Module<T> {
|
||||
type Key = AuthorityId;
|
||||
|
||||
fn on_genesis_session<'a, I: 'a>(validators: I)
|
||||
where I: Iterator<Item=(&'a T::AccountId, AuthorityId)>
|
||||
{
|
||||
let authorities = validators.map(|(_, k)| (k, 1)).collect::<Vec<_>>();
|
||||
Self::initialize_authorities(&authorities);
|
||||
}
|
||||
|
||||
fn on_new_session<'a, I: 'a>(changed: bool, validators: I, _queued_validators: I)
|
||||
where I: Iterator<Item=(&'a T::AccountId, AuthorityId)>
|
||||
{
|
||||
// instant changes
|
||||
if changed {
|
||||
let next_authorities = validators.map(|(_, k)| (k, 1u64)).collect::<Vec<_>>();
|
||||
let next_authorities = validators.map(|(_, k)| (k, 1)).collect::<Vec<_>>();
|
||||
let last_authorities = <Module<T>>::grandpa_authorities();
|
||||
if next_authorities != last_authorities {
|
||||
if let Some((further_wait, median)) = <Stalled<T>>::take() {
|
||||
|
||||
@@ -85,7 +85,7 @@ pub fn new_test_ext(authorities: Vec<(u64, u64)>) -> runtime_io::TestExternaliti
|
||||
let mut t = system::GenesisConfig::default().build_storage::<Test>().unwrap();
|
||||
GenesisConfig {
|
||||
authorities: to_authorities(authorities),
|
||||
}.assimilate_storage(&mut t).unwrap();
|
||||
}.assimilate_storage::<Test>(&mut t).unwrap();
|
||||
t.into()
|
||||
}
|
||||
|
||||
|
||||
@@ -177,13 +177,25 @@ decl_storage! {
|
||||
GossipAt get(gossip_at): T::BlockNumber;
|
||||
|
||||
/// The current set of keys that may issue a heartbeat.
|
||||
Keys get(keys) config(): Vec<AuthorityId>;
|
||||
Keys get(keys): Vec<AuthorityId>;
|
||||
|
||||
/// For each session index we keep a mapping of `AuthorityId`
|
||||
/// to `offchain::OpaqueNetworkState`.
|
||||
ReceivedHeartbeats get(received_heartbeats): double_map SessionIndex,
|
||||
blake2_256(AuthIndex) => Vec<u8>;
|
||||
}
|
||||
add_extra_genesis {
|
||||
config(keys): Vec<AuthorityId>;
|
||||
build(|
|
||||
storage: &mut (sr_primitives::StorageOverlay, sr_primitives::ChildrenStorageOverlay),
|
||||
config: &GenesisConfig
|
||||
| {
|
||||
sr_io::with_storage(
|
||||
storage,
|
||||
|| Module::<T>::initialize_keys(&config.keys),
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -355,11 +367,24 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
fn initialize_keys(keys: &[AuthorityId]) {
|
||||
if !keys.is_empty() {
|
||||
assert!(Keys::get().is_empty(), "Keys are already initialized!");
|
||||
Keys::put_ref(keys);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> session::OneSessionHandler<T::AccountId> for Module<T> {
|
||||
type Key = AuthorityId;
|
||||
|
||||
fn on_genesis_session<'a, I: 'a>(validators: I)
|
||||
where I: Iterator<Item=(&'a T::AccountId, AuthorityId)>
|
||||
{
|
||||
let keys = validators.map(|x| x.1).collect::<Vec<_>>();
|
||||
Self::initialize_keys(&keys);
|
||||
}
|
||||
|
||||
fn on_new_session<'a, I: 'a>(_changed: bool, validators: I, _queued_validators: I)
|
||||
where I: Iterator<Item=(&'a T::AccountId, AuthorityId)>
|
||||
{
|
||||
|
||||
@@ -187,6 +187,12 @@ impl<A> OnSessionEnding<A> for () {
|
||||
|
||||
/// Handler for when a session keys set changes.
|
||||
pub trait SessionHandler<ValidatorId> {
|
||||
/// 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<Ks: OpaqueKeys>(validators: &[(ValidatorId, Ks)]);
|
||||
|
||||
/// Session set has changed; act appropriately.
|
||||
fn on_new_session<Ks: OpaqueKeys>(
|
||||
changed: bool,
|
||||
@@ -203,14 +209,19 @@ pub trait OneSessionHandler<ValidatorId> {
|
||||
/// The key type expected.
|
||||
type Key: Decode + Default + AppKey;
|
||||
|
||||
fn on_genesis_session<'a, I: 'a>(validators: I)
|
||||
where I: Iterator<Item=(&'a ValidatorId, Self::Key)>, ValidatorId: 'a;
|
||||
|
||||
fn on_new_session<'a, I: 'a>(changed: bool, validators: I, queued_validators: I)
|
||||
where I: Iterator<Item=(&'a ValidatorId, Self::Key)>, ValidatorId: 'a;
|
||||
|
||||
fn on_disabled(i: usize);
|
||||
}
|
||||
|
||||
macro_rules! impl_session_handlers {
|
||||
() => (
|
||||
impl<AId> SessionHandler<AId> for () {
|
||||
fn on_genesis_session<Ks: OpaqueKeys>(_: &[(AId, Ks)]) {}
|
||||
fn on_new_session<Ks: OpaqueKeys>(_: bool, _: &[(AId, Ks)], _: &[(AId, Ks)]) {}
|
||||
fn on_disabled(_: usize) {}
|
||||
}
|
||||
@@ -218,6 +229,15 @@ macro_rules! impl_session_handlers {
|
||||
|
||||
( $($t:ident)* ) => {
|
||||
impl<AId, $( $t: OneSessionHandler<AId> ),*> SessionHandler<AId> for ( $( $t , )* ) {
|
||||
fn on_genesis_session<Ks: OpaqueKeys>(validators: &[(AId, Ks)]) {
|
||||
$(
|
||||
let our_keys: Box<dyn Iterator<Item=_>> = Box::new(validators.iter()
|
||||
.map(|k| (&k.0, k.1.get::<$t::Key>(<$t::Key as AppKey>::ID)
|
||||
.unwrap_or_default())));
|
||||
|
||||
$t::on_genesis_session(our_keys);
|
||||
)*
|
||||
}
|
||||
fn on_new_session<Ks: OpaqueKeys>(
|
||||
changed: bool,
|
||||
validators: &[(AId, Ks)],
|
||||
@@ -348,6 +368,9 @@ decl_storage! {
|
||||
))
|
||||
.collect();
|
||||
|
||||
// Tell everyone about the genesis session keys
|
||||
T::SessionHandler::on_genesis_session::<T::Keys>(&queued_keys);
|
||||
|
||||
<Validators<T>>::put(initial_validators);
|
||||
<QueuedKeys<T>>::put(queued_keys);
|
||||
});
|
||||
|
||||
@@ -62,6 +62,7 @@ impl ShouldEndSession<u64> for TestShouldEndSession {
|
||||
|
||||
pub struct TestSessionHandler;
|
||||
impl SessionHandler<u64> for TestSessionHandler {
|
||||
fn on_genesis_session<T: OpaqueKeys>(_validators: &[(u64, T)]) {}
|
||||
fn on_new_session<T: OpaqueKeys>(
|
||||
changed: bool,
|
||||
validators: &[(u64, T)],
|
||||
|
||||
@@ -52,6 +52,8 @@ thread_local! {
|
||||
|
||||
pub struct TestSessionHandler;
|
||||
impl session::SessionHandler<AccountId> for TestSessionHandler {
|
||||
fn on_genesis_session<Ks: OpaqueKeys>(_validators: &[(AccountId, Ks)]) {}
|
||||
|
||||
fn on_new_session<Ks: OpaqueKeys>(
|
||||
_changed: bool,
|
||||
validators: &[(AccountId, Ks)],
|
||||
|
||||
Reference in New Issue
Block a user