forktree/
lib.rs

1// This file is part of Tetcore.
2
3// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Utility library for managing tree-like ordered data with logic for pruning
19//! the tree while finalizing nodes.
20
21#![warn(missing_docs)]
22
23use std::cmp::Reverse;
24use std::fmt;
25use codec::{Decode, Encode};
26
27/// Error occurred when iterating with the tree.
28#[derive(Clone, Debug, PartialEq)]
29pub enum Error<E> {
30	/// Adding duplicate node to tree.
31	Duplicate,
32	/// Finalizing descendent of tree node without finalizing ancestor(s).
33	UnfinalizedAncestor,
34	/// Imported or finalized node that is an ancestor of previously finalized node.
35	Revert,
36	/// Error throw by client when checking for node ancestry.
37	Client(E),
38}
39
40impl<E: std::error::Error> fmt::Display for Error<E> {
41	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42		let message = match *self {
43			Error::Duplicate => "Hash already exists in Tree".into(),
44			Error::UnfinalizedAncestor => "Finalized descendent of Tree node without finalizing its ancestor(s) first".into(),
45			Error::Revert => "Tried to import or finalize node that is an ancestor of a previously finalized node".into(),
46			Error::Client(ref err) => format!("Client error: {}", err),
47		};
48		write!(f, "{}", message)
49	}
50}
51
52impl<E: std::error::Error> std::error::Error for Error<E> {
53	fn cause(&self) -> Option<&dyn std::error::Error> {
54		None
55	}
56}
57
58impl<E: std::error::Error> From<E> for Error<E> {
59	fn from(err: E) -> Error<E> {
60		Error::Client(err)
61	}
62}
63
64/// Result of finalizing a node (that could be a part of the tree or not).
65#[derive(Debug, PartialEq)]
66pub enum FinalizationResult<V> {
67	/// The tree has changed, optionally return the value associated with the finalized node.
68	Changed(Option<V>),
69	/// The tree has not changed.
70	Unchanged,
71}
72
73/// A tree data structure that stores several nodes across multiple branches.
74/// Top-level branches are called roots. The tree has functionality for
75/// finalizing nodes, which means that that node is traversed, and all competing
76/// branches are pruned. It also guarantees that nodes in the tree are finalized
77/// in order. Each node is uniquely identified by its hash but can be ordered by
78/// its number. In order to build the tree an external function must be provided
79/// when interacting with the tree to establish a node's ancestry.
80#[derive(Clone, Debug, Decode, Encode, PartialEq)]
81pub struct ForkTree<H, N, V> {
82	roots: Vec<Node<H, N, V>>,
83	best_finalized_number: Option<N>,
84}
85
86impl<H, N, V> ForkTree<H, N, V> where
87	H: PartialEq + Clone,
88	N: Ord + Clone,
89	V: Clone,
90{
91	/// Prune the tree, removing all non-canonical nodes. We find the node in the
92	/// tree that is the deepest ancestor of the given hash and that passes the
93	/// given predicate. If such a node exists, we re-root the tree to this
94	/// node. Otherwise the tree remains unchanged. The given function
95	/// `is_descendent_of` should return `true` if the second hash (target) is a
96	/// descendent of the first hash (base).
97	///
98	/// Returns all pruned node data.
99	pub fn prune<F, E, P>(
100		&mut self,
101		hash: &H,
102		number: &N,
103		is_descendent_of: &F,
104		predicate: &P,
105	) -> Result<impl Iterator<Item=(H, N, V)>, Error<E>>
106		where E: std::error::Error,
107			  F: Fn(&H, &H) -> Result<bool, E>,
108			  P: Fn(&V) -> bool,
109	{
110		let new_root_index = self.find_node_index_where(
111			hash,
112			number,
113			is_descendent_of,
114			predicate,
115		)?;
116
117		let removed = if let Some(mut root_index) = new_root_index {
118			let mut old_roots = std::mem::take(&mut self.roots);
119
120			let mut root = None;
121			let mut cur_children = Some(&mut old_roots);
122
123			while let Some(cur_index) = root_index.pop() {
124				if let Some(children) = cur_children.take() {
125					if root_index.is_empty() {
126						root = Some(children.remove(cur_index));
127					} else {
128						cur_children = Some(&mut children[cur_index].children);
129					}
130				}
131			}
132
133			let mut root = root
134				.expect("find_node_index_where will return array with at least one index; \
135						 this results in at least one item in removed; qed");
136
137			let mut removed = old_roots;
138
139			// we found the deepest ancestor of the finalized block, so we prune
140			// out any children that don't include the finalized block.
141			let root_children = std::mem::take(&mut root.children);
142			let mut is_first = true;
143
144			for child in root_children {
145				if is_first &&
146					(child.number == *number && child.hash == *hash ||
147					 child.number < *number && is_descendent_of(&child.hash, hash)?)
148				{
149					root.children.push(child);
150					// assuming that the tree is well formed only one child should pass this requirement
151					// due to ancestry restrictions (i.e. they must be different forks).
152					is_first = false;
153				} else {
154					removed.push(child);
155				}
156			}
157
158			self.roots = vec![root];
159
160			removed
161		} else {
162			Vec::new()
163		};
164
165		self.rebalance();
166
167		Ok(RemovedIterator { stack: removed })
168	}
169}
170
171impl<H, N, V> ForkTree<H, N, V> where
172	H: PartialEq,
173	N: Ord,
174{
175	/// Create a new empty tree.
176	pub fn new() -> ForkTree<H, N, V> {
177		ForkTree {
178			roots: Vec::new(),
179			best_finalized_number: None,
180		}
181	}
182
183	/// Rebalance the tree, i.e. sort child nodes by max branch depth
184	/// (decreasing).
185	///
186	/// Most operations in the tree are performed with depth-first search
187	/// starting from the leftmost node at every level, since this tree is meant
188	/// to be used in a blockchain context, a good heuristic is that the node
189	/// we'll be looking
190	/// for at any point will likely be in one of the deepest chains (i.e. the
191	/// longest ones).
192	pub fn rebalance(&mut self) {
193		self.roots.sort_by_key(|n| Reverse(n.max_depth()));
194		for root in &mut self.roots {
195			root.rebalance();
196		}
197	}
198
199	/// Import a new node into the tree. The given function `is_descendent_of`
200	/// should return `true` if the second hash (target) is a descendent of the
201	/// first hash (base). This method assumes that nodes in the same branch are
202	/// imported in order.
203	///
204	/// Returns `true` if the imported node is a root.
205	pub fn import<F, E>(
206		&mut self,
207		mut hash: H,
208		mut number: N,
209		mut data: V,
210		is_descendent_of: &F,
211	) -> Result<bool, Error<E>>
212		where E: std::error::Error,
213			  F: Fn(&H, &H) -> Result<bool, E>,
214	{
215		if let Some(ref best_finalized_number) = self.best_finalized_number {
216			if number <= *best_finalized_number {
217				return Err(Error::Revert);
218			}
219		}
220
221		for root in self.roots.iter_mut() {
222			if root.hash == hash {
223				return Err(Error::Duplicate);
224			}
225
226			match root.import(hash, number, data, is_descendent_of)? {
227				Some((h, n, d)) => {
228					hash = h;
229					number = n;
230					data = d;
231				},
232				None => {
233					self.rebalance();
234					return Ok(false);
235				},
236			}
237		}
238
239		self.roots.push(Node {
240			data,
241			hash: hash,
242			number: number,
243			children: Vec::new(),
244		});
245
246		self.rebalance();
247
248		Ok(true)
249	}
250
251	/// Iterates over the existing roots in the tree.
252	pub fn roots(&self) -> impl Iterator<Item=(&H, &N, &V)> {
253		self.roots.iter().map(|node| (&node.hash, &node.number, &node.data))
254	}
255
256	fn node_iter(&self) -> impl Iterator<Item=&Node<H, N, V>> {
257		// we need to reverse the order of roots to maintain the expected
258		// ordering since the iterator uses a stack to track state.
259		ForkTreeIterator { stack: self.roots.iter().rev().collect() }
260	}
261
262	/// Iterates the nodes in the tree in pre-order.
263	pub fn iter(&self) -> impl Iterator<Item=(&H, &N, &V)> {
264		self.node_iter().map(|node| (&node.hash, &node.number, &node.data))
265	}
266
267	/// Find a node in the tree that is the deepest ancestor of the given
268	/// block hash and which passes the given predicate. The given function
269	/// `is_descendent_of` should return `true` if the second hash (target)
270	/// is a descendent of the first hash (base).
271	pub fn find_node_where<F, E, P>(
272		&self,
273		hash: &H,
274		number: &N,
275		is_descendent_of: &F,
276		predicate: &P,
277	) -> Result<Option<&Node<H, N, V>>, Error<E>> where
278		E: std::error::Error,
279		F: Fn(&H, &H) -> Result<bool, E>,
280		P: Fn(&V) -> bool,
281	{
282		// search for node starting from all roots
283		for root in self.roots.iter() {
284			let node = root.find_node_where(hash, number, is_descendent_of, predicate)?;
285
286			// found the node, early exit
287			if let FindOutcome::Found(node) = node {
288				return Ok(Some(node));
289			}
290		}
291
292		Ok(None)
293	}
294
295	/// Map fork tree into values of new types.
296	pub fn map<VT, F>(
297		self,
298		f: &mut F,
299	) -> ForkTree<H, N, VT> where
300		F: FnMut(&H, &N, V) -> VT,
301	{
302		let roots = self.roots
303			.into_iter()
304			.map(|root| {
305				root.map(f)
306			})
307			.collect();
308
309		ForkTree {
310			roots,
311			best_finalized_number: self.best_finalized_number,
312		}
313	}
314
315	/// Same as [`find_node_where`](ForkTree::find_node_where), but returns mutable reference.
316	pub fn find_node_where_mut<F, E, P>(
317		&mut self,
318		hash: &H,
319		number: &N,
320		is_descendent_of: &F,
321		predicate: &P,
322	) -> Result<Option<&mut Node<H, N, V>>, Error<E>> where
323		E: std::error::Error,
324		F: Fn(&H, &H) -> Result<bool, E>,
325		P: Fn(&V) -> bool,
326	{
327		// search for node starting from all roots
328		for root in self.roots.iter_mut() {
329			let node = root.find_node_where_mut(hash, number, is_descendent_of, predicate)?;
330
331			// found the node, early exit
332			if let FindOutcome::Found(node) = node {
333				return Ok(Some(node));
334			}
335		}
336
337		Ok(None)
338	}
339
340	/// Same as [`find_node_where`](ForkTree::find_node_where), but returns indexes.
341	pub fn find_node_index_where<F, E, P>(
342		&self,
343		hash: &H,
344		number: &N,
345		is_descendent_of: &F,
346		predicate: &P,
347	) -> Result<Option<Vec<usize>>, Error<E>> where
348		E: std::error::Error,
349		F: Fn(&H, &H) -> Result<bool, E>,
350		P: Fn(&V) -> bool,
351	{
352		// search for node starting from all roots
353		for (index, root) in self.roots.iter().enumerate() {
354			let node = root.find_node_index_where(hash, number, is_descendent_of, predicate)?;
355
356			// found the node, early exit
357			if let FindOutcome::Found(mut node) = node {
358				node.push(index);
359				return Ok(Some(node));
360			}
361		}
362
363		Ok(None)
364	}
365
366	/// Finalize a root in the tree and return it, return `None` in case no root
367	/// with the given hash exists. All other roots are pruned, and the children
368	/// of the finalized node become the new roots.
369	pub fn finalize_root(&mut self, hash: &H) -> Option<V> {
370		self.roots.iter().position(|node| node.hash == *hash)
371			.map(|position| self.finalize_root_at(position))
372	}
373
374	/// Finalize root at given position. See `finalize_root` comment for details.
375	fn finalize_root_at(&mut self, position: usize) -> V {
376		let node = self.roots.swap_remove(position);
377		self.roots = node.children;
378		self.best_finalized_number = Some(node.number);
379		return node.data;
380	}
381
382	/// Finalize a node in the tree. This method will make sure that the node
383	/// being finalized is either an existing root (and return its data), or a
384	/// node from a competing branch (not in the tree), tree pruning is done
385	/// accordingly. The given function `is_descendent_of` should return `true`
386	/// if the second hash (target) is a descendent of the first hash (base).
387	pub fn finalize<F, E>(
388		&mut self,
389		hash: &H,
390		number: N,
391		is_descendent_of: &F,
392	) -> Result<FinalizationResult<V>, Error<E>>
393		where E: std::error::Error,
394			  F: Fn(&H, &H) -> Result<bool, E>
395	{
396		if let Some(ref best_finalized_number) = self.best_finalized_number {
397			if number <= *best_finalized_number {
398				return Err(Error::Revert);
399			}
400		}
401
402		// check if one of the current roots is being finalized
403		if let Some(root) = self.finalize_root(hash) {
404			return Ok(FinalizationResult::Changed(Some(root)));
405		}
406
407		// make sure we're not finalizing a descendent of any root
408		for root in self.roots.iter() {
409			if number > root.number && is_descendent_of(&root.hash, hash)? {
410				return Err(Error::UnfinalizedAncestor);
411			}
412		}
413
414		// we finalized a block earlier than any existing root (or possibly
415		// another fork not part of the tree). make sure to only keep roots that
416		// are part of the finalized branch
417		let mut changed = false;
418		let roots = std::mem::take(&mut self.roots);
419
420		for root in roots {
421			if root.number > number && is_descendent_of(hash, &root.hash)? {
422				self.roots.push(root);
423			} else {
424				changed = true;
425			}
426		}
427
428		self.best_finalized_number = Some(number);
429
430		if changed {
431			Ok(FinalizationResult::Changed(None))
432		} else {
433			Ok(FinalizationResult::Unchanged)
434		}
435	}
436
437	/// Finalize a node in the tree and all its ancestors. The given function
438	/// `is_descendent_of` should return `true` if the second hash (target) is
439	// a descendent of the first hash (base).
440	pub fn finalize_with_ancestors<F, E>(
441		&mut self,
442		hash: &H,
443		number: N,
444		is_descendent_of: &F,
445	) -> Result<FinalizationResult<V>, Error<E>>
446		where E: std::error::Error,
447				F: Fn(&H, &H) -> Result<bool, E>
448	{
449		if let Some(ref best_finalized_number) = self.best_finalized_number {
450			if number <= *best_finalized_number {
451				return Err(Error::Revert);
452			}
453		}
454
455		// check if one of the current roots is being finalized
456		if let Some(root) = self.finalize_root(hash) {
457			return Ok(FinalizationResult::Changed(Some(root)));
458		}
459
460		// we need to:
461		// 1) remove all roots that are not ancestors AND not descendants of finalized block;
462		// 2) if node is descendant - just leave it;
463		// 3) if node is ancestor - 'open it'
464		let mut changed = false;
465		let mut idx = 0;
466		while idx != self.roots.len() {
467			let (is_finalized, is_descendant, is_ancestor) = {
468				let root = &self.roots[idx];
469				let is_finalized = root.hash == *hash;
470				let is_descendant =
471					!is_finalized && root.number > number && is_descendent_of(hash, &root.hash)?;
472				let is_ancestor = !is_finalized
473					&& !is_descendant && root.number < number
474					&& is_descendent_of(&root.hash, hash)?;
475				(is_finalized, is_descendant, is_ancestor)
476			};
477
478			// if we have met finalized root - open it and return
479			if is_finalized {
480				return Ok(FinalizationResult::Changed(Some(
481					self.finalize_root_at(idx),
482				)));
483			}
484
485			// if node is descendant of finalized block - just leave it as is
486			if is_descendant {
487				idx += 1;
488				continue;
489			}
490
491			// if node is ancestor of finalized block - remove it and continue with children
492			if is_ancestor {
493				let root = self.roots.swap_remove(idx);
494				self.roots.extend(root.children);
495				changed = true;
496				continue;
497			}
498
499			// if node is neither ancestor, nor descendant of the finalized block - remove it
500			self.roots.swap_remove(idx);
501			changed = true;
502		}
503
504		self.best_finalized_number = Some(number);
505
506		if changed {
507			Ok(FinalizationResult::Changed(None))
508		} else {
509			Ok(FinalizationResult::Unchanged)
510		}
511	}
512
513	/// Checks if any node in the tree is finalized by either finalizing the
514	/// node itself or a child node that's not in the tree, guaranteeing that
515	/// the node being finalized isn't a descendent of any of the node's
516	/// children. Returns `Some(true)` if the node being finalized is a root,
517	/// `Some(false)` if the node being finalized is not a root, and `None` if
518	/// no node in the tree is finalized. The given `predicate` is checked on
519	/// the prospective finalized root and must pass for finalization to occur.
520	/// The given function `is_descendent_of` should return `true` if the second
521	/// hash (target) is a descendent of the first hash (base).
522	pub fn finalizes_any_with_descendent_if<F, P, E>(
523		&self,
524		hash: &H,
525		number: N,
526		is_descendent_of: &F,
527		predicate: P,
528	) -> Result<Option<bool>, Error<E>>
529		where E: std::error::Error,
530			  F: Fn(&H, &H) -> Result<bool, E>,
531			  P: Fn(&V) -> bool,
532	{
533		if let Some(ref best_finalized_number) = self.best_finalized_number {
534			if number <= *best_finalized_number {
535				return Err(Error::Revert);
536			}
537		}
538
539		// check if the given hash is equal or a descendent of any node in the
540		// tree, if we find a valid node that passes the predicate then we must
541		// ensure that we're not finalizing past any of its child nodes.
542		for node in self.node_iter() {
543			if predicate(&node.data) {
544				if node.hash == *hash || is_descendent_of(&node.hash, hash)? {
545					for node in node.children.iter() {
546						if node.number <= number && is_descendent_of(&node.hash, &hash)? {
547							return Err(Error::UnfinalizedAncestor);
548						}
549					}
550
551					return Ok(Some(self.roots.iter().any(|root| root.hash == node.hash)));
552				}
553			}
554		}
555
556		Ok(None)
557	}
558
559	/// Finalize a root in the tree by either finalizing the node itself or a
560	/// child node that's not in the tree, guaranteeing that the node being
561	/// finalized isn't a descendent of any of the root's children. The given
562	/// `predicate` is checked on the prospective finalized root and must pass for
563	/// finalization to occur. The given function `is_descendent_of` should
564	/// return `true` if the second hash (target) is a descendent of the first
565	/// hash (base).
566	pub fn finalize_with_descendent_if<F, P, E>(
567		&mut self,
568		hash: &H,
569		number: N,
570		is_descendent_of: &F,
571		predicate: P,
572	) -> Result<FinalizationResult<V>, Error<E>>
573		where E: std::error::Error,
574			  F: Fn(&H, &H) -> Result<bool, E>,
575			  P: Fn(&V) -> bool,
576	{
577		if let Some(ref best_finalized_number) = self.best_finalized_number {
578			if number <= *best_finalized_number {
579				return Err(Error::Revert);
580			}
581		}
582
583		// check if the given hash is equal or a a descendent of any root, if we
584		// find a valid root that passes the predicate then we must ensure that
585		// we're not finalizing past any children node.
586		let mut position = None;
587		for (i, root) in self.roots.iter().enumerate() {
588			if predicate(&root.data) {
589				if root.hash == *hash || is_descendent_of(&root.hash, hash)? {
590					for node in root.children.iter() {
591						if node.number <= number && is_descendent_of(&node.hash, &hash)? {
592							return Err(Error::UnfinalizedAncestor);
593						}
594					}
595
596					position = Some(i);
597					break;
598				}
599			}
600		}
601
602		let node_data = position.map(|i| {
603			let node = self.roots.swap_remove(i);
604			self.roots = node.children;
605			self.best_finalized_number = Some(node.number);
606			node.data
607		});
608
609		// if the block being finalized is earlier than a given root, then it
610		// must be its ancestor, otherwise we can prune the root. if there's a
611		// root at the same height then the hashes must match. otherwise the
612		// node being finalized is higher than the root so it must be its
613		// descendent (in this case the node wasn't finalized earlier presumably
614		// because the predicate didn't pass).
615		let mut changed = false;
616		let roots = std::mem::take(&mut self.roots);
617
618		for root in roots {
619			let retain = root.number > number && is_descendent_of(hash, &root.hash)?
620				|| root.number == number && root.hash == *hash
621				|| is_descendent_of(&root.hash, hash)?;
622
623			if retain {
624				self.roots.push(root);
625			} else {
626				changed = true;
627			}
628		}
629
630		self.best_finalized_number = Some(number);
631
632		match (node_data, changed) {
633			(Some(data), _) => Ok(FinalizationResult::Changed(Some(data))),
634			(None, true) => Ok(FinalizationResult::Changed(None)),
635			(None, false) => Ok(FinalizationResult::Unchanged),
636		}
637	}
638}
639
640// Workaround for: https://github.com/rust-lang/rust/issues/34537
641mod node_implementation {
642	use super::*;
643
644	/// The outcome of a search within a node.
645	pub enum FindOutcome<T> {
646		// this is the node we were looking for.
647		Found(T),
648		// not the node we're looking for. contains a flag indicating
649		// whether the node was a descendent. true implies the predicate failed.
650		Failure(bool),
651		// Abort search.
652		Abort,
653	}
654
655	#[derive(Clone, Debug, Decode, Encode, PartialEq)]
656	pub struct Node<H, N, V> {
657		pub hash: H,
658		pub number: N,
659		pub data: V,
660		pub children: Vec<Node<H, N, V>>,
661	}
662
663	impl<H: PartialEq, N: Ord, V> Node<H, N, V> {
664		/// Rebalance the tree, i.e. sort child nodes by max branch depth (decreasing).
665		pub fn rebalance(&mut self) {
666			self.children.sort_by_key(|n| Reverse(n.max_depth()));
667			for child in &mut self.children {
668				child.rebalance();
669			}
670		}
671
672		/// Finds the max depth among all branches descendent from this node.
673		pub fn max_depth(&self) -> usize {
674			let mut max = 0;
675
676			for node in &self.children {
677				max = node.max_depth().max(max)
678			}
679
680			max + 1
681		}
682
683		/// Map node data into values of new types.
684		pub fn map<VT, F>(
685			self,
686			f: &mut F,
687		) -> Node<H, N, VT> where
688			F: FnMut(&H, &N, V) -> VT,
689		{
690			let children = self.children
691				.into_iter()
692				.map(|node| {
693					node.map(f)
694				})
695				.collect();
696
697			let vt = f(&self.hash, &self.number, self.data);
698			Node {
699				hash: self.hash,
700				number: self.number,
701				data: vt,
702				children,
703			}
704		}
705
706		pub fn import<F, E: std::error::Error>(
707			&mut self,
708			mut hash: H,
709			mut number: N,
710			mut data: V,
711			is_descendent_of: &F,
712		) -> Result<Option<(H, N, V)>, Error<E>>
713			where E: fmt::Debug,
714				  F: Fn(&H, &H) -> Result<bool, E>,
715		{
716			if self.hash == hash {
717				return Err(Error::Duplicate);
718			};
719
720			if number <= self.number { return Ok(Some((hash, number, data))); }
721
722			for node in self.children.iter_mut() {
723				match node.import(hash, number, data, is_descendent_of)? {
724					Some((h, n, d)) => {
725						hash = h;
726						number = n;
727						data = d;
728					},
729					None => return Ok(None),
730				}
731			}
732
733			if is_descendent_of(&self.hash, &hash)? {
734				self.children.push(Node {
735					data,
736					hash: hash,
737					number: number,
738					children: Vec::new(),
739				});
740
741				Ok(None)
742			} else {
743				Ok(Some((hash, number, data)))
744			}
745		}
746
747		/// Find a node in the tree that is the deepest ancestor of the given
748		/// block hash which also passes the given predicate, backtracking
749		/// when the predicate fails.
750		/// The given function `is_descendent_of` should return `true` if the second hash (target)
751		/// is a descendent of the first hash (base).
752		///
753		/// The returned indices are from last to first. The earliest index in the traverse path
754		/// goes last, and the final index in the traverse path goes first. An empty list means
755		/// that the current node is the result.
756		pub fn find_node_index_where<F, P, E>(
757			&self,
758			hash: &H,
759			number: &N,
760			is_descendent_of: &F,
761			predicate: &P,
762		) -> Result<FindOutcome<Vec<usize>>, Error<E>>
763			where E: std::error::Error,
764				  F: Fn(&H, &H) -> Result<bool, E>,
765				  P: Fn(&V) -> bool,
766		{
767			// stop searching this branch
768			if *number < self.number {
769				return Ok(FindOutcome::Failure(false));
770			}
771
772			let mut known_descendent_of = false;
773
774			// continue depth-first search through all children
775			for (i, node) in self.children.iter().enumerate() {
776				// found node, early exit
777				match node.find_node_index_where(hash, number, is_descendent_of, predicate)? {
778					FindOutcome::Abort => return Ok(FindOutcome::Abort),
779					FindOutcome::Found(mut x) => {
780						x.push(i);
781						return Ok(FindOutcome::Found(x))
782					},
783					FindOutcome::Failure(true) => {
784						// if the block was a descendent of this child,
785						// then it cannot be a descendent of any others,
786						// so we don't search them.
787						known_descendent_of = true;
788						break;
789					},
790					FindOutcome::Failure(false) => {},
791				}
792			}
793
794			// node not found in any of the descendents, if the node we're
795			// searching for is a descendent of this node then we will stop the
796			// search here, since there aren't any more children and we found
797			// the correct node so we don't want to backtrack.
798			let is_descendent_of = known_descendent_of || is_descendent_of(&self.hash, hash)?;
799			if is_descendent_of {
800				// if the predicate passes we return the node
801				if predicate(&self.data) {
802					return Ok(FindOutcome::Found(Vec::new()));
803				}
804			}
805
806			// otherwise, tell our ancestor that we failed, and whether
807			// the block was a descendent.
808			Ok(FindOutcome::Failure(is_descendent_of))
809		}
810
811		/// Find a node in the tree that is the deepest ancestor of the given
812		/// block hash which also passes the given predicate, backtracking
813		/// when the predicate fails.
814		/// The given function `is_descendent_of` should return `true` if the second hash (target)
815		/// is a descendent of the first hash (base).
816		pub fn find_node_where<F, P, E>(
817			&self,
818			hash: &H,
819			number: &N,
820			is_descendent_of: &F,
821			predicate: &P,
822		) -> Result<FindOutcome<&Node<H, N, V>>, Error<E>>
823			where E: std::error::Error,
824				  F: Fn(&H, &H) -> Result<bool, E>,
825				  P: Fn(&V) -> bool,
826		{
827			let outcome = self.find_node_index_where(hash, number, is_descendent_of, predicate)?;
828
829			match outcome {
830				FindOutcome::Abort => Ok(FindOutcome::Abort),
831				FindOutcome::Failure(f) => Ok(FindOutcome::Failure(f)),
832				FindOutcome::Found(mut indexes) => {
833					let mut cur = self;
834
835					while let Some(i) = indexes.pop() {
836						cur = &cur.children[i];
837					}
838					Ok(FindOutcome::Found(cur))
839				},
840			}
841		}
842
843		/// Find a node in the tree that is the deepest ancestor of the given
844		/// block hash which also passes the given predicate, backtracking
845		/// when the predicate fails.
846		/// The given function `is_descendent_of` should return `true` if the second hash (target)
847		/// is a descendent of the first hash (base).
848		pub fn find_node_where_mut<F, P, E>(
849			&mut self,
850			hash: &H,
851			number: &N,
852			is_descendent_of: &F,
853			predicate: &P,
854		) -> Result<FindOutcome<&mut Node<H, N, V>>, Error<E>>
855			where E: std::error::Error,
856				  F: Fn(&H, &H) -> Result<bool, E>,
857				  P: Fn(&V) -> bool,
858		{
859			let outcome = self.find_node_index_where(hash, number, is_descendent_of, predicate)?;
860
861			match outcome {
862				FindOutcome::Abort => Ok(FindOutcome::Abort),
863				FindOutcome::Failure(f) => Ok(FindOutcome::Failure(f)),
864				FindOutcome::Found(mut indexes) => {
865					let mut cur = self;
866
867					while let Some(i) = indexes.pop() {
868						cur = &mut cur.children[i];
869					}
870					Ok(FindOutcome::Found(cur))
871				},
872			}
873		}
874	}
875}
876
877// Workaround for: https://github.com/rust-lang/rust/issues/34537
878use node_implementation::{Node, FindOutcome};
879
880struct ForkTreeIterator<'a, H, N, V> {
881	stack: Vec<&'a Node<H, N, V>>,
882}
883
884impl<'a, H, N, V> Iterator for ForkTreeIterator<'a, H, N, V> {
885	type Item = &'a Node<H, N, V>;
886
887	fn next(&mut self) -> Option<Self::Item> {
888		self.stack.pop().map(|node| {
889			// child nodes are stored ordered by max branch height (decreasing),
890			// we want to keep this ordering while iterating but since we're
891			// using a stack for iterator state we need to reverse it.
892			self.stack.extend(node.children.iter().rev());
893			node
894		})
895	}
896}
897
898struct RemovedIterator<H, N, V> {
899	stack: Vec<Node<H, N, V>>,
900}
901
902impl<H, N, V> Iterator for RemovedIterator<H, N, V> {
903	type Item = (H, N, V);
904
905	fn next(&mut self) -> Option<Self::Item> {
906		self.stack.pop().map(|mut node| {
907			// child nodes are stored ordered by max branch height (decreasing),
908			// we want to keep this ordering while iterating but since we're
909			// using a stack for iterator state we need to reverse it.
910			let children = std::mem::take(&mut node.children);
911
912			self.stack.extend(children.into_iter().rev());
913			(node.hash, node.number, node.data)
914		})
915	}
916}
917
918#[cfg(test)]
919mod test {
920	use super::{FinalizationResult, ForkTree, Error};
921
922	#[derive(Debug, PartialEq)]
923	struct TestError;
924
925	impl std::fmt::Display for TestError {
926		fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
927			write!(f, "TestError")
928		}
929	}
930
931	impl std::error::Error for TestError {}
932
933	fn test_forktree<'a>() -> (ForkTree<&'a str, u64, ()>, impl Fn(&&str, &&str) -> Result<bool, TestError>)  {
934		let mut tree = ForkTree::new();
935
936		//
937		//     - B - C - D - E
938		//    /
939		//   /   - G
940		//  /   /
941		// A - F - H - I
942		//          \
943		//           - L - M
944		//              \
945		//               - O
946		//  \
947		//   — J - K
948		//
949		// (where N is not a part of fork tree)
950		//
951		// NOTE: the tree will get automatically rebalance on import and won't be laid out like the
952		// diagram above. the children will be ordered by subtree depth and the longest branches
953		// will be on the leftmost side of the tree.
954		let is_descendent_of = |base: &&str, block: &&str| -> Result<bool, TestError> {
955			let letters = vec!["B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "O"];
956			match (*base, *block) {
957				("A", b) => Ok(letters.into_iter().any(|n| n == b)),
958				("B", b) => Ok(b == "C" || b == "D" || b == "E"),
959				("C", b) => Ok(b == "D" || b == "E"),
960				("D", b) => Ok(b == "E"),
961				("E", _) => Ok(false),
962				("F", b) => Ok(b == "G" || b == "H" || b == "I" || b == "L" || b == "M" || b == "O"),
963				("G", _) => Ok(false),
964				("H", b) => Ok(b == "I" || b == "L" || b == "M" || b == "O"),
965				("I", _) => Ok(false),
966				("J", b) => Ok(b == "K"),
967				("K", _) => Ok(false),
968				("L", b) => Ok(b == "M" || b == "O"),
969				("M", _) => Ok(false),
970				("O", _) => Ok(false),
971				("0", _) => Ok(true),
972				_ => Ok(false),
973			}
974		};
975
976		tree.import("A", 1, (), &is_descendent_of).unwrap();
977
978		tree.import("B", 2, (), &is_descendent_of).unwrap();
979		tree.import("C", 3, (), &is_descendent_of).unwrap();
980		tree.import("D", 4, (), &is_descendent_of).unwrap();
981		tree.import("E", 5, (), &is_descendent_of).unwrap();
982
983		tree.import("F", 2, (), &is_descendent_of).unwrap();
984		tree.import("G", 3, (), &is_descendent_of).unwrap();
985
986		tree.import("H", 3, (), &is_descendent_of).unwrap();
987		tree.import("I", 4, (), &is_descendent_of).unwrap();
988		tree.import("L", 4, (), &is_descendent_of).unwrap();
989		tree.import("M", 5, (), &is_descendent_of).unwrap();
990		tree.import("O", 5, (), &is_descendent_of).unwrap();
991
992		tree.import("J", 2, (), &is_descendent_of).unwrap();
993		tree.import("K", 3, (), &is_descendent_of).unwrap();
994
995		(tree, is_descendent_of)
996	}
997
998	#[test]
999	fn import_doesnt_revert() {
1000		let (mut tree, is_descendent_of) = test_forktree();
1001
1002		tree.finalize_root(&"A");
1003
1004		assert_eq!(
1005			tree.best_finalized_number,
1006			Some(1),
1007		);
1008
1009		assert_eq!(
1010			tree.import("A", 1, (), &is_descendent_of),
1011			Err(Error::Revert),
1012		);
1013	}
1014
1015	#[test]
1016	fn import_doesnt_add_duplicates() {
1017		let (mut tree, is_descendent_of) = test_forktree();
1018
1019		assert_eq!(
1020			tree.import("A", 1, (), &is_descendent_of),
1021			Err(Error::Duplicate),
1022		);
1023
1024		assert_eq!(
1025			tree.import("I", 4, (), &is_descendent_of),
1026			Err(Error::Duplicate),
1027		);
1028
1029		assert_eq!(
1030			tree.import("G", 3, (), &is_descendent_of),
1031			Err(Error::Duplicate),
1032		);
1033
1034		assert_eq!(
1035			tree.import("K", 3, (), &is_descendent_of),
1036			Err(Error::Duplicate),
1037		);
1038	}
1039
1040	#[test]
1041	fn finalize_root_works() {
1042		let finalize_a = || {
1043			let (mut tree, ..) = test_forktree();
1044
1045			assert_eq!(
1046				tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1047				vec![("A", 1)],
1048			);
1049
1050			// finalizing "A" opens up three possible forks
1051			tree.finalize_root(&"A");
1052
1053			assert_eq!(
1054				tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1055				vec![("B", 2), ("F", 2), ("J", 2)],
1056			);
1057
1058			tree
1059		};
1060
1061		{
1062			let mut tree = finalize_a();
1063
1064			// finalizing "B" will progress on its fork and remove any other competing forks
1065			tree.finalize_root(&"B");
1066
1067			assert_eq!(
1068				tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1069				vec![("C", 3)],
1070			);
1071
1072			// all the other forks have been pruned
1073			assert!(tree.roots.len() == 1);
1074		}
1075
1076		{
1077			let mut tree = finalize_a();
1078
1079			// finalizing "J" will progress on its fork and remove any other competing forks
1080			tree.finalize_root(&"J");
1081
1082			assert_eq!(
1083				tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1084				vec![("K", 3)],
1085			);
1086
1087			// all the other forks have been pruned
1088			assert!(tree.roots.len() == 1);
1089		}
1090	}
1091
1092	#[test]
1093	fn finalize_works() {
1094		let (mut tree, is_descendent_of) = test_forktree();
1095
1096		let original_roots = tree.roots.clone();
1097
1098		// finalizing a block prior to any in the node doesn't change the tree
1099		assert_eq!(
1100			tree.finalize(&"0", 0, &is_descendent_of),
1101			Ok(FinalizationResult::Unchanged),
1102		);
1103
1104		assert_eq!(tree.roots, original_roots);
1105
1106		// finalizing "A" opens up three possible forks
1107		assert_eq!(
1108			tree.finalize(&"A", 1, &is_descendent_of),
1109			Ok(FinalizationResult::Changed(Some(()))),
1110		);
1111
1112		assert_eq!(
1113			tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1114			vec![("B", 2), ("F", 2), ("J", 2)],
1115		);
1116
1117		// finalizing anything lower than what we observed will fail
1118		assert_eq!(
1119			tree.best_finalized_number,
1120			Some(1),
1121		);
1122
1123		assert_eq!(
1124			tree.finalize(&"Z", 1, &is_descendent_of),
1125			Err(Error::Revert),
1126		);
1127
1128		// trying to finalize a node without finalizing its ancestors first will fail
1129		assert_eq!(
1130			tree.finalize(&"H", 3, &is_descendent_of),
1131			Err(Error::UnfinalizedAncestor),
1132		);
1133
1134		// after finalizing "F" we can finalize "H"
1135		assert_eq!(
1136			tree.finalize(&"F", 2, &is_descendent_of),
1137			Ok(FinalizationResult::Changed(Some(()))),
1138		);
1139
1140		assert_eq!(
1141			tree.finalize(&"H", 3, &is_descendent_of),
1142			Ok(FinalizationResult::Changed(Some(()))),
1143		);
1144
1145		assert_eq!(
1146			tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1147			vec![("L", 4), ("I", 4)],
1148		);
1149
1150		// finalizing a node from another fork that isn't part of the tree clears the tree
1151		assert_eq!(
1152			tree.finalize(&"Z", 5, &is_descendent_of),
1153			Ok(FinalizationResult::Changed(None)),
1154		);
1155
1156		assert!(tree.roots.is_empty());
1157	}
1158
1159	#[test]
1160	fn finalize_with_ancestor_works() {
1161		let (mut tree, is_descendent_of) = test_forktree();
1162
1163		let original_roots = tree.roots.clone();
1164
1165		// finalizing a block prior to any in the node doesn't change the tree
1166		assert_eq!(
1167			tree.finalize_with_ancestors(&"0", 0, &is_descendent_of),
1168			Ok(FinalizationResult::Unchanged),
1169		);
1170
1171		assert_eq!(tree.roots, original_roots);
1172
1173		// finalizing "A" opens up three possible forks
1174		assert_eq!(
1175			tree.finalize_with_ancestors(&"A", 1, &is_descendent_of),
1176			Ok(FinalizationResult::Changed(Some(()))),
1177		);
1178
1179		assert_eq!(
1180			tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1181			vec![("B", 2), ("F", 2), ("J", 2)],
1182		);
1183
1184		// finalizing H:
1185		// 1) removes roots that are not ancestors/descendants of H (B, J)
1186		// 2) opens root that is ancestor of H (F -> G+H)
1187		// 3) finalizes the just opened root H (H -> I + L)
1188		assert_eq!(
1189			tree.finalize_with_ancestors(&"H", 3, &is_descendent_of),
1190			Ok(FinalizationResult::Changed(Some(()))),
1191		);
1192
1193		assert_eq!(
1194			tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1195			vec![("L", 4), ("I", 4)],
1196		);
1197
1198		assert_eq!(
1199			tree.best_finalized_number,
1200			Some(3),
1201		);
1202
1203		// finalizing N (which is not a part of the tree):
1204		// 1) removes roots that are not ancestors/descendants of N (I)
1205		// 2) opens root that is ancestor of N (L -> M+O)
1206		// 3) removes roots that are not ancestors/descendants of N (O)
1207		// 4) opens root that is ancestor of N (M -> {})
1208		assert_eq!(
1209			tree.finalize_with_ancestors(&"N", 6, &is_descendent_of),
1210			Ok(FinalizationResult::Changed(None)),
1211		);
1212
1213		assert_eq!(
1214			tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1215			vec![],
1216		);
1217
1218		assert_eq!(
1219			tree.best_finalized_number,
1220			Some(6),
1221		);
1222	}
1223
1224	#[test]
1225	fn finalize_with_descendent_works() {
1226		#[derive(Debug, PartialEq)]
1227		struct Change { effective: u64 }
1228
1229		let (mut tree, is_descendent_of) = {
1230			let mut tree = ForkTree::new();
1231
1232			let is_descendent_of = |base: &&str, block: &&str| -> Result<bool, TestError> {
1233
1234				//
1235				// A0 #1 - (B #2) - (C #5) - D #10 - E #15 - (F #100)
1236				//                            \
1237				//                             - (G #100)
1238				//
1239				// A1 #1
1240				//
1241				// Nodes B, C, F and G  are not part of the tree.
1242				match (*base, *block) {
1243					("A0", b) => Ok(b == "B" || b == "C" || b == "D" || b == "G"),
1244					("A1", _) => Ok(false),
1245					("C", b) => Ok(b == "D"),
1246					("D", b) => Ok(b == "E" || b == "F" || b == "G"),
1247					("E", b) => Ok(b == "F"),
1248					_ => Ok(false),
1249				}
1250			};
1251
1252			tree.import("A0", 1, Change { effective: 5 }, &is_descendent_of).unwrap();
1253			tree.import("A1", 1, Change { effective: 5 }, &is_descendent_of).unwrap();
1254			tree.import("D", 10, Change { effective: 10 }, &is_descendent_of).unwrap();
1255			tree.import("E", 15, Change { effective: 50 }, &is_descendent_of).unwrap();
1256
1257			(tree, is_descendent_of)
1258		};
1259
1260		assert_eq!(
1261			tree.finalizes_any_with_descendent_if(
1262				&"B",
1263				2,
1264				&is_descendent_of,
1265				|c| c.effective <= 2,
1266			),
1267			Ok(None),
1268		);
1269
1270		// finalizing "D" will finalize a block from the tree, but it can't be applied yet
1271		// since it is not a root change
1272		assert_eq!(
1273			tree.finalizes_any_with_descendent_if(
1274				&"D",
1275				10,
1276				&is_descendent_of,
1277				|c| c.effective == 10,
1278			),
1279			Ok(Some(false)),
1280		);
1281
1282		// finalizing "B" doesn't finalize "A0" since the predicate doesn't pass,
1283		// although it will clear out "A1" from the tree
1284		assert_eq!(
1285			tree.finalize_with_descendent_if(
1286				&"B",
1287				2,
1288				&is_descendent_of,
1289				|c| c.effective <= 2,
1290			),
1291			Ok(FinalizationResult::Changed(None)),
1292		);
1293
1294		assert_eq!(
1295			tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1296			vec![("A0", 1)],
1297		);
1298
1299		// finalizing "C" will finalize the node "A0" and prune it out of the tree
1300		assert_eq!(
1301			tree.finalizes_any_with_descendent_if(
1302				&"C",
1303				5,
1304				&is_descendent_of,
1305				|c| c.effective <= 5,
1306			),
1307			Ok(Some(true)),
1308		);
1309
1310		assert_eq!(
1311			tree.finalize_with_descendent_if(
1312				&"C",
1313				5,
1314				&is_descendent_of,
1315				|c| c.effective <= 5,
1316			),
1317			Ok(FinalizationResult::Changed(Some(Change { effective: 5 }))),
1318		);
1319
1320		assert_eq!(
1321			tree.roots().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1322			vec![("D", 10)],
1323		);
1324
1325		// finalizing "F" will fail since it would finalize past "E" without finalizing "D" first
1326		assert_eq!(
1327			tree.finalizes_any_with_descendent_if(
1328				&"F",
1329				100,
1330				&is_descendent_of,
1331				|c| c.effective <= 100,
1332			),
1333			Err(Error::UnfinalizedAncestor),
1334		);
1335
1336		// it will work with "G" though since it is not in the same branch as "E"
1337		assert_eq!(
1338			tree.finalizes_any_with_descendent_if(
1339				&"G",
1340				100,
1341				&is_descendent_of,
1342				|c| c.effective <= 100,
1343			),
1344			Ok(Some(true)),
1345		);
1346
1347		assert_eq!(
1348			tree.finalize_with_descendent_if(
1349				&"G",
1350				100,
1351				&is_descendent_of,
1352				|c| c.effective <= 100,
1353			),
1354			Ok(FinalizationResult::Changed(Some(Change { effective: 10 }))),
1355		);
1356
1357		// "E" will be pruned out
1358		assert_eq!(tree.roots().count(), 0);
1359	}
1360
1361	#[test]
1362	fn iter_iterates_in_preorder() {
1363		let (tree, ..) = test_forktree();
1364		assert_eq!(
1365			tree.iter().map(|(h, n, _)| (h.clone(), n.clone())).collect::<Vec<_>>(),
1366			vec![
1367				("A", 1),
1368				("B", 2), ("C", 3), ("D", 4), ("E", 5),
1369				("F", 2), ("H", 3), ("L", 4), ("M", 5),
1370				("O", 5),
1371				("I", 4),
1372				("G", 3),
1373				("J", 2), ("K", 3),
1374			],
1375		);
1376	}
1377
1378	#[test]
1379	fn minimizes_calls_to_is_descendent_of() {
1380		use std::sync::atomic::{AtomicUsize, Ordering};
1381
1382		let n_is_descendent_of_calls = AtomicUsize::new(0);
1383
1384		let is_descendent_of = |_: &&str, _: &&str| -> Result<bool, TestError> {
1385			n_is_descendent_of_calls.fetch_add(1, Ordering::SeqCst);
1386			Ok(true)
1387		};
1388
1389		{
1390			// Deep tree where we want to call `finalizes_any_with_descendent_if`. The
1391			// search for the node should first check the predicate (which is cheaper) and
1392			// only then call `is_descendent_of`
1393			let mut tree = ForkTree::new();
1394			let letters = vec!["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"];
1395
1396			for (i, letter) in letters.iter().enumerate() {
1397				tree.import::<_, TestError>(*letter, i, i, &|_, _| Ok(true)).unwrap();
1398			}
1399
1400			// "L" is a descendent of "K", but the predicate will only pass for "K",
1401			// therefore only one call to `is_descendent_of` should be made
1402			assert_eq!(
1403				tree.finalizes_any_with_descendent_if(
1404					&"L",
1405					11,
1406					&is_descendent_of,
1407					|i| *i == 10,
1408				),
1409				Ok(Some(false)),
1410			);
1411
1412			assert_eq!(
1413				n_is_descendent_of_calls.load(Ordering::SeqCst),
1414				1,
1415			);
1416		}
1417
1418		n_is_descendent_of_calls.store(0, Ordering::SeqCst);
1419
1420		{
1421			// Multiple roots in the tree where we want to call `finalize_with_descendent_if`.
1422			// The search for the root node should first check the predicate (which is cheaper)
1423			// and only then call `is_descendent_of`
1424			let mut tree = ForkTree::new();
1425			let letters = vec!["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"];
1426
1427			for (i, letter) in letters.iter().enumerate() {
1428				tree.import::<_, TestError>(*letter, i, i, &|_, _| Ok(false)).unwrap();
1429			}
1430
1431			// "L" is a descendent of "K", but the predicate will only pass for "K",
1432			// therefore only one call to `is_descendent_of` should be made
1433			assert_eq!(
1434				tree.finalize_with_descendent_if(
1435					&"L",
1436					11,
1437					&is_descendent_of,
1438					|i| *i == 10,
1439				),
1440				Ok(FinalizationResult::Changed(Some(10))),
1441			);
1442
1443			assert_eq!(
1444				n_is_descendent_of_calls.load(Ordering::SeqCst),
1445				1,
1446			);
1447		}
1448	}
1449
1450	#[test]
1451	fn find_node_works() {
1452		let (tree, is_descendent_of) = test_forktree();
1453
1454		let node = tree.find_node_where(
1455			&"D",
1456			&4,
1457			&is_descendent_of,
1458			&|_| true,
1459		).unwrap().unwrap();
1460
1461		assert_eq!(node.hash, "C");
1462		assert_eq!(node.number, 3);
1463	}
1464
1465	#[test]
1466	fn map_works() {
1467		let (tree, _is_descendent_of) = test_forktree();
1468
1469		let _tree = tree.map(&mut |_, _, _| ());
1470	}
1471
1472	#[test]
1473	fn prune_works() {
1474		let (mut tree, is_descendent_of) = test_forktree();
1475
1476		let removed = tree.prune(
1477			&"C",
1478			&3,
1479			&is_descendent_of,
1480			&|_| true,
1481		).unwrap();
1482
1483		assert_eq!(
1484			tree.roots.iter().map(|node| node.hash).collect::<Vec<_>>(),
1485			vec!["B"],
1486		);
1487
1488		assert_eq!(
1489			tree.iter().map(|(hash, _, _)| *hash).collect::<Vec<_>>(),
1490			vec!["B", "C", "D", "E"],
1491		);
1492
1493		assert_eq!(
1494			removed.map(|(hash, _, _)| hash).collect::<Vec<_>>(),
1495			vec!["A", "F", "H", "L", "M", "O", "I", "G", "J", "K"]
1496		);
1497
1498		let removed = tree.prune(
1499			&"E",
1500			&5,
1501			&is_descendent_of,
1502			&|_| true,
1503		).unwrap();
1504
1505		assert_eq!(
1506			tree.roots.iter().map(|node| node.hash).collect::<Vec<_>>(),
1507			vec!["D"],
1508		);
1509
1510		assert_eq!(
1511			tree.iter().map(|(hash, _, _)| *hash).collect::<Vec<_>>(),
1512			vec!["D", "E"],
1513		);
1514
1515		assert_eq!(
1516			removed.map(|(hash, _, _)| hash).collect::<Vec<_>>(),
1517			vec!["B", "C"]
1518		);
1519	}
1520
1521	#[test]
1522	fn find_node_backtracks_after_finding_highest_descending_node() {
1523		let mut tree = ForkTree::new();
1524
1525		//
1526		// A - B
1527		//  \
1528		//   — C
1529		//
1530		let is_descendent_of = |base: &&str, block: &&str| -> Result<bool, TestError> {
1531			match (*base, *block) {
1532				("A", b) => Ok(b == "B" || b == "C" || b == "D"),
1533				("B", b) | ("C", b) => Ok(b == "D"),
1534				("0", _) => Ok(true),
1535				_ => Ok(false),
1536			}
1537		};
1538
1539		tree.import("A", 1, 1, &is_descendent_of).unwrap();
1540		tree.import("B", 2, 2, &is_descendent_of).unwrap();
1541		tree.import("C", 2, 4, &is_descendent_of).unwrap();
1542
1543		// when searching the tree we reach node `C`, but the
1544		// predicate doesn't pass. we should backtrack to `B`, but not to `A`,
1545		// since "B" fulfills the predicate.
1546		let node = tree.find_node_where(
1547			&"D",
1548			&3,
1549			&is_descendent_of,
1550			&|data| *data < 3,
1551		).unwrap();
1552
1553		assert_eq!(node.unwrap().hash, "B");
1554	}
1555
1556	#[test]
1557	fn tree_rebalance() {
1558		let (mut tree, _) = test_forktree();
1559
1560		// the tree is automatically rebalanced on import, therefore we should iterate in preorder
1561		// exploring the longest forks first. check the ascii art above to understand the expected
1562		// output below.
1563		assert_eq!(
1564			tree.iter().map(|(h, _, _)| *h).collect::<Vec<_>>(),
1565			vec!["A", "B", "C", "D", "E", "F", "H", "L", "M", "O", "I", "G", "J", "K"],
1566		);
1567
1568		// let's add a block "P" which is a descendent of block "O"
1569		let is_descendent_of = |base: &&str, block: &&str| -> Result<bool, TestError> {
1570			match (*base, *block) {
1571				(b, "P") => Ok(vec!["A", "F", "L", "O"].into_iter().any(|n| n == b)),
1572				_ => Ok(false),
1573			}
1574		};
1575
1576		tree.import("P", 6, (), &is_descendent_of).unwrap();
1577
1578		// this should re-order the tree, since the branch "A -> B -> C -> D -> E" is no longer tied
1579		// with 5 blocks depth. additionally "O" should be visited before "M" now, since it has one
1580		// descendent "P" which makes that branch 6 blocks long.
1581		assert_eq!(
1582			tree.iter().map(|(h, _, _)| *h).collect::<Vec<_>>(),
1583			["A", "F", "H", "L", "O", "P", "M", "I", "G", "B", "C", "D", "E", "J", "K"]
1584		);
1585	}
1586}