Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
ccb5674
fix: starting switch to HistoricalVotes
seerscode May 13, 2019
1b18516
fix: migration compiles
seerscode May 13, 2019
8a5f42e
fix: add test
seerscode May 14, 2019
ee8bd02
refactor
seerscode May 14, 2019
2d12240
chore: use master finality-grandpa
seerscode May 14, 2019
74502ce
fix: bump finality grandpa
seerscode May 16, 2019
ee82bca
fix: make it compile
seerscode May 16, 2019
65898a6
fix: add Cargo.lock
seerscode May 16, 2019
1d6b75a
fix test
seerscode May 16, 2019
e7ef2d7
fix: test
seerscode May 16, 2019
1c44f35
grandpa: initial structure for catch up messages
andresilva May 20, 2019
8520269
grandpa: answer catch up requests
andresilva May 20, 2019
859ed15
grandpa: inject catch up messages into global stream
andresilva May 20, 2019
42bee80
grandpa: keep track of pending catch up request
andresilva May 21, 2019
1cc9758
grandpa: block catchup until all referenced blocks are imported
andresilva May 29, 2019
bfa1182
grandpa: unify catch up and commit streams
andresilva Jun 5, 2019
8b17873
grandpa: simplify communication stream/sink types
andresilva Jun 5, 2019
58e7fcb
grandpa: note gossip validator on catch up message import
andresilva Jun 5, 2019
c8657ec
Merge branch 'master' into andre/grandpa-catchup-messages
andresilva Jun 19, 2019
c672592
grandpa: fix cost on catch up message validation
andresilva Jun 19, 2019
ddc4173
grandpa: check signatures on catch up messages
andresilva Jun 19, 2019
519d707
grandpa: clean up catch up request handling state
andresilva Jun 20, 2019
346a38e
Merge branch 'master' into andre/grandpa-catchup-messages
andresilva Jun 20, 2019
7559fbc
grandpa: adjust costs on invalid catch up requests
andresilva Jun 20, 2019
61a2281
grandpa: release lock before pushing catch up message
andresilva Jun 20, 2019
093bfa0
grandpa: validate catch up request against peer view
andresilva Jun 20, 2019
f4a6a30
grandpa: catch up docs
andresilva Jun 20, 2019
8f1691a
grandpa: fix tests
andresilva Jun 21, 2019
fb1c19c
grandpa: until_imported: add tests for catch up messages
andresilva Jun 24, 2019
80e60f4
grandpa: add tests for catch up message gossip validation
andresilva Jun 24, 2019
135e245
grandpa: integrate HistoricalVotes changes
andresilva Jun 24, 2019
55e0b5c
grandpa: add test for neighbor packet triggering catch up
andresilva Jun 24, 2019
f14b991
grandpa: add test for full voter catch up
andresilva Jun 24, 2019
a91582a
Merge branch 'master' into andre/grandpa-catchup-messages
andresilva Jun 26, 2019
1b584be
grandpa: depend on finality-grandpa 0.8 from crates
andresilva Jun 27, 2019
8056f46
granda: use finality-grandpa test helpers
andresilva Jul 1, 2019
41fb86f
grandpa: add PSM cost for answering catch up requests
andresilva Jul 1, 2019
4bf6dab
grandpa: code style fixes
andresilva Jul 1, 2019
ff83f49
grandpa: more trailing commas
andresilva Jul 1, 2019
e36eeed
grandpa: lower cost of invalid catch up requests near set change
andresilva Jul 1, 2019
72afe9b
grandpa: process catch up sending on import of neighbor message
andresilva Jul 1, 2019
57184eb
grandpa: add comments on HistoricalVotes
andresilva Jul 1, 2019
1bddbbd
Merge master
seerscode Jul 4, 2019
403c598
Merge master
seerscode Jul 4, 2019
bdb4b4a
Fix some compilation errors
seerscode Jul 5, 2019
8e55dcd
Add test
seerscode Jul 5, 2019
974346f
merge master
seerscode Jul 5, 2019
3ad8276
Remove unused file
seerscode Jul 5, 2019
8546d36
Fix aux_schema
seerscode Jul 6, 2019
5f96c4e
Merge master
seerscode Jul 10, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 73 additions & 73 deletions Cargo.lock

Large diffs are not rendered by default.

420 changes: 362 additions & 58 deletions core/finality-grandpa/src/aux_schema.rs

