pub fn finalize_with_descendent_if<F, P, E>(
		&mut self,
		hash: &H,
		number: N,
		is_descendent_of: &F,
		predicate: P,
	) -> Result<FinalizationResult<V>, Error<E>>
		where E: std::error::Error,
			  F: Fn(&H, &H) -> Result<bool, E>,
			  P: Fn(&V) -> bool,
	{
		if let Some(ref best_finalized_number) = self.best_finalized_number {
			if number <= *best_finalized_number {
				return Err(Error::Revert);
			}
		}

		// check if the given hash is equal or a a descendent of any root, if we
		// find a valid root that passes the predicate then we must ensure that
		// we're not finalizing past any children node.
		let mut position = None;
		for (i, root) in self.roots.iter().enumerate() {
			if predicate(&root.data) {
				if root.hash == *hash || is_descendent_of(&root.hash, hash)? {
					for node in root.children.iter() {
						if node.number <= number && is_descendent_of(&node.hash, &hash)? {
							return Err(Error::UnfinalizedAncestor);
						}
					}

					position = Some(i);
					break;
				}
			}
		}

		let node_data = position.map(|i| {
			let node = self.roots.swap_remove(i);
			self.roots = node.children;
			self.best_finalized_number = Some(node.number);
			node.data
		});

		// if the block being finalized is earlier than a given root, then it
		// must be its ancestor, otherwise we can prune the root. if there's a
		// root at the same height then the hashes must match. otherwise the
		// node being finalized is higher than the root so it must be its
		// descendent (in this case the node wasn't finalized earlier presumably
		// because the predicate didn't pass).
		let mut changed = false;
		self.roots.retain(|root| {
			let retain =
				root.number > number && is_descendent_of(hash, &root.hash).unwrap_or(false) ||
				root.number == number && root.hash == *hash ||
				is_descendent_of(&root.hash, hash).unwrap_or(false);

			if !retain {
				changed = true;
			}

			retain
		});

		self.best_finalized_number = Some(number);

		match (node_data, changed) {
			(Some(data), _) => Ok(FinalizationResult::Changed(Some(data))),
			(None, true) => Ok(FinalizationResult::Changed(None)),
			(None, false) => Ok(FinalizationResult::Unchanged),
		}
	}
/// Finalize a root in the tree by either finalizing the node itself or a
/// child node that's not in the tree, guaranteeing that the node being
/// finalized isn't a descendent of any of the root's children. The given
/// `predicate` is checked on the prospective finalized root and must pass for
/// finalization to occur. The given function `is_descendent_of` should
/// return `true` if the second hash (target) is a descendent of the first
/// hash (base).
Finalize a root in the tree by either finalizing the node itself or a
child node that's not in the tree, guaranteeing that the node being
finalized isn't a descendent of any of the root's children. The given
`predicate` is checked on the prospective finalized root and must pass for
finalization to occur. The given function `is_descendent_of` should
return `true` if the second hash (target) is a descendent of the first
hash (base).
Finalize a root in the tree by either finalizing the node itself or a child node that ' s not in the tree guaranteeing that the node being finalized isn ' t a descendent of any of the root ' s children . The given ` predicate ` is checked on the prospective finalized root and must pass for finalization to occur . The given function ` is_descendent_of ` should return ` true ` if the second hash ( target ) is a descendent of the first hash ( base ) .
pub fn finalize_with_descendent_if<F, P, E>(
		&mut self,
		hash: &H,
		number: N,
		is_descendent_of: &F,
		predicate: P,
	) -> Result<FinalizationResult<V>, Error<E>>
		where E: std::error::Error,
			  F: Fn(&H, &H) -> Result<bool, E>,
			  P: Fn(&V) -> bool,
	{
		if let Some(ref best_finalized_number) = self.best_finalized_number {
			if number <= *best_finalized_number {
				return Err(Error::Revert);
			}
		}
		// check if the given hash is equal or a a descendent of any root, if we
		// find a valid root that passes the predicate then we must ensure that
		// we're not finalizing past any children node.
		let mut position = None;
		for (i, root) in self.roots.iter().enumerate() {
			if predicate(&root.data) {
				if root.hash == *hash || is_descendent_of(&root.hash, hash)? {
					for node in root.children.iter() {
						if node.number <= number && is_descendent_of(&node.hash, &hash)? {
							return Err(Error::UnfinalizedAncestor);
						}
					}
					position = Some(i);
					break;
				}
			}
		}
		let node_data = position.map(|i| {
			let node = self.roots.swap_remove(i);
			self.roots = node.children;
			self.best_finalized_number = Some(node.number);
			node.data
		});
		// if the block being finalized is earlier than a given root, then it
		// must be its ancestor, otherwise we can prune the root. if there's a
		// root at the same height then the hashes must match. otherwise the
		// node being finalized is higher than the root so it must be its
		// descendent (in this case the node wasn't finalized earlier presumably
		// because the predicate didn't pass).
		let mut changed = false;
		self.roots.retain(|root| {
			let retain =
				root.number > number && is_descendent_of(hash, &root.hash).unwrap_or(false) ||
				root.number == number && root.hash == *hash ||
				is_descendent_of(&root.hash, hash).unwrap_or(false);
			if !retain {
				changed = true;
			}
			retain
		});
		self.best_finalized_number = Some(number);
		match (node_data, changed) {
			(Some(data), _) => Ok(FinalizationResult::Changed(Some(data))),
			(None, true) => Ok(FinalizationResult::Changed(None)),
			(None, false) => Ok(FinalizationResult::Unchanged),
		}
	}
