Skip to content

Commit f887457

Browse files
committed
chore: re-define errors within rust crate
1 parent f01c7e6 commit f887457

File tree

3 files changed

+131
-96
lines changed

3 files changed

+131
-96
lines changed

mrkle/src/builder.rs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#![allow(dead_code)]
22
use crate::{
33
DefaultIx, GenericArray, Hasher, IndexType, MrkleHasher, MrkleNode, MrkleTree, Node, NodeError,
4-
NodeIndex, Tree, TreeError, prelude::*,
4+
NodeIndex, Tree, TreeError, error::MrkleError, prelude::*,
55
};
66

77
/// A builder for constructing Merkle trees with default configuration.
@@ -290,21 +290,21 @@ impl<T, D: Digest, Ix: IndexType> MrkleDefaultBuilder<T, D, Ix> {
290290
pub fn insert_internal(
291291
&mut self,
292292
children: Vec<NodeIndex<Ix>>,
293-
) -> Result<NodeIndex<Ix>, TreeError> {
293+
) -> Result<NodeIndex<Ix>, MrkleError> {
294294
self.check_not_finalized()?;
295295

296296
if children.is_empty() {
297-
return Err(TreeError::InvalidOperation {
297+
return Err(MrkleError::from(TreeError::InvalidOperation {
298298
operation: "insert_internal",
299299
reason: "internal nodes must have at least one child".to_string(),
300-
});
300+
}));
301301
}
302302

303303
self.validate_children(&children)?;
304304

305-
let hash = self.compute_internal_hash(&children)?;
306-
307-
let index = self.tree.push(MrkleNode::internal(children.clone(), hash));
305+
let index = self
306+
.tree
307+
.push(MrkleNode::internal(&self.tree, children.clone())?);
308308

309309
self.set_parent_relationships(&children, index);
310310

@@ -345,7 +345,7 @@ impl<T, D: Digest, Ix: IndexType> MrkleDefaultBuilder<T, D, Ix> {
345345
/// # Ok(())
346346
/// # }
347347
/// ```
348-
pub fn finish(mut self, root: NodeIndex<Ix>) -> Result<MrkleTree<T, D, Ix>, TreeError> {
348+
pub fn finish(mut self, root: NodeIndex<Ix>) -> Result<MrkleTree<T, D, Ix>, MrkleError> {
349349
self.check_not_finalized()?;
350350

351351
// Validate the root node
@@ -356,11 +356,11 @@ impl<T, D: Digest, Ix: IndexType> MrkleDefaultBuilder<T, D, Ix> {
356356

357357
// Perform comprehensive tree validation
358358
if let Err(errors) = self.validate() {
359-
return Err(TreeError::ValidationFailed {
359+
return Err(MrkleError::from(TreeError::ValidationFailed {
360360
count: errors.len(),
361361
summary: "Tree structure validation failed".to_string(),
362362
errors,
363-
});
363+
}));
364364
}
365365

366366
self.finalized = true;
@@ -508,10 +508,10 @@ impl<T, D: Digest, Ix: IndexType> MrkleDefaultBuilder<T, D, Ix> {
508508
len: self.tree.len(),
509509
})?;
510510
if node.parent().is_some() {
511-
return Err(TreeError::ParentConflict {
511+
return Err(TreeError::from(NodeError::ParentConflict {
512512
parent: node.parent().unwrap().index(),
513513
child: child.index(),
514-
});
514+
}));
515515
}
516516
}
517517
Ok(())
@@ -684,14 +684,14 @@ where
684684
pub fn build_complete_tree_from_leaves(
685685
&mut self,
686686
mut leaves: Vec<NodeIndex<Ix>>,
687-
) -> Result<NodeIndex<Ix>, TreeError> {
687+
) -> Result<NodeIndex<Ix>, MrkleError> {
688688
self.check_not_finalized()?;
689689

690690
if leaves.is_empty() {
691-
return Err(TreeError::InvalidOperation {
691+
return Err(MrkleError::from(TreeError::InvalidOperation {
692692
operation: "build_complete_tree_from_leaves",
693693
reason: "cannot build tree from empty leaves vector".to_string(),
694-
});
694+
}));
695695
}
696696

697697
// Base case: if there is only one node, create a root for single node.
@@ -743,7 +743,7 @@ where
743743
/// # Ok(())
744744
/// # }
745745
/// ```
746-
pub fn build_from_data<I>(data_iter: I) -> Result<MrkleTree<T, D, Ix>, TreeError>
746+
pub fn build_from_data<I>(data_iter: I) -> Result<MrkleTree<T, D, Ix>, MrkleError>
747747
where
748748
T: Clone,
749749
I: IntoIterator<Item = T>,
@@ -820,7 +820,7 @@ impl<T: AsRef<[u8]>, D: Digest, Ix: IndexType> MrkleDefaultBuilder<T, D, Ix> {
820820
/// # Ok(())
821821
/// # }
822822
/// ```
823-
pub fn build_and_finish(mut self) -> Result<MrkleTree<T, D, Ix>, TreeError>
823+
pub fn build_and_finish(mut self) -> Result<MrkleTree<T, D, Ix>, MrkleError>
824824
where
825825
T: Clone,
826826
{
@@ -947,12 +947,12 @@ mod tests {
947947

948948
// Test empty children vector
949949
let result = builder.insert_internal(vec![]);
950-
assert!(matches!(result, Err(TreeError::InvalidOperation { .. })));
950+
assert!(result.is_err());
951951

952952
// Test invalid child index
953953
let invalid_child = NodeIndex::new(999);
954954
let result = builder.insert_internal(vec![invalid_child]);
955-
assert!(matches!(result, Err(TreeError::IndexOutOfBounds { .. })));
955+
assert!(result.is_err());
956956

957957
Ok(())
958958
}
@@ -968,7 +968,7 @@ mod tests {
968968

969969
// Try to create second internal node with same children (should fail)
970970
let result = builder.insert_internal(vec![leaf1]);
971-
assert!(matches!(result, Err(TreeError::ParentConflict { .. })));
971+
assert!(result.is_err());
972972

973973
Ok(())
974974
}

mrkle/src/error.rs

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,27 @@ pub enum NodeError {
1010
/// The duplicate child index.
1111
child: usize,
1212
},
13+
14+
/// Attempted to assign a parent to a node that already has one.
15+
///
16+
/// Each non-root node must have a single unique parent.
17+
#[error(
18+
"Cannot add child {child} to {parent}: \
19+
node already has a parent."
20+
)]
21+
ParentConflict {
22+
/// The node that is already the parent.
23+
parent: usize,
24+
/// The child node in conflict.
25+
child: usize,
26+
},
27+
28+
/// An index was used that is outside the bounds of the tree.
29+
#[error("Node at {index:?} could not be found with in tree.")]
30+
NodeNotFound {
31+
/// node index within tree.
32+
index: usize,
33+
},
1334
}
1435

1536
/// Errors that may occur when converting a byte slice into an [`entry`](crate::entry).
@@ -42,20 +63,6 @@ pub enum TreeError {
4263
len: usize,
4364
},
4465

45-
/// Attempted to assign a parent to a node that already has one.
46-
///
47-
/// Each non-root node must have a single unique parent.
48-
#[error(
49-
"Cannot add child {child} to {parent}: \
50-
node already has a parent."
51-
)]
52-
ParentConflict {
53-
/// The node that is already the parent.
54-
parent: usize,
55-
/// The child node in conflict.
56-
child: usize,
57-
},
58-
5966
/// An error occurred while operating on a [`Node`](crate::tree::Node).
6067
#[error("{0}")]
6168
NodeError(#[from] NodeError),

mrkle/src/lib.rs

Lines changed: 90 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub mod tree;
3232
/// Includes errors for tree construction, hashing, and I/O operations.
3333
pub mod error;
3434

35+
use crate::error::MrkleError;
3536
pub(crate) use crate::error::{EntryError, NodeError, ProofError, TreeError};
3637
pub(crate) use crate::tree::DefaultIx;
3738

@@ -279,7 +280,7 @@ where
279280
}
280281

281282
impl<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>
10921130
where
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)]
11071185
mod 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

Comments
 (0)