mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-21 03:21:08 +03:00
Formatting
This commit is contained in:
parent
26ce1d27d7
commit
9703cba92a
1 changed files with 743 additions and 693 deletions
|
@ -16,8 +16,8 @@
|
|||
//! Generic sum-merkle tree. See `doc/merkle.md` for design and motivation for
|
||||
//! this structure. Most trees in Grin are stored and transmitted as either
|
||||
//! (a) only a root, or (b) the entire unpruned tree. For these it is sufficient
|
||||
//! to have a root-calculating function, for which the `compute_root` function should
|
||||
//! be used.
|
||||
//! to have a root-calculating function, for which the `compute_root` function
|
||||
//! should be used.
|
||||
//!
|
||||
//! The output set structure has much stronger requirements, as it is updated
|
||||
//! and pruned in place, and needs to be efficiently storable even when it is
|
||||
|
@ -29,10 +29,11 @@ use ser::{self, Readable, Reader, Writeable, Writer};
|
|||
use std::collections::HashMap;
|
||||
use std::{self, mem, ops};
|
||||
|
||||
/// Trait describing an object that has a well-defined sum that the tree can sum over
|
||||
/// Trait describing an object that has a well-defined sum that the tree can
|
||||
/// sum over
|
||||
pub trait Summable {
|
||||
/// The type of an object's sum
|
||||
type Sum: Clone + ops::Add<Output=Self::Sum> + Readable + Writeable;
|
||||
type Sum: Clone + ops::Add<Output = Self::Sum> + Readable + Writeable;
|
||||
|
||||
/// Obtain the sum of the object
|
||||
fn sum(&self) -> Self::Sum;
|
||||
|
@ -43,7 +44,9 @@ pub trait Summable {
|
|||
pub struct NullSum;
|
||||
impl ops::Add for NullSum {
|
||||
type Output = NullSum;
|
||||
fn add(self, _: NullSum) -> NullSum { NullSum }
|
||||
fn add(self, _: NullSum) -> NullSum {
|
||||
NullSum
|
||||
}
|
||||
}
|
||||
|
||||
impl Readable for NullSum {
|
||||
|
@ -62,7 +65,9 @@ impl Writeable for NullSum {
|
|||
pub struct NoSum<T>(T);
|
||||
impl<T> Summable for NoSum<T> {
|
||||
type Sum = NullSum;
|
||||
fn sum(&self) -> NullSum { NullSum }
|
||||
fn sum(&self) -> NullSum {
|
||||
NullSum
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -75,7 +80,7 @@ enum NodeData<T: Summable> {
|
|||
Internal {
|
||||
lchild: Box<Node<T>>,
|
||||
rchild: Box<Node<T>>,
|
||||
sum: T::Sum
|
||||
sum: T::Sum,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -85,7 +90,7 @@ impl<T: Summable> Summable for NodeData<T> {
|
|||
match *self {
|
||||
NodeData::Pruned(ref sum) => sum.clone(),
|
||||
NodeData::Leaf(ref data) => data.sum(),
|
||||
NodeData::Internal { ref sum, .. } => sum.clone()
|
||||
NodeData::Internal { ref sum, .. } => sum.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +100,7 @@ struct Node<T: Summable> {
|
|||
full: bool,
|
||||
data: NodeData<T>,
|
||||
hash: Hash,
|
||||
depth: u8
|
||||
depth: u8,
|
||||
}
|
||||
|
||||
impl<T: Summable> Summable for Node<T> {
|
||||
|
@ -115,14 +120,18 @@ impl<T: Summable> Node<T> {
|
|||
if self.full {
|
||||
1 << self.depth
|
||||
} else {
|
||||
if let NodeData::Internal{ ref lchild, ref rchild, .. } = self.data {
|
||||
if let NodeData::Internal {
|
||||
ref lchild,
|
||||
ref rchild,
|
||||
..
|
||||
} = self.data
|
||||
{
|
||||
lchild.n_children() + rchild.n_children()
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// An insertion ordered merkle sum tree.
|
||||
|
@ -131,17 +140,18 @@ pub struct SumTree<T: Summable + Writeable> {
|
|||
/// Index mapping data to its index in the tree
|
||||
index: HashMap<Hash, usize>,
|
||||
/// Tree contents
|
||||
root: Option<Node<T>>
|
||||
root: Option<Node<T>>,
|
||||
}
|
||||
|
||||
impl<T> SumTree<T>
|
||||
where T: Summable + Writeable
|
||||
where
|
||||
T: Summable + Writeable,
|
||||
{
|
||||
/// Create a new empty tree
|
||||
pub fn new() -> SumTree<T> {
|
||||
SumTree {
|
||||
index: HashMap::new(),
|
||||
root: None
|
||||
root: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,15 +182,25 @@ impl<T> SumTree<T>
|
|||
full: parent_full,
|
||||
data: parent_data,
|
||||
hash: parent_hash,
|
||||
depth: parent_depth
|
||||
depth: parent_depth,
|
||||
}
|
||||
// If we are inserting next to a partial node, we should actually be
|
||||
// inserting under the node, so we recurse. The right child of a partial
|
||||
// node is always another partial node or a leaf.
|
||||
} else {
|
||||
if let NodeData::Internal{ ref lchild, ref mut rchild, ref mut sum } = old.data {
|
||||
if let NodeData::Internal {
|
||||
ref lchild,
|
||||
ref mut rchild,
|
||||
ref mut sum,
|
||||
} = old.data
|
||||
{
|
||||
// Recurse
|
||||
let dummy_child = Node { full: true, data: NodeData::Pruned(sum.clone()), hash: old.hash, depth: 0 };
|
||||
let dummy_child = Node {
|
||||
full: true,
|
||||
data: NodeData::Pruned(sum.clone()),
|
||||
hash: old.hash,
|
||||
depth: 0,
|
||||
};
|
||||
let moved_rchild = mem::replace(&mut **rchild, dummy_child);
|
||||
mem::replace(&mut **rchild, SumTree::insert_right_of(moved_rchild, new));
|
||||
// Update this node's states to reflect the new right child
|
||||
|
@ -205,7 +225,7 @@ impl<T> SumTree<T>
|
|||
pub fn unpruned_len(&self) -> usize {
|
||||
match self.root {
|
||||
None => 0,
|
||||
Some(ref node) => node.n_children()
|
||||
Some(ref node) => node.n_children(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +247,7 @@ impl<T> SumTree<T>
|
|||
full: true,
|
||||
data: NodeData::Leaf(elem),
|
||||
hash: elem_hash,
|
||||
depth: 0
|
||||
depth: 0,
|
||||
});
|
||||
self.index.insert(index_hash, 0);
|
||||
return true;
|
||||
|
@ -242,7 +262,7 @@ impl<T> SumTree<T>
|
|||
full: true,
|
||||
data: NodeData::Leaf(elem),
|
||||
hash: elem_hash,
|
||||
depth: 0
|
||||
depth: 0,
|
||||
};
|
||||
|
||||
// Put new root in place and record insertion
|
||||
|
@ -261,7 +281,11 @@ impl<T> SumTree<T>
|
|||
node.data = NodeData::Leaf(new_elem);
|
||||
} else {
|
||||
match node.data {
|
||||
NodeData::Internal { ref mut lchild, ref mut rchild, ref mut sum } => {
|
||||
NodeData::Internal {
|
||||
ref mut lchild,
|
||||
ref mut rchild,
|
||||
ref mut sum,
|
||||
} => {
|
||||
let bit = index & (1 << (node.depth - 1));
|
||||
if bit > 0 {
|
||||
SumTree::replace_recurse(rchild, index - bit, new_elem);
|
||||
|
@ -273,7 +297,7 @@ impl<T> SumTree<T>
|
|||
}
|
||||
// Pruned data would not have been in the index
|
||||
NodeData::Pruned(_) => unreachable!(),
|
||||
NodeData::Leaf(_) => unreachable!()
|
||||
NodeData::Leaf(_) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -286,7 +310,9 @@ impl<T> SumTree<T>
|
|||
|
||||
let root = match self.root {
|
||||
Some(ref mut node) => node,
|
||||
None => { return false; }
|
||||
None => {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
match self.index.remove(&index_hash) {
|
||||
|
@ -324,14 +350,20 @@ impl<T> SumTree<T>
|
|||
} else {
|
||||
let mut prune_me = None;
|
||||
match node.data {
|
||||
NodeData::Internal { ref mut lchild, ref mut rchild, .. } => {
|
||||
NodeData::Internal {
|
||||
ref mut lchild,
|
||||
ref mut rchild,
|
||||
..
|
||||
} => {
|
||||
let bit = index & (1 << (node.depth - 1));
|
||||
if bit > 0 {
|
||||
SumTree::prune_recurse(rchild, index - bit);
|
||||
} else {
|
||||
SumTree::prune_recurse(lchild, index);
|
||||
}
|
||||
if let (&NodeData::Pruned(ref lsum), &NodeData::Pruned(ref rsum)) = (&lchild.data, &rchild.data) {
|
||||
if let (&NodeData::Pruned(ref lsum), &NodeData::Pruned(ref rsum)) =
|
||||
(&lchild.data, &rchild.data)
|
||||
{
|
||||
if node.full {
|
||||
prune_me = Some(lsum.clone() + rsum.clone());
|
||||
}
|
||||
|
@ -340,7 +372,7 @@ impl<T> SumTree<T>
|
|||
NodeData::Pruned(_) => {
|
||||
// Already pruned. Ok.
|
||||
}
|
||||
NodeData::Leaf(_) => unreachable!()
|
||||
NodeData::Leaf(_) => unreachable!(),
|
||||
}
|
||||
if let Some(sum) = prune_me {
|
||||
node.data = NodeData::Pruned(sum);
|
||||
|
@ -355,7 +387,9 @@ impl<T> SumTree<T>
|
|||
|
||||
let root = match self.root {
|
||||
Some(ref mut node) => node,
|
||||
None => { return false; }
|
||||
None => {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
match self.index.remove(&index_hash) {
|
||||
|
@ -384,18 +418,20 @@ impl<T> SumTree<T>
|
|||
// For a pruned internal node, it is followed by nothing.
|
||||
//
|
||||
impl<T> Writeable for SumTree<T>
|
||||
where T: Summable + Writeable
|
||||
where
|
||||
T: Summable + Writeable,
|
||||
{
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
|
||||
match self.root {
|
||||
None => writer.write_u8(0),
|
||||
Some(ref node) => node.write(writer)
|
||||
Some(ref node) => node.write(writer),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Writeable for Node<T>
|
||||
where T: Summable + Writeable
|
||||
where
|
||||
T: Summable + Writeable,
|
||||
{
|
||||
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), ser::Error> {
|
||||
assert!(self.depth < 64);
|
||||
|
@ -414,23 +450,28 @@ impl<T> Writeable for Node<T>
|
|||
try!(writer.write_u8(depth));
|
||||
try!(self.hash.write(writer));
|
||||
match self.data {
|
||||
NodeData::Pruned(ref sum) => {
|
||||
sum.write(writer)
|
||||
},
|
||||
NodeData::Leaf(ref data) => {
|
||||
data.write(writer)
|
||||
},
|
||||
NodeData::Internal { ref lchild, ref rchild, ref sum } => {
|
||||
NodeData::Pruned(ref sum) => sum.write(writer),
|
||||
NodeData::Leaf(ref data) => data.write(writer),
|
||||
NodeData::Internal {
|
||||
ref lchild,
|
||||
ref rchild,
|
||||
ref sum,
|
||||
} => {
|
||||
try!(sum.write(writer));
|
||||
try!(lchild.write(writer));
|
||||
rchild.write(writer)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn node_read_recurse<T>(reader: &mut Reader, index: &mut HashMap<Hash, usize>, tree_index: &mut usize) -> Result<Node<T>, ser::Error>
|
||||
where T: Summable + Readable + Hashed
|
||||
fn node_read_recurse<T>(
|
||||
reader: &mut Reader,
|
||||
index: &mut HashMap<Hash, usize>,
|
||||
tree_index: &mut usize,
|
||||
) -> Result<Node<T>, ser::Error>
|
||||
where
|
||||
T: Summable + Readable + Hashed,
|
||||
{
|
||||
// Read depth byte
|
||||
let depth = try!(reader.read_u8());
|
||||
|
@ -462,7 +503,7 @@ fn node_read_recurse<T>(reader: &mut Reader, index: &mut HashMap<Hash, usize>, t
|
|||
NodeData::Internal {
|
||||
lchild: Box::new(try!(node_read_recurse(reader, index, tree_index))),
|
||||
rchild: Box::new(try!(node_read_recurse(reader, index, tree_index))),
|
||||
sum: sum
|
||||
sum: sum,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -471,12 +512,13 @@ fn node_read_recurse<T>(reader: &mut Reader, index: &mut HashMap<Hash, usize>, t
|
|||
full: full,
|
||||
data: data,
|
||||
hash: hash,
|
||||
depth: depth
|
||||
depth: depth,
|
||||
})
|
||||
}
|
||||
|
||||
impl<T> Readable for SumTree<T>
|
||||
where T: Summable + Writeable + Readable + Hashed
|
||||
where
|
||||
T: Summable + Writeable + Readable + Hashed,
|
||||
{
|
||||
fn read(reader: &mut Reader) -> Result<SumTree<T>, ser::Error> {
|
||||
// Read depth byte of root node
|
||||
|
@ -489,7 +531,7 @@ impl<T> Readable for SumTree<T>
|
|||
if pruned && !full {
|
||||
return Ok(SumTree {
|
||||
index: HashMap::new(),
|
||||
root: None
|
||||
root: None,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -509,7 +551,7 @@ impl<T> Readable for SumTree<T>
|
|||
NodeData::Internal {
|
||||
lchild: Box::new(try!(node_read_recurse(reader, &mut index, &mut tree_index))),
|
||||
rchild: Box::new(try!(node_read_recurse(reader, &mut index, &mut tree_index))),
|
||||
sum: sum
|
||||
sum: sum,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -520,8 +562,8 @@ impl<T> Readable for SumTree<T>
|
|||
full: full,
|
||||
data: data,
|
||||
hash: hash,
|
||||
depth: depth
|
||||
})
|
||||
depth: depth,
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -535,8 +577,9 @@ const MAX_MMR_HEIGHT: usize = 48;
|
|||
/// https://github.com/opentimestamps/opentimestamps-server/blob/master/python-opentimestamps/opentimestamps/core/timestamp.py#L324
|
||||
///
|
||||
fn compute_peaks<S, I>(iter: I, peaks: &mut [Option<(u8, Hash, S)>])
|
||||
where S: Clone + ops::Add<Output=S> + Writeable,
|
||||
I: Iterator<Item=(u8, Hash, S)>
|
||||
where
|
||||
S: Clone + ops::Add<Output = S> + Writeable,
|
||||
I: Iterator<Item = (u8, Hash, S)>,
|
||||
{
|
||||
for peak in peaks.iter_mut() {
|
||||
*peak = None;
|
||||
|
@ -558,16 +601,20 @@ fn compute_peaks<S, I>(iter: I, peaks: &mut [Option<(u8, Hash, S)>])
|
|||
/// Directly compute the Merkle root of a sum-tree whose contents are given
|
||||
/// explicitly in the passed iterator.
|
||||
pub fn compute_root<'a, T, I>(iter: I) -> Option<(Hash, T::Sum)>
|
||||
where T: 'a + Summable + Writeable,
|
||||
I: Iterator<Item=&'a T>
|
||||
where
|
||||
T: 'a + Summable + Writeable,
|
||||
I: Iterator<Item = &'a T>,
|
||||
{
|
||||
let mut peaks = vec![None; MAX_MMR_HEIGHT];
|
||||
compute_peaks(iter.map(|elem| {
|
||||
compute_peaks(
|
||||
iter.map(|elem| {
|
||||
let depth = 0u8;
|
||||
let sum = elem.sum();
|
||||
let hash = (depth, &sum, Hashed::hash(elem)).hash();
|
||||
(depth, hash, sum)
|
||||
}), &mut peaks);
|
||||
}),
|
||||
&mut peaks,
|
||||
);
|
||||
|
||||
let mut ret = None;
|
||||
for peak in peaks {
|
||||
|
@ -587,8 +634,9 @@ pub fn compute_root<'a, T, I>(iter: I) -> Option<(Hash, T::Sum)>
|
|||
// a couple functions that help debugging
|
||||
#[allow(dead_code)]
|
||||
fn print_node<T>(node: &Node<T>, tab_level: usize)
|
||||
where T: Summable + Writeable,
|
||||
T::Sum: std::fmt::Debug
|
||||
where
|
||||
T: Summable + Writeable,
|
||||
T::Sum: std::fmt::Debug,
|
||||
{
|
||||
for _ in 0..tab_level {
|
||||
print!(" ");
|
||||
|
@ -597,7 +645,11 @@ fn print_node<T>(node: &Node<T>, tab_level: usize)
|
|||
match node.data {
|
||||
NodeData::Pruned(_) => println!(" X"),
|
||||
NodeData::Leaf(_) => println!(" L"),
|
||||
NodeData::Internal { ref lchild, ref rchild, .. } => {
|
||||
NodeData::Internal {
|
||||
ref lchild,
|
||||
ref rchild,
|
||||
..
|
||||
} => {
|
||||
println!(":");
|
||||
print_node(lchild, tab_level + 1);
|
||||
print_node(rchild, tab_level + 1);
|
||||
|
@ -607,8 +659,9 @@ fn print_node<T>(node: &Node<T>, tab_level: usize)
|
|||
|
||||
#[allow(dead_code)]
|
||||
fn print_tree<T>(tree: &SumTree<T>)
|
||||
where T: Summable + Writeable,
|
||||
T::Sum: std::fmt::Debug
|
||||
where
|
||||
T: Summable + Writeable,
|
||||
T::Sum: std::fmt::Debug,
|
||||
{
|
||||
match tree.root {
|
||||
None => println!("[empty tree]"),
|
||||
|
@ -632,9 +685,7 @@ mod test {
|
|||
fn sum(&self) -> u64 {
|
||||
// sums are not allowed to overflow, so we use this simple
|
||||
// non-injective "sum" function that will still be homomorphic
|
||||
self.0[0] as u64 * 0x1000 +
|
||||
self.0[1] as u64 * 0x100 +
|
||||
self.0[2] as u64 * 0x10 +
|
||||
self.0[0] as u64 * 0x1000 + self.0[1] as u64 * 0x100 + self.0[2] as u64 * 0x10 +
|
||||
self.0[3] as u64
|
||||
}
|
||||
}
|
||||
|
@ -679,10 +730,16 @@ mod test {
|
|||
}
|
||||
};
|
||||
|
||||
let mut elems = [TestElem([0, 0, 0, 1]), TestElem([0, 0, 0, 2]),
|
||||
TestElem([0, 0, 0, 3]), TestElem([0, 0, 0, 4]),
|
||||
TestElem([0, 0, 0, 5]), TestElem([0, 0, 0, 6]),
|
||||
TestElem([0, 0, 0, 7]), TestElem([1, 0, 0, 0])];
|
||||
let mut elems = [
|
||||
TestElem([0, 0, 0, 1]),
|
||||
TestElem([0, 0, 0, 2]),
|
||||
TestElem([0, 0, 0, 3]),
|
||||
TestElem([0, 0, 0, 4]),
|
||||
TestElem([0, 0, 0, 5]),
|
||||
TestElem([0, 0, 0, 6]),
|
||||
TestElem([0, 0, 0, 7]),
|
||||
TestElem([1, 0, 0, 0]),
|
||||
];
|
||||
|
||||
assert_eq!(tree.root_sum(), None);
|
||||
assert_eq!(tree.root_sum(), compute_root(elems[0..0].iter()));
|
||||
|
@ -702,9 +759,7 @@ mod test {
|
|||
assert_eq!(tree.contains(&elems[1]), None);
|
||||
assert!(tree.push(elems[1]));
|
||||
assert_eq!(tree.contains(&elems[1]), Some(1));
|
||||
let expected = node!(leaf!(elems[0]),
|
||||
leaf!(elems[1])
|
||||
).hash();
|
||||
let expected = node!(leaf!(elems[0]), leaf!(elems[1])).hash();
|
||||
assert_eq!(tree.root_sum(), Some((expected, 3)));
|
||||
assert_eq!(tree.root_sum(), compute_root(elems[0..2].iter()));
|
||||
assert_eq!(tree.unpruned_len(), 2);
|
||||
|
@ -714,10 +769,7 @@ mod test {
|
|||
assert_eq!(tree.contains(&elems[2]), None);
|
||||
assert!(tree.push(elems[2]));
|
||||
assert_eq!(tree.contains(&elems[2]), Some(2));
|
||||
let expected = node!(node!(leaf!(elems[0]),
|
||||
leaf!(elems[1])),
|
||||
leaf!(elems[2])
|
||||
).hash();
|
||||
let expected = node!(node!(leaf!(elems[0]), leaf!(elems[1])), leaf!(elems[2])).hash();
|
||||
assert_eq!(tree.root_sum(), Some((expected, 6)));
|
||||
assert_eq!(tree.root_sum(), compute_root(elems[0..3].iter()));
|
||||
assert_eq!(tree.unpruned_len(), 3);
|
||||
|
@ -727,10 +779,9 @@ mod test {
|
|||
assert_eq!(tree.contains(&elems[3]), None);
|
||||
assert!(tree.push(elems[3]));
|
||||
assert_eq!(tree.contains(&elems[3]), Some(3));
|
||||
let expected = node!(node!(leaf!(elems[0]),
|
||||
leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]),
|
||||
leaf!(elems[3]))
|
||||
let expected = node!(
|
||||
node!(leaf!(elems[0]), leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]), leaf!(elems[3]))
|
||||
).hash();
|
||||
assert_eq!(tree.root_sum(), Some((expected, 10)));
|
||||
assert_eq!(tree.root_sum(), compute_root(elems[0..4].iter()));
|
||||
|
@ -741,10 +792,11 @@ mod test {
|
|||
assert_eq!(tree.contains(&elems[4]), None);
|
||||
assert!(tree.push(elems[4]));
|
||||
assert_eq!(tree.contains(&elems[4]), Some(4));
|
||||
let expected = node!(node!(node!(leaf!(elems[0]),
|
||||
leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]),
|
||||
leaf!(elems[3]))),
|
||||
let expected = node!(
|
||||
node!(
|
||||
node!(leaf!(elems[0]), leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]), leaf!(elems[3]))
|
||||
),
|
||||
leaf!(elems[4])
|
||||
).hash();
|
||||
assert_eq!(tree.root_sum(), Some((expected, 15)));
|
||||
|
@ -756,12 +808,12 @@ mod test {
|
|||
assert_eq!(tree.contains(&elems[5]), None);
|
||||
assert!(tree.push(elems[5]));
|
||||
assert_eq!(tree.contains(&elems[5]), Some(5));
|
||||
let expected = node!(node!(node!(leaf!(elems[0]),
|
||||
leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]),
|
||||
leaf!(elems[3]))),
|
||||
node!(leaf!(elems[4]),
|
||||
leaf!(elems[5]))
|
||||
let expected = node!(
|
||||
node!(
|
||||
node!(leaf!(elems[0]), leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]), leaf!(elems[3]))
|
||||
),
|
||||
node!(leaf!(elems[4]), leaf!(elems[5]))
|
||||
).hash();
|
||||
assert_eq!(tree.root_sum(), Some((expected, 21)));
|
||||
assert_eq!(tree.root_sum(), compute_root(elems[0..6].iter()));
|
||||
|
@ -772,13 +824,12 @@ mod test {
|
|||
assert_eq!(tree.contains(&elems[6]), None);
|
||||
assert!(tree.push(elems[6]));
|
||||
assert_eq!(tree.contains(&elems[6]), Some(6));
|
||||
let expected = node!(node!(node!(leaf!(elems[0]),
|
||||
leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]),
|
||||
leaf!(elems[3]))),
|
||||
node!(node!(leaf!(elems[4]),
|
||||
leaf!(elems[5])),
|
||||
leaf!(elems[6]))
|
||||
let expected = node!(
|
||||
node!(
|
||||
node!(leaf!(elems[0]), leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]), leaf!(elems[3]))
|
||||
),
|
||||
node!(node!(leaf!(elems[4]), leaf!(elems[5])), leaf!(elems[6]))
|
||||
).hash();
|
||||
assert_eq!(tree.root_sum(), Some((expected, 28)));
|
||||
assert_eq!(tree.root_sum(), compute_root(elems[0..7].iter()));
|
||||
|
@ -789,14 +840,15 @@ mod test {
|
|||
assert_eq!(tree.contains(&elems[7]), None);
|
||||
assert!(tree.push(elems[7]));
|
||||
assert_eq!(tree.contains(&elems[7]), Some(7));
|
||||
let expected = node!(node!(node!(leaf!(elems[0]),
|
||||
leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]),
|
||||
leaf!(elems[3]))),
|
||||
node!(node!(leaf!(elems[4]),
|
||||
leaf!(elems[5])),
|
||||
node!(leaf!(elems[6]),
|
||||
leaf!(elems[7])))
|
||||
let expected = node!(
|
||||
node!(
|
||||
node!(leaf!(elems[0]), leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]), leaf!(elems[3]))
|
||||
),
|
||||
node!(
|
||||
node!(leaf!(elems[4]), leaf!(elems[5])),
|
||||
node!(leaf!(elems[6]), leaf!(elems[7]))
|
||||
)
|
||||
).hash();
|
||||
assert_eq!(tree.root_sum(), Some((expected, 28 + 0x1000)));
|
||||
assert_eq!(tree.root_sum(), compute_root(elems[0..8].iter()));
|
||||
|
@ -814,14 +866,15 @@ mod test {
|
|||
assert_eq!(tree.contains(&elems[i]), Some(i));
|
||||
assert_eq!(tree.contains(&old_elem), None);
|
||||
}
|
||||
let expected = node!(node!(node!(leaf!(elems[0]),
|
||||
leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]),
|
||||
leaf!(elems[3]))),
|
||||
node!(node!(leaf!(elems[4]),
|
||||
leaf!(elems[5])),
|
||||
node!(leaf!(elems[6]),
|
||||
leaf!(elems[7])))
|
||||
let expected = node!(
|
||||
node!(
|
||||
node!(leaf!(elems[0]), leaf!(elems[1])),
|
||||
node!(leaf!(elems[2]), leaf!(elems[3]))
|
||||
),
|
||||
node!(
|
||||
node!(leaf!(elems[4]), leaf!(elems[5])),
|
||||
node!(leaf!(elems[6]), leaf!(elems[7]))
|
||||
)
|
||||
).hash();
|
||||
assert_eq!(tree.root_sum(), Some((expected, 28 + 36 * 0x10 + 0x1000)));
|
||||
assert_eq!(tree.root_sum(), compute_root(elems[0..8].iter()));
|
||||
|
@ -903,6 +956,3 @@ mod test {
|
|||
assert!(tree.push(elem));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue