core/state/snapshot: reduce storage snapshot cache key allocations

This commit is contained in:
Sahil Sojitra 2026-04-27 21:24:42 +05:30
parent 822e7c6486
commit 3916587150
2 changed files with 14 additions and 6 deletions

View file

@ -29,6 +29,13 @@ import (
"github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb"
) )
func storageCacheKey(accountHash, storageHash common.Hash) [2 * common.HashLength]byte {
var key [2 * common.HashLength]byte
copy(key[:common.HashLength], accountHash[:])
copy(key[common.HashLength:], storageHash[:])
return key
}
// diskLayer is a low level persistent snapshot built on top of a key-value store. // diskLayer is a low level persistent snapshot built on top of a key-value store.
type diskLayer struct { type diskLayer struct {
diskdb ethdb.KeyValueStore // Key-value store containing the base snapshot diskdb ethdb.KeyValueStore // Key-value store containing the base snapshot
@ -148,25 +155,25 @@ func (dl *diskLayer) Storage(accountHash, storageHash common.Hash) ([]byte, erro
if dl.stale { if dl.stale {
return nil, ErrSnapshotStale return nil, ErrSnapshotStale
} }
key := append(accountHash[:], storageHash[:]...) key := storageCacheKey(accountHash, storageHash)
// If the layer is being generated, ensure the requested hash has already been // If the layer is being generated, ensure the requested hash has already been
// covered by the generator. // covered by the generator.
if dl.genMarker != nil && bytes.Compare(key, dl.genMarker) > 0 { if dl.genMarker != nil && bytes.Compare(key[:], dl.genMarker) > 0 {
return nil, ErrNotCoveredYet return nil, ErrNotCoveredYet
} }
// If we're in the disk layer, all diff layers missed // If we're in the disk layer, all diff layers missed
snapshotDirtyStorageMissMeter.Mark(1) snapshotDirtyStorageMissMeter.Mark(1)
// Try to retrieve the storage slot from the memory cache // Try to retrieve the storage slot from the memory cache
if blob, found := dl.cache.HasGet(nil, key); found { if blob, found := dl.cache.HasGet(nil, key[:]); found {
snapshotCleanStorageHitMeter.Mark(1) snapshotCleanStorageHitMeter.Mark(1)
snapshotCleanStorageReadMeter.Mark(int64(len(blob))) snapshotCleanStorageReadMeter.Mark(int64(len(blob)))
return blob, nil return blob, nil
} }
// Cache doesn't contain storage slot, pull from disk and cache for later // Cache doesn't contain storage slot, pull from disk and cache for later
blob := rawdb.ReadStorageSnapshot(dl.diskdb, accountHash, storageHash) blob := rawdb.ReadStorageSnapshot(dl.diskdb, accountHash, storageHash)
dl.cache.Set(key, blob) dl.cache.Set(key[:], blob)
snapshotCleanStorageMissMeter.Mark(1) snapshotCleanStorageMissMeter.Mark(1)
if n := len(blob); n > 0 { if n := len(blob); n > 0 {

View file

@ -581,13 +581,14 @@ func diffToDisk(bottom *diffLayer) *diskLayer {
if midAccount && bytes.Compare(storageHash[:], base.genMarker[common.HashLength:]) > 0 { if midAccount && bytes.Compare(storageHash[:], base.genMarker[common.HashLength:]) > 0 {
continue continue
} }
cacheKey := storageCacheKey(accountHash, storageHash)
if len(data) > 0 { if len(data) > 0 {
rawdb.WriteStorageSnapshot(batch, accountHash, storageHash, data) rawdb.WriteStorageSnapshot(batch, accountHash, storageHash, data)
base.cache.Set(append(accountHash[:], storageHash[:]...), data) base.cache.Set(cacheKey[:], data)
snapshotCleanStorageWriteMeter.Mark(int64(len(data))) snapshotCleanStorageWriteMeter.Mark(int64(len(data)))
} else { } else {
rawdb.DeleteStorageSnapshot(batch, accountHash, storageHash) rawdb.DeleteStorageSnapshot(batch, accountHash, storageHash)
base.cache.Set(append(accountHash[:], storageHash[:]...), nil) base.cache.Set(cacheKey[:], nil)
} }
snapshotFlushStorageItemMeter.Mark(1) snapshotFlushStorageItemMeter.Mark(1)
snapshotFlushStorageSizeMeter.Mark(int64(len(data))) snapshotFlushStorageSizeMeter.Mark(int64(len(data)))