Large diffs are not rendered by default.

26 changes: 15 additions & 11 deletions core/finality-grandpa/src/communication/gossip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,7 @@ impl<Block: BlockT> Inner<Block> {
// code below assumes this invariant is maintained when creating the
// catch up reply since peers won't accept catch-up messages that have
// too many equivocations (we exceed the fault-tolerance bound).
for vote in last_completed_round.votes {
for vote in last_completed_round.historical_votes.seen().clone() {
match vote.message {
grandpa::Message::Prevote(prevote) => {
prevotes.push(grandpa::SignedPrevote {
Expand Down Expand Up @@ -1231,6 +1231,7 @@ impl<B: BlockT, N: super::Network<B>> Future for ReportingTask<B, N> {
mod tests {
use super::*;
use super::environment::SharedVoterSetState;
use crate::HistoricalVotes;
use network_gossip::Validator as GossipValidatorT;
use network::test::Block;

Expand All @@ -1246,24 +1247,27 @@ mod tests {

// dummy voter set state
fn voter_set_state() -> SharedVoterSetState<Block> {
use crate::authorities::AuthoritySet;
use crate::environment::{CompletedRound, CompletedRounds, HasVoted, VoterSetState};
use grandpa::round::State as RoundState;
use substrate_primitives::H256;

let state = RoundState::genesis((H256::zero(), 0));
let base = state.prevote_ghost.unwrap();
let voters = AuthoritySet::genesis(Vec::new());
let voters = Vec::new();
let completed_round = CompletedRound {
state,
number: 0,
base,
historical_votes: HistoricalVotes::<Block>::new(),
};
let mut rounds = VecDeque::new();
rounds.push_back(completed_round);

let set_state = VoterSetState::Live {
completed_rounds: CompletedRounds::new(
CompletedRound {
state,
number: 0,
votes: Vec::new(),
base,
},
rounds,
0,
&voters,
voters,
),
current_round: HasVoted::No,
};
Expand Down Expand Up @@ -1545,7 +1549,7 @@ mod tests {
number: 1,
state: grandpa::round::State::genesis(Default::default()),
base: Default::default(),
votes: Default::default(),
historical_votes: HistoricalVotes::<Block>::new(),
}));

let set_state = environment::VoterSetState::<Block>::Live {
Expand Down
4 changes: 2 additions & 2 deletions core/finality-grandpa/src/communication/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ impl<B: BlockT, N: Network<B>> NetworkBridge<B, N> {
// messages will be ignored.
validator.note_round(Round(round.number), |_, _| {});

for signed in round.votes.iter() {
for signed in round.historical_votes.seen().iter() {
let message = gossip::GossipMessage::VoteOrPrecommit(
gossip::VoteOrPrecommitMessage::<B> {
message: signed.clone(),
Expand All @@ -282,7 +282,7 @@ impl<B: BlockT, N: Network<B>> NetworkBridge<B, N> {

trace!(target: "afg",
"Registered {} messages for topic {:?} (round: {}, set_id: {})",
round.votes.len(),
round.historical_votes.seen().len(),
topic,
round.number,
set_id,
Expand Down
22 changes: 13 additions & 9 deletions core/finality-grandpa/src/communication/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ use network::test::{Block, Hash};
use network_gossip::Validator;
use tokio::runtime::current_thread;
use std::sync::Arc;
use std::collections::VecDeque;
use keyring::AuthorityKeyring;
use parity_codec::Encode;

use crate::environment::SharedVoterSetState;
use crate::HistoricalVotes;
use super::gossip::{self, GossipValidator};
use super::{AuthorityId, VoterSet, Round, SetId};

Expand Down Expand Up @@ -140,24 +142,26 @@ fn config() -> crate::Config {

// dummy voter set state
fn voter_set_state() -> SharedVoterSetState<Block> {
use crate::authorities::AuthoritySet;
use crate::environment::{CompletedRound, CompletedRounds, HasVoted, VoterSetState};
use grandpa::round::State as RoundState;
use substrate_primitives::H256;

let state = RoundState::genesis((H256::zero(), 0));
let base = state.prevote_ghost.unwrap();
let voters = AuthoritySet::genesis(Vec::new());
let voters = Vec::new();
let completed_round = CompletedRound {
state,
number: 0,
base,
historical_votes: HistoricalVotes::<Block>::new(),
};
let mut rounds = VecDeque::new();
rounds.push_back(completed_round);
let set_state = VoterSetState::Live {
completed_rounds: CompletedRounds::new(
CompletedRound {
state,
number: 0,
votes: Vec::new(),
base,
},
rounds,
0,
&voters,
voters,
),
current_round: HasVoted::No,
};
Expand Down
20 changes: 7 additions & 13 deletions core/finality-grandpa/src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ use substrate_telemetry::{telemetry, CONSENSUS_INFO};

use crate::{
CommandOrError, Commit, Config, Error, Network, Precommit, Prevote,
PrimaryPropose, SignedMessage, NewAuthoritySet, VoterCommand,
PrimaryPropose, NewAuthoritySet, VoterCommand,
};

use consensus_common::SelectChain;

use crate::authorities::{AuthoritySet, SharedAuthoritySet};
use crate::authorities::SharedAuthoritySet;
use crate::consensus_changes::SharedConsensusChanges;
use crate::justification::GrandpaJustification;
use crate::until_imported::UntilVoteTargetImported;
Expand All @@ -70,7 +70,7 @@ pub struct CompletedRound<Block: BlockT> {
/// The target block base used for voting in the round.
pub base: (Block::Hash, NumberFor<Block>),
/// All the votes observed in the round.
pub votes: Vec<SignedMessage<Block>>,
pub historical_votes: HistoricalVotes<Block>,
}

// Data about last completed rounds within a single voter set. Stores NUM_LAST_COMPLETED_ROUNDS and always
Expand All @@ -82,6 +82,7 @@ pub struct CompletedRounds<Block: BlockT> {
voters: Vec<AuthorityId>,
}


// NOTE: the current strategy for persisting completed rounds is very naive
// (update everything) and we also rely on cloning to do atomic updates,
// therefore this value should be kept small for now.
Expand All @@ -108,16 +109,12 @@ impl<Block: BlockT> Decode for CompletedRounds<Block> {
impl<Block: BlockT> CompletedRounds<Block> {
/// Create a new completed rounds tracker with NUM_LAST_COMPLETED_ROUNDS capacity.
pub(crate) fn new(
genesis: CompletedRound<Block>,
rounds: VecDeque<CompletedRound<Block>>,
set_id: u64,
voters: &AuthoritySet<Block::Hash, NumberFor<Block>>,
voters: Vec<AuthorityId>,
)
-> CompletedRounds<Block>
{
let mut rounds = VecDeque::with_capacity(NUM_LAST_COMPLETED_ROUNDS);
rounds.push_back(genesis);

let voters = voters.current().1.iter().map(|(a, _)| a.clone()).collect();
CompletedRounds { rounds, set_id, voters }
}

Expand Down Expand Up @@ -668,15 +665,12 @@ where
self.update_voter_set_state(|voter_set_state| {
let mut completed_rounds = voter_set_state.completed_rounds();

// TODO: Future integration will store the prevote and precommit index. See #2611.
let votes = historical_votes.seen().clone();

// NOTE: the Environment assumes that rounds are *always* completed in-order.
if !completed_rounds.push(CompletedRound {
number: round,
state: state.clone(),
base,
votes,
historical_votes: historical_votes.clone(),
}) {
let msg = "Voter completed round that is older than the last completed round.";
return Err(Error::Safety(msg.to_string()));
Expand Down
48 changes: 37 additions & 11 deletions core/finality-grandpa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ use grandpa::{voter, round::State as RoundState, BlockNumberOps, voter_set::Vote
use std::fmt;
use std::sync::Arc;
use std::time::Duration;
use std::collections::VecDeque;

mod authorities;
mod aux_schema;
Expand Down Expand Up @@ -115,6 +116,7 @@ mod tests;

/// A GRANDPA message for a substrate chain.
pub type Message<Block> = grandpa::Message<<Block as BlockT>::Hash, NumberFor<Block>>;

/// A signed message.
pub type SignedMessage<Block> = grandpa::SignedMessage<
<Block as BlockT>::Hash,
Expand All @@ -123,33 +125,47 @@ pub type SignedMessage<Block> = grandpa::SignedMessage<
AuthorityId,
>;

/// An ordered set of historical votes.
pub type HistoricalVotes<Block> = grandpa::HistoricalVotes<
<Block as BlockT>::Hash,
NumberFor<Block>,
AuthoritySignature,
AuthorityId,
>;

/// A primary propose message for this chain's block type.
pub type PrimaryPropose<Block> = grandpa::PrimaryPropose<<Block as BlockT>::Hash, NumberFor<Block>>;

/// A prevote message for this chain's block type.
pub type Prevote<Block> = grandpa::Prevote<<Block as BlockT>::Hash, NumberFor<Block>>;

/// A precommit message for this chain's block type.
pub type Precommit<Block> = grandpa::Precommit<<Block as BlockT>::Hash, NumberFor<Block>>;

/// A catch up message for this chain's block type.
pub type CatchUp<Block> = grandpa::CatchUp<
<Block as BlockT>::Hash,
NumberFor<Block>,
AuthoritySignature,
AuthorityId,
>;

/// A commit message for this chain's block type.
pub type Commit<Block> = grandpa::Commit<
<Block as BlockT>::Hash,
NumberFor<Block>,
AuthoritySignature,
AuthorityId,
>;

/// A compact commit message for this chain's block type.
pub type CompactCommit<Block> = grandpa::CompactCommit<
<Block as BlockT>::Hash,
NumberFor<Block>,
AuthoritySignature,
AuthorityId,
>;

/// A global communication input stream for commits and catch up messages. Not
/// exposed publicly, used internally to simplify types in the communication
/// layer.
Expand Down Expand Up @@ -663,19 +679,29 @@ pub fn run_grandpa_voter<B, E, Block: BlockT<Hash=H256>, N, RA, SC, X>(
// start the new authority set using the block where the
// set changed (not where the signal happened!) as the base.
let genesis_state = RoundState::genesis((new.canon_hash, new.canon_number));

// always start at round 0 when changing sets.
let completed_round = CompletedRound {
number: 0,
state: genesis_state,
base: (new.canon_hash, new.canon_number),
historical_votes: HistoricalVotes::<Block>::new(),
};

let mut rounds = VecDeque::new();
rounds.push_back(completed_round);

let voters = authority_set.inner().read()
.current().1.iter().map(|(a, _)| a.clone()).collect();

let completed_rounds = CompletedRounds::new(
rounds,
new.set_id,
voters,
);

let set_state = VoterSetState::Live {
// always start at round 0 when changing sets.
completed_rounds: CompletedRounds::new(
CompletedRound {
number: 0,
state: genesis_state,
base: (new.canon_hash, new.canon_number),
votes: Vec::new(),
},
new.set_id,
&*authority_set.inner().read(),
),
completed_rounds,
current_round: HasVoted::No,
};

Expand Down
33 changes: 21 additions & 12 deletions core/finality-grandpa/src/observer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
// along with Substrate. If not, see <http://www.gnu.org/licenses/>.

use std::sync::Arc;
use std::collections::VecDeque;

use futures::prelude::*;
use futures::future::{self, Loop as FutureLoop};

use grandpa::{
BlockNumberOps, Error as GrandpaError, round::State as RoundState, voter, voter_set::VoterSet
BlockNumberOps, Error as GrandpaError, round::State as RoundState, voter, voter_set::VoterSet,
HistoricalVotes,
};
use log::{debug, info, warn};

Expand Down Expand Up @@ -239,19 +241,26 @@ pub fn run_grandpa_observer<B, E, Block: BlockT<Hash=H256>, N, RA, SC>(
// start the new authority set using the block where the
// set changed (not where the signal happened!) as the base.
let genesis_state = RoundState::genesis((new.canon_hash, new.canon_number));

let completed_round = CompletedRound {
number: 0,
state: genesis_state,
base: (new.canon_hash, new.canon_number),
historical_votes: HistoricalVotes::new(),
};
let mut rounds = VecDeque::new();
rounds.push_back(completed_round);
let voters_set = &*authority_set.inner().read();
let voters = voters_set
.current().1.iter().map(|(a, _)| a.clone()).collect();

let completed_rounds = CompletedRounds::new(
rounds,
new.set_id,
voters,
);
let set_state = VoterSetState::Live::<Block> {
// always start at round 0 when changing sets.
completed_rounds: CompletedRounds::new(
CompletedRound {
number: 0,
state: genesis_state,
base: (new.canon_hash, new.canon_number),
votes: Vec::new(),
},
new.set_id,
&*authority_set.inner().read(),
),
completed_rounds,
current_round: HasVoted::No,
};

Expand Down