@ -2,7 +2,7 @@ use super::*;
use crate ::{
use crate ::{
hash ::rpo ::Rpo256 ,
hash ::rpo ::Rpo256 ,
merkle ::{ int_to_node , MerklePathSet } ,
merkle ::{ int_to_node , MerklePathSet } ,
Felt , Word ,
Felt , Word , WORD_SIZE , ZERO ,
} ;
} ;
const KEYS4 : [ u64 ; 4 ] = [ 0 , 1 , 2 , 3 ] ;
const KEYS4 : [ u64 ; 4 ] = [ 0 , 1 , 2 , 3 ] ;
@ -12,6 +12,7 @@ const LEAVES4: [Word; 4] = [
int_to_node ( 3 ) ,
int_to_node ( 3 ) ,
int_to_node ( 4 ) ,
int_to_node ( 4 ) ,
] ;
] ;
const EMPTY : Word = [ ZERO ; WORD_SIZE ] ;
#[ test ]
#[ test ]
fn test_root_not_in_store ( ) -> Result < ( ) , MerkleError > {
fn test_root_not_in_store ( ) -> Result < ( ) , MerkleError > {
@ -141,6 +142,51 @@ fn test_merkle_tree() -> Result<(), MerkleError> {
Ok ( ( ) )
Ok ( ( ) )
}
}
#[ test ]
fn test_empty_roots ( ) {
let store = MerkleStore ::default ( ) ;
let mut root = RpoDigest ::new ( EMPTY ) ;
for depth in 0 . . 255 {
root = Rpo256 ::merge ( & [ root ; 2 ] ) ;
assert ! (
store . get_node ( root . into ( ) , NodeIndex ::new ( 0 , 0 ) ) . is_ok ( ) ,
"The root of the empty tree of depth {depth} must be registered"
) ;
}
}
#[ test ]
fn test_leaf_paths_for_empty_trees ( ) -> Result < ( ) , MerkleError > {
let store = MerkleStore ::default ( ) ;
// Starts at 1 because leafs are not included in the store.
// Ends at 64 because it is not possible to represent an index of a depth greater than 64,
// because a u64 is used to index the leaf.
for depth in 1 . . 64 {
let smt = SimpleSmt ::new ( depth ) ? ;
let index = NodeIndex ::new ( depth , 0 ) ;
let store_path = store . get_path ( smt . root ( ) , index ) ? ;
let smt_path = smt . get_path ( index ) ? ;
assert_eq ! (
store_path . value , EMPTY ,
"the leaf of an empty tree is always ZERO"
) ;
assert_eq ! (
store_path . path , smt_path ,
"the returned merkle path does not match the computed values"
) ;
assert_eq ! (
store_path . path . compute_root ( depth . into ( ) , EMPTY ) ,
smt . root ( ) ,
"computed root from the path must match the empty tree root"
) ;
}
Ok ( ( ) )
}
#[ test ]
#[ test ]
fn test_get_invalid_node ( ) {
fn test_get_invalid_node ( ) {
let mut store = MerkleStore ::default ( ) ;
let mut store = MerkleStore ::default ( ) ;
@ -211,6 +257,11 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
Ok ( LEAVES4 [ 3 ] ) ,
Ok ( LEAVES4 [ 3 ] ) ,
"node 3 must be in the tree"
"node 3 must be in the tree"
) ;
) ;
assert_eq ! (
store . get_node ( smt . root ( ) , NodeIndex ::new ( smt . depth ( ) , 4 ) ) ,
Ok ( EMPTY ) ,
"unmodified node 4 must be ZERO"
) ;
// STORE LEAVES MATCH TREE ===============================================================
// STORE LEAVES MATCH TREE ===============================================================
// sanity check the values returned by the store and the tree
// sanity check the values returned by the store and the tree
@ -234,6 +285,11 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
store . get_node ( smt . root ( ) , NodeIndex ::new ( smt . depth ( ) , 3 ) ) ,
store . get_node ( smt . root ( ) , NodeIndex ::new ( smt . depth ( ) , 3 ) ) ,
"node 3 must be the same for both SparseMerkleTree and MerkleStore"
"node 3 must be the same for both SparseMerkleTree and MerkleStore"
) ;
) ;
assert_eq ! (
smt . get_node ( & NodeIndex ::new ( smt . depth ( ) , 4 ) ) ,
store . get_node ( smt . root ( ) , NodeIndex ::new ( smt . depth ( ) , 4 ) ) ,
"node 4 must be the same for both SparseMerkleTree and MerkleStore"
) ;
// STORE MERKLE PATH MATCHS ==============================================================
// STORE MERKLE PATH MATCHS ==============================================================
// assert the merkle path returned by the store is the same as the one in the tree
// assert the merkle path returned by the store is the same as the one in the tree
@ -255,7 +311,7 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
. unwrap ( ) ;
. unwrap ( ) ;
assert_eq ! (
assert_eq ! (
LEAVES4 [ 1 ] , result . value ,
LEAVES4 [ 1 ] , result . value ,
"Value for merkle path at index 0 must match leaf value"
"Value for merkle path at index 1 must match leaf value"
) ;
) ;
assert_eq ! (
assert_eq ! (
smt . get_path ( NodeIndex ::new ( smt . depth ( ) , 1 ) ) ,
smt . get_path ( NodeIndex ::new ( smt . depth ( ) , 1 ) ) ,
@ -268,12 +324,12 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
. unwrap ( ) ;
. unwrap ( ) ;
assert_eq ! (
assert_eq ! (
LEAVES4 [ 2 ] , result . value ,
LEAVES4 [ 2 ] , result . value ,
"Value for merkle path at index 0 must match leaf value"
"Value for merkle path at index 2 must match leaf value"
) ;
) ;
assert_eq ! (
assert_eq ! (
smt . get_path ( NodeIndex ::new ( smt . depth ( ) , 2 ) ) ,
smt . get_path ( NodeIndex ::new ( smt . depth ( ) , 2 ) ) ,
Ok ( result . path ) ,
Ok ( result . path ) ,
"merkle path for index 0 must be the same for the MerkleTree and MerkleStore"
"merkle path for index 2 must be the same for the MerkleTree and MerkleStore"
) ;
) ;
let result = store
let result = store
@ -281,12 +337,25 @@ fn test_sparse_merkle_tree() -> Result<(), MerkleError> {
. unwrap ( ) ;
. unwrap ( ) ;
assert_eq ! (
assert_eq ! (
LEAVES4 [ 3 ] , result . value ,
LEAVES4 [ 3 ] , result . value ,
"Value for merkle path at index 0 must match leaf value"
"Value for merkle path at index 3 must match leaf value"
) ;
) ;
assert_eq ! (
assert_eq ! (
smt . get_path ( NodeIndex ::new ( smt . depth ( ) , 3 ) ) ,
smt . get_path ( NodeIndex ::new ( smt . depth ( ) , 3 ) ) ,
Ok ( result . path ) ,
Ok ( result . path ) ,
"merkle path for index 0 must be the same for the MerkleTree and MerkleStore"
"merkle path for index 3 must be the same for the MerkleTree and MerkleStore"
) ;
let result = store
. get_path ( smt . root ( ) , NodeIndex ::new ( smt . depth ( ) , 4 ) )
. unwrap ( ) ;
assert_eq ! (
EMPTY , result . value ,
"Value for merkle path at index 4 must match leaf value"
) ;
assert_eq ! (
smt . get_path ( NodeIndex ::new ( smt . depth ( ) , 4 ) ) ,
Ok ( result . path ) ,
"merkle path for index 4 must be the same for the MerkleTree and MerkleStore"
) ;
) ;
Ok ( ( ) )
Ok ( ( ) )