1
1
use crate :: {
2
2
node_type:: { Child , Children , InternalNode , LeafNode , Node , NodeKey , NodeType } ,
3
3
proof:: { definition:: UpdateMerkleProof , SparseMerkleLeafNode , SparseMerkleNode } ,
4
- storage:: { Node :: Leaf , TreeReader , TreeReaderExt , TreeUpdateBatch } ,
4
+ storage:: { Node :: Leaf , TreeReader , TreeUpdateBatch } ,
5
5
tree_cache:: { FreezeError , NodeAlreadyExists , TreeCache } ,
6
6
types:: {
7
7
nibble:: {
@@ -14,7 +14,7 @@ use crate::{
14
14
Bytes32Ext , KeyHash , MissingRootError , OwnedValue , RootHash , SimpleHasher , ValueHash ,
15
15
} ;
16
16
use alloc:: { collections:: BTreeMap , vec, vec:: Vec } ;
17
- use anyhow:: { bail , format_err} ;
17
+ use anyhow:: format_err;
18
18
use core:: { cmp:: Ordering , convert:: TryInto , marker:: PhantomData } ;
19
19
20
20
#[ cfg( not( feature = "std" ) ) ]
@@ -57,8 +57,17 @@ pub enum LookupError<E> {
57
57
ValueNotFound { version : u64 , key_hash : KeyHash } ,
58
58
#[ error( "Non-root null node exists with node key {key:?}" ) ]
59
59
NonRootNullNodeExists { key : NodeKey } ,
60
+ #[ error( "Internal node has no children" ) ]
61
+ InternalNodeHasNoChildren ,
60
62
#[ error( "Jellyfish Merkle tree has cyclic graph inside." ) ]
61
63
CyclicGraphDetected ,
64
+ #[ error( "Found exact key when searching for bounding path for nonexistence proof" ) ]
65
+ FoundKeyInBoundingPath ,
66
+ #[ error( "Invalid exclusion proof" ) ]
67
+ ExclusionProofIsNotValid ,
68
+ // Some actions might fail because the tree is empty.
69
+ #[ error( "{msg}" ) ]
70
+ TreeIsEmpty { msg : & ' static str } ,
62
71
}
63
72
64
73
/// Errors that can occur when a value set is [applied] to a [`JellyfishMerkleTree<'a, R, H>`].
@@ -1145,7 +1154,7 @@ where
1145
1154
extreme : Extreme ,
1146
1155
to : NibblePath ,
1147
1156
parents : Vec < InternalNode > ,
1148
- ) -> Result < Option < KeyHash > , anyhow :: Error > {
1157
+ ) -> Result < Option < KeyHash > , LookupError < R :: Error > > {
1149
1158
fn neighbor_nibble (
1150
1159
node : & InternalNode ,
1151
1160
child_index : Nibble ,
@@ -1190,27 +1199,35 @@ where
1190
1199
& self ,
1191
1200
version : Version ,
1192
1201
search_key : KeyHash ,
1193
- ) -> Result < SearchResult , anyhow :: Error > {
1202
+ ) -> Result < SearchResult , LookupError < R :: Error > > {
1194
1203
let search_path = NibblePath :: new ( search_key. 0 . to_vec ( ) ) ;
1195
1204
let mut search_nibbles = search_path. nibbles ( ) ;
1196
1205
let mut next_node_key = NodeKey :: new_empty_path ( version) ;
1197
1206
let mut internal_nodes = vec ! [ ] ;
1198
1207
1199
1208
for nibble_depth in 0 ..=ROOT_NIBBLE_HEIGHT {
1200
- let next_node = self . reader . get_node ( & next_node_key) . map_err ( |err| {
1201
- if nibble_depth == 0 {
1202
- anyhow:: anyhow!( MissingRootError { version } )
1203
- } else {
1204
- err
1205
- }
1206
- } ) ?;
1209
+ let next_node = self
1210
+ . reader
1211
+ . get_node_option ( & next_node_key)
1212
+ . map_err ( LookupError :: Read ) ?
1213
+ . ok_or_else ( || {
1214
+ if nibble_depth == 0 {
1215
+ // If this is the first loop iteration, we are missing our root.
1216
+ LookupError :: RootMissing ( MissingRootError { version } )
1217
+ } else {
1218
+ // Otherwise, we are missing some other node.
1219
+ LookupError :: NodeMissing {
1220
+ nibble_depth,
1221
+ key : next_node_key. clone ( ) ,
1222
+ }
1223
+ }
1224
+ } ) ?;
1207
1225
1208
1226
match next_node {
1209
1227
Node :: Internal ( node) => {
1210
1228
internal_nodes. push ( node. clone ( ) ) ;
1211
- let queried_child_index = search_nibbles
1212
- . next ( )
1213
- . ok_or_else ( || format_err ! ( "ran out of nibbles" ) ) ?;
1229
+ let queried_child_index =
1230
+ search_nibbles. next ( ) . ok_or ( LookupError :: RanOutOfNibbles ) ?;
1214
1231
1215
1232
let child_node_key =
1216
1233
node. get_only_child_without_siblings ( & next_node_key, queried_child_index) ;
@@ -1240,27 +1257,25 @@ where
1240
1257
}
1241
1258
Node :: Null => {
1242
1259
if nibble_depth == 0 {
1243
- bail ! (
1244
- "Cannot manufacture nonexistence proof by exclusion for the empty tree"
1245
- ) ;
1260
+ return Err ( LookupError :: TreeIsEmpty {
1261
+ msg : "Cannot manufacture nonexistence proof by exclusion for the \
1262
+ empty tree",
1263
+ } ) ;
1246
1264
} else {
1247
- bail ! (
1248
- "Non-root null node exists with node key {:?}" ,
1249
- next_node_key
1250
- ) ;
1265
+ return Err ( LookupError :: NonRootNullNodeExists { key : next_node_key } ) ;
1251
1266
}
1252
1267
}
1253
1268
}
1254
1269
}
1255
1270
1256
- bail ! ( "Jellyfish Merkle tree has cyclic graph inside." ) ;
1271
+ return Err ( LookupError :: CyclicGraphDetected ) ;
1257
1272
}
1258
1273
1259
1274
fn get_bounding_path (
1260
1275
& self ,
1261
1276
search_key : KeyHash ,
1262
1277
version : Version ,
1263
- ) -> Result < ( Option < KeyHash > , Option < KeyHash > ) , anyhow :: Error > {
1278
+ ) -> Result < ( Option < KeyHash > , Option < KeyHash > ) , LookupError < R :: Error > > {
1264
1279
let search_result = self . search_for_closest_node ( version, search_key) ?;
1265
1280
1266
1281
match search_result {
@@ -1295,7 +1310,7 @@ where
1295
1310
Ok ( ( rightmost_left_keyhash, Some ( leaf_hash) ) )
1296
1311
}
1297
1312
Ordering :: Equal => {
1298
- bail ! ( "found exact key when searching for bounding path for nonexistence proof" )
1313
+ return Err ( LookupError :: FoundKeyInBoundingPath ) ;
1299
1314
}
1300
1315
}
1301
1316
}
@@ -1321,12 +1336,21 @@ where
1321
1336
}
1322
1337
}
1323
1338
1324
- /// Returns the value (if applicable) and the corresponding merkle proof.
1339
+ /// Returns the [value] (if applicable) and the corresponding [merkle proof].
1340
+ ///
1341
+ /// - Returns a tuple `Ok(Ok((value, proof)))` if a value associated with the given key exists.
1342
+ /// - Returns an [`ExclusionProof<H>`] as `Ok(Err(exclusion_proof))` if no value associated
1343
+ /// with the given key exists.
1344
+ /// - Returns `Err(e)` if an unexpected error was encountered while retrieving the value.
1345
+ ///
1346
+ /// [value]: OwnedValue
1347
+ /// [merkle proof]: SparseMerkleProof
1325
1348
pub fn get_with_exclusion_proof (
1326
1349
& self ,
1327
1350
key_hash : KeyHash ,
1328
1351
version : Version ,
1329
- ) -> Result < Result < ( OwnedValue , SparseMerkleProof < H > ) , ExclusionProof < H > > , anyhow:: Error > {
1352
+ ) -> Result < Result < ( OwnedValue , SparseMerkleProof < H > ) , ExclusionProof < H > > , LookupError < R :: Error > >
1353
+ {
1330
1354
// Optimistically attempt get_with_proof, if that succeeds, we're done.
1331
1355
if let ( Some ( value) , proof) = self . get_with_proof ( key_hash, version) ? {
1332
1356
return Ok ( Ok ( ( value, proof) ) ) ;
@@ -1361,7 +1385,7 @@ where
1361
1385
leftmost_right_proof : right_proof,
1362
1386
} ) )
1363
1387
}
1364
- _ => bail ! ( "Invalid exclusion proof" ) ,
1388
+ _ => return Err ( LookupError :: ExclusionProofIsNotValid ) ,
1365
1389
}
1366
1390
}
1367
1391
@@ -1371,7 +1395,7 @@ where
1371
1395
mut node_key : NodeKey ,
1372
1396
nibble_depth : usize ,
1373
1397
extreme : Extreme ,
1374
- ) -> Result < KeyHash , anyhow :: Error > {
1398
+ ) -> Result < KeyHash , LookupError < R :: Error > > {
1375
1399
// Depending on the extreme specified, get either the least nibble or the most nibble
1376
1400
let min_or_max = |internal_node : & InternalNode | {
1377
1401
match extreme {
@@ -1384,13 +1408,22 @@ where
1384
1408
// We limit the number of loops here deliberately to avoid potential cyclic graph bugs
1385
1409
// in the tree structure.
1386
1410
for nibble_depth in nibble_depth..=ROOT_NIBBLE_HEIGHT {
1387
- let node = self . reader . get_node ( & node_key) . map_err ( |err| {
1388
- if nibble_depth == 0 {
1389
- anyhow:: anyhow!( MissingRootError { version } )
1390
- } else {
1391
- err
1392
- }
1393
- } ) ?;
1411
+ let node = self
1412
+ . reader
1413
+ . get_node_option ( & node_key)
1414
+ . map_err ( LookupError :: Read ) ?
1415
+ . ok_or_else ( || {
1416
+ if nibble_depth == 0 {
1417
+ // If this is the first loop iteration, we are missing our root.
1418
+ LookupError :: RootMissing ( MissingRootError { version } )
1419
+ } else {
1420
+ // Otherwise, we are missing some other node.
1421
+ LookupError :: NodeMissing {
1422
+ nibble_depth,
1423
+ key : node_key. clone ( ) ,
1424
+ }
1425
+ }
1426
+ } ) ?;
1394
1427
match node {
1395
1428
Node :: Internal ( internal_node) => {
1396
1429
// Find the leftmost nibble in the children
@@ -1401,18 +1434,23 @@ where
1401
1434
// Proceed downwards
1402
1435
node_key = match child_node_key {
1403
1436
Some ( node_key) => node_key,
1404
- None => {
1405
- bail ! ( "Internal node has no children" ) ;
1406
- }
1437
+ None => return Err ( LookupError :: InternalNodeHasNoChildren ) ,
1407
1438
} ;
1408
1439
}
1409
- Node :: Leaf ( leaf_node) => {
1410
- return Ok ( leaf_node. key_hash ( ) ) ;
1440
+ Node :: Leaf ( leaf_node) => return Ok ( leaf_node. key_hash ( ) ) ,
1441
+ Node :: Null => {
1442
+ if nibble_depth == 0 {
1443
+ return Err ( LookupError :: TreeIsEmpty {
1444
+ msg : "Null node cannot have children" ,
1445
+ } ) ;
1446
+ } else {
1447
+ return Err ( LookupError :: NonRootNullNodeExists { key : node_key } ) ;
1448
+ }
1411
1449
}
1412
- Node :: Null => bail ! ( "Null node cannot have children" ) ,
1413
1450
}
1414
1451
}
1415
- bail ! ( "Jellyfish Merkle tree has cyclic graph inside." ) ;
1452
+
1453
+ return Err ( LookupError :: CyclicGraphDetected ) ;
1416
1454
}
1417
1455
1418
1456
fn get_without_proof (
0 commit comments