diff --git a/core/types/state_account.go b/core/types/state_account.go index 52ef843b35..81a0c3c025 100644 --- a/core/types/state_account.go +++ b/core/types/state_account.go @@ -18,6 +18,7 @@ package types import ( "bytes" + "fmt" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rlp" @@ -87,6 +88,17 @@ func SlimAccountRLP(account StateAccount) []byte { return data } +func FullToSlimAccountRLP(data []byte) []byte { + if data == nil { + return nil + } + var account StateAccount + if err := rlp.DecodeBytes(data, &account); err != nil { + panic(fmt.Sprintf("full to slim account rlp failed, err %v", err)) + } + return SlimAccountRLP(account) +} + // FullAccount decodes the data on the 'slim RLP' format and returns // the consensus format account. func FullAccount(data []byte) (*StateAccount, error) { @@ -119,3 +131,14 @@ func FullAccountRLP(data []byte) ([]byte, error) { } return rlp.EncodeToBytes(account) } + +func MustFullAccountRLP(data []byte) []byte { + if data == nil { + return nil + } + val, err := FullAccountRLP(data) + if err != nil { + panic(fmt.Sprintf("must full account rlp faield, err %v", err)) + } + return val +} diff --git a/triedb/pathdb/asyncnodebuffer.go b/triedb/pathdb/asyncnodebuffer.go index dfae9cdbe3..67d92f082e 100644 --- a/triedb/pathdb/asyncnodebuffer.go +++ b/triedb/pathdb/asyncnodebuffer.go @@ -7,6 +7,7 @@ import ( "sync/atomic" "time" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/trie/triestate" "github.com/ethereum/go-ethereum/common" @@ -449,7 +450,7 @@ func (nc *nodecache) flush(db ethdb.KeyValueStore, clean *cleanCache, id uint64) clean.plainStorages.Reset() } for h, acc := range nc.LatestAccounts { - clean.plainAccounts.Set(h.Bytes(), acc) + clean.plainAccounts.Set(h.Bytes(), types.FullToSlimAccountRLP(acc)) } for h, storages := range nc.LatestStorages { diff --git a/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index 28a550bf4f..0c1d6a6376 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -27,6 +27,7 @@ import ( "github.com/VictoriaMetrics/fastcache" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" @@ -127,11 +128,14 @@ func newDiskLayer(root common.Hash, id uint64, db *Database, cleans *cleanCache, // the original disk layer). if cleans == nil && db.config.CleanCacheSize != 0 { cleans = &cleanCache{} - cleans.nodes = fastcache.New(db.config.CleanCacheSize * 1 / 2) - cleans.plainAccounts = fastcache.New(db.config.CleanCacheSize * 1 / 4) - cleans.plainStorages = fastcache.New(db.config.CleanCacheSize * 1 / 4) - log.Info("Allocate clean cache in disklayer", "nodes", common.StorageSize(db.config.CleanCacheSize*1/2), - "plainAccount", common.StorageSize(db.config.CleanCacheSize*1/4), "plainStorage", common.StorageSize(db.config.CleanCacheSize*1/4)) + nodeCacheSize := db.config.CleanCacheSize * 42 / 100 + plainAccountsCacheSize := db.config.CleanCacheSize * 58 / 100 * 1 / 4 + plainStoragesCacheSize := db.config.CleanCacheSize * 58 / 100 * 3 / 4 + cleans.nodes = fastcache.New(nodeCacheSize) + cleans.plainAccounts = fastcache.New(plainAccountsCacheSize) + cleans.plainStorages = fastcache.New(plainStoragesCacheSize) + log.Info("Allocate clean cache in disklayer", "nodes", common.StorageSize(nodeCacheSize), + "plainAccount", common.StorageSize(plainAccountsCacheSize), "plainStorage", common.StorageSize(plainStoragesCacheSize)) } return &diskLayer{ root: root, @@ -189,11 +193,11 @@ func (dl *diskLayer) Account(hash common.Hash) ([]byte, error) { } if data, ok := dl.cleans.plainAccounts.HasGet(nil, hash.Bytes()); ok { - return data, nil + return types.MustFullAccountRLP(data), nil } blob := dl.readAccountTrie(hash) - dl.cleans.plainAccounts.Set(hash.Bytes(), blob) + dl.cleans.plainAccounts.Set(hash.Bytes(), types.FullToSlimAccountRLP(blob)) return blob, nil }