mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 04:01:02 +00:00
Import multiple authority set change blocks (#1808)
* core: implement logic for tracking dag of possible pending changes * core: move pending justifications dag to its own crate * core: remove unnecessary clone bounds on dag * core: request justifications in-order from the dag * core: dag: rename changes variables to node * core: dag: allow finalizing blocks not part of dag * core: dag: track best finalized number * core: dag: add more tests * core: sync: clean up pending justifications dag * core: dag: derive codec decode encode * core: dag: better error support * core: dag: add finalization guarded by predicate * core: grandpa: track multiple authority set changes in dag * core: dag: add pre-order iterator * core: grandpa: request justifications on startup * core: dag: rearrange order of definitions * core: rename util/dag to util/fork_tree * core: fork_tree: add docs * core: fork_tree: add more tests * core: fork_tree: fix issues found in tests * core: grandpa: fix authorities tests * core: grandpa: add docs for is_descendent_of * core: sync: add docs for PendingJustifications * core: sync: add test for justification requests across forks * core: sync: don't resend import or finality notifications in tests * core: grandpa: add test for importing multiple change blocks * core: grandpa: fix logic for checking if a block enacts a change * core: grandpa: fix authorities tests
This commit is contained in:
@@ -368,6 +368,7 @@ impl<Block: BlockT> From<GrandpaJustification<Block>> for JustificationOrCommit<
|
||||
/// Finalize the given block and apply any authority set changes. If an
|
||||
/// authority set change is enacted then a justification is created (if not
|
||||
/// given) and stored with the block when finalizing it.
|
||||
/// This method assumes that the block being finalized has already been imported.
|
||||
pub(crate) fn finalize_block<B, Block: BlockT<Hash=H256>, E, RA>(
|
||||
client: &Client<B, E, Block, RA>,
|
||||
authority_set: &SharedAuthoritySet<Block::Hash, NumberFor<Block>>,
|
||||
@@ -391,9 +392,11 @@ pub(crate) fn finalize_block<B, Block: BlockT<Hash=H256>, E, RA>(
|
||||
let mut old_last_completed = None;
|
||||
|
||||
let mut consensus_changes = consensus_changes.lock();
|
||||
let status = authority_set.apply_changes(number, |canon_number| {
|
||||
canonical_at_height(client, (hash, number), canon_number)
|
||||
})?;
|
||||
let status = authority_set.apply_changes(
|
||||
hash,
|
||||
number,
|
||||
&is_descendent_of(client, None),
|
||||
).map_err(|e| Error::Safety(e.to_string()))?;
|
||||
|
||||
if status.changed {
|
||||
// write new authority set state to disk.
|
||||
@@ -599,3 +602,41 @@ pub(crate) fn canonical_at_height<B, E, Block: BlockT<Hash=H256>, RA>(
|
||||
|
||||
Ok(Some(current.hash()))
|
||||
}
|
||||
|
||||
/// Returns a function for checking block ancestry, the returned function will
|
||||
/// return `true` if the given hash (second parameter) is a descendent of the
|
||||
/// base (first parameter). If the `current` parameter is defined, it should
|
||||
/// represent the current block `hash` and its `parent hash`, if given the
|
||||
/// function that's returned will assume that `hash` isn't part of the local DB
|
||||
/// yet, and all searches in the DB will instead reference the parent.
|
||||
pub fn is_descendent_of<'a, B, E, Block: BlockT<Hash=H256>, RA>(
|
||||
client: &'a Client<B, E, Block, RA>,
|
||||
current: Option<(&'a H256, &'a H256)>,
|
||||
) -> impl Fn(&H256, &H256) -> Result<bool, client::error::Error> + 'a
|
||||
where B: Backend<Block, Blake2Hasher>,
|
||||
E: CallExecutor<Block, Blake2Hasher> + Send + Sync,
|
||||
{
|
||||
move |base, hash| {
|
||||
if base == hash { return Ok(false); }
|
||||
|
||||
let mut hash = hash;
|
||||
if let Some((current_hash, current_parent_hash)) = current {
|
||||
if base == current_hash { return Ok(false); }
|
||||
if hash == current_hash {
|
||||
if base == current_parent_hash {
|
||||
return Ok(true);
|
||||
} else {
|
||||
hash = current_parent_hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let tree_route = client::blockchain::tree_route(
|
||||
client.backend().blockchain(),
|
||||
BlockId::Hash(*hash),
|
||||
BlockId::Hash(*base),
|
||||
)?;
|
||||
|
||||
Ok(tree_route.common_block().hash == *base)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user