Correctly handle NotFound for prefix
This change correctly handles the NotFound error if the prefix provided
to the leaves method specifies a non-existent branch.
It also adds a test to validate the appropriate results.
@@ -155,21 +155,21 @@ impl MerkleRadixLeafReader for MerkleState {
.leaves(subtree)
.map(|iter| {
Box::new(iter.map(|item| {
- item.map_err(|e| match e {
- // the subtree doesn't exist
- StateDatabaseError::NotFound(msg) => {
- MerkleRadixLeafReadError::InvalidStateError(
- InvalidStateError::with_message(msg),
- )
- }
- _ => MerkleRadixLeafReadError::InternalError(InternalError::from_source(
+ item.map_err(|e| {
+ MerkleRadixLeafReadError::InternalError(InternalError::from_source(
Box::new(e),
- )),
+ ))
})
})) as Box<dyn Iterator<Item = _>>
})
- .map_err(|e| {
+ .map_err(|e| match e {
+ // the subtree doesn't exist
+ StateDatabaseError::NotFound(msg) => MerkleRadixLeafReadError::InvalidStateError(
+ InvalidStateError::with_message(msg),
+ ),
+ _ => {
MerkleRadixLeafReadError::InternalError(InternalError::from_source(Box::new(e)))
+ }
})
}
}
@@ -797,3 +797,45 @@ fn hash(input: &[u8]) -> Vec<u8> {
let (hash, _rest) = bytes.split_at(bytes.len() / 2);
hash.to_vec()
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ use crate::database::btree::BTreeDatabase;
+
+ #[test]
+ /// This test checks that the MerkleRadixLeafReader produces the correct error types under the
+ /// correct conditions:
+ /// 1: Invalid state ID => InvalidStateError on initial result
+ /// 2: Missing subtree => InvalidStateError on initial result
+ fn leaf_read_errors() -> Result<(), Box<dyn std::error::Error>> {
+ let btree_db = BTreeDatabase::new(&INDEXES);
+
+ let merkle_state = MerkleState::new(Box::new(btree_db.clone()));
+
+ // invalid state id
+ let res = merkle_state.leaves(&"abcdef0123456789".to_string(), None);
+
+ assert!(matches!(
+ res,
+ Err(MerkleRadixLeafReadError::InvalidStateError(_))
+ ));
+
+ let initial_state_root_hash =
+ MerkleRadixTree::new(Box::new(btree_db), None)?.get_merkle_root();
+
+ let res = merkle_state
+ .leaves(&initial_state_root_hash, None)
+ .map(|iter| iter.collect::<Vec<_>>())?;
+ assert!(res.is_empty());
+
+ let res = merkle_state.leaves(&initial_state_root_hash, Some("0123456789abcdef"));
+ assert!(matches!(
+ res,
+ Err(MerkleRadixLeafReadError::InvalidStateError(_))
+ ));
+
+ Ok(())
+ }
+}
