mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 16:51:03 +00:00
GRANDPA links set IDs to sessions. (#3472)
* introduce some type aliases for round and set-id * overhaul session "changed" flag and document better * do_initialize in BABE when getting new session * grandpa module tracks set IDs * update runtime versions * doc comment -> comment * Include docs fixes from Gav Co-Authored-By: Gavin Wood <gavin@parity.io> * some more review changes * fix srml-grandpa compilation
This commit is contained in:
committed by
Gavin Wood
parent
bdd6bba20a
commit
b50596428e
@@ -52,6 +52,12 @@ pub type AuthorityWeight = u64;
|
||||
/// The index of an authority.
|
||||
pub type AuthorityIndex = u64;
|
||||
|
||||
/// The identifier of a GRANDPA set.
|
||||
pub type SetId = u64;
|
||||
|
||||
/// The round indicator.
|
||||
pub type RoundNumber = u64;
|
||||
|
||||
/// A scheduled change of authority set.
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
|
||||
#[derive(Clone, Eq, PartialEq, Encode, Decode)]
|
||||
|
||||
@@ -26,7 +26,7 @@ use grandpa::round::State as RoundState;
|
||||
use sr_primitives::traits::{Block as BlockT, NumberFor};
|
||||
use log::{info, warn};
|
||||
use substrate_telemetry::{telemetry, CONSENSUS_INFO};
|
||||
use fg_primitives::AuthorityId;
|
||||
use fg_primitives::{AuthorityId, AuthorityWeight, SetId, RoundNumber};
|
||||
|
||||
use crate::authorities::{AuthoritySet, SharedAuthoritySet, PendingChange, DelayKind};
|
||||
use crate::consensus_changes::{SharedConsensusChanges, ConsensusChanges};
|
||||
@@ -47,16 +47,16 @@ const CURRENT_VERSION: u32 = 2;
|
||||
#[cfg_attr(test, derive(PartialEq))]
|
||||
pub enum V1VoterSetState<H, N> {
|
||||
/// The voter set state, currently paused.
|
||||
Paused(u64, RoundState<H, N>),
|
||||
Paused(RoundNumber, RoundState<H, N>),
|
||||
/// The voter set state, currently live.
|
||||
Live(u64, RoundState<H, N>),
|
||||
Live(RoundNumber, RoundState<H, N>),
|
||||
}
|
||||
|
||||
type V0VoterSetState<H, N> = (u64, RoundState<H, N>);
|
||||
type V0VoterSetState<H, N> = (RoundNumber, RoundState<H, N>);
|
||||
|
||||
#[derive(Debug, Clone, Encode, Decode, PartialEq)]
|
||||
struct V0PendingChange<H, N> {
|
||||
next_authorities: Vec<(AuthorityId, u64)>,
|
||||
next_authorities: Vec<(AuthorityId, AuthorityWeight)>,
|
||||
delay: N,
|
||||
canon_height: N,
|
||||
canon_hash: H,
|
||||
@@ -64,8 +64,8 @@ struct V0PendingChange<H, N> {
|
||||
|
||||
#[derive(Debug, Clone, Encode, Decode, PartialEq)]
|
||||
struct V0AuthoritySet<H, N> {
|
||||
current_authorities: Vec<(AuthorityId, u64)>,
|
||||
set_id: u64,
|
||||
current_authorities: Vec<(AuthorityId, AuthorityWeight)>,
|
||||
set_id: SetId,
|
||||
pending_changes: Vec<V0PendingChange<H, N>>,
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ pub(crate) fn load_persistent<Block: BlockT, B, G>(
|
||||
-> ClientResult<PersistentData<Block>>
|
||||
where
|
||||
B: AuxStore,
|
||||
G: FnOnce() -> ClientResult<Vec<(AuthorityId, u64)>>,
|
||||
G: FnOnce() -> ClientResult<Vec<(AuthorityId, AuthorityWeight)>>,
|
||||
{
|
||||
let version: Option<u32> = load_decode(backend, VERSION_KEY)?;
|
||||
let consensus_changes = load_decode(backend, CONSENSUS_CHANGES_KEY)?
|
||||
@@ -448,7 +448,7 @@ mod test {
|
||||
|
||||
let authorities = vec![(AuthorityId::default(), 100)];
|
||||
let set_id = 3;
|
||||
let round_number: u64 = 42;
|
||||
let round_number: RoundNumber = 42;
|
||||
let round_state = RoundState::<H256, u64> {
|
||||
prevote_ghost: Some((H256::random(), 32)),
|
||||
finalized: None,
|
||||
@@ -536,7 +536,7 @@ mod test {
|
||||
|
||||
let authorities = vec![(AuthorityId::default(), 100)];
|
||||
let set_id = 3;
|
||||
let round_number: u64 = 42;
|
||||
let round_number: RoundNumber = 42;
|
||||
let round_state = RoundState::<H256, u64> {
|
||||
prevote_ghost: Some((H256::random(), 32)),
|
||||
finalized: None,
|
||||
|
||||
@@ -50,7 +50,9 @@ use crate::environment::HasVoted;
|
||||
use gossip::{
|
||||
GossipMessage, FullCatchUpMessage, FullCommitMessage, VoteOrPrecommitMessage, GossipValidator
|
||||
};
|
||||
use fg_primitives::{AuthorityPair, AuthorityId, AuthoritySignature};
|
||||
use fg_primitives::{
|
||||
AuthorityPair, AuthorityId, AuthoritySignature, SetId as SetIdNumber, RoundNumber,
|
||||
};
|
||||
|
||||
pub mod gossip;
|
||||
mod periodic;
|
||||
@@ -129,12 +131,12 @@ pub trait Network<Block: BlockT>: Clone + Send + 'static {
|
||||
}
|
||||
|
||||
/// Create a unique topic for a round and set-id combo.
|
||||
pub(crate) fn round_topic<B: BlockT>(round: u64, set_id: u64) -> B::Hash {
|
||||
pub(crate) fn round_topic<B: BlockT>(round: RoundNumber, set_id: SetIdNumber) -> B::Hash {
|
||||
<<B::Header as HeaderT>::Hashing as HashT>::hash(format!("{}-{}", set_id, round).as_bytes())
|
||||
}
|
||||
|
||||
/// Create a unique topic for global messages on a set ID.
|
||||
pub(crate) fn global_topic<B: BlockT>(set_id: u64) -> B::Hash {
|
||||
pub(crate) fn global_topic<B: BlockT>(set_id: SetIdNumber) -> B::Hash {
|
||||
<<B::Header as HeaderT>::Hashing as HashT>::hash(format!("{}-GLOBAL", set_id).as_bytes())
|
||||
}
|
||||
|
||||
@@ -618,25 +620,25 @@ impl<B: BlockT, N: Network<B>> Clone for NetworkBridge<B, N> {
|
||||
}
|
||||
}
|
||||
|
||||
fn localized_payload<E: Encode>(round: u64, set_id: u64, message: &E) -> Vec<u8> {
|
||||
fn localized_payload<E: Encode>(round: RoundNumber, set_id: SetIdNumber, message: &E) -> Vec<u8> {
|
||||
(message, round, set_id).encode()
|
||||
}
|
||||
|
||||
/// Type-safe wrapper around u64 when indicating that it's a round number.
|
||||
/// Type-safe wrapper around a round number.
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Encode, Decode)]
|
||||
pub struct Round(pub u64);
|
||||
pub struct Round(pub RoundNumber);
|
||||
|
||||
/// Type-safe wrapper around u64 when indicating that it's a set ID.
|
||||
/// Type-safe wrapper around a set ID.
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Encode, Decode)]
|
||||
pub struct SetId(pub u64);
|
||||
pub struct SetId(pub SetIdNumber);
|
||||
|
||||
// check a message.
|
||||
pub(crate) fn check_message_sig<Block: BlockT>(
|
||||
message: &Message<Block>,
|
||||
id: &AuthorityId,
|
||||
signature: &AuthoritySignature,
|
||||
round: u64,
|
||||
set_id: u64,
|
||||
round: RoundNumber,
|
||||
set_id: SetIdNumber,
|
||||
) -> Result<(), ()> {
|
||||
let as_public = id.clone();
|
||||
let encoded_raw = localized_payload(round, set_id, message);
|
||||
@@ -656,8 +658,8 @@ pub(crate) fn check_message_sig<Block: BlockT>(
|
||||
/// `ed25519` and `BLS` signatures (which we might use in the future), care must
|
||||
/// be taken when switching to different key types.
|
||||
struct OutgoingMessages<Block: BlockT, N: Network<Block>> {
|
||||
round: u64,
|
||||
set_id: u64,
|
||||
round: RoundNumber,
|
||||
set_id: SetIdNumber,
|
||||
locals: Option<(AuthorityPair, AuthorityId)>,
|
||||
sender: mpsc::UnboundedSender<SignedMessage<Block>>,
|
||||
network: N,
|
||||
@@ -851,8 +853,8 @@ fn check_catch_up<Block: BlockT>(
|
||||
|
||||
fn check_signatures<'a, B, I>(
|
||||
messages: I,
|
||||
round: u64,
|
||||
set_id: u64,
|
||||
round: RoundNumber,
|
||||
set_id: SetIdNumber,
|
||||
mut signatures_checked: usize,
|
||||
) -> Result<usize, i32> where
|
||||
B: BlockT,
|
||||
@@ -919,7 +921,7 @@ impl<Block: BlockT, N: Network<Block>> CommitsOut<Block, N> {
|
||||
/// Create a new commit output stream.
|
||||
pub(crate) fn new(
|
||||
network: N,
|
||||
set_id: u64,
|
||||
set_id: SetIdNumber,
|
||||
is_voter: bool,
|
||||
gossip_validator: Arc<GossipValidator<Block>>,
|
||||
) -> Self {
|
||||
@@ -933,10 +935,10 @@ impl<Block: BlockT, N: Network<Block>> CommitsOut<Block, N> {
|
||||
}
|
||||
|
||||
impl<Block: BlockT, N: Network<Block>> Sink for CommitsOut<Block, N> {
|
||||
type SinkItem = (u64, Commit<Block>);
|
||||
type SinkItem = (RoundNumber, Commit<Block>);
|
||||
type SinkError = Error;
|
||||
|
||||
fn start_send(&mut self, input: (u64, Commit<Block>)) -> StartSend<Self::SinkItem, Error> {
|
||||
fn start_send(&mut self, input: (RoundNumber, Commit<Block>)) -> StartSend<Self::SinkItem, Error> {
|
||||
if !self.is_voter {
|
||||
return Ok(AsyncSink::Ready);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ use crate::authorities::{AuthoritySet, SharedAuthoritySet};
|
||||
use crate::consensus_changes::SharedConsensusChanges;
|
||||
use crate::justification::GrandpaJustification;
|
||||
use crate::until_imported::UntilVoteTargetImported;
|
||||
use fg_primitives::{AuthorityId, AuthoritySignature};
|
||||
use fg_primitives::{AuthorityId, AuthoritySignature, SetId, RoundNumber};
|
||||
|
||||
type HistoricalVotes<Block> = grandpa::HistoricalVotes<
|
||||
<Block as BlockT>::Hash,
|
||||
@@ -65,7 +65,7 @@ type HistoricalVotes<Block> = grandpa::HistoricalVotes<
|
||||
#[derive(Debug, Clone, Decode, Encode, PartialEq)]
|
||||
pub struct CompletedRound<Block: BlockT> {
|
||||
/// The round number.
|
||||
pub number: u64,
|
||||
pub number: RoundNumber,
|
||||
/// The round state (prevote ghost, estimate, finalized, etc.)
|
||||
pub state: RoundState<Block::Hash, NumberFor<Block>>,
|
||||
/// The target block base used for voting in the round.
|
||||
@@ -80,7 +80,7 @@ pub struct CompletedRound<Block: BlockT> {
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct CompletedRounds<Block: BlockT> {
|
||||
rounds: Vec<CompletedRound<Block>>,
|
||||
set_id: u64,
|
||||
set_id: SetId,
|
||||
voters: Vec<AuthorityId>,
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ impl<Block: BlockT> codec::EncodeLike for CompletedRounds<Block> {}
|
||||
|
||||
impl<Block: BlockT> Decode for CompletedRounds<Block> {
|
||||
fn decode<I: codec::Input>(value: &mut I) -> Result<Self, codec::Error> {
|
||||
<(Vec<CompletedRound<Block>>, u64, Vec<AuthorityId>)>::decode(value)
|
||||
<(Vec<CompletedRound<Block>>, SetId, Vec<AuthorityId>)>::decode(value)
|
||||
.map(|(rounds, set_id, voters)| CompletedRounds {
|
||||
rounds: rounds.into(),
|
||||
set_id,
|
||||
@@ -113,7 +113,7 @@ impl<Block: BlockT> CompletedRounds<Block> {
|
||||
/// Create a new completed rounds tracker with NUM_LAST_COMPLETED_ROUNDS capacity.
|
||||
pub(crate) fn new(
|
||||
genesis: CompletedRound<Block>,
|
||||
set_id: u64,
|
||||
set_id: SetId,
|
||||
voters: &AuthoritySet<Block::Hash, NumberFor<Block>>,
|
||||
)
|
||||
-> CompletedRounds<Block>
|
||||
@@ -126,7 +126,7 @@ impl<Block: BlockT> CompletedRounds<Block> {
|
||||
}
|
||||
|
||||
/// Get the set-id and voter set of the completed rounds.
|
||||
pub fn set_info(&self) -> (u64, &[AuthorityId]) {
|
||||
pub fn set_info(&self) -> (SetId, &[AuthorityId]) {
|
||||
(self.set_id, &self.voters[..])
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ impl<Block: BlockT> CompletedRounds<Block> {
|
||||
|
||||
/// A map with voter status information for currently live rounds,
|
||||
/// which votes have we cast and what are they.
|
||||
pub type CurrentRounds<Block> = BTreeMap<u64, HasVoted<Block>>;
|
||||
pub type CurrentRounds<Block> = BTreeMap<RoundNumber, HasVoted<Block>>;
|
||||
|
||||
/// The state of the current voter set, whether it is currently active or not
|
||||
/// and information related to the previously completed rounds. Current round
|
||||
@@ -190,7 +190,7 @@ impl<Block: BlockT> VoterSetState<Block> {
|
||||
/// the given genesis state and the given authorities. Round 1 is added as a
|
||||
/// current round (with state `HasVoted::No`).
|
||||
pub(crate) fn live(
|
||||
set_id: u64,
|
||||
set_id: SetId,
|
||||
authority_set: &AuthoritySet<Block::Hash, NumberFor<Block>>,
|
||||
genesis_state: (Block::Hash, NumberFor<Block>),
|
||||
) -> VoterSetState<Block> {
|
||||
@@ -237,7 +237,7 @@ impl<Block: BlockT> VoterSetState<Block> {
|
||||
|
||||
/// Returns the voter set state validating that it includes the given round
|
||||
/// in current rounds and that the voter isn't paused.
|
||||
pub fn with_current_round(&self, round: u64)
|
||||
pub fn with_current_round(&self, round: RoundNumber)
|
||||
-> Result<(&CompletedRounds<Block>, &CurrentRounds<Block>), Error>
|
||||
{
|
||||
if let VoterSetState::Live { completed_rounds, current_rounds } = self {
|
||||
@@ -344,7 +344,7 @@ impl<Block: BlockT> SharedVoterSetState<Block> {
|
||||
}
|
||||
|
||||
/// Return vote status information for the current round.
|
||||
pub(crate) fn has_voted(&self, round: u64) -> HasVoted<Block> {
|
||||
pub(crate) fn has_voted(&self, round: RoundNumber) -> HasVoted<Block> {
|
||||
match &*self.inner.read() {
|
||||
VoterSetState::Live { current_rounds, .. } => {
|
||||
current_rounds.get(&round).and_then(|has_voted| match has_voted {
|
||||
@@ -375,7 +375,7 @@ pub(crate) struct Environment<B, E, Block: BlockT, N: Network<Block>, RA, SC> {
|
||||
pub(crate) authority_set: SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
|
||||
pub(crate) consensus_changes: SharedConsensusChanges<Block::Hash, NumberFor<Block>>,
|
||||
pub(crate) network: crate::communication::NetworkBridge<Block, N>,
|
||||
pub(crate) set_id: u64,
|
||||
pub(crate) set_id: SetId,
|
||||
pub(crate) voter_set_state: SharedVoterSetState<Block>,
|
||||
}
|
||||
|
||||
@@ -554,7 +554,7 @@ where
|
||||
|
||||
fn round_data(
|
||||
&self,
|
||||
round: u64
|
||||
round: RoundNumber,
|
||||
) -> voter::RoundData<Self::Id, Self::Timer, Self::In, Self::Out> {
|
||||
let now = Instant::now();
|
||||
let prevote_timer = Delay::new(now + self.config.gossip_duration * 2);
|
||||
@@ -601,7 +601,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn proposed(&self, round: u64, propose: PrimaryPropose<Block>) -> Result<(), Self::Error> {
|
||||
fn proposed(&self, round: RoundNumber, propose: PrimaryPropose<Block>) -> Result<(), Self::Error> {
|
||||
let local_id = crate::is_voter(&self.voters, &self.config.keystore);
|
||||
|
||||
let local_id = match local_id {
|
||||
@@ -641,7 +641,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn prevoted(&self, round: u64, prevote: Prevote<Block>) -> Result<(), Self::Error> {
|
||||
fn prevoted(&self, round: RoundNumber, prevote: Prevote<Block>) -> Result<(), Self::Error> {
|
||||
let local_id = crate::is_voter(&self.voters, &self.config.keystore);
|
||||
|
||||
let local_id = match local_id {
|
||||
@@ -683,7 +683,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn precommitted(&self, round: u64, precommit: Precommit<Block>) -> Result<(), Self::Error> {
|
||||
fn precommitted(&self, round: RoundNumber, precommit: Precommit<Block>) -> Result<(), Self::Error> {
|
||||
let local_id = crate::is_voter(&self.voters, &self.config.keystore);
|
||||
|
||||
let local_id = match local_id {
|
||||
@@ -737,7 +737,7 @@ where
|
||||
|
||||
fn completed(
|
||||
&self,
|
||||
round: u64,
|
||||
round: RoundNumber,
|
||||
state: RoundState<Block::Hash, NumberFor<Block>>,
|
||||
base: (Block::Hash, NumberFor<Block>),
|
||||
historical_votes: &HistoricalVotes<Block>,
|
||||
@@ -794,7 +794,13 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn finalize_block(&self, hash: Block::Hash, number: NumberFor<Block>, round: u64, commit: Commit<Block>) -> Result<(), Self::Error> {
|
||||
fn finalize_block(
|
||||
&self,
|
||||
hash: Block::Hash,
|
||||
number: NumberFor<Block>,
|
||||
round: RoundNumber,
|
||||
commit: Commit<Block>,
|
||||
) -> Result<(), Self::Error> {
|
||||
finalize_block(
|
||||
&*self.inner,
|
||||
&self.authority_set,
|
||||
@@ -818,7 +824,7 @@ where
|
||||
|
||||
fn prevote_equivocation(
|
||||
&self,
|
||||
_round: u64,
|
||||
_round: RoundNumber,
|
||||
equivocation: ::grandpa::Equivocation<Self::Id, Prevote<Block>, Self::Signature>
|
||||
) {
|
||||
warn!(target: "afg", "Detected prevote equivocation in the finality worker: {:?}", equivocation);
|
||||
@@ -827,7 +833,7 @@ where
|
||||
|
||||
fn precommit_equivocation(
|
||||
&self,
|
||||
_round: u64,
|
||||
_round: RoundNumber,
|
||||
equivocation: Equivocation<Self::Id, Precommit<Block>, Self::Signature>
|
||||
) {
|
||||
warn!(target: "afg", "Detected precommit equivocation in the finality worker: {:?}", equivocation);
|
||||
@@ -837,11 +843,11 @@ where
|
||||
|
||||
pub(crate) enum JustificationOrCommit<Block: BlockT> {
|
||||
Justification(GrandpaJustification<Block>),
|
||||
Commit((u64, Commit<Block>)),
|
||||
Commit((RoundNumber, Commit<Block>)),
|
||||
}
|
||||
|
||||
impl<Block: BlockT> From<(u64, Commit<Block>)> for JustificationOrCommit<Block> {
|
||||
fn from(commit: (u64, Commit<Block>)) -> JustificationOrCommit<Block> {
|
||||
impl<Block: BlockT> From<(RoundNumber, Commit<Block>)> for JustificationOrCommit<Block> {
|
||||
fn from(commit: (RoundNumber, Commit<Block>)) -> JustificationOrCommit<Block> {
|
||||
JustificationOrCommit::Commit(commit)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ use import::GrandpaBlockImport;
|
||||
use until_imported::UntilGlobalMessageBlocksImported;
|
||||
use communication::NetworkBridge;
|
||||
use service::TelemetryOnConnect;
|
||||
use fg_primitives::AuthoritySignature;
|
||||
use fg_primitives::{AuthoritySignature, SetId, AuthorityWeight};
|
||||
|
||||
// Re-export these two because it's just so damn convenient.
|
||||
pub use fg_primitives::{AuthorityId, ScheduledChange};
|
||||
@@ -267,8 +267,8 @@ impl<B, E, Block: BlockT<Hash=H256>, RA> BlockStatus<Block> for Arc<Client<B, E,
|
||||
pub(crate) struct NewAuthoritySet<H, N> {
|
||||
pub(crate) canon_number: N,
|
||||
pub(crate) canon_hash: H,
|
||||
pub(crate) set_id: u64,
|
||||
pub(crate) authorities: Vec<(AuthorityId, u64)>,
|
||||
pub(crate) set_id: SetId,
|
||||
pub(crate) authorities: Vec<(AuthorityId, AuthorityWeight)>,
|
||||
}
|
||||
|
||||
/// Commands issued to the voter.
|
||||
@@ -399,7 +399,7 @@ where
|
||||
}
|
||||
|
||||
fn global_communication<Block: BlockT<Hash=H256>, B, E, N, RA>(
|
||||
set_id: u64,
|
||||
set_id: SetId,
|
||||
voters: &Arc<VoterSet<AuthorityId>>,
|
||||
client: &Arc<Client<B, E, Block, RA>>,
|
||||
network: &NetworkBridge<Block, N>,
|
||||
|
||||
@@ -36,7 +36,7 @@ use sr_primitives::Justification;
|
||||
use sr_primitives::traits::{
|
||||
NumberFor, Block as BlockT, Header as HeaderT, ProvideRuntimeApi, DigestFor,
|
||||
};
|
||||
use fg_primitives::{GrandpaApi, AuthorityId};
|
||||
use fg_primitives::{self, GrandpaApi, AuthorityId};
|
||||
use sr_primitives::generic::BlockId;
|
||||
use primitives::{H256, Blake2Hasher};
|
||||
|
||||
@@ -192,7 +192,7 @@ impl LightAuthoritySet {
|
||||
/// Get a genesis set with given authorities.
|
||||
pub fn genesis(initial: Vec<(AuthorityId, u64)>) -> Self {
|
||||
LightAuthoritySet {
|
||||
set_id: 0,
|
||||
set_id: fg_primitives::SetId::default(),
|
||||
authorities: initial,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user