@@ -216,7 +216,7 @@ func proofToPath(rootHash common.Hash, root node, key []byte, proofDb ethdb.KeyV
216216//
217217// Note we have the assumption here the given boundary keys are different
218218// 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 ) {
220220 left , right = keybytesToHex (left ), keybytesToHex (right )
221221
222222 // Step down to the fork point. There are two scenarios can happen:
@@ -278,45 +278,55 @@ findFork:
278278 // - left proof points to the shortnode, but right proof is greater
279279 // - right proof points to the shortnode, but left proof is less
280280 if shortForkLeft == - 1 && shortForkRight == - 1 {
281- return errors .New ("empty range" )
281+ return false , errors .New ("empty range" )
282282 }
283283 if shortForkLeft == 1 && shortForkRight == 1 {
284- return errors .New ("empty range" )
284+ return false , errors .New ("empty range" )
285285 }
286286 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+ }
287291 parent .(* fullNode ).Children [left [pos - 1 ]] = nil
288- return nil
292+ return false , nil
289293 }
290294 // Only one proof points to non-existent key.
291295 if shortForkRight != 0 {
292- // Unset left proof's path
293296 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+ }
294301 parent .(* fullNode ).Children [left [pos - 1 ]] = nil
295- return nil
302+ return false , nil
296303 }
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 )
298305 }
299306 if shortForkLeft != 0 {
300- // Unset right proof's path.
301307 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+ }
302312 parent .(* fullNode ).Children [right [pos - 1 ]] = nil
303- return nil
313+ return false , nil
304314 }
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 )
306316 }
307- return nil
317+ return false , nil
308318 case * fullNode :
309319 // unset all internal nodes in the forkpoint
310320 for i := left [pos ] + 1 ; i < right [pos ]; i ++ {
311321 rn .Children [i ] = nil
312322 }
313323 if err := unset (rn , rn.Children [left [pos ]], left [pos :], 1 , false ); err != nil {
314- return err
324+ return false , err
315325 }
316326 if err := unset (rn , rn.Children [right [pos ]], right [pos :], 1 , true ); err != nil {
317- return err
327+ return false , err
318328 }
319- return nil
329+ return false , nil
320330 default :
321331 panic (fmt .Sprintf ("%T: invalid node: %v" , n , n ))
322332 }
@@ -560,7 +570,8 @@ func VerifyRangeProof(rootHash common.Hash, firstKey []byte, lastKey []byte, key
560570 }
561571 // Remove all internal references. All the removed parts should
562572 // 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 {
564575 return nil , nil , nil , false , err
565576 }
566577 // 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
570581 triedb = NewDatabase (diskdb )
571582 )
572583 tr := & Trie {root : root , db : triedb }
584+ if empty {
585+ tr .root = nil
586+ }
573587 for index , key := range keys {
574588 tr .TryUpdate (key , values [index ])
575589 }
0 commit comments