@@ -63,6 +63,8 @@ type Config struct {
63
63
BloomSize uint64 // The Megabytes of memory allocated to bloom-filter
64
64
Threads int // The maximum number of threads spawned in dumpRawTrieDescendants and removeOtherRoots
65
65
CleanCacheSize int // The Megabytes of clean cache size used in dumpRawTrieDescendants
66
+
67
+ ParallelPrune bool // Whether to prune in parallel per account
66
68
}
67
69
68
70
// Pruner is an offline tool to prune the stale state with the
@@ -429,59 +431,88 @@ func dumpRawTrieDescendants(db ethdb.Database, root common.Hash, output *stateBl
429
431
threadLastLog := time .Now ()
430
432
431
433
var processedNodes uint64
432
- for i := int64 ( 1 ); i <= 32 ; i ++ {
433
- err = <- resultsPerAccount
434
+ if ! config . ParallelPrune {
435
+ storageIt , err := storageTr . NodeIterator ( nil )
434
436
if err != nil {
435
437
return
436
438
}
437
- var startIterator trie.NodeIterator
438
- startIterator , err = storageTr .NodeIterator (big .NewInt ((i - 1 ) << 3 ).Bytes ())
439
+ var processedNodes uint64
440
+ for storageIt .Next (true ) {
441
+ storageTrieHash := storageIt .Hash ()
442
+ if storageTrieHash != (common.Hash {}) {
443
+ // The inner bloomfilter library has a mutex so concurrency is fine here
444
+ err = output .Put (storageTrieHash .Bytes (), nil )
445
+ if err != nil {
446
+ return
447
+ }
448
+ }
449
+ processedNodes ++
450
+ if time .Since (threadLastLog ) > 5 * time .Minute {
451
+ elapsedTotal := time .Since (startedAt )
452
+ elapsedThread := time .Since (threadStartedAt )
453
+ log .Info ("traversing trie database - traversing storage trie taking long" , "key" , key , "elapsedTotal" , elapsedTotal , "elapsedThread" , elapsedThread , "processedNodes" , processedNodes , "threadsRunning" , threadsRunning .Load ())
454
+ threadLastLog = time .Now ()
455
+ }
456
+ }
457
+ err = storageIt .Error ()
439
458
if err != nil {
440
459
return
441
460
}
442
- go func (startIt trie.NodeIterator , iteration int64 ) {
443
- threadsRunning .Add (1 )
444
- defer threadsRunning .Add (- 1 )
445
- var err error
446
- defer func () {
447
- resultsPerAccount <- err
448
- }()
449
-
450
- // Traverse the storage trie, and stop if we reach the end of the trie or the end of the current part
451
- var startItPath , endItPath []byte
452
-
453
- key := keybytesToHex (big .NewInt ((iteration ) << 3 ).Bytes ())
454
- key = key [:len (key )- 1 ]
455
- for startIt .Next (true ) {
456
- if iteration != 32 && bytes .Compare (startIt .Path (), key ) >= 0 {
457
- break
458
- }
459
- if startItPath == nil {
460
- startItPath = startIt .Path ()
461
- }
462
- endItPath = startIt .Path ()
463
- storageTrieHash := startIt .Hash ()
464
- if storageTrieHash != (common.Hash {}) {
465
- // The inner bloomfilter library has a mutex so concurrency is fine here
466
- err = output .Put (storageTrieHash .Bytes (), nil )
467
- if err != nil {
468
- return
469
- }
470
- }
471
- processedNodes ++
472
- if time .Since (threadLastLog ) > 5 * time .Minute {
473
- elapsedTotal := time .Since (startedAt )
474
- elapsedThread := time .Since (threadStartedAt )
475
- log .Info ("traversing trie database - traversing storage trie taking long" , "key" , key , "elapsedTotal" , elapsedTotal , "elapsedThread" , elapsedThread , "processedNodes" , processedNodes , "threadsRunning" , threadsRunning .Load ())
476
- threadLastLog = time .Now ()
477
- }
461
+ } else {
462
+ for i := int64 (1 ); i <= 32 ; i ++ {
463
+ err = <- resultsPerAccount
464
+ if err != nil {
465
+ return
478
466
}
479
- err = startIt .Error ()
467
+ var startIterator trie.NodeIterator
468
+ startIterator , err = storageTr .NodeIterator (big .NewInt ((i - 1 ) << 3 ).Bytes ())
480
469
if err != nil {
481
470
return
482
471
}
483
- log .Trace ("Finished traversing storage trie" , "key" , key , "startPath" , startItPath , "endPath" , endItPath )
484
- }(startIterator , i )
472
+ go func (startIt trie.NodeIterator , iteration int64 ) {
473
+ threadsRunning .Add (1 )
474
+ defer threadsRunning .Add (- 1 )
475
+ var err error
476
+ defer func () {
477
+ resultsPerAccount <- err
478
+ }()
479
+
480
+ // Traverse the storage trie, and stop if we reach the end of the trie or the end of the current part
481
+ var startItPath , endItPath []byte
482
+
483
+ key := keybytesToHex (big .NewInt ((iteration ) << 3 ).Bytes ())
484
+ key = key [:len (key )- 1 ]
485
+ for startIt .Next (true ) {
486
+ if iteration != 32 && bytes .Compare (startIt .Path (), key ) >= 0 {
487
+ break
488
+ }
489
+ if startItPath == nil {
490
+ startItPath = startIt .Path ()
491
+ }
492
+ endItPath = startIt .Path ()
493
+ storageTrieHash := startIt .Hash ()
494
+ if storageTrieHash != (common.Hash {}) {
495
+ // The inner bloomfilter library has a mutex so concurrency is fine here
496
+ err = output .Put (storageTrieHash .Bytes (), nil )
497
+ if err != nil {
498
+ return
499
+ }
500
+ }
501
+ processedNodes ++
502
+ if time .Since (threadLastLog ) > 5 * time .Minute {
503
+ elapsedTotal := time .Since (startedAt )
504
+ elapsedThread := time .Since (threadStartedAt )
505
+ log .Info ("traversing trie database - traversing storage trie taking long" , "key" , key , "elapsedTotal" , elapsedTotal , "elapsedThread" , elapsedThread , "processedNodes" , processedNodes , "threadsRunning" , threadsRunning .Load ())
506
+ threadLastLog = time .Now ()
507
+ }
508
+ }
509
+ err = startIt .Error ()
510
+ if err != nil {
511
+ return
512
+ }
513
+ log .Trace ("Finished traversing storage trie" , "key" , key , "startPath" , startItPath , "endPath" , endItPath )
514
+ }(startIterator , i )
515
+ }
485
516
}
486
517
}()
487
518
}
0 commit comments