Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d69971a

Browse files
committedFeb 20, 2023
fix issues and add more tests
1 parent 2bcfdb3 commit d69971a

File tree

2 files changed

+33
-19
lines changed

2 files changed

+33
-19
lines changed
 

‎base_layer/mmr/src/balanced_binary_merkle_proof.rs

+31-17
Original file line numberDiff line numberDiff line change
@@ -30,41 +30,44 @@ use crate::{common::hash_together, BalancedBinaryMerkleTree, Hash};
3030
#[derive(Debug)]
3131
pub struct BalancedBinaryMerkleProof<D> {
3232
pub path: Vec<Hash>,
33-
pub leaf_index: usize,
33+
pub node_index: usize,
3434
_phantom: PhantomData<D>,
3535
}
3636

37+
// Since this is balanced tree, the index `2k+1` is always left child and `2k` is right child
38+
3739
impl<D> BalancedBinaryMerkleProof<D>
3840
where D: Digest + DomainDigest
3941
{
40-
pub fn verify_consume(mut self, root: &Hash, leaf_hash: Hash) -> bool {
42+
pub fn verify(&self, root: &Hash, leaf_hash: Hash) -> bool {
4143
let mut computed_root = leaf_hash;
44+
let mut node_index = self.node_index;
4245
for sibling in self.path.iter() {
43-
if self.leaf_index & 1 == 1 {
46+
if node_index & 1 == 1 {
4447
computed_root = hash_together::<D>(&computed_root, sibling);
4548
} else {
4649
computed_root = hash_together::<D>(sibling, &computed_root);
4750
}
48-
self.leaf_index = (self.leaf_index - 1) >> 1;
51+
node_index = (node_index - 1) >> 1;
4952
}
5053
&computed_root == root
5154
}
5255

5356
pub fn generate_proof(tree: &BalancedBinaryMerkleTree<D>, leaf_index: usize) -> Self {
54-
let mut index = tree.get_leaf_index(leaf_index);
57+
let mut node_index = tree.get_node_index(leaf_index);
5558
let mut proof = Vec::new();
56-
while index > 0 {
59+
while node_index > 0 {
5760
// Sibling
58-
let parent = (index - 1) >> 1;
61+
let parent = (node_index - 1) >> 1;
5962
// The children are 2i+1 and 2i+2, so together are 4i+3, we substract one, we get the other.
60-
let sibling = 4 * parent + 3 - index;
63+
let sibling = 4 * parent + 3 - node_index;
6164
proof.push(tree.get_hash(sibling).clone());
62-
// Parent
63-
index = parent;
65+
// Traverse to parent
66+
node_index = parent;
6467
}
6568
Self {
6669
path: proof,
67-
leaf_index: tree.get_leaf_index(leaf_index),
70+
node_index: tree.get_node_index(leaf_index),
6871
_phantom: PhantomData,
6972
}
7073
}
@@ -78,11 +81,22 @@ mod test {
7881
hash_domain!(TestDomain, "testing", 0);
7982

8083
#[test]
81-
fn test_generate_and_verify() {
82-
let leaves = vec![vec![0; 32]; 3000];
83-
let bmt = BalancedBinaryMerkleTree::<DomainSeparatedHasher<Blake256, TestDomain>>::create(leaves);
84-
let root = bmt.get_merkle_root();
85-
let proof = BalancedBinaryMerkleProof::generate_proof(&bmt, 0);
86-
assert!(proof.verify_consume(&root, vec![0; 32]));
84+
fn test_generate_and_verify_big_tree() {
85+
for n in [1usize, 100, 1000, 10000] {
86+
let leaves = (0..n)
87+
.map(|i| [i.to_le_bytes().to_vec(), vec![0u8; 24]].concat())
88+
.collect::<Vec<_>>();
89+
let hash_0 = leaves[0].clone();
90+
let hash_n_half = leaves[n / 2].clone();
91+
let hash_last = leaves[n - 1].clone();
92+
let bmt = BalancedBinaryMerkleTree::<DomainSeparatedHasher<Blake256, TestDomain>>::create(leaves);
93+
let root = bmt.get_merkle_root();
94+
let proof = BalancedBinaryMerkleProof::generate_proof(&bmt, 0);
95+
assert!(proof.verify(&root, hash_0));
96+
let proof = BalancedBinaryMerkleProof::generate_proof(&bmt, n / 2);
97+
assert!(proof.verify(&root, hash_n_half));
98+
let proof = BalancedBinaryMerkleProof::generate_proof(&bmt, n - 1);
99+
assert!(proof.verify(&root, hash_last));
100+
}
87101
}
88102
}

‎base_layer/mmr/src/balanced_binary_merkle_tree.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ where D: Digest + DomainDigest
8080
}
8181

8282
pub fn get_leaf(&self, leaf_index: usize) -> &Hash {
83-
&self.hashes[leaf_index + (self.hashes.len() >> 1)]
83+
self.get_hash(self.get_node_index(leaf_index))
8484
}
8585

86-
pub(crate) fn get_leaf_index(&self, leaf_index: usize) -> usize {
86+
pub(crate) fn get_node_index(&self, leaf_index: usize) -> usize {
8787
leaf_index + (self.hashes.len() >> 1)
8888
}
8989

0 commit comments

Comments
 (0)
Please sign in to comment.