diff --git a/cmd/hack/hack.go b/cmd/hack/hack.go index 8baa96d2e948a3e1c21a570b495a6a7062fa71e8..687b2bbe9870e45f604f5d8e2a015223a1f354cf 100644 --- a/cmd/hack/hack.go +++ b/cmd/hack/hack.go @@ -1231,6 +1231,22 @@ func printBranches(block uint64) { } } +func readPlainAccount(chaindata string, address common.Address) { + ethDb, err := ethdb.NewBoltDatabase(chaindata) + check(err) + var acc accounts.Account + enc, err := ethDb.Get(dbutils.PlainStateBucket, address[:]) + if err != nil { + panic(err) + } else if enc == nil { + panic("acc not found") + } + if err = acc.DecodeForStorage(enc); err != nil { + panic(err) + } + fmt.Printf("%x\n%x\n%x\n%d\n", address, acc.Root, acc.CodeHash, acc.Incarnation) +} + func readAccount(chaindata string, account common.Address, block uint64, rewind uint64) { ethDb, err := ethdb.NewBoltDatabase(chaindata) check(err) @@ -2300,6 +2316,9 @@ func main() { if *action == "readAccount" { readAccount(*chaindata, common.HexToAddress(*account), uint64(*block), uint64(*rewind)) } + if *action == "readPlainAccount" { + readPlainAccount(*chaindata, common.HexToAddress(*account)) + } if *action == "fixAccount" { fixAccount(*chaindata, common.HexToHash(*account), common.HexToHash(*hash)) } diff --git a/core/state/db_state_reader.go b/core/state/db_state_reader.go index 3e0c9e6189f6153e50ad32cbb30c7d39a6221c95..d4160d23c19d7a5b84a95b6317c4d14cc9a4741f 100644 --- a/core/state/db_state_reader.go +++ b/core/state/db_state_reader.go @@ -2,12 +2,12 @@ package state import ( "bytes" + "encoding/binary" - lru "github.com/hashicorp/golang-lru" + "github.com/VictoriaMetrics/fastcache" "github.com/ledgerwatch/turbo-geth/common" "github.com/ledgerwatch/turbo-geth/common/dbutils" - "github.com/ledgerwatch/turbo-geth/core/rawdb" "github.com/ledgerwatch/turbo-geth/core/types/accounts" "github.com/ledgerwatch/turbo-geth/ethdb" ) @@ -16,10 +16,10 @@ import ( type DbStateReader struct { db ethdb.Getter incarnationMap map[common.Address]uint64 - accountCache *lru.Cache - storageCache *lru.Cache - codeCache *lru.Cache - codeSizeCache *lru.Cache + accountCache *fastcache.Cache + storageCache *fastcache.Cache + codeCache *fastcache.Cache + codeSizeCache *fastcache.Cache } func NewDbStateReader(db ethdb.Getter, incarnationMap map[common.Address]uint64) *DbStateReader { @@ -29,64 +29,53 @@ func NewDbStateReader(db ethdb.Getter, incarnationMap map[common.Address]uint64) } } -func (dbr *DbStateReader) SetAccountCache(accountCache *lru.Cache) { +func (dbr *DbStateReader) SetAccountCache(accountCache *fastcache.Cache) { dbr.accountCache = accountCache } -func (dbr *DbStateReader) SetStorageCache(storageCache *lru.Cache) { +func (dbr *DbStateReader) SetStorageCache(storageCache *fastcache.Cache) { dbr.storageCache = storageCache } -func (dbr *DbStateReader) SetCodeCache(codeCache *lru.Cache) { +func (dbr *DbStateReader) SetCodeCache(codeCache *fastcache.Cache) { dbr.codeCache = codeCache } -func (dbr *DbStateReader) SetCodeSizeCache(codeSizeCache *lru.Cache) { +func (dbr *DbStateReader) SetCodeSizeCache(codeSizeCache *fastcache.Cache) { dbr.codeSizeCache = codeSizeCache } func (dbr *DbStateReader) ReadAccountData(address common.Address) (*accounts.Account, error) { + var enc []byte + var ok bool if dbr.accountCache != nil { - if cached, ok := dbr.accountCache.Get(address); ok { - if cached == nil { - return nil, nil - } - return cached.(*accounts.Account), nil + enc, ok = dbr.accountCache.HasGet(nil, address[:]) + } + if !ok { + var err error + if addrHash, err1 := common.HashData(address[:]); err1 == nil { + enc, err = dbr.db.Get(dbutils.CurrentStateBucket, addrHash[:]) + } else { + return nil, err1 + } + if err != nil && !entryNotFound(err) { + return nil, err } } - addrHash, err := common.HashData(address[:]) - if err != nil { - return nil, err + if !ok && dbr.accountCache != nil { + dbr.accountCache.Set(address[:], enc) } - var a accounts.Account - if ok, err := rawdb.ReadAccount(dbr.db, addrHash, &a); err != nil { - return nil, err - } else if !ok { - if dbr.accountCache != nil { - dbr.accountCache.Add(address, nil) - } + if enc == nil { return nil, nil } - if dbr.accountCache != nil { - dbr.accountCache.Add(address, a.SelfCopy()) + acc := &accounts.Account{} + if err := acc.DecodeForStorage(enc); err != nil { + return nil, err } - return &a, nil + return acc, nil } func (dbr *DbStateReader) ReadAccountStorage(address common.Address, incarnation uint64, key *common.Hash) ([]byte, error) { - var storageKeyP *[20 + 32]byte - if dbr.storageCache != nil { - var storageKey [20 + 32]byte - copy(storageKey[:], address[:]) - copy(storageKey[20:], key[:]) - if cached, ok := dbr.storageCache.Get(storageKey); ok { - if cached == nil { - return nil, nil - } - return cached.([]byte), nil - } - storageKeyP = &storageKey - } addrHash, err := common.HashData(address[:]) if err != nil { return nil, err @@ -95,34 +84,39 @@ func (dbr *DbStateReader) ReadAccountStorage(address common.Address, incarnation if err1 != nil { return nil, err1 } - enc, err2 := dbr.db.Get(dbutils.CurrentStateBucket, dbutils.GenerateCompositeStorageKey(addrHash, incarnation, seckey)) - if err2 != nil && err2 != ethdb.ErrKeyNotFound { + compositeKey := dbutils.GenerateCompositeStorageKey(addrHash, incarnation, seckey) + if dbr.storageCache != nil { + if enc, ok := dbr.storageCache.HasGet(nil, compositeKey); ok { + return enc, nil + } + } + enc, err2 := dbr.db.Get(dbutils.CurrentStateBucket, compositeKey) + if err2 != nil && !entryNotFound(err2) { return nil, err2 } if dbr.storageCache != nil { - dbr.storageCache.Add(*storageKeyP, enc) + dbr.storageCache.Set(compositeKey, enc) } return enc, nil } -func (dbr *DbStateReader) ReadAccountCode(address common.Address, codeHash common.Hash) (code []byte, err error) { +func (dbr *DbStateReader) ReadAccountCode(address common.Address, codeHash common.Hash) ([]byte, error) { if bytes.Equal(codeHash[:], emptyCodeHash) { return nil, nil } if dbr.codeCache != nil { - if cached, ok := dbr.codeCache.Get(address); ok { - if cached == nil { - return nil, nil - } - return cached.([]byte), nil + if code, ok := dbr.codeCache.HasGet(nil, address[:]); ok { + return code, nil } } - code, err = dbr.db.Get(dbutils.CodeBucket, codeHash[:]) + code, err := dbr.db.Get(dbutils.CodeBucket, codeHash[:]) if dbr.codeCache != nil && len(code) <= 1024 { - dbr.codeCache.Add(address, code) + dbr.codeCache.Set(address[:], code) } if dbr.codeSizeCache != nil { - dbr.codeSizeCache.Add(address, len(code)) + var b [4]byte + binary.BigEndian.PutUint32(b[:], uint32(len(code))) + dbr.codeSizeCache.Set(address[:], b[:]) } return code, err } @@ -132,8 +126,8 @@ func (dbr *DbStateReader) ReadAccountCodeSize(address common.Address, codeHash c return 0, nil } if dbr.codeSizeCache != nil { - if cached, ok := dbr.codeSizeCache.Get(address); ok { - return cached.(int), nil + if b, ok := dbr.codeSizeCache.HasGet(nil, address[:]); ok { + return int(binary.BigEndian.Uint32(b)), nil } } var code []byte @@ -142,7 +136,9 @@ func (dbr *DbStateReader) ReadAccountCodeSize(address common.Address, codeHash c return 0, err } if dbr.codeSizeCache != nil { - dbr.codeSizeCache.Add(address, len(code)) + var b [4]byte + binary.BigEndian.PutUint32(b[:], uint32(len(code))) + dbr.codeSizeCache.Set(address[:], b[:]) } return len(code), nil } diff --git a/core/state/db_state_writer.go b/core/state/db_state_writer.go index 0050698e28ab9e3995a70b13bf27fd0651eda1a2..1387936b130ca50032abaf8d6fc1993f1decaaf1 100644 --- a/core/state/db_state_writer.go +++ b/core/state/db_state_writer.go @@ -2,9 +2,10 @@ package state import ( "context" + "encoding/binary" "fmt" - lru "github.com/hashicorp/golang-lru" + "github.com/VictoriaMetrics/fastcache" "github.com/ledgerwatch/turbo-geth/common" "github.com/ledgerwatch/turbo-geth/common/changeset" @@ -35,25 +36,25 @@ type DbStateWriter struct { blockNr uint64 csw *ChangeSetWriter incarnationMap map[common.Address]uint64 - accountCache *lru.Cache - storageCache *lru.Cache - codeCache *lru.Cache - codeSizeCache *lru.Cache + accountCache *fastcache.Cache + storageCache *fastcache.Cache + codeCache *fastcache.Cache + codeSizeCache *fastcache.Cache } -func (dsw *DbStateWriter) SetAccountCache(accountCache *lru.Cache) { +func (dsw *DbStateWriter) SetAccountCache(accountCache *fastcache.Cache) { dsw.accountCache = accountCache } -func (dsw *DbStateWriter) SetStorageCache(storageCache *lru.Cache) { +func (dsw *DbStateWriter) SetStorageCache(storageCache *fastcache.Cache) { dsw.storageCache = storageCache } -func (dsw *DbStateWriter) SetCodeCache(codeCache *lru.Cache) { +func (dsw *DbStateWriter) SetCodeCache(codeCache *fastcache.Cache) { dsw.codeCache = codeCache } -func (dsw *DbStateWriter) SetCodeSizeCache(codeSizeCache *lru.Cache) { +func (dsw *DbStateWriter) SetCodeSizeCache(codeSizeCache *fastcache.Cache) { dsw.codeSizeCache = codeSizeCache } @@ -84,11 +85,13 @@ func (dsw *DbStateWriter) UpdateAccountData(ctx context.Context, address common. if err != nil { return err } - if err := rawdb.WriteAccount(dsw.stateDb, addrHash, *account); err != nil { + value := make([]byte, account.EncodingLengthForStorage()) + account.EncodeForStorage(value) + if err := dsw.stateDb.Put(dbutils.CurrentStateBucket, addrHash[:], value); err != nil { return err } if dsw.accountCache != nil { - dsw.accountCache.Add(address, account.SelfCopy()) + dsw.accountCache.Set(address[:], value) } return nil } @@ -108,7 +111,15 @@ func (dsw *DbStateWriter) DeleteAccount(ctx context.Context, address common.Addr dsw.incarnationMap[address] = original.Incarnation } if dsw.accountCache != nil { - dsw.accountCache.Add(address, nil) + dsw.accountCache.Set(address[:], nil) + } + if dsw.codeCache != nil { + dsw.codeCache.Set(address[:], nil) + } + if dsw.codeSizeCache != nil { + var b [4]byte + binary.BigEndian.PutUint32(b[:], 0) + dsw.codeSizeCache.Set(address[:], b[:]) } return nil } @@ -129,11 +140,17 @@ func (dsw *DbStateWriter) UpdateAccountCode(address common.Address, incarnation if err := dsw.stateDb.Put(dbutils.ContractCodeBucket, dbutils.GenerateStoragePrefix(addrHash[:], incarnation), codeHash[:]); err != nil { return err } - if dsw.codeCache != nil && len(code) <= 1024 { - dsw.codeCache.Add(address, code) + if dsw.codeCache != nil { + if len(code) <= 1024 { + dsw.codeCache.Set(address[:], code) + } else { + dsw.codeCache.Del(address[:]) + } } if dsw.codeSizeCache != nil { - dsw.codeSizeCache.Add(address, len(code)) + var b [4]byte + binary.BigEndian.PutUint32(b[:], uint32(len(code))) + dsw.codeSizeCache.Set(address[:], b[:]) } return nil } @@ -156,18 +173,14 @@ func (dsw *DbStateWriter) WriteAccountStorage(ctx context.Context, address commo } compositeKey := dbutils.GenerateCompositeStorageKey(addrHash, incarnation, seckey) - v := common.CopyBytes(cleanUpTrailingZeroes(value[:])) + v := cleanUpTrailingZeroes(value[:]) if dsw.storageCache != nil { - var storageKey [20 + 32]byte - copy(storageKey[:], address[:]) - copy(storageKey[20:], key[:]) - dsw.storageCache.Add(storageKey, v) + dsw.storageCache.Set(compositeKey, v) } if len(v) == 0 { return dsw.stateDb.Delete(dbutils.CurrentStateBucket, compositeKey) - } else { - return dsw.stateDb.Put(dbutils.CurrentStateBucket, compositeKey, v) } + return dsw.stateDb.Put(dbutils.CurrentStateBucket, compositeKey, common.CopyBytes(v)) } func (dsw *DbStateWriter) CreateContract(address common.Address) error { diff --git a/core/state/plain_state_reader.go b/core/state/plain_state_reader.go index 496db821949b19d594463171f89c83b59527819c..cbd0a56132621a0d509dd3ad31be8717b26d5d9d 100644 --- a/core/state/plain_state_reader.go +++ b/core/state/plain_state_reader.go @@ -2,7 +2,8 @@ package state import ( "bytes" - lru "github.com/hashicorp/golang-lru" + "encoding/binary" + "github.com/VictoriaMetrics/fastcache" "github.com/ledgerwatch/turbo-geth/common" "github.com/ledgerwatch/turbo-geth/common/dbutils" @@ -18,104 +19,92 @@ var _ StateReader = (*PlainStateReader)(nil) type PlainStateReader struct { db ethdb.Getter uncommitedIncarnations map[common.Address]uint64 - accountCache *lru.Cache - storageCache *lru.Cache - codeCache *lru.Cache - codeSizeCache *lru.Cache + accountCache *fastcache.Cache + storageCache *fastcache.Cache + codeCache *fastcache.Cache + codeSizeCache *fastcache.Cache } -func NewPlainStateReaderWithFallback(db ethdb.Getter, incarnations map[common.Address]uint64) *PlainStateReader { +func NewPlainStateReader(db ethdb.Getter, incarnations map[common.Address]uint64) *PlainStateReader { return &PlainStateReader{ db: db, uncommitedIncarnations: incarnations, } } -func (r *PlainStateReader) SetAccountCache(accountCache *lru.Cache) { +func (r *PlainStateReader) SetAccountCache(accountCache *fastcache.Cache) { r.accountCache = accountCache } -func (r *PlainStateReader) SetStorageCache(storageCache *lru.Cache) { +func (r *PlainStateReader) SetStorageCache(storageCache *fastcache.Cache) { r.storageCache = storageCache } -func (r *PlainStateReader) SetCodeCache(codeCache *lru.Cache) { +func (r *PlainStateReader) SetCodeCache(codeCache *fastcache.Cache) { r.codeCache = codeCache } -func (r *PlainStateReader) SetCodeSizeCache(codeSizeCache *lru.Cache) { +func (r *PlainStateReader) SetCodeSizeCache(codeSizeCache *fastcache.Cache) { r.codeSizeCache = codeSizeCache } func (r *PlainStateReader) ReadAccountData(address common.Address) (*accounts.Account, error) { + var enc []byte + var ok bool if r.accountCache != nil { - if cached, ok := r.accountCache.Get(address); ok { - if cached == nil { - return nil, nil - } - return cached.(*accounts.Account), nil - } + enc, ok = r.accountCache.HasGet(nil, address[:]) } - enc, err := r.db.Get(dbutils.PlainStateBucket, address[:]) - if err == nil { - acc := &accounts.Account{} - if err = acc.DecodeForStorage(enc); err != nil { + if !ok { + var err error + enc, err = r.db.Get(dbutils.PlainStateBucket, address[:]) + if err != nil && !entryNotFound(err) { return nil, err } - if r.accountCache != nil { - r.accountCache.Add(address, acc) - } - return acc, nil - } else if !entryNotFound(err) { - return nil, err } - if r.accountCache != nil { - r.accountCache.Add(address, nil) + if !ok && r.accountCache != nil { + r.accountCache.Set(address[:], enc) + } + if enc == nil { + return nil, nil + } + acc := &accounts.Account{} + if err := acc.DecodeForStorage(enc); err != nil { + return nil, err } - return nil, nil + return acc, nil } func (r *PlainStateReader) ReadAccountStorage(address common.Address, incarnation uint64, key *common.Hash) ([]byte, error) { - var storageKeyP *[20 + 32]byte + compositeKey := dbutils.PlainGenerateCompositeStorageKey(address, incarnation, *key) if r.storageCache != nil { - var storageKey [20 + 32]byte - copy(storageKey[:], address[:]) - copy(storageKey[20:], key[:]) - if cached, ok := r.storageCache.Get(storageKey); ok { - if cached == nil { - return nil, nil - } - return cached.([]byte), nil + if enc, ok := r.storageCache.HasGet(nil, compositeKey); ok { + return enc, nil } - storageKeyP = &storageKey } - enc, err := r.db.Get(dbutils.PlainStateBucket, dbutils.PlainGenerateCompositeStorageKey(address, incarnation, *key)) - if err == nil { - if r.storageCache != nil { - r.storageCache.Add(*storageKeyP, enc) - } - return enc, nil - } else if !entryNotFound(err) { + enc, err := r.db.Get(dbutils.PlainStateBucket, compositeKey) + if err != nil && !entryNotFound(err) { return nil, err } if r.storageCache != nil { - r.storageCache.Add(*storageKeyP, nil) + r.storageCache.Set(compositeKey, enc) } - return nil, nil + return enc, nil } func (r *PlainStateReader) ReadAccountCode(address common.Address, codeHash common.Hash) ([]byte, error) { - if bytes.Equal(codeHash[:], emptyCodeHash) { - return nil, nil - } if r.codeCache != nil { - if cached, ok := r.codeCache.Get(address); ok { - return cached.([]byte), nil + if code, ok := r.codeCache.HasGet(nil, address[:]); ok { + return code, nil } } code, err := r.db.Get(dbutils.CodeBucket, codeHash[:]) - if r.codeCache != nil { - r.codeCache.Add(address, code) + if r.codeCache != nil && len(code) <= 1024 { + r.codeCache.Set(address[:], code) + } + if r.codeSizeCache != nil { + var b [4]byte + binary.BigEndian.PutUint32(b[:], uint32(len(code))) + r.codeSizeCache.Set(address[:], b[:]) } return code, err } @@ -125,8 +114,8 @@ func (r *PlainStateReader) ReadAccountCodeSize(address common.Address, codeHash return 0, nil } if r.codeSizeCache != nil { - if cached, ok := r.codeSizeCache.Get(address); ok { - return cached.(int), nil + if b, ok := r.codeSizeCache.HasGet(nil, address[:]); ok { + return int(binary.BigEndian.Uint32(b)), nil } } code, err := r.db.Get(dbutils.CodeBucket, codeHash[:]) @@ -134,7 +123,9 @@ func (r *PlainStateReader) ReadAccountCodeSize(address common.Address, codeHash return 0, err } if r.codeSizeCache != nil { - r.codeSizeCache.Add(address, len(code)) + var b [4]byte + binary.BigEndian.PutUint32(b[:], uint32(len(code))) + r.codeSizeCache.Set(address[:], b[:]) } return len(code), nil } diff --git a/core/state/plain_state_writer.go b/core/state/plain_state_writer.go index 6c9969c064af59ef65f2649936a4a63be3d35503..00e48f8cbede3ac7777f075e2f4c11384c1ce257 100644 --- a/core/state/plain_state_writer.go +++ b/core/state/plain_state_writer.go @@ -2,8 +2,9 @@ package state import ( "context" + "encoding/binary" - lru "github.com/hashicorp/golang-lru" + "github.com/VictoriaMetrics/fastcache" "github.com/ledgerwatch/turbo-geth/common" "github.com/ledgerwatch/turbo-geth/common/changeset" @@ -20,10 +21,10 @@ type PlainStateWriter struct { uncommitedIncarnations map[common.Address]uint64 csw *ChangeSetWriter blockNumber uint64 - accountCache *lru.Cache - storageCache *lru.Cache - codeCache *lru.Cache - codeSizeCache *lru.Cache + accountCache *fastcache.Cache + storageCache *fastcache.Cache + codeCache *fastcache.Cache + codeSizeCache *fastcache.Cache } func NewPlainStateWriter(stateDb, changeDb ethdb.Database, blockNumber uint64, uncommitedIncarnations map[common.Address]uint64) *PlainStateWriter { @@ -36,19 +37,19 @@ func NewPlainStateWriter(stateDb, changeDb ethdb.Database, blockNumber uint64, u } } -func (w *PlainStateWriter) SetAccountCache(accountCache *lru.Cache) { +func (w *PlainStateWriter) SetAccountCache(accountCache *fastcache.Cache) { w.accountCache = accountCache } -func (w *PlainStateWriter) SetStorageCache(storageCache *lru.Cache) { +func (w *PlainStateWriter) SetStorageCache(storageCache *fastcache.Cache) { w.storageCache = storageCache } -func (w *PlainStateWriter) SetCodeCache(codeCache *lru.Cache) { +func (w *PlainStateWriter) SetCodeCache(codeCache *fastcache.Cache) { w.codeCache = codeCache } -func (w *PlainStateWriter) SetCodeSizeCache(codeSizeCache *lru.Cache) { +func (w *PlainStateWriter) SetCodeSizeCache(codeSizeCache *fastcache.Cache) { w.codeSizeCache = codeSizeCache } @@ -56,11 +57,11 @@ func (w *PlainStateWriter) UpdateAccountData(ctx context.Context, address common if err := w.csw.UpdateAccountData(ctx, address, original, account); err != nil { return err } - if w.accountCache != nil { - w.accountCache.Add(address, account) - } value := make([]byte, account.EncodingLengthForStorage()) account.EncodeForStorage(value) + if w.accountCache != nil { + w.accountCache.Set(address[:], value) + } return w.stateDb.Put(dbutils.PlainStateBucket, address[:], value) } @@ -69,10 +70,16 @@ func (w *PlainStateWriter) UpdateAccountCode(address common.Address, incarnation return err } if w.codeCache != nil { - w.codeCache.Add(address, code) + if len(code) <= 1024 { + w.codeCache.Set(address[:], code) + } else { + w.codeCache.Del(address[:]) + } } if w.codeSizeCache != nil { - w.codeSizeCache.Add(address, len(code)) + var b [4]byte + binary.BigEndian.PutUint32(b[:], uint32(len(code))) + w.codeSizeCache.Set(address[:], b[:]) } if err := w.stateDb.Put(dbutils.CodeBucket, codeHash[:], code); err != nil { return err @@ -88,14 +95,17 @@ func (w *PlainStateWriter) DeleteAccount(ctx context.Context, address common.Add w.uncommitedIncarnations[address] = original.Incarnation } if w.accountCache != nil { - w.accountCache.Add(address, nil) + w.accountCache.Set(address[:], nil) } - if err := w.stateDb.Delete(dbutils.PlainStateBucket, address[:]); err != nil { - if err != ethdb.ErrKeyNotFound { - return err - } + if w.codeCache != nil { + w.codeCache.Set(address[:], nil) } - return nil + if w.codeSizeCache != nil { + var b [4]byte + binary.BigEndian.PutUint32(b[:], 0) + w.codeSizeCache.Set(address[:], b[:]) + } + return w.stateDb.Delete(dbutils.PlainStateBucket, address[:]) } func (w *PlainStateWriter) WriteAccountStorage(ctx context.Context, address common.Address, incarnation uint64, key, original, value *common.Hash) error { @@ -105,25 +115,16 @@ func (w *PlainStateWriter) WriteAccountStorage(ctx context.Context, address comm if *original == *value { return nil } - compositeKey := dbutils.PlainGenerateCompositeStorageKey(address, incarnation, *key) - v := common.CopyBytes(cleanUpTrailingZeroes(value[:])) + v := cleanUpTrailingZeroes(value[:]) if w.storageCache != nil { - var storageKey [20 + 32]byte - copy(storageKey[:], address[:]) - copy(storageKey[20:], key[:]) - w.storageCache.Add(storageKey, v) + w.storageCache.Set(compositeKey, v) } if len(v) == 0 { - if err := w.stateDb.Delete(dbutils.PlainStateBucket, compositeKey); err != nil { - if err != ethdb.ErrKeyNotFound { - return err - } - } - return nil + return w.stateDb.Delete(dbutils.PlainStateBucket, compositeKey) } - return w.stateDb.Put(dbutils.PlainStateBucket, compositeKey, v) + return w.stateDb.Put(dbutils.PlainStateBucket, compositeKey, common.CopyBytes(v)) } func (w *PlainStateWriter) CreateContract(address common.Address) error { diff --git a/eth/downloader/stagedsync_stage_execute.go b/eth/downloader/stagedsync_stage_execute.go index 6961077fb8b0919fae7f93eca86e321232cd5cff..d3999a04f9157572b573158e064803c4fad2317c 100644 --- a/eth/downloader/stagedsync_stage_execute.go +++ b/eth/downloader/stagedsync_stage_execute.go @@ -8,7 +8,7 @@ import ( "sync/atomic" "time" - lru "github.com/hashicorp/golang-lru" + "github.com/VictoriaMetrics/fastcache" "github.com/ledgerwatch/turbo-geth/common" "github.com/ledgerwatch/turbo-geth/common/dbutils" @@ -100,10 +100,10 @@ func spawnExecuteBlocksStage(stateDB ethdb.Database, blockchain BlockChain) (uin progressLogger.Start(&nextBlockNumber) defer progressLogger.Stop() - accountCache, _ := lru.New(400000) - storageCache, _ := lru.New(400000) - codeCache, _ := lru.New(1000) - codeSizeCache, _ := lru.New(400000) + accountCache := fastcache.New(128 * 1024 * 1024) // 128 Mb + storageCache := fastcache.New(128 * 1024 * 1024) // 128 Mb + codeCache := fastcache.New(32 * 1024 * 1024) // 32 Mb (the minimum) + codeSizeCache := fastcache.New(32 * 1024 * 1024) // 32 Mb (the minimum) // uncommitedIncarnations map holds incarnations for accounts that were deleted, // but their storage is not yet committed var uncommitedIncarnations = make(map[common.Address]uint64) @@ -123,7 +123,7 @@ func spawnExecuteBlocksStage(stateDB ethdb.Database, blockchain BlockChain) (uin var stateWriter state.WriterWithChangeSets if core.UsePlainStateExecution { - plainReader := state.NewPlainStateReaderWithFallback(stateBatch, uncommitedIncarnations) + plainReader := state.NewPlainStateReader(stateBatch, uncommitedIncarnations) plainReader.SetAccountCache(accountCache) plainReader.SetStorageCache(storageCache) plainReader.SetCodeCache(codeCache)