mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
core/state/snapshot: retain cumulative across states
This commit is contained in:
parent
59009896b9
commit
26876ee39a
4 changed files with 42 additions and 23 deletions
|
|
@ -231,32 +231,38 @@ func (dl *diffLayer) initBloom() {
|
||||||
// bloom
|
// bloom
|
||||||
func (dl *diffLayer) Prepare(origin *diskLayer) {
|
func (dl *diffLayer) Prepare(origin *diskLayer) {
|
||||||
dl.lock.Lock()
|
dl.lock.Lock()
|
||||||
|
defer dl.lock.Unlock()
|
||||||
|
// If we already have a cumulative bloom, we're done here
|
||||||
|
if dl.cumulative != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Traverse up the parent tree
|
||||||
dl.cumulative, _ = dl.diffed.Copy()
|
dl.cumulative, _ = dl.diffed.Copy()
|
||||||
layer := dl
|
layer := dl
|
||||||
for {
|
for {
|
||||||
if parent, ok := layer.parent.(*diffLayer); ok {
|
parent, ok := layer.parent.(*diffLayer)
|
||||||
parent.lock.RLock()
|
if !ok {
|
||||||
dl.cumulative.UnionInPlace(parent.diffed)
|
break // We hit the disk layer
|
||||||
parent.lock.RUnlock()
|
}
|
||||||
layer = parent
|
parent.lock.Lock()
|
||||||
} else {
|
// If we're lucky, the parent has a cumulative we can use.
|
||||||
|
if parent.cumulative != nil {
|
||||||
|
// Copy, nuke and done.
|
||||||
|
dl.cumulative.UnionInPlace(parent.cumulative)
|
||||||
|
parent.cumulative = nil
|
||||||
|
parent.lock.Unlock()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
dl.cumulative.UnionInPlace(parent.diffed)
|
||||||
|
parent.lock.Unlock()
|
||||||
|
layer = parent
|
||||||
}
|
}
|
||||||
dl.origin = origin
|
dl.origin = origin
|
||||||
dl.lock.Unlock()
|
|
||||||
// Calculate the current false positive rate and update the error rate meter.
|
// Calculate the current false positive rate and update the error rate meter.
|
||||||
k := float64(dl.cumulative.K())
|
k := float64(dl.cumulative.K())
|
||||||
n := float64(dl.cumulative.N())
|
n := float64(dl.cumulative.N())
|
||||||
m := float64(dl.cumulative.M())
|
m := float64(dl.cumulative.M())
|
||||||
snapshotBloomErrorGauge.Update(math.Pow(1.0-math.Exp((-k)*(n+0.5)/(m-1)), k))
|
snapshotBloomErrorGauge.Update(math.Pow(1.0-math.Exp((-k)*(n+0.5)/(m-1)), k))
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dl *diffLayer) Release() {
|
|
||||||
dl.lock.Lock()
|
|
||||||
dl.cumulative = nil
|
|
||||||
dl.lock.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Root returns the root hash for which this snapshot was made.
|
// Root returns the root hash for which this snapshot was made.
|
||||||
|
|
|
||||||
|
|
@ -166,4 +166,3 @@ func (dl *diskLayer) Update(blockHash common.Hash, destructs map[common.Hash]str
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dl *diskLayer) Prepare(*diskLayer) {}
|
func (dl *diskLayer) Prepare(*diskLayer) {}
|
||||||
func (dl *diskLayer) Release() {}
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
|
@ -65,6 +66,7 @@ var (
|
||||||
snapshotFlushStorageItemMeter = metrics.NewRegisteredMeter("state/snapshot/flush/storage/item", nil)
|
snapshotFlushStorageItemMeter = metrics.NewRegisteredMeter("state/snapshot/flush/storage/item", nil)
|
||||||
snapshotFlushStorageSizeMeter = metrics.NewRegisteredMeter("state/snapshot/flush/storage/size", nil)
|
snapshotFlushStorageSizeMeter = metrics.NewRegisteredMeter("state/snapshot/flush/storage/size", nil)
|
||||||
|
|
||||||
|
snapshotBloomPrepareTimer = metrics.NewRegisteredResettingTimer("state/snapshot/bloom/prepare", nil)
|
||||||
snapshotBloomIndexTimer = metrics.NewRegisteredResettingTimer("state/snapshot/bloom/index", nil)
|
snapshotBloomIndexTimer = metrics.NewRegisteredResettingTimer("state/snapshot/bloom/index", nil)
|
||||||
snapshotBloomErrorGauge = metrics.NewRegisteredGaugeFloat64("state/snapshot/bloom/error", nil)
|
snapshotBloomErrorGauge = metrics.NewRegisteredGaugeFloat64("state/snapshot/bloom/error", nil)
|
||||||
|
|
||||||
|
|
@ -107,7 +109,6 @@ type Snapshot interface {
|
||||||
// Storage directly retrieves the storage data associated with a particular hash,
|
// Storage directly retrieves the storage data associated with a particular hash,
|
||||||
// within a particular account.
|
// within a particular account.
|
||||||
Storage(accountHash, storageHash common.Hash) ([]byte, error)
|
Storage(accountHash, storageHash common.Hash) ([]byte, error)
|
||||||
Release()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// snapshot is the internal version of the snapshot data layer that supports some
|
// snapshot is the internal version of the snapshot data layer that supports some
|
||||||
|
|
@ -219,6 +220,9 @@ func (t *Tree) waitBuild() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tree) PrepareSnapshot(blockRoot common.Hash) Snapshot {
|
func (t *Tree) PrepareSnapshot(blockRoot common.Hash) Snapshot {
|
||||||
|
defer func(start time.Time) {
|
||||||
|
snapshotBloomPrepareTimer.Update(time.Since(start))
|
||||||
|
}(time.Now())
|
||||||
t.lock.RLock()
|
t.lock.RLock()
|
||||||
defer t.lock.RUnlock()
|
defer t.lock.RUnlock()
|
||||||
if snap := t.layers[blockRoot]; snap != nil {
|
if snap := t.layers[blockRoot]; snap != nil {
|
||||||
|
|
@ -324,9 +328,6 @@ func (t *Tree) Cap(root common.Hash, layers int) error {
|
||||||
default:
|
default:
|
||||||
// Many layers requested to be retained, cap normally
|
// Many layers requested to be retained, cap normally
|
||||||
persisted = t.cap(diff, layers)
|
persisted = t.cap(diff, layers)
|
||||||
if persisted != nil {
|
|
||||||
t.diskLayer = persisted
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Remove any layer that is stale or links into a stale layer
|
// Remove any layer that is stale or links into a stale layer
|
||||||
children := make(map[common.Hash][]common.Hash)
|
children := make(map[common.Hash][]common.Hash)
|
||||||
|
|
@ -349,7 +350,21 @@ func (t *Tree) Cap(root common.Hash, layers int) error {
|
||||||
remove(root)
|
remove(root)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the disk layer was modified, regenerate all the cummulative blooms
|
// If the disk layer was modified, wipe all the cumulative blooms
|
||||||
|
if persisted != nil {
|
||||||
|
// Update ref
|
||||||
|
t.diskLayer = persisted
|
||||||
|
var wipeCumulative func(root common.Hash)
|
||||||
|
wipeCumulative = func(root common.Hash) {
|
||||||
|
if diff, ok := t.layers[root].(*diffLayer); ok {
|
||||||
|
diff.cumulative = nil
|
||||||
|
}
|
||||||
|
for _, child := range children[root] {
|
||||||
|
wipeCumulative(child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wipeCumulative(persisted.root)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -866,7 +866,6 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
|
||||||
log.Warn("Failed to cap snapshot tree", "root", root, "layers", 127, "err", err)
|
log.Warn("Failed to cap snapshot tree", "root", root, "layers", 127, "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.snap.Release()
|
|
||||||
s.snap, s.snapDestructs, s.snapAccounts, s.snapStorage = nil, nil, nil, nil
|
s.snap, s.snapDestructs, s.snapAccounts, s.snapStorage = nil, nil, nil, nil
|
||||||
}
|
}
|
||||||
return root, err
|
return root, err
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue