mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 06:31:09 +00:00
Dispatch on-disabled digests from consensus modules (#3055)
* on-disable primitives for engines * dispatch on-disabled digests from SRML consensus * bump runtime versions * use find_map
This commit is contained in:
committed by
Gavin Wood
parent
3d72844710
commit
13b9e49688
@@ -26,11 +26,18 @@ use runtime_primitives::ConsensusEngineId;
|
||||
/// The `ConsensusEngineId` of AuRa.
|
||||
pub const AURA_ENGINE_ID: ConsensusEngineId = [b'a', b'u', b'r', b'a'];
|
||||
|
||||
/// The index of an authority.
|
||||
pub type AuthorityIndex = u64;
|
||||
|
||||
/// An consensus log item for Aura.
|
||||
#[derive(Decode, Encode)]
|
||||
pub enum ConsensusLog<AuthorityId: Codec> {
|
||||
/// The authorities have changed.
|
||||
#[codec(index = "1")]
|
||||
AuthoritiesChange(Vec<AuthorityId>),
|
||||
/// Disable the authority with given index.
|
||||
#[codec(index = "2")]
|
||||
OnDisabled(AuthorityIndex),
|
||||
}
|
||||
|
||||
decl_runtime_apis! {
|
||||
|
||||
@@ -564,14 +564,19 @@ impl<B: Block, C, P> Verifier<B> for AuraVerifier<C, P> where
|
||||
trace!(target: "aura", "Checked {:?}; importing.", pre_header);
|
||||
telemetry!(CONSENSUS_TRACE; "aura.checked_and_importing"; "pre_header" => ?pre_header);
|
||||
|
||||
// `Consensus` is the Aura-specific authorities change log.
|
||||
// Look for an authorities-change log.
|
||||
let maybe_keys = pre_header.digest()
|
||||
.convert_first(|l| l.try_to::<ConsensusLog<AuthorityId<P>>>(
|
||||
.logs()
|
||||
.iter()
|
||||
.filter_map(|l| l.try_to::<ConsensusLog<AuthorityId<P>>>(
|
||||
OpaqueDigestItemId::Consensus(&AURA_ENGINE_ID)
|
||||
))
|
||||
.map(|ConsensusLog::AuthoritiesChange(a)|
|
||||
vec![(well_known_cache_keys::AUTHORITIES, a.encode())]
|
||||
);
|
||||
.find_map(|l| match l {
|
||||
ConsensusLog::AuthoritiesChange(a) => Some(
|
||||
vec![(well_known_cache_keys::AUTHORITIES, a.encode())]
|
||||
),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let import_block = ImportBlock {
|
||||
origin,
|
||||
|
||||
@@ -40,6 +40,29 @@ pub const VRF_PROOF_LENGTH: usize = 64;
|
||||
/// The length of the public key
|
||||
pub const PUBLIC_KEY_LENGTH: usize = 32;
|
||||
|
||||
/// The index of an authority.
|
||||
pub type AuthorityIndex = u64;
|
||||
|
||||
/// A slot number.
|
||||
pub type SlotNumber = u64;
|
||||
|
||||
/// The weight of an authority.
|
||||
pub type Weight = u64;
|
||||
|
||||
/// An consensus log item for BABE.
|
||||
#[derive(Decode, Encode)]
|
||||
pub enum ConsensusLog {
|
||||
/// The epoch has changed. This provides information about the
|
||||
/// epoch _after_ next: what slot number it will start at, who are the authorities (and their weights)
|
||||
/// and the next epoch randomness. The information for the _next_ epoch should already
|
||||
/// be available.
|
||||
#[codec(index = "1")]
|
||||
NextEpochData(SlotNumber, Vec<(AuthorityId, Weight)>, [u8; VRF_OUTPUT_LENGTH]),
|
||||
/// Disable the authority with given index.
|
||||
#[codec(index = "2")]
|
||||
OnDisabled(AuthorityIndex),
|
||||
}
|
||||
|
||||
/// Configuration data used by the BABE consensus engine.
|
||||
#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug, Encode, Decode)]
|
||||
pub struct BabeConfiguration {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//! Private implementation details of BABE digests.
|
||||
|
||||
use primitives::sr25519::Signature;
|
||||
use babe_primitives::{self, BABE_ENGINE_ID};
|
||||
use babe_primitives::{self, BABE_ENGINE_ID, SlotNumber};
|
||||
use runtime_primitives::{DigestItem, generic::OpaqueDigestItemId};
|
||||
use std::fmt::Debug;
|
||||
use parity_codec::{Decode, Encode, Codec, Input};
|
||||
@@ -33,8 +33,8 @@ use schnorrkel::{vrf::{VRFProof, VRFOutput, VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH}
|
||||
pub struct BabePreDigest {
|
||||
pub(super) vrf_output: VRFOutput,
|
||||
pub(super) proof: VRFProof,
|
||||
pub(super) index: u64,
|
||||
pub(super) slot_num: u64,
|
||||
pub(super) index: babe_primitives::AuthorityIndex,
|
||||
pub(super) slot_num: SlotNumber,
|
||||
}
|
||||
|
||||
/// The prefix used by BABE for its VRF keys.
|
||||
|
||||
@@ -23,7 +23,7 @@ extern crate alloc;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use serde::Serialize;
|
||||
use parity_codec::{Encode, Decode};
|
||||
use parity_codec::{Encode, Decode, Codec};
|
||||
use sr_primitives::{ConsensusEngineId, traits::{DigestFor, NumberFor}};
|
||||
use client::decl_runtime_apis;
|
||||
use rstd::vec::Vec;
|
||||
@@ -44,16 +44,75 @@ pub const GRANDPA_ENGINE_ID: ConsensusEngineId = *b"FRNK";
|
||||
/// The weight of an authority.
|
||||
pub type AuthorityWeight = u64;
|
||||
|
||||
/// The index of an authority.
|
||||
pub type AuthorityIndex = u64;
|
||||
|
||||
/// A scheduled change of authority set.
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
|
||||
#[derive(Clone, Eq, PartialEq, Encode, Decode)]
|
||||
pub struct ScheduledChange<N> {
|
||||
/// The new authorities after the change, along with their respective weights.
|
||||
pub next_authorities: Vec<(AuthorityId, u64)>,
|
||||
pub next_authorities: Vec<(AuthorityId, AuthorityWeight)>,
|
||||
/// The number of blocks to delay.
|
||||
pub delay: N,
|
||||
}
|
||||
|
||||
/// An consensus log item for GRANDPA.
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Debug))]
|
||||
#[derive(Decode, Encode, PartialEq, Eq, Clone)]
|
||||
pub enum ConsensusLog<N: Codec> {
|
||||
/// Schedule an authority set change.
|
||||
///
|
||||
/// Precedence towards earlier or later digest items can be given
|
||||
/// based on the rules of the chain.
|
||||
///
|
||||
/// No change should be scheduled if one is already and the delay has not
|
||||
/// passed completely.
|
||||
///
|
||||
/// This should be a pure function: i.e. as long as the runtime can interpret
|
||||
/// the digest type it should return the same result regardless of the current
|
||||
/// state.
|
||||
#[codec(index = "1")]
|
||||
ScheduledChange(ScheduledChange<N>),
|
||||
/// Force an authority set change.
|
||||
///
|
||||
/// Forced changes are applied after a delay of _imported_ blocks,
|
||||
/// while pending changes are applied after a delay of _finalized_ blocks.
|
||||
///
|
||||
/// Precedence towards earlier or later digest items can be given
|
||||
/// based on the rules of the chain.
|
||||
///
|
||||
/// No change should be scheduled if one is already and the delay has not
|
||||
/// passed completely.
|
||||
///
|
||||
/// This should be a pure function: i.e. as long as the runtime can interpret
|
||||
/// the digest type it should return the same result regardless of the current
|
||||
/// state.
|
||||
#[codec(index = "2")]
|
||||
ForcedChange(N, ScheduledChange<N>),
|
||||
/// Note that the authority with given index is disabled until the next change.
|
||||
#[codec(index = "3")]
|
||||
OnDisabled(AuthorityIndex),
|
||||
}
|
||||
|
||||
impl<N: Codec> ConsensusLog<N> {
|
||||
/// Try to cast the log entry as a contained signal.
|
||||
pub fn try_into_change(self) -> Option<ScheduledChange<N>> {
|
||||
match self {
|
||||
ConsensusLog::ScheduledChange(change) => Some(change),
|
||||
ConsensusLog::ForcedChange(_, _) | ConsensusLog::OnDisabled(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to cast the log entry as a contained forced signal.
|
||||
pub fn try_into_forced_change(self) -> Option<(N, ScheduledChange<N>)> {
|
||||
match self {
|
||||
ConsensusLog::ForcedChange(median, change) => Some((median, change)),
|
||||
ConsensusLog::ScheduledChange(_) | ConsensusLog::OnDisabled(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// WASM function call to check for pending changes.
|
||||
pub const PENDING_CHANGE_CALL: &str = "grandpa_pending_change";
|
||||
/// WASM function call to get current GRANDPA authorities.
|
||||
|
||||
@@ -71,9 +71,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: 105,
|
||||
impl_version: 105,
|
||||
spec_version: 106,
|
||||
impl_version: 106,
|
||||
apis: RUNTIME_API_VERSIONS,
|
||||
};
|
||||
|
||||
|
||||
@@ -200,8 +200,13 @@ impl<T: Trait> session::OneSessionHandler<T::AccountId> for Module<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
fn on_disabled(_i: usize) {
|
||||
// ignore?
|
||||
fn on_disabled(i: usize) {
|
||||
let log: DigestItem<T::Hash> = DigestItem::Consensus(
|
||||
AURA_ENGINE_ID,
|
||||
ConsensusLog::<T::AuthorityId>::OnDisabled(i as u64).encode(),
|
||||
);
|
||||
|
||||
<system::Module<T>>::deposit_log(log.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ use parity_codec::{Encode, Decode};
|
||||
use inherents::{RuntimeString, InherentIdentifier, InherentData, ProvideInherent, MakeFatalError};
|
||||
#[cfg(feature = "std")]
|
||||
use inherents::{InherentDataProviders, ProvideInherentData};
|
||||
use babe_primitives::BABE_ENGINE_ID;
|
||||
use babe_primitives::{BABE_ENGINE_ID, ConsensusLog};
|
||||
pub use babe_primitives::{AuthorityId, VRF_OUTPUT_LENGTH, VRF_PROOF_LENGTH, PUBLIC_KEY_LENGTH};
|
||||
|
||||
/// The BABE inherent identifier.
|
||||
@@ -128,13 +128,13 @@ decl_storage! {
|
||||
/// (like everything else on-chain) it is public. For example, it can be
|
||||
/// used where a number is needed that cannot have been chosen by an
|
||||
/// adversary, for purposes such as public-coin zero-knowledge proofs.
|
||||
EpochRandomness get(epoch_randomness): [u8; 32];
|
||||
EpochRandomness get(epoch_randomness): [u8; VRF_OUTPUT_LENGTH];
|
||||
|
||||
/// The randomness under construction
|
||||
UnderConstruction: [u8; 32];
|
||||
UnderConstruction: [u8; VRF_OUTPUT_LENGTH];
|
||||
|
||||
/// The randomness for the next epoch
|
||||
NextEpochRandomness: [u8; 32];
|
||||
NextEpochRandomness: [u8; VRF_OUTPUT_LENGTH];
|
||||
|
||||
/// The current epoch
|
||||
EpochIndex get(epoch_index): u64;
|
||||
@@ -162,7 +162,7 @@ decl_module! {
|
||||
}
|
||||
|
||||
impl<T: Trait> RandomnessBeacon for Module<T> {
|
||||
fn random() -> [u8; 32] {
|
||||
fn random() -> [u8; VRF_OUTPUT_LENGTH] {
|
||||
Self::epoch_randomness()
|
||||
}
|
||||
}
|
||||
@@ -245,8 +245,13 @@ impl<T: Trait> session::OneSessionHandler<T::AccountId> for Module<T> {
|
||||
s[40..].copy_from_slice(&rho);
|
||||
NextEpochRandomness::put(runtime_io::blake2_256(&s))
|
||||
}
|
||||
fn on_disabled(_i: usize) {
|
||||
// ignore?
|
||||
|
||||
fn on_disabled(i: usize) {
|
||||
let log: DigestItem<T::Hash> = DigestItem::Consensus(
|
||||
BABE_ENGINE_ID,
|
||||
ConsensusLog::OnDisabled(i as u64).encode(),
|
||||
);
|
||||
<system::Module<T>>::deposit_log(log.into());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@
|
||||
// re-export since this is necessary for `impl_apis` in runtime.
|
||||
pub use substrate_finality_grandpa_primitives as fg_primitives;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use serde::Serialize;
|
||||
use rstd::prelude::*;
|
||||
use parity_codec::{self as codec, Encode, Decode};
|
||||
use srml_support::{
|
||||
@@ -40,44 +38,13 @@ use srml_support::{
|
||||
use primitives::{
|
||||
generic::{DigestItem, OpaqueDigestItemId}, traits::CurrentHeight
|
||||
};
|
||||
use fg_primitives::{ScheduledChange, GRANDPA_ENGINE_ID};
|
||||
use fg_primitives::{ScheduledChange, ConsensusLog, GRANDPA_ENGINE_ID};
|
||||
pub use fg_primitives::{AuthorityId, AuthorityWeight};
|
||||
use system::{ensure_signed, DigestOf};
|
||||
|
||||
mod mock;
|
||||
mod tests;
|
||||
|
||||
/// Consensus log type of this module.
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Debug))]
|
||||
#[derive(Encode, Decode, PartialEq, Eq, Clone)]
|
||||
pub enum Signal<N> {
|
||||
/// Authorities set change has been signaled. Contains the new set of authorities
|
||||
/// and the delay in blocks _to finalize_ before applying.
|
||||
AuthoritiesChange(ScheduledChange<N>),
|
||||
/// A forced authorities set change. Contains in this order: the median last
|
||||
/// finalized block when the change was signaled, the delay in blocks _to import_
|
||||
/// before applying and the new set of authorities.
|
||||
ForcedAuthoritiesChange(N, ScheduledChange<N>),
|
||||
}
|
||||
|
||||
impl<N> Signal<N> {
|
||||
/// Try to cast the log entry as a contained signal.
|
||||
pub fn try_into_change(self) -> Option<ScheduledChange<N>> {
|
||||
match self {
|
||||
Signal::AuthoritiesChange(change) => Some(change),
|
||||
Signal::ForcedAuthoritiesChange(_, _) => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to cast the log entry as a contained forced signal.
|
||||
pub fn try_into_forced_change(self) -> Option<(N, ScheduledChange<N>)> {
|
||||
match self {
|
||||
Signal::ForcedAuthoritiesChange(median, change) => Some((median, change)),
|
||||
Signal::AuthoritiesChange(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Trait: system::Trait {
|
||||
/// The event type of this module.
|
||||
type Event: From<Event> + Into<<Self as system::Trait>::Event>;
|
||||
@@ -161,7 +128,7 @@ decl_module! {
|
||||
if let Some(pending_change) = <PendingChange<T>>::get() {
|
||||
if block_number == pending_change.scheduled_at {
|
||||
if let Some(median) = pending_change.forced {
|
||||
Self::deposit_log(Signal::ForcedAuthoritiesChange(
|
||||
Self::deposit_log(ConsensusLog::ForcedChange(
|
||||
median,
|
||||
ScheduledChange{
|
||||
delay: pending_change.delay,
|
||||
@@ -169,7 +136,7 @@ decl_module! {
|
||||
}
|
||||
))
|
||||
} else {
|
||||
Self::deposit_log(Signal::AuthoritiesChange(
|
||||
Self::deposit_log(ConsensusLog::ScheduledChange(
|
||||
ScheduledChange{
|
||||
delay: pending_change.delay,
|
||||
next_authorities: pending_change.next_authorities.clone(),
|
||||
@@ -242,16 +209,16 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
|
||||
/// Deposit one of this module's logs.
|
||||
fn deposit_log(log: Signal<T::BlockNumber>) {
|
||||
fn deposit_log(log: ConsensusLog<T::BlockNumber>) {
|
||||
let log: DigestItem<T::Hash> = DigestItem::Consensus(GRANDPA_ENGINE_ID, log.encode());
|
||||
<system::Module<T>>::deposit_log(log.into());
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
pub fn grandpa_log(digest: &DigestOf<T>) -> Option<Signal<T::BlockNumber>> {
|
||||
pub fn grandpa_log(digest: &DigestOf<T>) -> Option<ConsensusLog<T::BlockNumber>> {
|
||||
let id = OpaqueDigestItemId::Consensus(&GRANDPA_ENGINE_ID);
|
||||
digest.convert_first(|l| l.try_to::<Signal<T::BlockNumber>>(id))
|
||||
digest.convert_first(|l| l.try_to::<ConsensusLog<T::BlockNumber>>(id))
|
||||
}
|
||||
|
||||
pub fn pending_change(digest: &DigestOf<T>)
|
||||
@@ -287,8 +254,8 @@ impl<T: Trait> session::OneSessionHandler<T::AccountId> for Module<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
fn on_disabled(_i: usize) {
|
||||
// ignore?
|
||||
fn on_disabled(i: usize) {
|
||||
Self::deposit_log(ConsensusLog::OnDisabled(i as u64))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,17 +23,15 @@ use runtime_io;
|
||||
use srml_support::{impl_outer_origin, impl_outer_event};
|
||||
use substrate_primitives::{H256, Blake2Hasher};
|
||||
use parity_codec::{Encode, Decode};
|
||||
use crate::{AuthorityId, GenesisConfig, Trait, Module, Signal};
|
||||
use crate::{AuthorityId, GenesisConfig, Trait, Module, ConsensusLog};
|
||||
use substrate_finality_grandpa_primitives::GRANDPA_ENGINE_ID;
|
||||
|
||||
impl_outer_origin!{
|
||||
pub enum Origin for Test {}
|
||||
}
|
||||
|
||||
impl From<Signal<u64>> for DigestItem<H256> {
|
||||
fn from(log: Signal<u64>) -> DigestItem<H256> {
|
||||
DigestItem::Consensus(GRANDPA_ENGINE_ID, log.encode())
|
||||
}
|
||||
pub fn grandpa_log(log: ConsensusLog<u64>) -> DigestItem<H256> {
|
||||
DigestItem::Consensus(GRANDPA_ENGINE_ID, log.encode())
|
||||
}
|
||||
|
||||
// Workaround for https://github.com/rust-lang/rust/issues/26925 . Remove when sorted.
|
||||
|
||||
@@ -39,9 +39,9 @@ fn authorities_change_logged() {
|
||||
let header = System::finalize();
|
||||
assert_eq!(header.digest, Digest {
|
||||
logs: vec![
|
||||
Signal::AuthoritiesChange(
|
||||
grandpa_log(ConsensusLog::ScheduledChange(
|
||||
ScheduledChange { delay: 0, next_authorities: to_authorities(vec![(4, 1), (5, 1), (6, 1)]) }
|
||||
).into(),
|
||||
)),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -64,9 +64,9 @@ fn authorities_change_logged_after_delay() {
|
||||
let header = System::finalize();
|
||||
assert_eq!(header.digest, Digest {
|
||||
logs: vec![
|
||||
Signal::AuthoritiesChange(
|
||||
grandpa_log(ConsensusLog::ScheduledChange(
|
||||
ScheduledChange { delay: 1, next_authorities: to_authorities(vec![(4, 1), (5, 1), (6, 1)]) }
|
||||
).into(),
|
||||
)),
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user