@@ -32,6 +32,7 @@ pub mod tree;
3232/// Includes errors for tree construction, hashing, and I/O operations.
3333pub mod error;
3434
35+ use crate :: error:: MrkleError ;
3536pub ( crate ) use crate :: error:: { EntryError , NodeError , ProofError , TreeError } ;
3637pub ( crate ) use crate :: tree:: DefaultIx ;
3738
@@ -279,7 +280,7 @@ where
279280}
280281
281282impl < T , D : Digest , Ix : IndexType > MrkleNode < T , D , Ix > {
282- /// Creates a new internal (non-leaf) node with the specified children and hash .
283+ /// Creates a new internal (non-leaf) node with the specified children and tree .
283284 ///
284285 /// Internal nodes represent the structural components of the Merkle tree that
285286 /// combine child node hashes. They do not store application data directly
@@ -325,7 +326,44 @@ impl<T, D: Digest, Ix: IndexType> MrkleNode<T, D, Ix> {
325326 ///
326327 /// This method is `pub(crate)` as internal node creation should typically be
327328 /// managed by the tree construction algorithms rather than external users.
328- pub fn internal ( children : Vec < NodeIndex < Ix > > , hash : GenericArray < D > ) -> Self {
329+ #[ inline]
330+ pub fn internal (
331+ tree : & Tree < MrkleNode < T , D , Ix > , Ix > ,
332+ children : Vec < NodeIndex < Ix > > ,
333+ ) -> Result < Self , MrkleError > {
334+ let mut hasher = D :: new ( ) ;
335+ children
336+ . iter ( )
337+ . try_for_each ( |& idx| {
338+ if let Some ( node) = tree. get ( idx. index ( ) ) {
339+ if node. parent ( ) . is_some ( ) {
340+ return Err ( TreeError :: from ( NodeError :: ParentConflict {
341+ parent : node. parent ( ) . unwrap ( ) . index ( ) ,
342+ child : idx. index ( ) ,
343+ } ) ) ;
344+ }
345+ hasher. update ( & node. hash ( ) ) ;
346+ Ok ( ( ) )
347+ } else {
348+ Err ( TreeError :: from ( NodeError :: NodeNotFound {
349+ index : idx. index ( ) ,
350+ } ) )
351+ }
352+ } )
353+ . map_err ( |e| MrkleError :: from ( e) ) ?;
354+
355+ let hash = hasher. finalize ( ) ;
356+
357+ Ok ( Self {
358+ payload : Payload :: Internal ,
359+ parent : None ,
360+ children,
361+ hash,
362+ } )
363+ }
364+
365+ /// Creates a new internal (non-leaf) node with the specified children and tree.
366+ pub fn internal_with_hash ( hash : GenericArray < D > , children : Vec < NodeIndex < Ix > > ) -> Self {
329367 Self {
330368 payload : Payload :: Internal ,
331369 parent : None ,
@@ -823,7 +861,7 @@ where
823861 ///
824862 /// let tree = MrkleTree::<&str, Sha1>::from_leaves(leaves);
825863 /// ```
826- pub fn from_leaves ( leaves : Vec < T > ) -> Result < MrkleTree < T , D , Ix > , TreeError > {
864+ pub fn from_leaves ( leaves : Vec < T > ) -> Result < MrkleTree < T , D , Ix > , MrkleError > {
827865 MrkleDefaultBuilder :: build_from_data ( leaves)
828866
829867 // let mut tree = Tree::new();
@@ -1088,25 +1126,65 @@ where
10881126}
10891127
10901128#[ cfg( feature = "serde" ) ]
1091- impl < ' de , T , D : Digest , Ix : IndexType > serde:: Deserialize < ' de > for MrkleTree < T , D , Ix >
1129+ impl < ' de , T , D , Ix > serde:: Deserialize < ' de > for MrkleTree < T , D , Ix >
10921130where
1093- T : serde:: Deserialize < ' de > ,
1094- Ix : serde:: Deserialize < ' de > ,
1131+ T : AsRef < [ u8 ] > + serde:: Deserialize < ' de > ,
1132+ D : Digest + Default ,
1133+ Ix : IndexType + serde:: Deserialize < ' de > ,
10951134{
1096- fn deserialize < _D > ( deserializer : _D ) -> Result < Self , _D :: Error >
1135+ fn deserialize < De > ( deserializer : De ) -> Result < Self , De :: Error >
10971136 where
1098- _D : serde:: Deserializer < ' de > ,
1137+ De : serde:: Deserializer < ' de > ,
10991138 {
1100- Ok ( MrkleTree {
1101- core : Tree :: < MrkleNode < T , D , Ix > , Ix > :: deserialize ( deserializer) ?,
1102- } )
1139+ // First, deserialize the underlying core tree structure
1140+ let core = Tree :: < MrkleNode < T , D , Ix > , Ix > :: deserialize ( deserializer) ?;
1141+
1142+ // Verify all nodes (leaf and internal) match their expected hashes
1143+ for node in core. iter ( ) {
1144+ let mut digest = D :: new ( ) ;
1145+
1146+ if node. is_leaf ( ) {
1147+ let value = node. value ( ) . ok_or_else ( || {
1148+ serde:: de:: Error :: custom ( "Leaf node missing value during deserialization" )
1149+ } ) ?;
1150+
1151+ digest. update ( value. as_ref ( ) ) ;
1152+ let computed = digest. finalize ( ) ;
1153+
1154+ if computed. as_slice ( ) != node. hash ( ) . as_slice ( ) {
1155+ return Err ( serde:: de:: Error :: custom ( "Merkle tree leaf hash mismatch" ) ) ;
1156+ }
1157+ } else {
1158+ if node. child_count ( ) == 0 {
1159+ return Err ( serde:: de:: Error :: custom (
1160+ "Internal node should never have no children." ,
1161+ ) ) ;
1162+ }
1163+
1164+ for child in node. children ( ) {
1165+ let child_node = core. get ( child. index ( ) ) . ok_or_else ( || {
1166+ serde:: de:: Error :: custom ( "Missing child node during deserialization" )
1167+ } ) ?;
1168+ digest. update ( child_node. hash ( ) ) ;
1169+ }
1170+
1171+ let computed = digest. finalize ( ) ;
1172+ if & computed != node. hash ( ) {
1173+ return Err ( serde:: de:: Error :: custom (
1174+ "Merkle tree internal hash mismatch" ,
1175+ ) ) ;
1176+ }
1177+ }
1178+ }
1179+
1180+ Ok ( MrkleTree { core } )
11031181 }
11041182}
11051183
11061184#[ cfg( test) ]
11071185mod test {
11081186
1109- use crate :: { Hasher , MrkleHasher , MrkleNode , MrkleTree , Node , NodeIndex , prelude:: * } ;
1187+ use crate :: { MrkleHasher , MrkleNode , MrkleTree , Node , NodeIndex , prelude:: * } ;
11101188 use sha1:: Digest ;
11111189
11121190 const DATA_PAYLOAD : [ u8 ; 32 ] = [ 0u8 ; 32 ] ;
@@ -1118,16 +1196,6 @@ mod test {
11181196 assert ! ( tree. is_empty( ) )
11191197 }
11201198
1121- #[ test]
1122- fn test_is_leaf_logic ( ) {
1123- let leaf = MrkleNode :: < _ , sha1:: Sha1 > :: leaf ( DATA_PAYLOAD ) ;
1124- assert ! ( leaf. is_leaf( ) ) ;
1125-
1126- let hash = MrkleHasher :: < sha1:: Sha1 > :: digest ( leaf. hash ) ;
1127- let internal = MrkleNode :: < [ u8 ; 32 ] , sha1:: Sha1 > :: internal ( vec ! [ NodeIndex :: new( 1 ) ] , hash) ;
1128- assert ! ( !internal. is_leaf( ) )
1129- }
1130-
11311199 #[ test]
11321200 fn test_default_mrkle_node ( ) {
11331201 let node = MrkleNode :: < _ , sha1:: Sha1 , usize > :: leaf ( DATA_PAYLOAD ) ;
@@ -1143,46 +1211,6 @@ mod test {
11431211 assert_eq ! ( node. hash, sha1:: Sha1 :: digest( DATA_PAYLOAD ) )
11441212 }
11451213
1146- #[ test]
1147- fn test_build_internal_mrkle_node ( ) {
1148- let hasher = MrkleHasher :: < sha1:: Sha1 > :: new ( ) ;
1149- let node1 = MrkleNode :: < _ , sha1:: Sha1 , usize > :: leaf_with_hasher ( DATA_PAYLOAD , & hasher) ;
1150- let node2 = MrkleNode :: < _ , sha1:: Sha1 , usize > :: leaf_with_hasher ( DATA_PAYLOAD , & hasher) ;
1151-
1152- let children: Vec < NodeIndex < usize > > = vec ! [ NodeIndex :: new( 0 ) , NodeIndex :: new( 1 ) ] ;
1153-
1154- let hash = hasher. concat_slice ( & [ node1. hash , node2. hash ] ) ;
1155-
1156- let parent: MrkleNode < [ u8 ; 32 ] , sha1:: Sha1 , usize > = MrkleNode :: internal ( children, hash) ;
1157-
1158- // The expected hash should be just concat the two child
1159- // using the same digest.
1160- let expected = {
1161- let mut hasher = sha1:: Sha1 :: new ( ) ;
1162- hasher. update ( node1. hash ) ;
1163- hasher. update ( node2. hash ) ;
1164- hasher. finalize ( )
1165- } ;
1166-
1167- assert_eq ! ( parent. hash, expected) ;
1168- }
1169-
1170- #[ test]
1171- fn test_internal_contains_node_index ( ) {
1172- let hasher = MrkleHasher :: < sha1:: Sha1 > :: new ( ) ;
1173-
1174- let node1 = MrkleNode :: < _ , sha1:: Sha1 , usize > :: leaf_with_hasher ( DATA_PAYLOAD , & hasher) ;
1175- let node2 = MrkleNode :: < _ , sha1:: Sha1 , usize > :: leaf_with_hasher ( DATA_PAYLOAD , & hasher) ;
1176-
1177- let children: Vec < NodeIndex < usize > > = vec ! [ NodeIndex :: new( 0 ) , NodeIndex :: new( 1 ) ] ;
1178-
1179- let hash = hasher. concat_slice ( & [ node1. hash , node2. hash ] ) ;
1180-
1181- let parent: MrkleNode < [ u8 ; 32 ] , sha1:: Sha1 , usize > = MrkleNode :: internal ( children, hash) ;
1182-
1183- assert ! ( parent. contains( & NodeIndex :: new( 0 ) ) ) ;
1184- }
1185-
11861214 #[ test]
11871215 fn test_building_binary_tree_base_case ( ) {
11881216 let leaves: Vec < & str > = vec ! [ "A" ] ;
0 commit comments