From b8407f792b869b07603a872f3a508fc4c8293ae0 Mon Sep 17 00:00:00 2001 From: Brandon Vrooman Date: Mon, 10 Jul 2023 14:31:41 -0400 Subject: [PATCH] bug: Remove leaf data from BMT proofs (#502) * Update BMT prove and verify * Update binary.rs * Update * Update test helpers verify * Clippy * comment * Clippy * Update merkle_tree.rs * whitespace * fmt * Update CHANGELOG.md --- CHANGELOG.md | 7 + fuel-merkle/src/binary/in_memory.rs | 89 +++----- fuel-merkle/src/binary/merkle_tree.rs | 193 ++++++------------ fuel-merkle/src/binary/verify.rs | 44 ++-- fuel-merkle/src/sparse/in_memory.rs | 5 +- .../test-helpers/src/binary/merkle_tree.rs | 48 ++--- fuel-merkle/test-helpers/src/binary/verify.rs | 93 +++++---- fuel-merkle/test-helpers/src/data/binary.rs | 11 +- .../fixtures/Test 0 Leaves.yaml | 4 +- .../fixtures/Test 1 Leaf Index 0.yaml | 4 +- .../Test 1 Leaf Invalid Proof Index.yaml | 4 +- .../fixtures/Test 1 Leaf Invalid Root.yaml | 4 +- .../fixtures/Test 10 Leaves Index 4.yaml | 2 - .../fixtures/Test 100 Leaves Index 10.yaml | 2 - .../fixtures/Test 1024 Leaves Index 512.yaml | 2 - .../Test 1024 Leaves Invalid Root.yaml | 2 - 16 files changed, 202 insertions(+), 312 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7da5f15836..f556cbb52e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/). Description of the upcoming release here. +### Breaking + +- [#502](https://github.com/FuelLabs/fuel-vm/pull/502) The algorithm used by the + binary Merkle tree for generating Merkle proofs has been updated to remove + the leaf data from the proof set. This change allows BMT proofs to conform + to the format expected by the Solidity contracts used for verifying proofs. + ## [Version 0.34.1] Mainly new opcodes prices and small performance improvements in the `BinaryMerkleTree`. diff --git a/fuel-merkle/src/binary/in_memory.rs b/fuel-merkle/src/binary/in_memory.rs index 90fb0d35bc..c082d2f81a 100644 --- a/fuel-merkle/src/binary/in_memory.rs +++ b/fuel-merkle/src/binary/in_memory.rs @@ -171,12 +171,9 @@ mod test { let leaf_0 = leaf_sum(data[0]); { - let proof = tree.prove(0).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(0).unwrap(); assert_eq!(root, leaf_0); - assert_eq!(set[0], leaf_0); + assert!(proof_set.is_empty()); } } @@ -220,80 +217,52 @@ mod test { let node_7 = node_sum(&node_3, &node_11); { - let proof = tree.prove(0).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(0).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_0); - assert_eq!(set[1], leaf_1); - assert_eq!(set[2], node_5); - assert_eq!(set[3], node_11); + assert_eq!(proof_set[0], leaf_1); + assert_eq!(proof_set[1], node_5); + assert_eq!(proof_set[2], node_11); } { - let proof = tree.prove(1).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(1).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_1); - assert_eq!(set[1], leaf_0); - assert_eq!(set[2], node_5); - assert_eq!(set[3], node_11); + assert_eq!(proof_set[0], leaf_0); + assert_eq!(proof_set[1], node_5); + assert_eq!(proof_set[2], node_11); } { - let proof = tree.prove(2).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(2).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_2); - assert_eq!(set[1], leaf_3); - assert_eq!(set[2], node_1); - assert_eq!(set[3], node_11); + assert_eq!(proof_set[0], leaf_3); + assert_eq!(proof_set[1], node_1); + assert_eq!(proof_set[2], node_11); } { - let proof = tree.prove(3).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(3).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_3); - assert_eq!(set[1], leaf_2); - assert_eq!(set[2], node_1); - assert_eq!(set[3], node_11); + assert_eq!(proof_set[0], leaf_2); + assert_eq!(proof_set[1], node_1); + assert_eq!(proof_set[2], node_11); } { - let proof = tree.prove(4).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(4).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_4); - assert_eq!(set[1], leaf_5); - assert_eq!(set[2], leaf_6); - assert_eq!(set[3], node_3); + assert_eq!(proof_set[0], leaf_5); + assert_eq!(proof_set[1], leaf_6); + assert_eq!(proof_set[2], node_3); } { - let proof = tree.prove(5).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(5).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_5); - assert_eq!(set[1], leaf_4); - assert_eq!(set[2], leaf_6); - assert_eq!(set[3], node_3); + assert_eq!(proof_set[0], leaf_4); + assert_eq!(proof_set[1], leaf_6); + assert_eq!(proof_set[2], node_3); } { - let proof = tree.prove(6).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(6).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_6); - assert_eq!(set[1], node_9); - assert_eq!(set[2], node_3); + assert_eq!(proof_set[0], node_9); + assert_eq!(proof_set[1], node_3); } } } diff --git a/fuel-merkle/src/binary/merkle_tree.rs b/fuel-merkle/src/binary/merkle_tree.rs index 68662a94fa..2b92b2c631 100644 --- a/fuel-merkle/src/binary/merkle_tree.rs +++ b/fuel-merkle/src/binary/merkle_tree.rs @@ -172,14 +172,6 @@ where let root_position = self.root_position(); let leaf_position = Position::from_leaf_index(proof_index); - let primitive = self - .storage - .get(&leaf_position.in_order_index())? - .ok_or(MerkleTreeError::LoadError(proof_index))? - .into_owned(); - let leaf_node = Node::from(primitive); - proof_set.push(*leaf_node.hash()); - let (_, mut side_positions): (Vec<_>, Vec<_>) = root_position .path(&leaf_position, self.leaves_count) .iter() @@ -653,12 +645,9 @@ mod test { let leaf_0 = leaf_sum(data[0]); { - let proof = tree.prove(0).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(0).unwrap(); assert_eq!(root, leaf_0); - assert_eq!(set[0], leaf_0); + assert!(proof_set.is_empty()); } } @@ -690,44 +679,28 @@ mod test { let node_3 = node_sum(&node_1, &node_5); { - let proof = tree.prove(0).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(0).unwrap(); assert_eq!(root, node_3); - assert_eq!(set[0], leaf_0); - assert_eq!(set[1], leaf_1); - assert_eq!(set[2], node_5); + assert_eq!(proof_set[0], leaf_1); + assert_eq!(proof_set[1], node_5); } { - let proof = tree.prove(1).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(1).unwrap(); assert_eq!(root, node_3); - assert_eq!(set[0], leaf_1); - assert_eq!(set[1], leaf_0); - assert_eq!(set[2], node_5); + assert_eq!(proof_set[0], leaf_0); + assert_eq!(proof_set[1], node_5); } { - let proof = tree.prove(2).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(2).unwrap(); assert_eq!(root, node_3); - assert_eq!(set[0], leaf_2); - assert_eq!(set[1], leaf_3); - assert_eq!(set[2], node_1); + assert_eq!(proof_set[0], leaf_3); + assert_eq!(proof_set[1], node_1); } { - let proof = tree.prove(3).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(3).unwrap(); assert_eq!(root, node_3); - assert_eq!(set[0], leaf_3); - assert_eq!(set[1], leaf_2); - assert_eq!(set[2], node_1); + assert_eq!(proof_set[0], leaf_2); + assert_eq!(proof_set[1], node_1); } } @@ -764,57 +737,37 @@ mod test { let node_7 = node_sum(&node_3, &leaf_4); { - let proof = tree.prove(0).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(0).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_0); - assert_eq!(set[1], leaf_1); - assert_eq!(set[2], node_5); - assert_eq!(set[3], leaf_4); + assert_eq!(proof_set[0], leaf_1); + assert_eq!(proof_set[1], node_5); + assert_eq!(proof_set[2], leaf_4); } { - let proof = tree.prove(1).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(1).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_1); - assert_eq!(set[1], leaf_0); - assert_eq!(set[2], node_5); - assert_eq!(set[3], leaf_4); + assert_eq!(proof_set[0], leaf_0); + assert_eq!(proof_set[1], node_5); + assert_eq!(proof_set[2], leaf_4); } { - let proof = tree.prove(2).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(2).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_2); - assert_eq!(set[1], leaf_3); - assert_eq!(set[2], node_1); - assert_eq!(set[3], leaf_4); + assert_eq!(proof_set[0], leaf_3); + assert_eq!(proof_set[1], node_1); + assert_eq!(proof_set[2], leaf_4); } { - let proof = tree.prove(3).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(3).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_3); - assert_eq!(set[1], leaf_2); - assert_eq!(set[2], node_1); - assert_eq!(set[3], leaf_4); + assert_eq!(proof_set[0], leaf_2); + assert_eq!(proof_set[1], node_1); + assert_eq!(proof_set[2], leaf_4); } { - let proof = tree.prove(4).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(4).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_4); - assert_eq!(set[1], node_3); + assert_eq!(proof_set[0], node_3); } } @@ -859,80 +812,52 @@ mod test { let node_7 = node_sum(&node_3, &node_11); { - let proof = tree.prove(0).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(0).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_0); - assert_eq!(set[1], leaf_1); - assert_eq!(set[2], node_5); - assert_eq!(set[3], node_11); + assert_eq!(proof_set[0], leaf_1); + assert_eq!(proof_set[1], node_5); + assert_eq!(proof_set[2], node_11); } { - let proof = tree.prove(1).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(1).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_1); - assert_eq!(set[1], leaf_0); - assert_eq!(set[2], node_5); - assert_eq!(set[3], node_11); + assert_eq!(proof_set[0], leaf_0); + assert_eq!(proof_set[1], node_5); + assert_eq!(proof_set[2], node_11); } { - let proof = tree.prove(2).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(2).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_2); - assert_eq!(set[1], leaf_3); - assert_eq!(set[2], node_1); - assert_eq!(set[3], node_11); + assert_eq!(proof_set[0], leaf_3); + assert_eq!(proof_set[1], node_1); + assert_eq!(proof_set[2], node_11); } { - let proof = tree.prove(3).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(3).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_3); - assert_eq!(set[1], leaf_2); - assert_eq!(set[2], node_1); - assert_eq!(set[3], node_11); + assert_eq!(proof_set[0], leaf_2); + assert_eq!(proof_set[1], node_1); + assert_eq!(proof_set[2], node_11); } { - let proof = tree.prove(4).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(4).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_4); - assert_eq!(set[1], leaf_5); - assert_eq!(set[2], leaf_6); - assert_eq!(set[3], node_3); + assert_eq!(proof_set[0], leaf_5); + assert_eq!(proof_set[1], leaf_6); + assert_eq!(proof_set[2], node_3); } { - let proof = tree.prove(5).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(5).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_5); - assert_eq!(set[1], leaf_4); - assert_eq!(set[2], leaf_6); - assert_eq!(set[3], node_3); + assert_eq!(proof_set[0], leaf_4); + assert_eq!(proof_set[1], leaf_6); + assert_eq!(proof_set[2], node_3); } { - let proof = tree.prove(6).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(6).unwrap(); assert_eq!(root, node_7); - assert_eq!(set[0], leaf_6); - assert_eq!(set[1], node_9); - assert_eq!(set[2], node_3); + assert_eq!(proof_set[0], node_9); + assert_eq!(proof_set[1], node_3); } } diff --git a/fuel-merkle/src/binary/verify.rs b/fuel-merkle/src/binary/verify.rs index 475c0979e1..14374d5bb9 100644 --- a/fuel-merkle/src/binary/verify.rs +++ b/fuel-merkle/src/binary/verify.rs @@ -11,44 +11,39 @@ use crate::{ pub fn verify>( root: &Bytes32, - digest: T, + data: &T, proof_set: &ProofSet, proof_index: u64, num_leaves: u64, ) -> bool { + let mut sum = leaf_sum(data.as_ref()); + if proof_index >= num_leaves { return false } if proof_set.is_empty() { - return false - } - - let mut height = 0usize; - let mut sum = proof_set[height]; - height += 1; - - let digest = leaf_sum(digest.as_ref()); - if digest != sum { - return false + return if num_leaves == 1 { *root == sum } else { false } } + let mut height = 1usize; let mut stable_end = proof_index; loop { let subtree_start_index = proof_index / (1 << height) * (1 << height); let subtree_end_index = subtree_start_index + (1 << height) - 1; + if subtree_end_index >= num_leaves { break } stable_end = subtree_end_index; - if proof_set.len() <= height { + if proof_set.len() < height { return false } - let proof_data = proof_set[height]; + let proof_data = proof_set[height - 1]; if proof_index - subtree_start_index < 1 << (height - 1) { sum = node_sum(&sum, &proof_data); } else { @@ -59,16 +54,16 @@ pub fn verify>( } if stable_end != num_leaves - 1 { - if proof_set.len() <= height { + if proof_set.len() < height { return false } - let proof_data = proof_set[height]; + let proof_data = proof_set[height - 1]; sum = node_sum(&sum, &proof_data); height += 1; } - while height < proof_set.len() { - let proof_data = proof_set[height]; + while height - 1 < proof_set.len() { + let proof_data = proof_set[height - 1]; sum = node_sum(&proof_data, &sum); height += 1; } @@ -112,14 +107,11 @@ mod test { tree.push(datum).unwrap(); } - let proof = tree.prove(PROOF_INDEX as u64).unwrap(); - let root = proof.0; - let set = proof.1; - + let (root, proof_set) = tree.prove(PROOF_INDEX as u64).unwrap(); let verification = verify( &root, - TEST_DATA[PROOF_INDEX], - &set, + &TEST_DATA[PROOF_INDEX], + &proof_set, PROOF_INDEX as u64, LEAVES_COUNT as u64, ); @@ -160,7 +152,7 @@ mod test { let verification = verify( &root, - TEST_DATA[PROOF_INDEX], + &TEST_DATA[PROOF_INDEX], &set, PROOF_INDEX as u64, LEAVES_COUNT as u64, @@ -175,7 +167,7 @@ mod test { let verification = verify( &Default::default(), - TEST_DATA[PROOF_INDEX], + &TEST_DATA[PROOF_INDEX], &vec![], PROOF_INDEX as u64, LEAVES_COUNT as u64, @@ -202,7 +194,7 @@ mod test { let verification = verify( &root, - TEST_DATA[PROOF_INDEX], + &TEST_DATA[PROOF_INDEX], &set, PROOF_INDEX as u64 + 15, LEAVES_COUNT as u64, diff --git a/fuel-merkle/src/sparse/in_memory.rs b/fuel-merkle/src/sparse/in_memory.rs index 56685f2c50..e6202ff7be 100644 --- a/fuel-merkle/src/sparse/in_memory.rs +++ b/fuel-merkle/src/sparse/in_memory.rs @@ -107,9 +107,8 @@ impl MerkleTree { } } - let tree = - sparse::MerkleTree::::from_set(EmptyStorage::default(), set) - .expect("`Storage` can't return error"); + let tree = sparse::MerkleTree::::from_set(EmptyStorage, set) + .expect("`Storage` can't return error"); tree.root() } diff --git a/fuel-merkle/test-helpers/src/binary/merkle_tree.rs b/fuel-merkle/test-helpers/src/binary/merkle_tree.rs index 4143051d1d..ac27d85366 100644 --- a/fuel-merkle/test-helpers/src/binary/merkle_tree.rs +++ b/fuel-merkle/test-helpers/src/binary/merkle_tree.rs @@ -5,6 +5,7 @@ use crate::binary::{ Data, Node, }; +use std::collections::VecDeque; type DataNode = Node; type ProofSet = Vec; @@ -88,7 +89,14 @@ impl MerkleTree { current = current.take_next().unwrap(); } - (self.root(), self.proof_set) + let root = self.root(); + + // The proof set starts with the hashed leaf data; remove the leaf data + // in order to conform with the proof set specification. + let mut proof_set = VecDeque::from(self.proof_set); + proof_set.pop_front(); + + (root, proof_set.into()) } // PRIVATE @@ -299,9 +307,7 @@ mod test { mt.push(datum); } - let proof = mt.prove(); - let root = proof.0; - let set = proof.1; + let (root, proof_set) = mt.prove(); // N3 // / \ @@ -320,8 +326,8 @@ mod test { let node_3 = node_sum(&node_1, &node_2); assert_eq!(root, node_3); - assert_eq!(set[0], leaf_1); - assert_eq!(set[1], leaf_2); + assert_eq!(proof_set[0], leaf_2); + assert_eq!(proof_set[1], node_2); } #[test] @@ -335,9 +341,7 @@ mod test { mt.push(datum); } - let proof = mt.prove(); - let root = proof.0; - let set = proof.1; + let (root, proof_set) = mt.prove(); // N4 // / \ @@ -360,10 +364,9 @@ mod test { let node_4 = node_sum(&node_3, &leaf_5); assert_eq!(root, node_4); - assert_eq!(set[0], leaf_3); - assert_eq!(set[1], leaf_4); - assert_eq!(set[2], node_1); - assert_eq!(set[3], leaf_5); + assert_eq!(proof_set[0], leaf_4); + assert_eq!(proof_set[1], node_1); + assert_eq!(proof_set[2], leaf_5); } #[test] @@ -377,9 +380,7 @@ mod test { mt.push(datum); } - let proof = mt.prove(); - let root = proof.0; - let set = proof.1; + let (root, proof_set) = mt.prove(); // N4 // / \ @@ -402,17 +403,13 @@ mod test { let node_4 = node_sum(&node_3, &leaf_5); assert_eq!(root, node_4); - assert_eq!(set[0], leaf_5); - assert_eq!(set[1], node_3); + assert_eq!(proof_set[0], node_3); } #[test] fn prove_returns_the_root_of_the_empty_merkle_tree_when_no_leaves_are_added() { let mt = MerkleTree::new(); - - let proof = mt.prove(); - let root = proof.0; - + let (root, _proof_set) = mt.prove(); let expected_root = empty_sum(); assert_eq!(&root, expected_root); } @@ -420,10 +417,7 @@ mod test { #[test] fn prove_returns_an_empty_proof_set_when_no_leaves_are_added() { let mt = MerkleTree::new(); - - let proof = mt.prove(); - let set = proof.1; - - assert_eq!(set.len(), 0); + let (_root, proof_set) = mt.prove(); + assert!(proof_set.is_empty()); } } diff --git a/fuel-merkle/test-helpers/src/binary/verify.rs b/fuel-merkle/test-helpers/src/binary/verify.rs index b2b3798a03..73a37e8c0e 100644 --- a/fuel-merkle/test-helpers/src/binary/verify.rs +++ b/fuel-merkle/test-helpers/src/binary/verify.rs @@ -1,42 +1,44 @@ use crate::binary::{ + leaf_sum, node_sum, Data, }; -pub fn verify( +pub fn verify>( root: &Data, + data: &T, proof_set: &Vec, proof_index: u64, num_leaves: u64, ) -> bool { + let mut sum = leaf_sum(data.as_ref()); + if proof_index >= num_leaves { return false } if proof_set.is_empty() { - return false + return if num_leaves == 1 { *root == sum } else { false } } - let mut height = 0usize; - let mut sum = proof_set[height]; - height += 1; - + let mut height = 1usize; let mut stable_end = proof_index; loop { let subtree_start_index = proof_index / (1 << height) * (1 << height); let subtree_end_index = subtree_start_index + (1 << height) - 1; + if subtree_end_index >= num_leaves { break } stable_end = subtree_end_index; - if proof_set.len() <= height { + if proof_set.len() < height { return false } - let proof_data = proof_set[height]; + let proof_data = proof_set[height - 1]; if proof_index - subtree_start_index < 1 << (height - 1) { sum = node_sum(&sum, &proof_data); } else { @@ -47,16 +49,16 @@ pub fn verify( } if stable_end != num_leaves - 1 { - if proof_set.len() <= height { + if proof_set.len() < height { return false } - let proof_data = proof_set[height]; + let proof_data = proof_set[height - 1]; sum = node_sum(&sum, &proof_data); height += 1; } - while height < proof_set.len() { - let proof_data = proof_set[height]; + while height - 1 < proof_set.len() { + let proof_data = proof_set[height - 1]; sum = node_sum(&proof_data, &sum); height += 1; } @@ -68,25 +70,33 @@ pub fn verify( mod test { use super::verify; use crate::{ - binary::MerkleTree, + binary::{ + Data, + MerkleTree, + }, TEST_DATA, }; #[test] fn verify_returns_true_when_the_given_proof_set_matches_the_given_merkle_root() { + let proof_index = 2; + let mut mt = MerkleTree::new(); - mt.set_proof_index(2); + mt.set_proof_index(proof_index); let data = &TEST_DATA[0..5]; // 5 leaves for datum in data.iter() { mt.push(datum); } - let proof = mt.prove(); - let root = proof.0; - let set = proof.1; - - let verification = verify(&root, &set, 2, 5); + let (root, proof_set) = mt.prove(); + let verification = verify( + &root, + &data[proof_index as usize], + &proof_set, + proof_index, + data.len() as u64, + ); assert!(verification); } @@ -97,60 +107,65 @@ mod test { // another tree's proof set: because the two roots come from different // trees, the comparison should fail. + let proof_index = 2; + // Generate the first Merkle tree and get its root let mut mt = MerkleTree::new(); - mt.set_proof_index(2); + mt.set_proof_index(proof_index); let data = &TEST_DATA[0..4]; for datum in data.iter() { mt.push(datum) } - let proof = mt.prove(); - let root = proof.0; + let (root, _proof_set) = mt.prove(); // Generate the second Merkle tree and get its proof set let mut mt = MerkleTree::new(); - mt.set_proof_index(2); + mt.set_proof_index(proof_index); let data = &TEST_DATA[5..10]; for datum in data.iter() { mt.push(datum); } - let proof = mt.prove(); - let set = proof.1; - - let verification = verify(&root, &set, 2, 5); + let proof_index = 2; + let (_, proof_set) = mt.prove(); + + let verification = verify( + &root, + &data[proof_index], + &proof_set, + proof_index as u64, + data.len() as u64, + ); assert!(!verification); } #[test] fn verify_returns_false_when_the_proof_set_is_empty() { - let mut mt = MerkleTree::new(); - mt.set_proof_index(0); + let proof_index = 2; - let proof = mt.prove(); - let root = proof.0; - let set = proof.1; + let mut mt = MerkleTree::new(); + mt.set_proof_index(proof_index); - let verification = verify(&root, &set, 0, 0); + let (root, proof_set) = mt.prove(); + let verification = verify(&root, &Data::default(), &proof_set, 0, 0); assert!(!verification); } #[test] fn verify_returns_false_when_the_proof_index_is_invalid() { + let proof_index = 2; + let mut mt = MerkleTree::new(); - mt.set_proof_index(0); + mt.set_proof_index(proof_index); let data = &TEST_DATA[0..4]; for datum in data.iter() { mt.push(datum); } - let proof = mt.prove(); - let root = proof.0; - let set = proof.1; - - let verification = verify(&root, &set, 15, 5); + let (root, proof_set) = mt.prove(); + let verification = verify(&root, &data[proof_index as usize], &proof_set, 15, 5); assert!(!verification); } } diff --git a/fuel-merkle/test-helpers/src/data/binary.rs b/fuel-merkle/test-helpers/src/data/binary.rs index b11e9d7e81..b8add24f60 100644 --- a/fuel-merkle/test-helpers/src/data/binary.rs +++ b/fuel-merkle/test-helpers/src/data/binary.rs @@ -39,9 +39,14 @@ impl ProofTest { .collect::>(); let data = self.data.into_bytes()?; let verification = - verify(&root, data, &proof_set, self.proof_index, self.num_leaves); - let verification_from_test_helper = - verify_from_test_helper(&root, &proof_set, self.proof_index, self.num_leaves); + verify(&root, &data, &proof_set, self.proof_index, self.num_leaves); + let verification_from_test_helper = verify_from_test_helper( + &root, + &data, + &proof_set, + self.proof_index, + self.num_leaves, + ); let expected_verification = self.expected_verification; if verification != verification_from_test_helper { diff --git a/fuel-merkle/tests-data-binary/fixtures/Test 0 Leaves.yaml b/fuel-merkle/tests-data-binary/fixtures/Test 0 Leaves.yaml index 1f2cc4f1c1..2fbbf117d3 100644 --- a/fuel-merkle/tests-data-binary/fixtures/Test 0 Leaves.yaml +++ b/fuel-merkle/tests-data-binary/fixtures/Test 0 Leaves.yaml @@ -7,9 +7,7 @@ root: data: value: 6ccf3bf0187426970d45aefb2e4b86bda1bc1769d69c3f48a3c64766669abf12 encoding: hex -proof_set: -- value: ce04537ec4b4b84cf02fa5c50c7810e2f6592e3b00de7423d7c3e7e7d8689a67 - encoding: hex +proof_set: [] proof_index: 0 num_leaves: 0 expected_verification: false diff --git a/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Index 0.yaml b/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Index 0.yaml index 418e9fdcc8..4828faa1d5 100644 --- a/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Index 0.yaml +++ b/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Index 0.yaml @@ -7,9 +7,7 @@ root: data: value: 573e3ac3738932ec6c1bcb33981470f1cdcd34d0cc64f5b7168ec6f0b4a66295 encoding: hex -proof_set: -- value: 40561de71f9ab9b37d9bb1194f96e73d9b24170d13e8fbe62216a5eddea86412 - encoding: hex +proof_set: [] proof_index: 0 num_leaves: 1 expected_verification: true diff --git a/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Invalid Proof Index.yaml b/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Invalid Proof Index.yaml index b33a949433..7f8fce7eed 100644 --- a/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Invalid Proof Index.yaml +++ b/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Invalid Proof Index.yaml @@ -7,9 +7,7 @@ root: data: value: c5211bc07d69b2071acd2315cb80b0e39352140a7f8b2b8f4216a455435153c5 encoding: hex -proof_set: -- value: bcd692b474ff28ad1b46171b907170afffe213d0a999d37172016371f89b1d50 - encoding: hex +proof_set: [] proof_index: 1 num_leaves: 1 expected_verification: false diff --git a/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Invalid Root.yaml b/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Invalid Root.yaml index 1a22cb55f6..919dead4e5 100644 --- a/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Invalid Root.yaml +++ b/fuel-merkle/tests-data-binary/fixtures/Test 1 Leaf Invalid Root.yaml @@ -7,9 +7,7 @@ root: data: value: 3ddceee04f31f8ba8ed2f2193157310529a8f9ba9427c3e8f1720d3a28ee49ed encoding: hex -proof_set: -- value: 8d216d9f1b01ce2f51e3be1243e0da2591679f57bf2d062b9dbaae361558bb21 - encoding: hex +proof_set: [] proof_index: 0 num_leaves: 1 expected_verification: false diff --git a/fuel-merkle/tests-data-binary/fixtures/Test 10 Leaves Index 4.yaml b/fuel-merkle/tests-data-binary/fixtures/Test 10 Leaves Index 4.yaml index 0c5fd3e0d5..9259c9bee7 100644 --- a/fuel-merkle/tests-data-binary/fixtures/Test 10 Leaves Index 4.yaml +++ b/fuel-merkle/tests-data-binary/fixtures/Test 10 Leaves Index 4.yaml @@ -8,8 +8,6 @@ data: value: 3d22b3c3a953a9f18ed12e1b28768132f84c6c69d18d88cfe71de0636a8b5c50 encoding: hex proof_set: -- value: 6fedf050a8f2b04e66b4b4bbe1a1bb083d1e1748c75d74cf2e31428542309ba3 - encoding: hex - value: 390af00738648704dbee5791e5a0dd83a0cf8e59901a519a2af4630ed9c2147b encoding: hex - value: 085c73fb213d3c8b32d104ca2236bc342eac5c204730cd2115f64e8cb754e66e diff --git a/fuel-merkle/tests-data-binary/fixtures/Test 100 Leaves Index 10.yaml b/fuel-merkle/tests-data-binary/fixtures/Test 100 Leaves Index 10.yaml index 04c0ac5413..9adebb2e01 100644 --- a/fuel-merkle/tests-data-binary/fixtures/Test 100 Leaves Index 10.yaml +++ b/fuel-merkle/tests-data-binary/fixtures/Test 100 Leaves Index 10.yaml @@ -8,8 +8,6 @@ data: value: 8ac6d60867dc72a799812086355af4ed38f68642e3857aea2cc48c94586179d1 encoding: hex proof_set: -- value: d1b2f3f5c5a9e0b1d31e9c7060682c161cfd429abc6dc709588a0f7a8b989e6e - encoding: hex - value: 51159906d4d62672664766ed8757915c7c925cfee778b8b3359df37a73ebeca7 encoding: hex - value: 2b4f180744f30b41daad98a0d9f80fd8302de65ef33487e75b3eec6122c8e3f3 diff --git a/fuel-merkle/tests-data-binary/fixtures/Test 1024 Leaves Index 512.yaml b/fuel-merkle/tests-data-binary/fixtures/Test 1024 Leaves Index 512.yaml index a4fddc0b04..f44ec3d152 100644 --- a/fuel-merkle/tests-data-binary/fixtures/Test 1024 Leaves Index 512.yaml +++ b/fuel-merkle/tests-data-binary/fixtures/Test 1024 Leaves Index 512.yaml @@ -8,8 +8,6 @@ data: value: 424c66d6981633789ccbd0a8e142ccff24208943cd143f0e2dc5d84542cb2ead encoding: hex proof_set: -- value: c00574a947cb3031d10fce0980c3711c70824c191e29c913f8da8b0d42da3c2e - encoding: hex - value: 5f7a260b5b5dc663ef6a338ba673c71ef611e4a5e52dc41e9bd82dd9a9507c30 encoding: hex - value: 51dbb7b62080c64fbc976425d0032933d1126df6f223420b332297c8ca133cee diff --git a/fuel-merkle/tests-data-binary/fixtures/Test 1024 Leaves Invalid Root.yaml b/fuel-merkle/tests-data-binary/fixtures/Test 1024 Leaves Invalid Root.yaml index c19a052fc7..5461afe744 100644 --- a/fuel-merkle/tests-data-binary/fixtures/Test 1024 Leaves Invalid Root.yaml +++ b/fuel-merkle/tests-data-binary/fixtures/Test 1024 Leaves Invalid Root.yaml @@ -8,8 +8,6 @@ data: value: 8711188204125cd3bde90be717dc0a106935559431c2bdc6d6d114cf71f46b4a encoding: hex proof_set: -- value: 0fd57bb7146938576395aa785eef8970dc33f294fa2d9a77fc1598e9084be008 - encoding: hex - value: bc6abd3c380c4d69085c2f879e784f096fcd0a9e921b359fecf87ef76ca4bc67 encoding: hex - value: c82561818abd7843b694824f21024c134158ce89445e7dc4a4aebebdb5a7dd5e