Skip to content

Commit 3dfa815

Browse files
committed
add option to enable paralle prune
1 parent b192b19 commit 3dfa815

File tree

1 file changed

+74
-43
lines changed

1 file changed

+74
-43
lines changed

core/state/pruner/pruner.go

Lines changed: 74 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ type Config struct {
6363
BloomSize uint64 // The Megabytes of memory allocated to bloom-filter
6464
Threads int // The maximum number of threads spawned in dumpRawTrieDescendants and removeOtherRoots
6565
CleanCacheSize int // The Megabytes of clean cache size used in dumpRawTrieDescendants
66+
67+
ParallelPrune bool // Whether to prune in parallel per account
6668
}
6769

6870
// 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
429431
threadLastLog := time.Now()
430432

431433
var processedNodes uint64
432-
for i := int64(1); i <= 32; i++ {
433-
err = <-resultsPerAccount
434+
if !config.ParallelPrune {
435+
storageIt, err := storageTr.NodeIterator(nil)
434436
if err != nil {
435437
return
436438
}
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()
439458
if err != nil {
440459
return
441460
}
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
478466
}
479-
err = startIt.Error()
467+
var startIterator trie.NodeIterator
468+
startIterator, err = storageTr.NodeIterator(big.NewInt((i - 1) << 3).Bytes())
480469
if err != nil {
481470
return
482471
}
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+
}
485516
}
486517
}()
487518
}

0 commit comments

Comments
 (0)