mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 01:11:10 +00:00
BABE's revert procedure (#11022)
* First rough draft for BABE revert * Proper babe revert test * Cleanup * Test trivial cleanup * Fix to make clippy happy * Check polkadot companion * Check cumulus companion * Remove babe's blocks weight on revert * Handle "empty" blockchain edge case * Run companions * Simplify the filter predicate * Saturating sub is not required * Run pipeline * Run pipeline again...
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
pub mod migration;
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use fork_tree::ForkTree;
|
||||
use fork_tree::{FilterAction, ForkTree};
|
||||
use sc_client_api::utils::is_descendent_of;
|
||||
use sp_blockchain::{Error as ClientError, HeaderBackend, HeaderMetadata};
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor, One, Zero};
|
||||
@@ -660,15 +660,6 @@ where
|
||||
parent_number: Number,
|
||||
slot: E::Slot,
|
||||
) -> Result<Option<ViableEpochDescriptor<Hash, Number, E>>, fork_tree::Error<D::Error>> {
|
||||
// find_node_where will give you the node in the fork-tree which is an ancestor
|
||||
// of the `parent_hash` by default. if the last epoch was signalled at the parent_hash,
|
||||
// then it won't be returned. we need to create a new fake chain head hash which
|
||||
// "descends" from our parent-hash.
|
||||
let fake_head_hash = fake_head_hash(parent_hash);
|
||||
|
||||
let is_descendent_of =
|
||||
descendent_of_builder.build_is_descendent_of(Some((fake_head_hash, *parent_hash)));
|
||||
|
||||
if parent_number == Zero::zero() {
|
||||
// need to insert the genesis epoch.
|
||||
return Ok(Some(ViableEpochDescriptor::UnimportedGenesis(slot)))
|
||||
@@ -683,6 +674,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// find_node_where will give you the node in the fork-tree which is an ancestor
|
||||
// of the `parent_hash` by default. if the last epoch was signalled at the parent_hash,
|
||||
// then it won't be returned. we need to create a new fake chain head hash which
|
||||
// "descends" from our parent-hash.
|
||||
let fake_head_hash = fake_head_hash(parent_hash);
|
||||
|
||||
let is_descendent_of =
|
||||
descendent_of_builder.build_is_descendent_of(Some((fake_head_hash, *parent_hash)));
|
||||
|
||||
// We want to find the deepest node in the tree which is an ancestor
|
||||
// of our block and where the start slot of the epoch was before the
|
||||
// slot of our block. The genesis special-case doesn't need to look
|
||||
@@ -798,6 +798,37 @@ where
|
||||
});
|
||||
self.epochs.insert((hash, number), persisted);
|
||||
}
|
||||
|
||||
/// Revert to a specified block given its `hash` and `number`.
|
||||
/// This removes all the epoch changes information that were announced by
|
||||
/// all the given block descendents.
|
||||
pub fn revert<D: IsDescendentOfBuilder<Hash>>(
|
||||
&mut self,
|
||||
descendent_of_builder: D,
|
||||
hash: Hash,
|
||||
number: Number,
|
||||
) {
|
||||
let is_descendent_of = descendent_of_builder.build_is_descendent_of(None);
|
||||
|
||||
let filter = |node_hash: &Hash, node_num: &Number, _: &PersistedEpochHeader<E>| {
|
||||
if number >= *node_num &&
|
||||
(is_descendent_of(node_hash, &hash).unwrap_or_default() || *node_hash == hash)
|
||||
{
|
||||
// Continue the search in this subtree.
|
||||
FilterAction::KeepNode
|
||||
} else if number < *node_num && is_descendent_of(&hash, node_hash).unwrap_or_default() {
|
||||
// Found a node to be removed.
|
||||
FilterAction::Remove
|
||||
} else {
|
||||
// Not a parent or child of the one we're looking for, stop processing this branch.
|
||||
FilterAction::KeepTree
|
||||
}
|
||||
};
|
||||
|
||||
self.inner.drain_filter(filter).for_each(|(h, n, _)| {
|
||||
self.epochs.remove(&(h, n));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Type alias to produce the epoch-changes tree from a block type.
|
||||
|
||||
Reference in New Issue
Block a user