Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
8f9808a
skeleton for finality tracker
rphmeier Jan 28, 2019
4e28e99
dispatch events when nothing finalized for a long time
rphmeier Jan 28, 2019
37af080
begin integrating finality tracker into grandpa
rphmeier Jan 29, 2019
1185041
add delay field to pending change
rphmeier Jan 29, 2019
1a48669
add has_api_with function to sr_version for querying APIs
rphmeier Jan 29, 2019
f84de0e
partially integrate new force changes into grandpa
rphmeier Jan 29, 2019
5b53bea
implement forced changes
rphmeier Jan 30, 2019
db20c36
get srml-grandpa compiling
rphmeier Jan 30, 2019
9df9464
Update core/finality-grandpa/src/authorities.rs
bkchr Jan 30, 2019
cc5d70b
Update core/finality-grandpa/src/authorities.rs
bkchr Jan 30, 2019
3e78042
Update core/finality-grandpa/src/authorities.rs
bkchr Jan 30, 2019
68c94bf
remove explicit dependence on CoreApi
rphmeier Jan 30, 2019
1fbb26c
increase node runtime version
rphmeier Jan 30, 2019
ecc489b
integrate grandpa forced changes into node runtime
rphmeier Jan 30, 2019
a75d5fd
add some tests to finality-tracker
rphmeier Jan 30, 2019
b9246b0
integrate finality tracking into node-runtime
rphmeier Jan 30, 2019
36dfdf7
Merge branch 'master' into rh-grandpa-offline-fallback
rphmeier Jan 30, 2019
619c7d4
test forced-change logic
rphmeier Jan 31, 2019
5e0a57a
test forced changes in the authority-set handler
rphmeier Jan 31, 2019
81ad7d7
kill some unneeded bounds in client
rphmeier Jan 31, 2019
a631a8d
test forced-changes in finality-grandpa and fix logic
rphmeier Jan 31, 2019
1ce7d40
Merge branch 'master' into rh-grandpa-offline-fallback: bump node ver…
rphmeier Jan 31, 2019
5ccd254
build wasm and finality-tracker is no-std
rphmeier Jan 31, 2019
b3291d4
Merge branch 'master' into rh-grandpa-offline-fallback
rphmeier Feb 4, 2019
386a5f9
restart voter on forced change
rphmeier Feb 5, 2019
7d1981c
Merge branch 'master' into rh-grandpa-offline-fallback
rphmeier Feb 11, 2019
a2add58
allow returning custom error type from lock_import_and_run
rphmeier Feb 14, 2019
35f444a
extract out most DB logic to aux_schema and use atomic client ops
rphmeier Feb 14, 2019
464f616
unify authority set writing
rphmeier Feb 14, 2019
bc2761f
implement set pausing
rphmeier Feb 14, 2019
08d5275
Merge branch 'master' into rh-grandpa-offline-fallback
rphmeier Feb 14, 2019
9518455
bump runtime version
rphmeier Feb 15, 2019
e7d24df
note on DB when we pause.
rphmeier Feb 15, 2019
8b018f1
Merge branch 'master' into rh-grandpa-offline-fallback
rphmeier Feb 15, 2019
4290f7d
Merge branch 'master' into rh-grandpa-offline-fallback
andresilva Feb 21, 2019
1a47254
core: grandpa: integrate forced changes with multiple pending standar…
andresilva Feb 22, 2019
e5b1c56
core: grandpa: fix AuthoritySet tests
andresilva Feb 22, 2019
f7420b7
Merge branch 'master' into rh-grandpa-offline-fallback
andresilva Feb 22, 2019
ad7a092
Merge branch 'master' into rh-grandpa-offline-fallback
andresilva Feb 25, 2019
0f21b3f
runtime: bump impl_version
andresilva Feb 25, 2019
2bcf2c7
core: clear pending justification requests after forced change import
andresilva Feb 25, 2019
33fe51f
srml: finality-tracker: use FinalizedInherentData
andresilva Feb 25, 2019
eb98d97
core: log requests for clearing justification requests
andresilva Feb 25, 2019
ed6b67e
core, node: update runtimes
andresilva Feb 25, 2019
ff1a8a5
core: grandpa: fix tests
andresilva Feb 25, 2019
30890ec
core: grandpa: remove todos and add comments
andresilva Feb 25, 2019
5bff073
core: grandpa: use has_api_with from ApiExt
andresilva Feb 25, 2019
f20746c
core: fix tests
andresilva Feb 25, 2019
c3d05fc
core: grandpa: remove unnecessary mut modifier
andresilva Feb 25, 2019
e537dd5
core: replace PostImportActions bitflags with struct
andresilva Feb 25, 2019
5d80af7
core: grandpa: restrict genesis on forced authority set change
andresilva Feb 26, 2019
abaccb3
core: grandpa: add more docs
andresilva Feb 26, 2019
94729c8
core: grandpa: prevent safety violations in Environment::finalize_block
andresilva Feb 26, 2019
9c43a28
core: grandpa: register finality tracker inherent data provider
andresilva Feb 26, 2019
3c37916
core: grandpa: fix tests
andresilva Feb 26, 2019
0976224
Merge branch 'master' into rh-grandpa-offline-fallback
andresilva Feb 26, 2019
de63d65
node: update runtime blobs
andresilva Feb 26, 2019
b5df296
core: grandpa: remove outdated todo
andresilva Mar 1, 2019
9799356
core: aura: fix typo in log message
andresilva Mar 1, 2019
fbd995b
core: grandpa: check re-finalization is on canonical chain
andresilva Mar 1, 2019
815410d
Merge branch 'master' into rh-grandpa-offline-fallback
andresilva Mar 1, 2019
d034c36
srml: finality-tracker: fix initialization
andresilva Mar 5, 2019
a391918
Merge branch 'master' into rh-grandpa-offline-fallback
andresilva Mar 5, 2019
93b98f7
node: update runtime wasm
andresilva Mar 5, 2019
cbb959f
srml: finality-tracker: don't re-initialize config keys
andresilva Mar 5, 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
25 changes: 25 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ members = [
"srml/example",
"srml/executive",
"srml/fees",
"srml/finality-tracker",
"srml/grandpa",
"srml/indices",
"srml/metadata",
Expand Down
19 changes: 11 additions & 8 deletions core/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use runtime_primitives::{
};
use consensus::{
Error as ConsensusError, ErrorKind as ConsensusErrorKind, ImportBlock, ImportResult,
BlockOrigin, ForkChoiceStrategy
BlockOrigin, ForkChoiceStrategy,
};
use runtime_primitives::traits::{
Block as BlockT, Header as HeaderT, Zero, As, NumberFor, CurrentHeight, BlockNumberToHash,
Expand Down Expand Up @@ -619,9 +619,10 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
}

/// Lock the import lock, and run operations inside.
pub fn lock_import_and_run<R, F: FnOnce(&mut ClientImportOperation<Block, Blake2Hasher, B>) -> error::Result<R>>(
&self, f: F
) -> error::Result<R> {
pub fn lock_import_and_run<R, Err, F>(&self, f: F) -> Result<R, Err> where
F: FnOnce(&mut ClientImportOperation<Block, Blake2Hasher, B>) -> Result<R, Err>,
Err: From<error::Error>,
{
let inner = || {
let _import_lock = self.import_lock.lock();

Expand Down Expand Up @@ -827,7 +828,7 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
operation.notify_imported = Some((hash, origin, import_headers.into_post(), is_new_best, storage_changes));
}

Ok(ImportResult::Queued)
Ok(ImportResult::imported())
}

fn block_execution(
Expand Down Expand Up @@ -1391,13 +1392,15 @@ impl<B, E, Block, RA> consensus::BlockImport<Block> for Client<B, E, Block, RA>
blockchain::BlockStatus::InChain => {},
blockchain::BlockStatus::Unknown => return Ok(ImportResult::UnknownParent),
}

match self.backend.blockchain().status(BlockId::Hash(hash))
.map_err(|e| ConsensusError::from(ConsensusErrorKind::ClientImport(e.to_string())))?
{
blockchain::BlockStatus::InChain => return Ok(ImportResult::AlreadyInChain),
blockchain::BlockStatus::Unknown => {},
}
Ok(ImportResult::Queued)

Ok(ImportResult::imported())
}
}

