mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-18 19:00:46 +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)")
|
log.Warn("Snapshot maintenance disabled (syncing)")
|
||||||
return snap, nil
|
return snap, nil
|
||||||
}
|
}
|
||||||
// Create the building waiter iff the background generation is allowed
|
|
||||||
if !config.NoBuild && !config.AsyncBuild {
|
|
||||||
defer snap.waitBuild()
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Failed to load snapshot", "err", err)
|
log.Warn("Failed to load snapshot", "err", err)
|
||||||
if !config.NoBuild {
|
if config.NoBuild {
|
||||||
snap.Rebuild(root)
|
return nil, err
|
||||||
return snap, nil
|
|
||||||
}
|
}
|
||||||
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
|
// Existing snapshot loaded, seed all the layers
|
||||||
for head != nil {
|
for ; head != nil; head = head.Parent() {
|
||||||
snap.layers[head.Root()] = head
|
snap.layers[head.Root()] = head
|
||||||
head = head.Parent()
|
|
||||||
}
|
}
|
||||||
return snap, nil
|
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
|
// Disable interrupts any pending snapshot generator, deletes all the snapshot
|
||||||
// layers in memory and marks snapshots disabled globally. In order to resume
|
// layers in memory and marks snapshots disabled globally. In order to resume
|
||||||
// the snapshot functionality, the caller must invoke Rebuild.
|
// 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
|
// Rebuild wipes all available snapshot data from the persistent database and
|
||||||
// discard all caches and diff layers. Afterwards, it starts a new snapshot
|
// discard all caches and diff layers. Afterwards, it starts a new snapshot
|
||||||
// generator with the given root hash.
|
// generator with the given root hash. The returned function blocks until
|
||||||
func (t *Tree) Rebuild(root common.Hash) {
|
// regeneration is complete.
|
||||||
|
func (t *Tree) Rebuild(root common.Hash) (wait func()) {
|
||||||
t.lock.Lock()
|
t.lock.Lock()
|
||||||
defer t.lock.Unlock()
|
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
|
// 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.
|
// generator will run a wiper first if there's not one running right now.
|
||||||
log.Info("Rebuilding state snapshot")
|
log.Info("Rebuilding state snapshot")
|
||||||
|
disk := generateSnapshot(t.diskdb, t.triedb, t.config.CacheSize, root)
|
||||||
t.layers = map[common.Hash]snapshot{
|
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
|
// AccountIterator creates a new account iterator for the specified root hash and
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue