core/state/snapshot: replace bigcache with fastcache
This commit is contained in:
parent
d754091a87
commit
f300c0df01
@ -19,7 +19,7 @@ package snapshot
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/allegro/bigcache"
|
"github.com/VictoriaMetrics/fastcache"
|
||||||
"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"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
@ -30,7 +30,7 @@ import (
|
|||||||
type diskLayer struct {
|
type diskLayer struct {
|
||||||
journal string // Path of the snapshot journal to use on shutdown
|
journal string // Path of the snapshot journal to use on shutdown
|
||||||
db ethdb.KeyValueStore // Key-value store containing the base snapshot
|
db ethdb.KeyValueStore // Key-value store containing the base snapshot
|
||||||
cache *bigcache.BigCache // Cache to avoid hitting the disk for direct access
|
cache *fastcache.Cache // Cache to avoid hitting the disk for direct access
|
||||||
|
|
||||||
root common.Hash // Root hash of the base snapshot
|
root common.Hash // Root hash of the base snapshot
|
||||||
stale bool // Signals that the layer became stale (state progressed)
|
stale bool // Signals that the layer became stale (state progressed)
|
||||||
@ -80,17 +80,15 @@ func (dl *diskLayer) AccountRLP(hash common.Hash) ([]byte, error) {
|
|||||||
if dl.stale {
|
if dl.stale {
|
||||||
return nil, ErrSnapshotStale
|
return nil, ErrSnapshotStale
|
||||||
}
|
}
|
||||||
key := string(hash[:])
|
|
||||||
|
|
||||||
// Try to retrieve the account from the memory cache
|
// Try to retrieve the account from the memory cache
|
||||||
if blob, err := dl.cache.Get(key); err == nil {
|
if blob := dl.cache.Get(nil, hash[:]); blob != nil {
|
||||||
snapshotCleanHitMeter.Mark(1)
|
snapshotCleanHitMeter.Mark(1)
|
||||||
snapshotCleanReadMeter.Mark(int64(len(blob)))
|
snapshotCleanReadMeter.Mark(int64(len(blob)))
|
||||||
return blob, nil
|
return blob, nil
|
||||||
}
|
}
|
||||||
// Cache doesn't contain account, pull from disk and cache for later
|
// Cache doesn't contain account, pull from disk and cache for later
|
||||||
blob := rawdb.ReadAccountSnapshot(dl.db, hash)
|
blob := rawdb.ReadAccountSnapshot(dl.db, hash)
|
||||||
dl.cache.Set(key, blob)
|
dl.cache.Set(hash[:], blob)
|
||||||
|
|
||||||
snapshotCleanMissMeter.Mark(1)
|
snapshotCleanMissMeter.Mark(1)
|
||||||
snapshotCleanWriteMeter.Mark(int64(len(blob)))
|
snapshotCleanWriteMeter.Mark(int64(len(blob)))
|
||||||
@ -109,10 +107,10 @@ func (dl *diskLayer) Storage(accountHash, storageHash common.Hash) ([]byte, erro
|
|||||||
if dl.stale {
|
if dl.stale {
|
||||||
return nil, ErrSnapshotStale
|
return nil, ErrSnapshotStale
|
||||||
}
|
}
|
||||||
key := string(append(accountHash[:], storageHash[:]...))
|
key := append(accountHash[:], storageHash[:]...)
|
||||||
|
|
||||||
// Try to retrieve the storage slot from the memory cache
|
// Try to retrieve the storage slot from the memory cache
|
||||||
if blob, err := dl.cache.Get(key); err == nil {
|
if blob := dl.cache.Get(nil, key); blob != nil {
|
||||||
snapshotCleanHitMeter.Mark(1)
|
snapshotCleanHitMeter.Mark(1)
|
||||||
snapshotCleanReadMeter.Mark(int64(len(blob)))
|
snapshotCleanReadMeter.Mark(int64(len(blob)))
|
||||||
return blob, nil
|
return blob, nil
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/allegro/bigcache"
|
"github.com/VictoriaMetrics/fastcache"
|
||||||
"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"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
@ -196,13 +196,7 @@ func generateSnapshot(db ethdb.KeyValueStore, journal string, root common.Hash)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// New snapshot generated, construct a brand new base layer
|
// New snapshot generated, construct a brand new base layer
|
||||||
cache, _ := bigcache.NewBigCache(bigcache.Config{ // TODO(karalabe): dedup
|
cache := fastcache.New(512 * 1024 * 1024)
|
||||||
Shards: 1024,
|
|
||||||
LifeWindow: time.Hour,
|
|
||||||
MaxEntriesInWindow: 512 * 1024,
|
|
||||||
MaxEntrySize: 512,
|
|
||||||
HardMaxCacheSize: 512,
|
|
||||||
})
|
|
||||||
return &diskLayer{
|
return &diskLayer{
|
||||||
journal: journal,
|
journal: journal,
|
||||||
db: db,
|
db: db,
|
||||||
|
@ -22,9 +22,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/allegro/bigcache"
|
"github.com/VictoriaMetrics/fastcache"
|
||||||
"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"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
@ -323,7 +322,7 @@ func diffToDisk(bottom *diffLayer) *diskLayer {
|
|||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
// Account was updated, push to disk
|
// Account was updated, push to disk
|
||||||
rawdb.WriteAccountSnapshot(batch, hash, data)
|
rawdb.WriteAccountSnapshot(batch, hash, data)
|
||||||
base.cache.Set(string(hash[:]), data)
|
base.cache.Set(hash[:], data)
|
||||||
|
|
||||||
if batch.ValueSize() > ethdb.IdealBatchSize {
|
if batch.ValueSize() > ethdb.IdealBatchSize {
|
||||||
if err := batch.Write(); err != nil {
|
if err := batch.Write(); err != nil {
|
||||||
@ -334,13 +333,13 @@ func diffToDisk(bottom *diffLayer) *diskLayer {
|
|||||||
} else {
|
} else {
|
||||||
// Account was deleted, remove all storage slots too
|
// Account was deleted, remove all storage slots too
|
||||||
rawdb.DeleteAccountSnapshot(batch, hash)
|
rawdb.DeleteAccountSnapshot(batch, hash)
|
||||||
base.cache.Set(string(hash[:]), nil)
|
base.cache.Set(hash[:], nil)
|
||||||
|
|
||||||
it := rawdb.IterateStorageSnapshots(base.db, hash)
|
it := rawdb.IterateStorageSnapshots(base.db, hash)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
if key := it.Key(); len(key) == 65 { // TODO(karalabe): Yuck, we should move this into the iterator
|
if key := it.Key(); len(key) == 65 { // TODO(karalabe): Yuck, we should move this into the iterator
|
||||||
batch.Delete(key)
|
batch.Delete(key)
|
||||||
base.cache.Delete(string(key[1:]))
|
base.cache.Del(key[1:])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it.Release()
|
it.Release()
|
||||||
@ -351,10 +350,10 @@ func diffToDisk(bottom *diffLayer) *diskLayer {
|
|||||||
for storageHash, data := range storage {
|
for storageHash, data := range storage {
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
rawdb.WriteStorageSnapshot(batch, accountHash, storageHash, data)
|
rawdb.WriteStorageSnapshot(batch, accountHash, storageHash, data)
|
||||||
base.cache.Set(string(append(accountHash[:], storageHash[:]...)), data)
|
base.cache.Set(append(accountHash[:], storageHash[:]...), data)
|
||||||
} else {
|
} else {
|
||||||
rawdb.DeleteStorageSnapshot(batch, accountHash, storageHash)
|
rawdb.DeleteStorageSnapshot(batch, accountHash, storageHash)
|
||||||
base.cache.Set(string(append(accountHash[:], storageHash[:]...)), nil)
|
base.cache.Set(append(accountHash[:], storageHash[:]...), nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if batch.ValueSize() > ethdb.IdealBatchSize {
|
if batch.ValueSize() > ethdb.IdealBatchSize {
|
||||||
@ -401,17 +400,10 @@ func loadSnapshot(db ethdb.KeyValueStore, journal string, root common.Hash) (sna
|
|||||||
if baseRoot == (common.Hash{}) {
|
if baseRoot == (common.Hash{}) {
|
||||||
return nil, errors.New("missing or corrupted snapshot")
|
return nil, errors.New("missing or corrupted snapshot")
|
||||||
}
|
}
|
||||||
cache, _ := bigcache.NewBigCache(bigcache.Config{ // TODO(karalabe): dedup
|
|
||||||
Shards: 1024,
|
|
||||||
LifeWindow: time.Hour,
|
|
||||||
MaxEntriesInWindow: 512 * 1024,
|
|
||||||
MaxEntrySize: 512,
|
|
||||||
HardMaxCacheSize: 512,
|
|
||||||
})
|
|
||||||
base := &diskLayer{
|
base := &diskLayer{
|
||||||
journal: journal,
|
journal: journal,
|
||||||
db: db,
|
db: db,
|
||||||
cache: cache,
|
cache: fastcache.New(512 * 1024 * 1024),
|
||||||
root: baseRoot,
|
root: baseRoot,
|
||||||
}
|
}
|
||||||
// Load all the snapshot diffs from the journal, failing if their chain is broken
|
// Load all the snapshot diffs from the journal, failing if their chain is broken
|
||||||
|
@ -19,9 +19,8 @@ package snapshot
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/allegro/bigcache"
|
"github.com/VictoriaMetrics/fastcache"
|
||||||
"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"
|
||||||
)
|
)
|
||||||
@ -31,11 +30,10 @@ import (
|
|||||||
// to check internal corner case around the bottom-most memory accumulator.
|
// to check internal corner case around the bottom-most memory accumulator.
|
||||||
func TestDiskLayerExternalInvalidationFullFlatten(t *testing.T) {
|
func TestDiskLayerExternalInvalidationFullFlatten(t *testing.T) {
|
||||||
// Create an empty base layer and a snapshot tree out of it
|
// Create an empty base layer and a snapshot tree out of it
|
||||||
cache, _ := bigcache.NewBigCache(bigcache.DefaultConfig(time.Minute))
|
|
||||||
base := &diskLayer{
|
base := &diskLayer{
|
||||||
db: rawdb.NewMemoryDatabase(),
|
db: rawdb.NewMemoryDatabase(),
|
||||||
root: common.HexToHash("0x01"),
|
root: common.HexToHash("0x01"),
|
||||||
cache: cache,
|
cache: fastcache.New(1024 * 500),
|
||||||
}
|
}
|
||||||
snaps := &Tree{
|
snaps := &Tree{
|
||||||
layers: map[common.Hash]snapshot{
|
layers: map[common.Hash]snapshot{
|
||||||
@ -77,11 +75,10 @@ func TestDiskLayerExternalInvalidationFullFlatten(t *testing.T) {
|
|||||||
// layer to check the usual mode of operation where the accumulator is retained.
|
// layer to check the usual mode of operation where the accumulator is retained.
|
||||||
func TestDiskLayerExternalInvalidationPartialFlatten(t *testing.T) {
|
func TestDiskLayerExternalInvalidationPartialFlatten(t *testing.T) {
|
||||||
// Create an empty base layer and a snapshot tree out of it
|
// Create an empty base layer and a snapshot tree out of it
|
||||||
cache, _ := bigcache.NewBigCache(bigcache.DefaultConfig(time.Minute))
|
|
||||||
base := &diskLayer{
|
base := &diskLayer{
|
||||||
db: rawdb.NewMemoryDatabase(),
|
db: rawdb.NewMemoryDatabase(),
|
||||||
root: common.HexToHash("0x01"),
|
root: common.HexToHash("0x01"),
|
||||||
cache: cache,
|
cache: fastcache.New(1024 * 500),
|
||||||
}
|
}
|
||||||
snaps := &Tree{
|
snaps := &Tree{
|
||||||
layers: map[common.Hash]snapshot{
|
layers: map[common.Hash]snapshot{
|
||||||
@ -126,11 +123,10 @@ func TestDiskLayerExternalInvalidationPartialFlatten(t *testing.T) {
|
|||||||
// to check internal corner case around the bottom-most memory accumulator.
|
// to check internal corner case around the bottom-most memory accumulator.
|
||||||
func TestDiffLayerExternalInvalidationFullFlatten(t *testing.T) {
|
func TestDiffLayerExternalInvalidationFullFlatten(t *testing.T) {
|
||||||
// Create an empty base layer and a snapshot tree out of it
|
// Create an empty base layer and a snapshot tree out of it
|
||||||
cache, _ := bigcache.NewBigCache(bigcache.DefaultConfig(time.Minute))
|
|
||||||
base := &diskLayer{
|
base := &diskLayer{
|
||||||
db: rawdb.NewMemoryDatabase(),
|
db: rawdb.NewMemoryDatabase(),
|
||||||
root: common.HexToHash("0x01"),
|
root: common.HexToHash("0x01"),
|
||||||
cache: cache,
|
cache: fastcache.New(1024 * 500),
|
||||||
}
|
}
|
||||||
snaps := &Tree{
|
snaps := &Tree{
|
||||||
layers: map[common.Hash]snapshot{
|
layers: map[common.Hash]snapshot{
|
||||||
@ -175,11 +171,10 @@ func TestDiffLayerExternalInvalidationFullFlatten(t *testing.T) {
|
|||||||
// layer to check the usual mode of operation where the accumulator is retained.
|
// layer to check the usual mode of operation where the accumulator is retained.
|
||||||
func TestDiffLayerExternalInvalidationPartialFlatten(t *testing.T) {
|
func TestDiffLayerExternalInvalidationPartialFlatten(t *testing.T) {
|
||||||
// Create an empty base layer and a snapshot tree out of it
|
// Create an empty base layer and a snapshot tree out of it
|
||||||
cache, _ := bigcache.NewBigCache(bigcache.DefaultConfig(time.Minute))
|
|
||||||
base := &diskLayer{
|
base := &diskLayer{
|
||||||
db: rawdb.NewMemoryDatabase(),
|
db: rawdb.NewMemoryDatabase(),
|
||||||
root: common.HexToHash("0x01"),
|
root: common.HexToHash("0x01"),
|
||||||
cache: cache,
|
cache: fastcache.New(1024 * 500),
|
||||||
}
|
}
|
||||||
snaps := &Tree{
|
snaps := &Tree{
|
||||||
layers: map[common.Hash]snapshot{
|
layers: map[common.Hash]snapshot{
|
||||||
@ -240,11 +235,10 @@ func TestPostCapBasicDataAccess(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Create a starting base layer and a snapshot tree out of it
|
// Create a starting base layer and a snapshot tree out of it
|
||||||
cache, _ := bigcache.NewBigCache(bigcache.DefaultConfig(time.Minute))
|
|
||||||
base := &diskLayer{
|
base := &diskLayer{
|
||||||
db: rawdb.NewMemoryDatabase(),
|
db: rawdb.NewMemoryDatabase(),
|
||||||
root: common.HexToHash("0x01"),
|
root: common.HexToHash("0x01"),
|
||||||
cache: cache,
|
cache: fastcache.New(1024 * 500),
|
||||||
}
|
}
|
||||||
snaps := &Tree{
|
snaps := &Tree{
|
||||||
layers: map[common.Hash]snapshot{
|
layers: map[common.Hash]snapshot{
|
||||||
|
Loading…
Reference in New Issue
Block a user