153 lines
4.8 KiB
Rust
153 lines
4.8 KiB
Rust
use crate::hash::rpo::RpoDigest;
|
|
|
|
use super::{
|
|
super::{int_to_digest, int_to_node, NodeIndex},
|
|
PartialMerkleTree, Rpo256,
|
|
};
|
|
|
|
// TEST DATA
|
|
// ================================================================================================
|
|
|
|
const NODE22: NodeIndex = NodeIndex::new_unchecked(2, 2);
|
|
|
|
const NODE32: NodeIndex = NodeIndex::new_unchecked(3, 2);
|
|
const NODE33: NodeIndex = NodeIndex::new_unchecked(3, 3);
|
|
|
|
// TESTS
|
|
// ================================================================================================
|
|
|
|
// with_paths CONSTRUCTOR TESTS
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
|
#[test]
|
|
fn get_root() {
|
|
let leaf0 = int_to_digest(0);
|
|
let leaf1 = int_to_digest(1);
|
|
let leaf2 = int_to_digest(2);
|
|
let leaf3 = int_to_digest(3);
|
|
|
|
let parent0 = calculate_parent_hash(leaf0, 0, leaf1);
|
|
let parent1 = calculate_parent_hash(leaf2, 2, leaf3);
|
|
|
|
let root_exp = calculate_parent_hash(parent0, 0, parent1);
|
|
|
|
let set =
|
|
super::PartialMerkleTree::with_paths([(0, leaf0, vec![*leaf1, *parent1].into())]).unwrap();
|
|
|
|
assert_eq!(set.root(), root_exp);
|
|
}
|
|
|
|
#[test]
|
|
fn add_and_get_paths() {
|
|
let value32 = int_to_digest(32);
|
|
let value33 = int_to_digest(33);
|
|
let value20 = int_to_digest(20);
|
|
let value22 = int_to_digest(22);
|
|
let value23 = int_to_digest(23);
|
|
|
|
let value21 = Rpo256::merge(&[value32, value33]);
|
|
let value10 = Rpo256::merge(&[value20, value21]);
|
|
let value11 = Rpo256::merge(&[value22, value23]);
|
|
|
|
let path_33 = vec![*value32, *value20, *value11];
|
|
|
|
let path_22 = vec![*value23, *value10];
|
|
|
|
let pmt = PartialMerkleTree::with_paths([
|
|
(3, value33, path_33.clone().into()),
|
|
(2, value22, path_22.clone().into()),
|
|
])
|
|
.unwrap();
|
|
let stored_path_33 = pmt.get_path(NODE33).unwrap();
|
|
let stored_path_22 = pmt.get_path(NODE22).unwrap();
|
|
|
|
assert_eq!(path_33, *stored_path_33);
|
|
assert_eq!(path_22, *stored_path_22);
|
|
}
|
|
|
|
#[test]
|
|
fn get_node() {
|
|
let path_6 = vec![int_to_node(7), int_to_node(45), int_to_node(123)];
|
|
let hash_6 = int_to_digest(6);
|
|
let index = NodeIndex::make(3, 6);
|
|
let pmt = PartialMerkleTree::with_paths([(index.value(), hash_6, path_6.into())]).unwrap();
|
|
|
|
assert_eq!(int_to_digest(6u64), pmt.get_node(index).unwrap());
|
|
}
|
|
|
|
#[test]
|
|
fn update_leaf() {
|
|
let value32 = int_to_digest(32);
|
|
let value33 = int_to_digest(33);
|
|
let value20 = int_to_digest(20);
|
|
let value22 = int_to_digest(22);
|
|
let value23 = int_to_digest(23);
|
|
|
|
let value21 = Rpo256::merge(&[value32, value33]);
|
|
let value10 = Rpo256::merge(&[value20, value21]);
|
|
let value11 = Rpo256::merge(&[value22, value23]);
|
|
|
|
let path_33 = vec![*value32, *value20, *value11];
|
|
|
|
let path_22 = vec![*value23, *value10];
|
|
|
|
let mut pmt =
|
|
PartialMerkleTree::with_paths([(3, value33, path_33.into()), (2, value22, path_22.into())])
|
|
.unwrap();
|
|
|
|
let new_value32 = int_to_digest(132);
|
|
let new_value21 = Rpo256::merge(&[new_value32, value33]);
|
|
let new_value10 = Rpo256::merge(&[value20, new_value21]);
|
|
let expected_root = Rpo256::merge(&[new_value10, value11]);
|
|
|
|
let old_leaf = pmt.update_leaf(NODE32, new_value32).unwrap();
|
|
|
|
assert_eq!(value32, old_leaf);
|
|
|
|
let new_root = pmt.root();
|
|
|
|
assert_eq!(new_root, expected_root);
|
|
}
|
|
|
|
#[test]
|
|
fn check_leaf_depth() {
|
|
let value32 = int_to_digest(32);
|
|
let value33 = int_to_digest(33);
|
|
let value20 = int_to_digest(20);
|
|
let value22 = int_to_digest(22);
|
|
let value23 = int_to_digest(23);
|
|
|
|
let value11 = Rpo256::merge(&[value22, value23]);
|
|
|
|
let path_33 = vec![*value32, *value20, *value11];
|
|
|
|
let pmt = PartialMerkleTree::with_paths([(3, value33, path_33.into())]).unwrap();
|
|
|
|
assert_eq!(pmt.get_leaf_depth(0).unwrap(), 2);
|
|
assert_eq!(pmt.get_leaf_depth(1).unwrap(), 2);
|
|
assert_eq!(pmt.get_leaf_depth(2).unwrap(), 3);
|
|
assert_eq!(pmt.get_leaf_depth(3).unwrap(), 3);
|
|
assert_eq!(pmt.get_leaf_depth(4).unwrap(), 1);
|
|
assert_eq!(pmt.get_leaf_depth(5).unwrap(), 1);
|
|
assert_eq!(pmt.get_leaf_depth(6).unwrap(), 1);
|
|
assert_eq!(pmt.get_leaf_depth(7).unwrap(), 1);
|
|
}
|
|
|
|
// TODO: add test for add_path function and check correctness of leaf determination (requires
|
|
// inner_nodes iter)
|
|
|
|
// HELPER FUNCTIONS
|
|
// --------------------------------------------------------------------------------------------
|
|
|
|
/// Calculates the hash of the parent node by two sibling ones
|
|
/// - node — current node
|
|
/// - node_pos — position of the current node
|
|
/// - sibling — neighboring vertex in the tree
|
|
fn calculate_parent_hash(node: RpoDigest, node_pos: u64, sibling: RpoDigest) -> RpoDigest {
|
|
let parity = node_pos & 1;
|
|
if parity == 0 {
|
|
Rpo256::merge(&[node, sibling])
|
|
} else {
|
|
Rpo256::merge(&[sibling, node])
|
|
}
|
|
}
|