Expand All @@ -1414,7 +1417,7 @@ impl<B, E, Block, RA> consensus::Authorities<Block> for Client<B, E, Block, RA>

impl<B, E, Block, RA> CurrentHeight for Client<B, E, Block, RA> where
B: backend::Backend<Block, Blake2Hasher>,
E: CallExecutor<Block, Blake2Hasher> + Clone,
E: CallExecutor<Block, Blake2Hasher>,
Block: BlockT<Hash=H256>,
{
type BlockNumber = <Block::Header as HeaderT>::Number;
Expand All @@ -1425,7 +1428,7 @@ impl<B, E, Block, RA> CurrentHeight for Client<B, E, Block, RA> where

impl<B, E, Block, RA> BlockNumberToHash for Client<B, E, Block, RA> where
B: backend::Backend<Block, Blake2Hasher>,
E: CallExecutor<Block, Blake2Hasher> + Clone,
E: CallExecutor<Block, Blake2Hasher>,
Block: BlockT<Hash=H256>,
{
type BlockNumber = <Block::Header as HeaderT>::Number;
Expand Down
35 changes: 28 additions & 7 deletions core/consensus/common/src/block_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,40 @@ use std::borrow::Cow;
/// Block import result.
#[derive(Debug, PartialEq, Eq)]
pub enum ImportResult {
/// Added to the import queue.
Queued,
/// Already in the import queue.
AlreadyQueued,
/// Block imported.
Imported(ImportedAux),
/// Already in the blockchain.
AlreadyInChain,
/// Block or parent is known to be bad.
KnownBad,
/// Block parent is not in the chain.
UnknownParent,
/// Added to the import queue but must be justified
/// (usually required to safely enact consensus changes).
NeedsJustification,
}

/// Auxiliary data associated with an imported block result.
#[derive(Debug, PartialEq, Eq)]
pub struct ImportedAux {
/// Clear all pending justification requests.
pub clear_justification_requests: bool,
/// Request a justification for the given block.
pub needs_justification: bool,
}

impl Default for ImportedAux {
fn default() -> ImportedAux {
ImportedAux {
clear_justification_requests: false,
needs_justification: false,
}
}
}

impl ImportResult {
/// Returns default value for `ImportResult::Imported` with both
/// `clear_justification_requests` and `needs_justification` set to false.
pub fn imported() -> ImportResult {
ImportResult::Imported(ImportedAux::default())
}
}

/// Block data origin.
Expand Down
58 changes: 28 additions & 30 deletions core/consensus/common/src/import_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
//! The `BasicQueue` and `BasicVerifier` traits allow serial queues to be
//! instantiated simply.

use crate::block_import::{ImportBlock, BlockImport, JustificationImport, ImportResult, BlockOrigin};
use crate::block_import::{
BlockImport, BlockOrigin, ImportBlock, ImportedAux, ImportResult, JustificationImport,
};
use crossbeam_channel::{self as channel, Receiver, Sender};

use std::collections::HashSet;
Expand Down Expand Up @@ -361,31 +363,37 @@ impl<B: BlockT> BlockImporter<B> {

match result {
Ok(BlockImportResult::ImportedKnown(number)) => link.block_imported(&hash, number),
Ok(BlockImportResult::ImportedUnknown(number)) => {
link.block_imported(&hash, number)
}
Ok(BlockImportResult::ImportedUnjustified(number)) => {
Ok(BlockImportResult::ImportedUnknown(number, aux)) => {
link.block_imported(&hash, number);
link.request_justification(&hash, number);

if aux.clear_justification_requests {
trace!(target: "sync", "Block imported clears all pending justification requests {}: {:?}", number, hash);
link.clear_justification_requests();
}

if aux.needs_justification {
trace!(target: "sync", "Block imported but requires justification {}: {:?}", number, hash);
link.request_justification(&hash, number);
}
},
Err(BlockImportError::IncompleteHeader(who)) => {
if let Some(peer) = who {
link.note_useless_and_restart_sync(peer, "Sent block with incomplete header to import");
}
}
},
Err(BlockImportError::VerificationFailed(who, e)) => {
if let Some(peer) = who {
link.note_useless_and_restart_sync(peer, &format!("Verification failed: {}", e));
}
}
},
Err(BlockImportError::BadBlock(who)) => {
if let Some(peer) = who {
link.note_useless_and_restart_sync(peer, "Sent us a bad block");
}
}
},
Err(BlockImportError::UnknownParent) | Err(BlockImportError::Error) => {
link.restart()
}
link.restart();
},
};
}
if let Some(link) = self.link.as_ref() {
Expand Down Expand Up @@ -529,11 +537,13 @@ impl<B: BlockT, V: 'static + Verifier<B>> BlockImportWorker<B, V> {
/// algorithm.
pub trait Link<B: BlockT>: Send {
/// Block imported.
fn block_imported(&self, _hash: &B::Hash, _number: NumberFor<B>) { }
fn block_imported(&self, _hash: &B::Hash, _number: NumberFor<B>) {}
/// Justification import result.
fn justification_imported(&self, _who: Origin, _hash: &B::Hash, _number: NumberFor<B>, _success: bool) { }
fn justification_imported(&self, _who: Origin, _hash: &B::Hash, _number: NumberFor<B>, _success: bool) {}
/// Clear all pending justification requests.
fn clear_justification_requests(&self) {}
/// Request a justification for the given block.
fn request_justification(&self, _hash: &B::Hash, _number: NumberFor<B>) { }
fn request_justification(&self, _hash: &B::Hash, _number: NumberFor<B>) {}
/// Maintain sync.
fn maintain_sync(&self) {}
/// Disconnect from peer.
Expand All @@ -550,9 +560,7 @@ pub enum BlockImportResult<N: ::std::fmt::Debug + PartialEq> {
/// Imported known block.
ImportedKnown(N),
/// Imported unknown block.
ImportedUnknown(N),
/// Imported unjustified block that requires one.
ImportedUnjustified(N),
ImportedUnknown(N, ImportedAux),
}

/// Block import error.
Expand Down Expand Up @@ -601,17 +609,7 @@ pub fn import_single_block<B: BlockT, V: Verifier<B>>(
trace!(target: "sync", "Block already in chain {}: {:?}", number, hash);
Ok(BlockImportResult::ImportedKnown(number))
},
Ok(ImportResult::AlreadyQueued) => {
trace!(target: "sync", "Block already queued {}: {:?}", number, hash);
Ok(BlockImportResult::ImportedKnown(number))
},
Ok(ImportResult::Queued) => {
Ok(BlockImportResult::ImportedUnknown(number))
},
Ok(ImportResult::NeedsJustification) => {
trace!(target: "sync", "Block queued but requires justification {}: {:?}", number, hash);
Ok(BlockImportResult::ImportedUnjustified(number))
},
Ok(ImportResult::Imported(aux)) => Ok(BlockImportResult::ImportedUnknown(number, aux)),
Ok(ImportResult::UnknownParent) => {
debug!(target: "sync", "Block with unknown parent {}: {:?}, parent: {:?}", number, hash, parent);
Err(BlockImportError::UnknownParent)
Expand All @@ -628,7 +626,7 @@ pub fn import_single_block<B: BlockT, V: Verifier<B>>(
};

match import_error(import_handle.check_block(hash, parent))? {
BlockImportResult::ImportedUnknown(_) => (),
BlockImportResult::ImportedUnknown { .. } => (),
r @ _ => return Ok(r), // Any other successfull result means that the block is already imported.
}

Expand Down Expand Up @@ -713,7 +711,7 @@ mod tests {
assert_eq!(link_port.recv(), Ok(LinkMsg::BlockImported));

// Send an unknown
let results = vec![(Ok(BlockImportResult::ImportedUnknown(Default::default())), Default::default())];
let results = vec![(Ok(BlockImportResult::ImportedUnknown(Default::default(), Default::default())), Default::default())];
let _ = result_sender.send(BlockImportWorkerMsg::Imported(results)).ok().unwrap();
assert_eq!(link_port.recv(), Ok(LinkMsg::BlockImported));

Expand Down
4 changes: 3 additions & 1 deletion core/consensus/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ pub mod evaluation;
const MAX_BLOCK_SIZE: usize = 4 * 1024 * 1024 + 512;

pub use self::error::{Error, ErrorKind};
pub use block_import::{BlockImport, JustificationImport, ImportBlock, BlockOrigin, ImportResult, ForkChoiceStrategy};
pub use block_import::{
BlockImport, BlockOrigin, ForkChoiceStrategy, ImportedAux, ImportBlock, ImportResult, JustificationImport,
};

/// Trait for getting the authorities at a given block.
pub trait Authorities<B: Block> {
Expand Down
2 changes: 2 additions & 0 deletions core/finality-grandpa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ runtime_primitives = { package = "sr-primitives", path = "../sr-primitives" }
consensus_common = { package = "substrate-consensus-common", path = "../consensus/common" }
substrate-primitives = { path = "../primitives" }
client = { package = "substrate-client", path = "../client" }
inherents = { package = "substrate-inherents", path = "../../core/inherents" }
network = { package = "substrate-network", path = "../network" }
service = { package = "substrate-service", path = "../service", optional = true }
srml-finality-tracker = { path = "../../srml/finality-tracker" }
fg_primitives = { package = "substrate-finality-grandpa-primitives", path = "primitives" }
grandpa = { package = "finality-grandpa", version = "0.6.0", features = ["derive-codec"] }

Expand Down
23 changes: 23 additions & 0 deletions core/finality-grandpa/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ decl_runtime_apis! {
/// applied in the runtime after those N blocks have passed.
///
/// The consensus protocol will coordinate the handoff externally.
#[api_version(2)]
pub trait GrandpaApi {
/// Check a digest for pending changes.
/// Return `None` if there are no pending changes.
Expand All @@ -77,6 +78,28 @@ decl_runtime_apis! {
fn grandpa_pending_change(digest: &DigestFor<Block>)
-> Option<ScheduledChange<NumberFor<Block>>>;

/// Check a digest for forced changes.
/// Return `None` if there are no forced changes. Otherwise, return a
/// tuple containing the pending change and the median last finalized
/// block number at the time the change was signalled.
///
/// Added in version 2.
///
/// 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.
fn grandpa_forced_change(digest: &DigestFor<Block>)
-> Option<(NumberFor<Block>, ScheduledChange<NumberFor<Block>>)>;

/// Get the current GRANDPA authorities and weights. This should not change except
/// for when changes are scheduled and the corresponding delay has passed.
///
Expand Down
Loading