mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 09:21:05 +00:00
pallet-mmr: move offchain logic to client-side gadget (#12753)
* Move MMR utils methods from pallet to primitives Signed-off-by: Serban Iorga <serban@parity.io> * Add method to MmrApi * Move forks expanding logic from babe to primitives * Implement MMR gadget * Remove prunning logic from the MMR pallet * Code review changes: 1st iteration * Replace MaybeCanonEngine with CanonEngineBuilder * fix mmr_leaves_count() for kitchen sink demo * Update client/merkle-mountain-range/src/canon_engine.rs Co-authored-by: Adrian Catangiu <adrian@parity.io> * Code review changes: 2nd iteration * fix INDEXING_PREFIX * impl review comments * add documentation and minor rename Signed-off-by: Serban Iorga <serban@parity.io> Co-authored-by: Adrian Catangiu <adrian@parity.io>
This commit is contained in:
@@ -21,9 +21,10 @@ use log::warn;
|
||||
use parking_lot::RwLock;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, Header as HeaderT, NumberFor},
|
||||
traits::{Block as BlockT, Header as HeaderT, NumberFor, Saturating},
|
||||
Justifications,
|
||||
};
|
||||
use std::collections::btree_set::BTreeSet;
|
||||
|
||||
use crate::header_metadata::HeaderMetadata;
|
||||
|
||||
@@ -84,6 +85,77 @@ pub trait HeaderBackend<Block: BlockT>: Send + Sync {
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles stale forks.
|
||||
pub trait ForkBackend<Block: BlockT>:
|
||||
HeaderMetadata<Block> + HeaderBackend<Block> + Send + Sync
|
||||
{
|
||||
/// Best effort to get all the header hashes that are part of the provided forks
|
||||
/// starting only from the fork heads.
|
||||
///
|
||||
/// The function tries to reconstruct the route from the fork head to the canonical chain.
|
||||
/// If any of the hashes on the route can't be found in the db, the function won't be able
|
||||
/// to reconstruct the route anymore. In this case it will give up expanding the current fork,
|
||||
/// move on to the next ones and at the end it will return an error that also contains
|
||||
/// the partially expanded forks.
|
||||
fn expand_forks(
|
||||
&self,
|
||||
fork_heads: &[Block::Hash],
|
||||
) -> std::result::Result<BTreeSet<Block::Hash>, (BTreeSet<Block::Hash>, Error)> {
|
||||
let mut missing_blocks = vec![];
|
||||
let mut expanded_forks = BTreeSet::new();
|
||||
for fork_head in fork_heads {
|
||||
let mut route_head = *fork_head;
|
||||
// Insert stale blocks hashes until canonical chain is reached.
|
||||
// If we reach a block that is already part of the `expanded_forks` we can stop
|
||||
// processing the fork.
|
||||
while expanded_forks.insert(route_head) {
|
||||
match self.header_metadata(route_head) {
|
||||
Ok(meta) => {
|
||||
// If the parent is part of the canonical chain or there doesn't exist a
|
||||
// block hash for the parent number (bug?!), we can abort adding blocks.
|
||||
let parent_number = meta.number.saturating_sub(1u32.into());
|
||||
match self.hash(parent_number) {
|
||||
Ok(Some(parent_hash)) =>
|
||||
if parent_hash == meta.parent {
|
||||
break
|
||||
},
|
||||
Ok(None) | Err(_) => {
|
||||
missing_blocks.push(BlockId::<Block>::Number(parent_number));
|
||||
break
|
||||
},
|
||||
}
|
||||
|
||||
route_head = meta.parent;
|
||||
},
|
||||
Err(_e) => {
|
||||
missing_blocks.push(BlockId::<Block>::Hash(route_head));
|
||||
break
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !missing_blocks.is_empty() {
|
||||
return Err((
|
||||
expanded_forks,
|
||||
Error::UnknownBlocks(format!(
|
||||
"Missing stale headers {:?} while expanding forks {:?}.",
|
||||
fork_heads, missing_blocks
|
||||
)),
|
||||
))
|
||||
}
|
||||
|
||||
Ok(expanded_forks)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Block, T> ForkBackend<Block> for T
|
||||
where
|
||||
Block: BlockT,
|
||||
T: HeaderMetadata<Block> + HeaderBackend<Block> + Send + Sync,
|
||||
{
|
||||
}
|
||||
|
||||
/// Blockchain database backend. Does not perform any validation.
|
||||
pub trait Backend<Block: BlockT>:
|
||||
HeaderBackend<Block> + HeaderMetadata<Block, Error = Error>
|
||||
|
||||
@@ -59,6 +59,9 @@ pub enum Error {
|
||||
#[error("UnknownBlock: {0}")]
|
||||
UnknownBlock(String),
|
||||
|
||||
#[error("UnknownBlocks: {0}")]
|
||||
UnknownBlocks(String),
|
||||
|
||||
#[error(transparent)]
|
||||
ApplyExtrinsicFailed(#[from] ApplyExtrinsicFailed),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user