mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-03-28 22:02:55 +00:00
core/state/snapshot: simplify snapshot rebuild (#30772)
This PR is purely for improved readability; I was doing work involving the file and think this may help others who are trying to understand what's going on. 1. `snapshot.Tree.Rebuild()` now returns a function that blocks until regeneration is complete, allowing `Tree.waitBuild()` to be removed entirely as all it did was search for the `done` channel behind this new function. 2. Its usage inside `New()` is also simplified by (a) only waiting if `!AsyncBuild`; and (b) avoiding the double negative of `if !NoBuild`. --------- Co-authored-by: Martin HS <martin@swende.se>
This commit is contained in:
parent
3c754e2a09
commit
23800122b3
1 changed files with 14 additions and 34 deletions
|
|
@ -206,47 +206,24 @@ func New(config Config, diskdb ethdb.KeyValueStore, triedb *triedb.Database, roo
|
|||
log.Warn("Snapshot maintenance disabled (syncing)")
|
||||
return snap, nil
|
||||
}
|
||||
// Create the building waiter iff the background generation is allowed
|
||||
if !config.NoBuild && !config.AsyncBuild {
|
||||
defer snap.waitBuild()
|
||||
}
|
||||
if err != nil {
|
||||
log.Warn("Failed to load snapshot", "err", err)
|
||||
if !config.NoBuild {
|
||||
snap.Rebuild(root)
|
||||
return snap, nil
|
||||
if config.NoBuild {
|
||||
return nil, err
|
||||
}
|
||||
return nil, err // Bail out the error, don't rebuild automatically.
|
||||
wait := snap.Rebuild(root)
|
||||
if !config.AsyncBuild {
|
||||
wait()
|
||||
}
|
||||
return snap, nil
|
||||
}
|
||||
// Existing snapshot loaded, seed all the layers
|
||||
for head != nil {
|
||||
for ; head != nil; head = head.Parent() {
|
||||
snap.layers[head.Root()] = head
|
||||
head = head.Parent()
|
||||
}
|
||||
return snap, nil
|
||||
}
|
||||
|
||||
// waitBuild blocks until the snapshot finishes rebuilding. This method is meant
|
||||
// to be used by tests to ensure we're testing what we believe we are.
|
||||
func (t *Tree) waitBuild() {
|
||||
// Find the rebuild termination channel
|
||||
var done chan struct{}
|
||||
|
||||
t.lock.RLock()
|
||||
for _, layer := range t.layers {
|
||||
if layer, ok := layer.(*diskLayer); ok {
|
||||
done = layer.genPending
|
||||
break
|
||||
}
|
||||
}
|
||||
t.lock.RUnlock()
|
||||
|
||||
// Wait until the snapshot is generated
|
||||
if done != nil {
|
||||
<-done
|
||||
}
|
||||
}
|
||||
|
||||
// Disable interrupts any pending snapshot generator, deletes all the snapshot
|
||||
// layers in memory and marks snapshots disabled globally. In order to resume
|
||||
// the snapshot functionality, the caller must invoke Rebuild.
|
||||
|
|
@ -688,8 +665,9 @@ func (t *Tree) Journal(root common.Hash) (common.Hash, error) {
|
|||
|
||||
// Rebuild wipes all available snapshot data from the persistent database and
|
||||
// discard all caches and diff layers. Afterwards, it starts a new snapshot
|
||||
// generator with the given root hash.
|
||||
func (t *Tree) Rebuild(root common.Hash) {
|
||||
// generator with the given root hash. The returned function blocks until
|
||||
// regeneration is complete.
|
||||
func (t *Tree) Rebuild(root common.Hash) (wait func()) {
|
||||
t.lock.Lock()
|
||||
defer t.lock.Unlock()
|
||||
|
||||
|
|
@ -721,9 +699,11 @@ func (t *Tree) Rebuild(root common.Hash) {
|
|||
// Start generating a new snapshot from scratch on a background thread. The
|
||||
// generator will run a wiper first if there's not one running right now.
|
||||
log.Info("Rebuilding state snapshot")
|
||||
disk := generateSnapshot(t.diskdb, t.triedb, t.config.CacheSize, root)
|
||||
t.layers = map[common.Hash]snapshot{
|
||||
root: generateSnapshot(t.diskdb, t.triedb, t.config.CacheSize, root),
|
||||
root: disk,
|
||||
}
|
||||
return func() { <-disk.genPending }
|
||||
}
|
||||
|
||||
// AccountIterator creates a new account iterator for the specified root hash and
|
||||
|
|
|
|||
Loading…
Reference in a new issue