@@ -216,7 +216,7 @@ func proofToPath(rootHash common.Hash, root node, key []byte, proofDb ethdb.KeyV
216
216
//
217
217
// Note we have the assumption here the given boundary keys are different
218
218
// and right is larger than left.
219
- func unsetInternal (n node , left []byte , right []byte ) error {
219
+ func unsetInternal (n node , left []byte , right []byte ) ( bool , error ) {
220
220
left , right = keybytesToHex (left ), keybytesToHex (right )
221
221
222
222
// Step down to the fork point. There are two scenarios can happen:
@@ -278,45 +278,55 @@ findFork:
278
278
// - left proof points to the shortnode, but right proof is greater
279
279
// - right proof points to the shortnode, but left proof is less
280
280
if shortForkLeft == - 1 && shortForkRight == - 1 {
281
- return errors .New ("empty range" )
281
+ return false , errors .New ("empty range" )
282
282
}
283
283
if shortForkLeft == 1 && shortForkRight == 1 {
284
- return errors .New ("empty range" )
284
+ return false , errors .New ("empty range" )
285
285
}
286
286
if shortForkLeft != 0 && shortForkRight != 0 {
287
+ // The fork point is root node, unset the entire trie
288
+ if parent == nil {
289
+ return true , nil
290
+ }
287
291
parent .(* fullNode ).Children [left [pos - 1 ]] = nil
288
- return nil
292
+ return false , nil
289
293
}
290
294
// Only one proof points to non-existent key.
291
295
if shortForkRight != 0 {
292
- // Unset left proof's path
293
296
if _ , ok := rn .Val .(valueNode ); ok {
297
+ // The fork point is root node, unset the entire trie
298
+ if parent == nil {
299
+ return true , nil
300
+ }
294
301
parent .(* fullNode ).Children [left [pos - 1 ]] = nil
295
- return nil
302
+ return false , nil
296
303
}
297
- return unset (rn , rn .Val , left [pos :], len (rn .Key ), false )
304
+ return false , unset (rn , rn .Val , left [pos :], len (rn .Key ), false )
298
305
}
299
306
if shortForkLeft != 0 {
300
- // Unset right proof's path.
301
307
if _ , ok := rn .Val .(valueNode ); ok {
308
+ // The fork point is root node, unset the entire trie
309
+ if parent == nil {
310
+ return true , nil
311
+ }
302
312
parent .(* fullNode ).Children [right [pos - 1 ]] = nil
303
- return nil
313
+ return false , nil
304
314
}
305
- return unset (rn , rn .Val , right [pos :], len (rn .Key ), true )
315
+ return false , unset (rn , rn .Val , right [pos :], len (rn .Key ), true )
306
316
}
307
- return nil
317
+ return false , nil
308
318
case * fullNode :
309
319
// unset all internal nodes in the forkpoint
310
320
for i := left [pos ] + 1 ; i < right [pos ]; i ++ {
311
321
rn .Children [i ] = nil
312
322
}
313
323
if err := unset (rn , rn.Children [left [pos ]], left [pos :], 1 , false ); err != nil {
314
- return err
324
+ return false , err
315
325
}
316
326
if err := unset (rn , rn.Children [right [pos ]], right [pos :], 1 , true ); err != nil {
317
- return err
327
+ return false , err
318
328
}
319
- return nil
329
+ return false , nil
320
330
default :
321
331
panic (fmt .Sprintf ("%T: invalid node: %v" , n , n ))
322
332
}
@@ -560,7 +570,8 @@ func VerifyRangeProof(rootHash common.Hash, firstKey []byte, lastKey []byte, key
560
570
}
561
571
// Remove all internal references. All the removed parts should
562
572
// be re-filled(or re-constructed) by the given leaves range.
563
- if err := unsetInternal (root , firstKey , lastKey ); err != nil {
573
+ empty , err := unsetInternal (root , firstKey , lastKey )
574
+ if err != nil {
564
575
return nil , nil , nil , false , err
565
576
}
566
577
// Rebuild the trie with the leaf stream, the shape of trie
@@ -570,6 +581,9 @@ func VerifyRangeProof(rootHash common.Hash, firstKey []byte, lastKey []byte, key
570
581
triedb = NewDatabase (diskdb )
571
582
)
572
583
tr := & Trie {root : root , db : triedb }
584
+ if empty {
585
+ tr .root = nil
586
+ }
573
587
for index , key := range keys {
574
588
tr .TryUpdate (key , values [index ])
575
589
}
0 commit comments