diff --git a/core/src/core/mod.rs b/core/src/core/mod.rs index 38ab95315..af4f88fed 100644 --- a/core/src/core/mod.rs +++ b/core/src/core/mod.rs @@ -17,6 +17,7 @@ pub mod block; pub mod build; pub mod hash; +pub mod pmmr; pub mod sumtree; pub mod target; pub mod transaction; diff --git a/core/src/core/sumtree.rs b/core/src/core/sumtree.rs index 76018e1bf..9c551231b 100644 --- a/core/src/core/sumtree.rs +++ b/core/src/core/sumtree.rs @@ -403,7 +403,50 @@ where } } - // TODO push_many to allow bulk updates + fn clone_pruned_recurse(node: &NodeData) -> NodeData { + if node.full { + // replaces full internal nodes, leaves and already pruned nodes are full + // as well + NodeData { + full: true, + node: Node::Pruned(node.sum()), + hash: node.hash, + depth: node.depth, + } + } else { + if let Node::Internal { ref lchild, ref rchild, ref sum } = node.node { + // just recurse on each side to get the pruned version + NodeData { + full: false, + node: Node::Internal { + lchild: Box::new(SumTree::clone_pruned_recurse(lchild)), + rchild: Box::new(SumTree::clone_pruned_recurse(rchild)), + sum: sum.clone(), + }, + hash: node.hash, + depth: node.depth, + } + } else { + unreachable!() + } + } + } + + /// Minimal clone of this tree, replacing all full nodes with a pruned node, + /// therefore only copying non-full subtrees. + pub fn clone_pruned(&self) -> SumTree { + match self.root { + Some(ref node) => { + SumTree { + index: HashMap::new(), + root: Some(SumTree::clone_pruned_recurse(node)), + } + }, + None => SumTree::new(), + } + } + + // TODO push_many, truncate to allow bulk updates } // A SumTree is encoded as follows: an empty tree is the single byte 0x00.