@@ -184,10 +184,11 @@ func journalProgress(db ethdb.KeyValueWriter, marker []byte, stats *generatorSta
184184// proofResult contains the output of range proving which can be used
185185// for further processing no matter it's successful or not.
186186type proofResult struct {
187- keys [][]byte // The key set of all elements being iterated, even proving is failed
188- vals [][]byte // The val set of all elements being iterated, even proving is failed
189- cont bool // Indicator if there exists more elements in the range, only meaningful when proving is successful
190- proofErr error // Indicator whether the given state range is valid or not
187+ keys [][]byte // The key set of all elements being iterated, even proving is failed
188+ vals [][]byte // The val set of all elements being iterated, even proving is failed
189+ cont bool // Indicator if there exists more elements in the range, only meaningful when proving is successful
190+ proofErr error // Indicator whether the given state range is valid or not
191+ tr * trie.Trie // The trie, in case the trie was resolved by the prover (may be nil)
191192}
192193
193194// valid returns the indicator that range proof is successful or not.
@@ -227,7 +228,7 @@ func (result *proofResult) forEach(callback func(key []byte, val []byte) error)
227228//
228229// The proof result will be returned if the range proving is finished, otherwise
229230// the error will be returned to abort the entire procedure.
230- func (dl * diskLayer ) proveRange (root common.Hash , tr * trie. Trie , prefix []byte , kind string , origin []byte , max int , valueConvertFn func ([]byte ) ([]byte , error )) (* proofResult , error ) {
231+ func (dl * diskLayer ) proveRange (root common.Hash , prefix []byte , kind string , origin []byte , max int , valueConvertFn func ([]byte ) ([]byte , error )) (* proofResult , error ) {
231232 var (
232233 keys [][]byte
233234 vals [][]byte
@@ -236,7 +237,6 @@ func (dl *diskLayer) proveRange(root common.Hash, tr *trie.Trie, prefix []byte,
236237 )
237238 iter := dl .diskdb .NewIterator (prefix , origin )
238239 defer iter .Release ()
239-
240240 for iter .Next () {
241241 key := iter .Key ()
242242 if len (key ) != len (prefix )+ common .HashLength {
@@ -269,6 +269,11 @@ func (dl *diskLayer) proveRange(root common.Hash, tr *trie.Trie, prefix []byte,
269269 }
270270 return & proofResult {keys : keys , vals : vals , cont : false , proofErr : nil }, nil
271271 }
272+ tr , err := trie .New (root , dl .triedb )
273+ if err != nil {
274+ log .Error ("Missing trie" , "root" , root , "err" , err )
275+ return nil , err
276+ }
272277 // Snap state is chunked, generate edge proofs for verification.
273278 // Firstly find out the key of last iterated element.
274279 var last []byte
@@ -281,40 +286,35 @@ func (dl *diskLayer) proveRange(root common.Hash, tr *trie.Trie, prefix []byte,
281286 }
282287 if err := tr .Prove (origin , 0 , proof ); err != nil {
283288 log .Debug ("Failed to prove range" , "kind" , kind , "origin" , origin , "err" , err )
284- return & proofResult {keys : keys , vals : vals , cont : false , proofErr : err }, nil
289+ return & proofResult {keys : keys , vals : vals , cont : false , proofErr : err , tr : tr }, nil
285290 }
286291 if last != nil {
287292 if err := tr .Prove (last , 0 , proof ); err != nil {
288293 log .Debug ("Failed to prove range" , "kind" , kind , "last" , last , "err" , err )
289- return & proofResult {keys : keys , vals : vals , cont : false , proofErr : err }, nil
294+ return & proofResult {keys : keys , vals : vals , cont : false , proofErr : err , tr : tr }, nil
290295 }
291296 }
292297 // Verify the state segment with range prover, ensure that all flat states
293298 // in this range correspond to merkle trie.
294299 _ , _ , _ , cont , err := trie .VerifyRangeProof (root , origin , last , keys , vals , proof )
295300 if err != nil {
296- return & proofResult {keys : keys , vals : vals , cont : false , proofErr : err }, nil
301+ return & proofResult {keys : keys , vals : vals , cont : false , proofErr : err , tr : tr }, nil
297302 }
298303 // Range prover says the trie still has some elements on the right side but
299304 // the database is exhausted, then data loss is detected.
300305 // TODO: Investigate if this is needed (the assumption is that it's not needed)
301306 //if cont && len(keys) < max {
302307 //return &proofResult{keys: keys, vals: vals, cont: true, proofErr: nil}, nil
303308 //}
304- return & proofResult {keys : keys , vals : vals , cont : cont , proofErr : nil }, nil
309+ return & proofResult {keys : keys , vals : vals , cont : cont , proofErr : nil , tr : tr }, nil
305310}
306311
307312// genRange generates the state segment with particular prefix. Generation can
308313// either verify the correctness of existing state through rangeproof and skip
309314// generation, or iterate trie to regenerate state on demand.
310315func (dl * diskLayer ) genRange (root common.Hash , prefix []byte , kind string , origin []byte , max int , stats * generatorStats , onState func (key []byte , val []byte , write bool , delete bool ) error , valueConvertFn func ([]byte ) ([]byte , error )) (bool , []byte , error ) {
311- tr , err := trie .New (root , dl .triedb )
312- if err != nil {
313- stats .Log ("Trie missing, state snapshotting paused" , root , dl .genMarker )
314- return false , nil , err
315- }
316316 // Use range prover to check the validity of the flat state in the range
317- result , err := dl .proveRange (root , tr , prefix , kind , origin , max , valueConvertFn )
317+ result , err := dl .proveRange (root , prefix , kind , origin , max , valueConvertFn )
318318 if err != nil {
319319 return false , nil , err
320320 }
@@ -353,6 +353,13 @@ func (dl *diskLayer) genRange(root common.Hash, prefix []byte, kind string, orig
353353 }
354354 meter .Mark (1 )
355355 }
356+ tr := result .tr
357+ if tr == nil {
358+ tr , err = trie .New (root , dl .triedb )
359+ if err != nil {
360+ return false , nil , err
361+ }
362+ }
356363 var (
357364 aborted bool
358365 iter = trie .NewIterator (tr .NodeIterator (origin ))
0 commit comments