code: remove accountTrieCache and storageTrieCache (#1949)
accountTrieCache and storageTrieCache were introduced in this PR: https://github.com/bnb-chain/bsc/pull/257, which is to improve performance. Actually the performance gain is quite limited, as there is already dirty and clean cache for trie node. And after big merge, these 2 cache can not be used when PBSS is enabled. So remove these code to simplify the logic.
This commit is contained in:
parent
fd6e7bb3b2
commit
3bf998f55c
@ -19,7 +19,6 @@ package state
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/lru"
|
||||
@ -29,25 +28,14 @@ import (
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||
exlru "github.com/hashicorp/golang-lru" //ex: external
|
||||
)
|
||||
|
||||
const (
|
||||
// Number of codehash->size associations to keep.
|
||||
codeSizeCacheSize = 100000
|
||||
|
||||
// Number of state trie in cache
|
||||
accountTrieCacheSize = 32
|
||||
|
||||
// Number of storage Trie in cache
|
||||
storageTrieCacheSize = 2000
|
||||
|
||||
// Cache size granted for caching clean code.
|
||||
codeCacheSize = 64 * 1024 * 1024
|
||||
|
||||
purgeInterval = 600
|
||||
|
||||
maxAccountTrieSize = 1024 * 1024
|
||||
)
|
||||
|
||||
// Database wraps access to tries and contract code.
|
||||
@ -73,15 +61,6 @@ type Database interface {
|
||||
// TrieDB returns the underlying trie database for managing trie nodes.
|
||||
TrieDB() *trie.Database
|
||||
|
||||
// Cache the account trie tree
|
||||
CacheAccount(root common.Hash, t Trie)
|
||||
|
||||
// Cache the storage trie tree
|
||||
CacheStorage(addrHash common.Hash, root common.Hash, t Trie)
|
||||
|
||||
// Purge cache
|
||||
Purge()
|
||||
|
||||
// NoTries returns whether the database has tries storage.
|
||||
NoTries() bool
|
||||
}
|
||||
@ -191,53 +170,12 @@ func NewDatabaseWithNodeDB(db ethdb.Database, triedb *trie.Database) Database {
|
||||
}
|
||||
}
|
||||
|
||||
func NewDatabaseWithConfigAndCache(db ethdb.Database, config *trie.Config) Database {
|
||||
atc, _ := exlru.New(accountTrieCacheSize)
|
||||
stc, _ := exlru.New(storageTrieCacheSize)
|
||||
noTries := config != nil && config.NoTries
|
||||
|
||||
database := &cachingDB{
|
||||
disk: db,
|
||||
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
|
||||
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
|
||||
triedb: trie.NewDatabase(db, config),
|
||||
accountTrieCache: atc,
|
||||
storageTrieCache: stc,
|
||||
noTries: noTries,
|
||||
}
|
||||
if !noTries {
|
||||
go database.purgeLoop()
|
||||
}
|
||||
return database
|
||||
}
|
||||
|
||||
type cachingDB struct {
|
||||
disk ethdb.KeyValueStore
|
||||
codeSizeCache *lru.Cache[common.Hash, int]
|
||||
codeCache *lru.SizeConstrainedCache[common.Hash, []byte]
|
||||
triedb *trie.Database
|
||||
accountTrieCache *exlru.Cache
|
||||
storageTrieCache *exlru.Cache
|
||||
noTries bool
|
||||
}
|
||||
|
||||
type triePair struct {
|
||||
root common.Hash
|
||||
trie Trie
|
||||
}
|
||||
|
||||
func (db *cachingDB) purgeLoop() {
|
||||
for {
|
||||
time.Sleep(purgeInterval * time.Second)
|
||||
_, accounts, ok := db.accountTrieCache.GetOldest()
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
tr := accounts.(*trie.SecureTrie).GetRawTrie()
|
||||
if tr.Size() > maxAccountTrieSize {
|
||||
db.Purge()
|
||||
}
|
||||
}
|
||||
disk ethdb.KeyValueStore
|
||||
codeSizeCache *lru.Cache[common.Hash, int]
|
||||
codeCache *lru.SizeConstrainedCache[common.Hash, []byte]
|
||||
triedb *trie.Database
|
||||
noTries bool
|
||||
}
|
||||
|
||||
// OpenTrie opens the main account trie at a specific root hash.
|
||||
@ -245,11 +183,6 @@ func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
|
||||
if db.noTries {
|
||||
return trie.NewEmptyTrie(), nil
|
||||
}
|
||||
if db.accountTrieCache != nil {
|
||||
if tr, exist := db.accountTrieCache.Get(root); exist {
|
||||
return tr.(Trie).(*trie.SecureTrie).Copy(), nil
|
||||
}
|
||||
}
|
||||
tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -262,16 +195,6 @@ func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Addre
|
||||
if db.noTries {
|
||||
return trie.NewEmptyTrie(), nil
|
||||
}
|
||||
if db.storageTrieCache != nil {
|
||||
if tries, exist := db.storageTrieCache.Get(crypto.Keccak256Hash(address.Bytes())); exist {
|
||||
triesPairs := tries.([3]*triePair)
|
||||
for _, triePair := range triesPairs {
|
||||
if triePair != nil && triePair.root == root {
|
||||
return triePair.trie.(*trie.SecureTrie).Copy(), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb)
|
||||
if err != nil {
|
||||
@ -280,56 +203,10 @@ func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Addre
|
||||
return tr, nil
|
||||
}
|
||||
|
||||
func (db *cachingDB) CacheAccount(root common.Hash, t Trie) {
|
||||
// only the hash scheme trie db support account cache, because the path scheme trie db
|
||||
// account trie bind the previous layer, touch the dirty data when next access. This is
|
||||
// related to the implementation of the Reader interface of pathdb.
|
||||
if db.TrieDB().Scheme() == rawdb.PathScheme {
|
||||
return
|
||||
}
|
||||
if db.accountTrieCache == nil {
|
||||
return
|
||||
}
|
||||
tr := t.(*trie.SecureTrie)
|
||||
db.accountTrieCache.Add(root, tr.ResetCopy())
|
||||
}
|
||||
|
||||
func (db *cachingDB) CacheStorage(addrHash common.Hash, root common.Hash, t Trie) {
|
||||
// ditto `CacheAccount`
|
||||
if db.TrieDB().Scheme() == rawdb.PathScheme {
|
||||
return
|
||||
}
|
||||
if db.storageTrieCache == nil {
|
||||
return
|
||||
}
|
||||
tr := t.(*trie.SecureTrie)
|
||||
if tries, exist := db.storageTrieCache.Get(addrHash); exist {
|
||||
triesArray := tries.([3]*triePair)
|
||||
newTriesArray := [3]*triePair{
|
||||
{root: root, trie: tr.ResetCopy()},
|
||||
triesArray[0],
|
||||
triesArray[1],
|
||||
}
|
||||
db.storageTrieCache.Add(addrHash, newTriesArray)
|
||||
} else {
|
||||
triesArray := [3]*triePair{{root: root, trie: tr.ResetCopy()}, nil, nil}
|
||||
db.storageTrieCache.Add(addrHash, triesArray)
|
||||
}
|
||||
}
|
||||
|
||||
func (db *cachingDB) NoTries() bool {
|
||||
return db.noTries
|
||||
}
|
||||
|
||||
func (db *cachingDB) Purge() {
|
||||
if db.storageTrieCache != nil {
|
||||
db.storageTrieCache.Purge()
|
||||
}
|
||||
if db.accountTrieCache != nil {
|
||||
db.accountTrieCache.Purge()
|
||||
}
|
||||
}
|
||||
|
||||
// CopyTrie returns an independent copy of the given trie.
|
||||
func (db *cachingDB) CopyTrie(t Trie) Trie {
|
||||
if t == nil {
|
||||
|
@ -464,9 +464,6 @@ func (s *stateObject) commit() (*trienode.NodeSet, error) {
|
||||
return nil, err
|
||||
}
|
||||
s.data.Root = root
|
||||
if s.data.Root != types.EmptyRootHash {
|
||||
s.db.db.CacheStorage(s.addrHash, s.data.Root, s.trie)
|
||||
}
|
||||
|
||||
// Update original account data after commit
|
||||
s.origin = s.data.Copy()
|
||||
|
@ -1691,9 +1691,6 @@ func (s *StateDB) Commit(block uint64, failPostCommitFunc func(), postCommitFunc
|
||||
return err
|
||||
}
|
||||
}
|
||||
if root != types.EmptyRootHash {
|
||||
s.db.CacheAccount(root, s.trie)
|
||||
}
|
||||
|
||||
origin := s.originalRoot
|
||||
if origin == (common.Hash{}) {
|
||||
|
@ -100,11 +100,6 @@ func (db *odrDatabase) TrieDB() *trie.Database {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *odrDatabase) CacheAccount(_ common.Hash, _ state.Trie) {}
|
||||
|
||||
func (db *odrDatabase) CacheStorage(_ common.Hash, _ common.Hash, _ state.Trie) {}
|
||||
|
||||
func (db *odrDatabase) Purge() {}
|
||||
func (db *odrDatabase) DiskDB() ethdb.KeyValueStore {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user