Sync block justifications (#1410)

* core: sync protocol for justifications

* core: basic test for justification sync

* core: pass block number with justification

* grandpa: request justifications when importing change blocks

* core: pass finality notifications to chain sync

* core: require justifications for pending change blocks on start

* core: avoid requesting justifications from previous failed peers

* core: timeout block justification requests

* core: add some docs

* core: fix unused variables warning

* core: tick pending justifications fetch periodically

* grandpa: add test for syncing justifications

* core: early exit dispatch of pending justifications

* core: style fix

* core: grandpa: change logging level

* core: sync: add missing docs

* core: network: report peer on bad justification

* core: replace mem::replace with Option::take

* core: revert authority set changes on failed block finalization

* core: grandpa: add docs to import_justification

* core: warn on re-finalization of last finalized block

* core: only notify sync with last finality notification

* core: style fix

* core: add docs for PendingJustifications

* core: network: use BlockRequest messages for justification requests

* core: reference issues in todo comments

* core: grandpa: revert authority set changes on db

* core: grandpa: remove inconsistent state warning
This commit is contained in:
André Silva
2019-01-21 06:04:01 +00:00
committed by Gav Wood
parent 3ea681998a
commit 399cee310a
13 changed files with 747 additions and 140 deletions
+19 -2
View File
@@ -728,7 +728,11 @@ impl<B, E, Block, RA> Client<B, E, Block, RA> where
// find tree route from last finalized to given block.
let last_finalized = self.backend.blockchain().last_finalized()?;
if block == last_finalized { return Ok(()) }
if block == last_finalized {
warn!("Possible safety violation: attempted to re-finalize last finalized block {:?} ", last_finalized);
return Ok(());
}
let route_from_finalized = crate::blockchain::tree_route(
self.backend.blockchain(),
BlockId::Hash(last_finalized),
@@ -1093,7 +1097,7 @@ impl<B, E, Block, RA> consensus::BlockImport<Block> for Client<B, E, Block, RA>
match self.backend.blockchain().status(BlockId::Hash(parent_hash)) {
Ok(blockchain::BlockStatus::InChain) => {},
Ok(blockchain::BlockStatus::Unknown) => return Ok(ImportResult::UnknownParent),
Err(e) => return Err(ConsensusErrorKind::ClientImport(e.to_string()).into())
Err(e) => return Err(ConsensusErrorKind::ClientImport(e.to_string()).into()),
}
let import_headers = if post_digests.is_empty() {
@@ -1131,6 +1135,19 @@ impl<B, E, Block, RA> consensus::BlockImport<Block> for Client<B, E, Block, RA>
);
result.map_err(|e| ConsensusErrorKind::ClientImport(e.to_string()).into())
}
/// Import a block justification and finalize the block. The justification
/// isn't interpreted by the client and is assumed to have been validated
/// previously. The block is finalized unconditionally.
fn import_justification(
&self,
hash: Block::Hash,
_number: NumberFor<Block>,
justification: Justification,
) -> Result<(), Self::Error> {
self.finalize_block(BlockId::Hash(hash), Some(justification), true)
.map_err(|_| ConsensusErrorKind::InvalidJustification.into())
}
}
impl<B, E, Block, RA> consensus::Authorities<Block> for Client<B, E, Block, RA> where