pub fn finalize_with_descendent_if < F , P , E > ( & mut self , hash : & H , number : N , is_descendent_of : & F , predicate : P , ) -> Result < FinalizationResult < V > , Error < E > > where E : std :: error :: Error , F : Fn ( & H , & H ) -> Result < bool , E > , P : Fn ( & V ) -> bool , { if let Some ( ref best_finalized_number ) = self . best_finalized_number { if number <= * best_finalized_number { return Err ( Error :: Revert ) ; } } // check if the given hash is equal or a a descendent of any root, if we // find a valid root that passes the predicate then we must ensure that // we're not finalizing past any children node. let mut position = None ; for ( i , root ) in self . roots . iter ( ) . enumerate ( ) { if predicate ( & root . data ) { if root . hash == * hash || is_descendent_of ( & root . hash , hash ) ? { for node in root . children . iter ( ) { if node . number <= number && is_descendent_of ( & node . hash , & hash ) ? { return Err ( Error :: UnfinalizedAncestor ) ; } } position = Some ( i ) ; break ; } } } let node_data = position . map ( | i | { let node = self . roots . swap_remove ( i ) ; self . roots = node . children ; self . best_finalized_number = Some ( node . number ) ; node . data } ) ; // if the block being finalized is earlier than a given root, then it // must be its ancestor, otherwise we can prune the root. if there's a // root at the same height then the hashes must match. otherwise the // node being finalized is higher than the root so it must be its // descendent (in this case the node wasn't finalized earlier presumably // because the predicate didn't pass). let mut changed = false ; self . roots . retain ( | root | { let retain = root . number > number && is_descendent_of ( hash , & root . hash ) . unwrap_or ( false ) || root . number == number && root . hash == * hash || is_descendent_of ( & root . hash , hash ) . unwrap_or ( false ) ; if ! retain { changed = true ; } retain } ) ; self . best_finalized_number = Some ( number ) ; match ( node_data , changed ) { ( Some ( data ) , _ ) => Ok ( FinalizationResult :: Changed ( Some ( data ) ) ) , ( None , true ) => Ok ( FinalizationResult :: Changed ( None ) ) , ( None , false ) => Ok ( FinalizationResult :: Unchanged ) , } }
Finalize a root in the tree by either finalizing the node itself or a
child node that's not in the tree, guaranteeing that the node being
finalized isn't a descendent of any of the root's children.
Finalize a root in the tree by either finalizing the node itself or a child node that ' s not in the tree guaranteeing that the node being finalized isn ' t a descendent of any of the root ' s children .
&mut self
hash
&H
number
N
is_descendent_of
&F
predicate
P
&mut self
hash
&H
number
N
is_descendent_of
&F
predicate
P