core, cmd, accounts, eth, light, trie: seperate out CodeStore interface

This commit is contained in:
Gary Rong 2023-09-01 10:51:23 +08:00
parent a7842c9cae
commit e104cbc902
38 changed files with 359 additions and 274 deletions

View file

@ -148,7 +148,7 @@ func (b *SimulatedBackend) rollback(parent *types.Block) {
blocks, _ := core.GenerateChain(b.config, parent, ethash.NewFaker(), b.database, 1, func(int, *core.BlockGen) {})
b.pendingBlock = blocks[0]
b.pendingState, _ = state.New(b.pendingBlock.Root(), b.blockchain.StateCache(), nil)
b.pendingState, _ = state.New(b.pendingBlock.Root(), state.NewDatabase(b.blockchain.CodeDB(), b.blockchain.TrieDB()), nil)
}
// Fork creates a side-chain that can be used to simulate reorgs.

View file

@ -336,7 +336,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
}
func MakePreState(db ethdb.Database, accounts core.GenesisAlloc) *state.StateDB {
sdb := state.NewDatabaseWithConfig(db, &trie.Config{Preimages: true})
tdb := trie.NewDatabase(db, &trie.Config{Preimages: true})
sdb := state.NewDatabase(state.NewCodeDB(db), tdb)
statedb, _ := state.New(types.EmptyRootHash, sdb, nil)
for addr, a := range accounts {
statedb.SetCode(addr, a.Code)

View file

@ -149,7 +149,7 @@ func runCmd(ctx *cli.Context) error {
})
defer triedb.Close()
genesis := gen.MustCommit(db, triedb)
sdb := state.NewDatabaseWithNodeDB(db, triedb)
sdb := state.NewDatabase(state.NewCodeDB(db), triedb)
statedb, _ = state.New(genesis.Root(), sdb, nil)
chainConfig = gen.Config
} else {
@ -159,7 +159,7 @@ func runCmd(ctx *cli.Context) error {
HashDB: hashdb.Defaults,
})
defer triedb.Close()
sdb := state.NewDatabaseWithNodeDB(db, triedb)
sdb := state.NewDatabase(state.NewCodeDB(db), triedb)
statedb, _ = state.New(types.EmptyRootHash, sdb, nil)
genesisConfig = new(core.Genesis)
}

View file

@ -476,7 +476,7 @@ func dump(ctx *cli.Context) error {
triedb := utils.MakeTrieDatabase(ctx, db, true, false) // always enable preimage lookup
defer triedb.Close()
state, err := state.New(root, state.NewDatabaseWithNodeDB(db, triedb), nil)
state, err := state.New(root, state.NewDatabase(state.NewCodeDB(db), triedb), nil)
if err != nil {
return err
}

View file

@ -209,8 +209,8 @@ type BlockChain struct {
gcproc time.Duration // Accumulates canonical block processing for trie dumping
lastWrite uint64 // Last block when the state was flushed
flushInterval atomic.Int64 // Time interval (processing time) after which to flush a state
codedb *state.CodeDB // The database handler for maintaining contract codes.
triedb *trie.Database // The database handler for maintaining trie nodes.
stateCache state.Database // State database to reuse between imports (contains state cache)
// txLookupLimit is the maximum number of blocks from head whose tx indices
// are reserved:
@ -289,6 +289,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
chainConfig: chainConfig,
cacheConfig: cacheConfig,
db: db,
codedb: state.NewCodeDB(db),
triedb: triedb,
triegc: prque.New[int64, common.Hash](nil),
quit: make(chan struct{}),
@ -304,7 +305,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
}
bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit))
bc.forker = NewForkChoice(bc, shouldPreserve)
bc.stateCache = state.NewDatabaseWithNodeDB(bc.db, bc.triedb)
bc.validator = NewBlockValidator(chainConfig, bc, engine)
bc.prefetcher = newStatePrefetcher(chainConfig, bc, engine)
bc.processor = NewStateProcessor(chainConfig, bc, engine)
@ -1781,11 +1781,10 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
if parent == nil {
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
}
statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps)
statedb, err := state.New(parent.Root, state.NewDatabase(bc.codedb, bc.triedb), bc.snaps)
if err != nil {
return it.index, err
}
// Enable prefetching to pull in trie node paths while processing transactions
statedb.StartPrefetcher("chain")
activeState = statedb
@ -1795,7 +1794,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
var followupInterrupt atomic.Bool
if !bc.cacheConfig.TrieCleanNoPrefetch {
if followup, err := it.peek(); followup != nil && err == nil {
throwaway, _ := state.New(parent.Root, bc.stateCache, bc.snaps)
throwaway, _ := state.New(parent.Root, state.NewDatabase(bc.codedb, bc.triedb), bc.snaps)
go func(start time.Time, followup *types.Block, throwaway *state.StateDB) {
bc.prefetcher.Prefetch(followup, throwaway, bc.vmConfig, &followupInterrupt)

View file

@ -278,7 +278,7 @@ func (bc *BlockChain) GetTd(hash common.Hash, number uint64) *big.Int {
// HasState checks if state trie is fully present in the database or not.
func (bc *BlockChain) HasState(hash common.Hash) bool {
_, err := bc.stateCache.OpenTrie(hash)
_, err := bc.StateAt(hash)
return err == nil
}
@ -311,12 +311,9 @@ func (bc *BlockChain) stateRecoverable(root common.Hash) bool {
// If the code doesn't exist in the in-memory cache, check the storage with
// new code scheme.
func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
type codeReader interface {
ContractCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error)
}
// TODO(rjl493456442) The associated account address is also required
// in Verkle scheme. Fix it once snap-sync is supported for Verkle.
return bc.stateCache.(codeReader).ContractCodeWithPrefix(common.Address{}, hash)
return bc.codedb.ReadCodeWithPrefix(common.Address{}, hash)
}
// State returns a new mutable state based on the current HEAD block.
@ -326,7 +323,7 @@ func (bc *BlockChain) State() (*state.StateDB, error) {
// StateAt returns a new mutable state based on a particular point in time.
func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
return state.New(root, bc.stateCache, bc.snaps)
return state.New(root, state.NewDatabase(bc.codedb, bc.triedb), bc.snaps)
}
// Config retrieves the chain's fork configuration.
@ -350,11 +347,6 @@ func (bc *BlockChain) Processor() Processor {
return bc.processor
}
// StateCache returns the caching database underpinning the blockchain instance.
func (bc *BlockChain) StateCache() state.Database {
return bc.stateCache
}
// GasLimit returns the gas limit of the current HEAD block.
func (bc *BlockChain) GasLimit() uint64 {
return bc.CurrentBlock().GasLimit
@ -387,6 +379,11 @@ func (bc *BlockChain) TrieDB() *trie.Database {
return bc.triedb
}
// CodeDB retrieves the low level code database used for contract code storage.
func (bc *BlockChain) CodeDB() *state.CodeDB {
return bc.codedb
}
// SubscribeRemovedLogsEvent registers a subscription of RemovedLogsEvent.
func (bc *BlockChain) SubscribeRemovedLogsEvent(ch chan<- RemovedLogsEvent) event.Subscription {
return bc.scope.Track(bc.rmLogsFeed.Subscribe(ch))

View file

@ -30,7 +30,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
@ -2040,7 +2039,6 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme
dbconfig.HashDB = hashdb.Defaults
}
chain.triedb = trie.NewDatabase(chain.db, dbconfig)
chain.stateCache = state.NewDatabaseWithNodeDB(chain.db, chain.triedb)
// Force run a freeze cycle
type freezer interface {

View file

@ -158,7 +158,8 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
}
return err
}
statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache, nil)
sdb := state.NewDatabase(blockchain.CodeDB(), blockchain.TrieDB())
statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), sdb, nil)
if err != nil {
return err
}

View file

@ -343,8 +343,10 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
triedb := trie.NewDatabase(db, trie.HashDefaults)
defer triedb.Close()
codedb := state.NewCodeDB(db)
for i := 0; i < n; i++ {
statedb, err := state.New(parent.Root(), state.NewDatabaseWithNodeDB(db, triedb), nil)
statedb, err := state.New(parent.Root(), state.NewDatabase(codedb, triedb), nil)
if err != nil {
panic(err)
}

View file

@ -124,7 +124,8 @@ func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
func (ga *GenesisAlloc) deriveHash() (common.Hash, error) {
// Create an ephemeral in-memory database for computing hash,
// all the derived states will be discarded to not pollute disk.
db := state.NewDatabase(rawdb.NewMemoryDatabase())
memorydb := rawdb.NewMemoryDatabase()
db := state.NewDatabase(state.NewCodeDB(memorydb), trie.NewDatabase(memorydb, trie.HashDefaults))
statedb, err := state.New(types.EmptyRootHash, db, nil)
if err != nil {
return common.Hash{}, err
@ -139,14 +140,14 @@ func (ga *GenesisAlloc) deriveHash() (common.Hash, error) {
statedb.SetState(addr, key, value)
}
}
return statedb.Commit(0, false)
return statedb.IntermediateRoot(false), nil
}
// flush is very similar with deriveHash, but the main difference is
// all the generated states will be persisted into the given database.
// Also, the genesis state specification will be flushed as well.
func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database, blockhash common.Hash) error {
statedb, err := state.New(types.EmptyRootHash, state.NewDatabaseWithNodeDB(db, triedb), nil)
statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(state.NewCodeDB(db), triedb), nil)
if err != nil {
return err
}

111
core/state/codestore.go Normal file
View file

@ -0,0 +1,111 @@
// Copyright 2023 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
package state
import (
"errors"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/lru"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb"
)
const (
// Number of codehash->size associations to keep.
codeSizeCacheSize = 100000
// Cache size granted for caching clean code.
codeCacheSize = 64 * 1024 * 1024
)
var errMismatchedLength = errors.New("provided lists have different lengths")
// CodeDB is an implementation of the CodeStore interface, designed for providing
// efficient read and write functionalities for contract code.
type CodeDB struct {
db ethdb.KeyValueStore
size *lru.Cache[common.Hash, int]
cache *lru.SizeConstrainedCache[common.Hash, []byte]
}
// NewCodeDB returns a codeDB instance with given database.
func NewCodeDB(db ethdb.KeyValueStore) *CodeDB {
return &CodeDB{
db: db,
size: lru.NewCache[common.Hash, int](codeSizeCacheSize),
cache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
}
}
// ReadCode implements CodeReader, retrieving a particular contract's code
// with given contract address and code hash.
func (db *CodeDB) ReadCode(address common.Address, codeHash common.Hash) ([]byte, error) {
code, _ := db.cache.Get(codeHash)
if len(code) > 0 {
return code, nil
}
code = rawdb.ReadCode(db.db, codeHash)
if len(code) > 0 {
db.cache.Add(codeHash, code)
db.size.Add(codeHash, len(code))
return code, nil
}
return nil, errors.New("not found")
}
// ReadCodeSize implements CodeReader, retrieving a particular contracts code's size
// with given contract address and code hash.
func (db *CodeDB) ReadCodeSize(addr common.Address, codeHash common.Hash) (int, error) {
if cached, ok := db.size.Get(codeHash); ok {
return cached, nil
}
code, err := db.ReadCode(addr, codeHash)
return len(code), err
}
// WriteCodes implements CodeWriter, writing the provided a list of contract codes
// into database.
func (db *CodeDB) WriteCodes(addresses []common.Address, hashes []common.Hash, codes [][]byte) error {
if len(addresses) != len(hashes) {
return errMismatchedLength
}
if len(addresses) != len(codes) {
return errMismatchedLength
}
batch := db.db.NewBatch()
for i := 0; i < len(addresses); i++ {
rawdb.WriteCode(batch, hashes[i], codes[i])
}
return batch.Write()
}
// ReadCodeWithPrefix retrieves a particular contract's code. If the code can't
// be found in the cache, then check the existence with **new** db scheme.
func (db *CodeDB) ReadCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error) {
code, _ := db.cache.Get(codeHash)
if len(code) > 0 {
return code, nil
}
code = rawdb.ReadCodeWithPrefix(db.db, codeHash)
if len(code) > 0 {
db.cache.Add(codeHash, code)
db.size.Add(codeHash, len(code))
return code, nil
}
return nil, errors.New("not found")
}

View file

@ -17,12 +17,9 @@
package state
import (
"errors"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/lru"
"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"
@ -30,16 +27,34 @@ import (
"github.com/ethereum/go-ethereum/trie/trienode"
)
const (
// Number of codehash->size associations to keep.
codeSizeCacheSize = 100000
// CodeReader wraps the ReadCode and ReadCodeSize methods of a backing contract
// code store, providing an interface for retrieving contract code and its size.
type CodeReader interface {
// ReadCode retrieves a particular contract's code.
ReadCode(addr common.Address, codeHash common.Hash) ([]byte, error)
// Cache size granted for caching clean code.
codeCacheSize = 64 * 1024 * 1024
)
// ReadCodeSize retrieves a particular contracts code's size.
ReadCodeSize(addr common.Address, codeHash common.Hash) (int, error)
}
// Database wraps access to tries and contract code.
// CodeWriter wraps the WriteCodes method of a backing contract code store,
// providing an interface for writing contract codes back to database.
type CodeWriter interface {
WriteCodes(addresses []common.Address, codeHashes []common.Hash, codes [][]byte) error
}
// CodeStore defines the essential methods for reading and writing contract codes,
// providing a comprehensive interface for code management.
type CodeStore interface {
CodeReader
CodeWriter
}
// Database defines the essential methods for reading and writing ethereum states,
// providing a comprehensive interface for ethereum state management.
type Database interface {
CodeStore
// OpenTrie opens the main account trie.
OpenTrie(root common.Hash) (Trie, error)
@ -49,20 +64,12 @@ type Database interface {
// CopyTrie returns an independent copy of the given trie.
CopyTrie(Trie) Trie
// ContractCode retrieves a particular contract's code.
ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error)
// ContractCodeSize retrieves a particular contracts code's size.
ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error)
// DiskDB returns the underlying key-value disk database.
DiskDB() ethdb.KeyValueStore
// TrieDB returns the underlying trie database for managing trie nodes.
TrieDB() *trie.Database
}
// Trie is a Ethereum Merkle Patricia trie.
// Trie is a Ethereum state trie interface, defining the essential methods
// to read and write states via trie.
type Trie interface {
// GetKey returns the sha3 preimage of a hashed key that was previously used
// to store a value.
@ -70,11 +77,6 @@ type Trie interface {
// TODO(fjl): remove this when StateTrie is removed
GetKey([]byte) []byte
// GetStorage returns the value for key stored in the trie. The value bytes
// must not be modified by the caller. If a node was not found in the database,
// a trie.MissingNodeError is returned.
GetStorage(addr common.Address, key []byte) ([]byte, error)
// GetAccount abstracts an account read from the trie. It retrieves the
// account blob from the trie with provided account address and decodes it
// with associated decoding algorithm. If the specified account is not in
@ -83,27 +85,32 @@ type Trie interface {
// be returned.
GetAccount(address common.Address) (*types.StateAccount, error)
// UpdateStorage associates key with value in the trie. If value has length zero,
// any existing value is deleted from the trie. The value bytes must not be modified
// by the caller while they are stored in the trie. If a node was not found in the
// database, a trie.MissingNodeError is returned.
UpdateStorage(addr common.Address, key, value []byte) error
// GetStorage returns the value for key stored in the trie. The value bytes
// must not be modified by the caller. If a node was not found in the database,
// a trie.MissingNodeError is returned.
GetStorage(addr common.Address, key []byte) ([]byte, error)
// UpdateAccount abstracts an account write to the trie. It encodes the
// provided account object with associated algorithm and then updates it
// in the trie with provided address.
UpdateAccount(address common.Address, account *types.StateAccount) error
// UpdateContractCode abstracts code write to the trie. It is expected
// to be moved to the stateWriter interface when the latter is ready.
UpdateContractCode(address common.Address, codeHash common.Hash, code []byte) error
// UpdateStorage associates key with value in the trie. If value has length zero,
// any existing value is deleted from the trie. The value bytes must not be modified
// by the caller while they are stored in the trie. If a node was not found in the
// database, a trie.MissingNodeError is returned.
UpdateStorage(addr common.Address, key, value []byte) error
// DeleteAccount abstracts an account deletion from the trie.
DeleteAccount(address common.Address) error
// DeleteStorage removes any existing value for key from the trie. If a node
// was not found in the database, a trie.MissingNodeError is returned.
DeleteStorage(addr common.Address, key []byte) error
// DeleteAccount abstracts an account deletion from the trie.
DeleteAccount(address common.Address) error
// UpdateContractCode abstracts code write to the trie. It is expected
// to be moved to the stateWriter interface when the latter is ready.
UpdateContractCode(address common.Address, codeHash common.Hash, code []byte) error
// Hash returns the root hash of the trie. It does not write to the database and
// can be used even if the trie doesn't have one.
@ -132,58 +139,37 @@ type Trie interface {
Prove(key []byte, proofDb ethdb.KeyValueWriter) error
}
// NewDatabase creates a backing store for state. The returned database is safe for
// concurrent use, but does not retain any recent trie nodes in memory. To keep some
// historical state in memory, use the NewDatabaseWithConfig constructor.
func NewDatabase(db ethdb.Database) Database {
return NewDatabaseWithConfig(db, nil)
}
// NewDatabaseWithConfig creates a backing store for state. The returned database
// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a
// large memory cache.
func NewDatabaseWithConfig(db ethdb.Database, config *trie.Config) Database {
// NewDatabase creates a state database with the provided contract code store
// and trie node database.
func NewDatabase(codedb *CodeDB, triedb *trie.Database) Database {
return &cachingDB{
disk: db,
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
triedb: trie.NewDatabase(db, config),
codedb: codedb,
triedb: triedb,
}
}
// NewDatabaseWithNodeDB creates a state database with an already initialized node database.
func NewDatabaseWithNodeDB(db ethdb.Database, triedb *trie.Database) Database {
return &cachingDB{
disk: db,
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
triedb: triedb,
}
// NewDatabaseForTesting is similar to NewDatabase, but it sets up a local code
// store and trie database with default config by using the provided database,
// specifically intended for testing.
func NewDatabaseForTesting(db ethdb.Database) Database {
return NewDatabase(NewCodeDB(db), trie.NewDatabase(db, nil))
}
// cachingDB is the implementation of Database interface, designed for providing
// functionalities to read and write states.
type cachingDB struct {
disk ethdb.KeyValueStore
codeSizeCache *lru.Cache[common.Hash, int]
codeCache *lru.SizeConstrainedCache[common.Hash, []byte]
triedb *trie.Database
codedb *CodeDB
triedb *trie.Database
}
// OpenTrie opens the main account trie at a specific root hash.
func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
if err != nil {
return nil, err
}
return tr, nil
return trie.NewStateTrie(trie.StateTrieID(root), db.triedb)
}
// OpenStorageTrie opens the storage trie of an account.
func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash) (Trie, error) {
tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb)
if err != nil {
return nil, err
}
return tr, nil
return trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb)
}
// CopyTrie returns an independent copy of the given trie.
@ -196,50 +182,21 @@ func (db *cachingDB) CopyTrie(t Trie) Trie {
}
}
// ContractCode retrieves a particular contract's code.
func (db *cachingDB) ContractCode(address common.Address, codeHash common.Hash) ([]byte, error) {
code, _ := db.codeCache.Get(codeHash)
if len(code) > 0 {
return code, nil
}
code = rawdb.ReadCode(db.disk, codeHash)
if len(code) > 0 {
db.codeCache.Add(codeHash, code)
db.codeSizeCache.Add(codeHash, len(code))
return code, nil
}
return nil, errors.New("not found")
// ReadCode implements CodeReader, retrieving a particular contract's code.
func (db *cachingDB) ReadCode(address common.Address, codeHash common.Hash) ([]byte, error) {
return db.codedb.ReadCode(address, codeHash)
}
// ContractCodeWithPrefix retrieves a particular contract's code. If the
// code can't be found in the cache, then check the existence with **new**
// db scheme.
func (db *cachingDB) ContractCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error) {
code, _ := db.codeCache.Get(codeHash)
if len(code) > 0 {
return code, nil
}
code = rawdb.ReadCodeWithPrefix(db.disk, codeHash)
if len(code) > 0 {
db.codeCache.Add(codeHash, code)
db.codeSizeCache.Add(codeHash, len(code))
return code, nil
}
return nil, errors.New("not found")
// ReadCodeSize implements CodeReader, retrieving a particular contracts
// code's size.
func (db *cachingDB) ReadCodeSize(addr common.Address, codeHash common.Hash) (int, error) {
return db.codedb.ReadCodeSize(addr, codeHash)
}
// ContractCodeSize retrieves a particular contracts code's size.
func (db *cachingDB) ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) {
if cached, ok := db.codeSizeCache.Get(codeHash); ok {
return cached, nil
}
code, err := db.ContractCode(addr, codeHash)
return len(code), err
}
// DiskDB returns the underlying key-value disk database.
func (db *cachingDB) DiskDB() ethdb.KeyValueStore {
return db.disk
// WriteCodes implements CodeWriter, writing the provided a list of contract
// codes into database.
func (db *cachingDB) WriteCodes(addresses []common.Address, hashes []common.Hash, codes [][]byte) error {
return db.codedb.WriteCodes(addresses, hashes, codes)
}
// TrieDB retrieves any intermediate trie-node caching layer.

View file

@ -136,7 +136,7 @@ func (it *nodeIterator) step() error {
}
if !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) {
it.codeHash = common.BytesToHash(account.CodeHash)
it.code, err = it.state.db.ContractCode(address, common.BytesToHash(account.CodeHash))
it.code, err = it.state.db.ReadCode(address, common.BytesToHash(account.CodeHash))
if err != nil {
return fmt.Errorf("code %x: %v", account.CodeHash, err)
}

View file

@ -472,7 +472,7 @@ func (s *stateObject) Code() []byte {
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
return nil
}
code, err := s.db.db.ContractCode(s.address, common.BytesToHash(s.CodeHash()))
code, err := s.db.db.ReadCode(s.address, common.BytesToHash(s.CodeHash()))
if err != nil {
s.db.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err))
}
@ -490,7 +490,7 @@ func (s *stateObject) CodeSize() int {
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
return 0
}
size, err := s.db.db.ContractCodeSize(s.address, common.BytesToHash(s.CodeHash()))
size, err := s.db.db.ReadCodeSize(s.address, common.BytesToHash(s.CodeHash()))
if err != nil {
s.db.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err))
}

View file

@ -37,14 +37,16 @@ type stateEnv struct {
func newStateEnv() *stateEnv {
db := rawdb.NewMemoryDatabase()
sdb, _ := New(types.EmptyRootHash, NewDatabase(db), nil)
sdb, _ := New(types.EmptyRootHash, NewDatabaseForTesting(db), nil)
return &stateEnv{db: db, state: sdb}
}
func TestDump(t *testing.T) {
db := rawdb.NewMemoryDatabase()
tdb := NewDatabaseWithConfig(db, &trie.Config{Preimages: true})
sdb, _ := New(types.EmptyRootHash, tdb, nil)
tdb := trie.NewDatabase(db, &trie.Config{Preimages: true})
defer tdb.Close()
sdb, _ := New(types.EmptyRootHash, NewDatabase(NewCodeDB(db), tdb), nil)
s := &stateEnv{db: db, state: sdb}
// generate a few entries
@ -61,7 +63,7 @@ func TestDump(t *testing.T) {
root, _ := s.state.Commit(0, false)
// check that DumpToCollector contains the state objects that are in trie
s.state, _ = New(root, tdb, nil)
s.state, _ = New(root, NewDatabase(NewCodeDB(db), tdb), nil)
got := string(s.state.Dump(nil))
want := `{
"root": "71edff0130dd2385947095001c73d9e28d862fc286fca2b922ca6f6f3cddfdd2",
@ -97,8 +99,10 @@ func TestDump(t *testing.T) {
func TestIterativeDump(t *testing.T) {
db := rawdb.NewMemoryDatabase()
tdb := NewDatabaseWithConfig(db, &trie.Config{Preimages: true})
sdb, _ := New(types.EmptyRootHash, tdb, nil)
tdb := trie.NewDatabase(db, &trie.Config{Preimages: true})
defer tdb.Close()
sdb, _ := New(types.EmptyRootHash, NewDatabase(NewCodeDB(db), tdb), nil)
s := &stateEnv{db: db, state: sdb}
// generate a few entries
@ -115,7 +119,7 @@ func TestIterativeDump(t *testing.T) {
s.state.updateStateObject(obj1)
s.state.updateStateObject(obj2)
root, _ := s.state.Commit(0, false)
s.state, _ = New(root, tdb, nil)
s.state, _ = New(root, NewDatabase(NewCodeDB(db), tdb), nil)
b := &bytes.Buffer{}
s.state.IterativeDump(nil, json.NewEncoder(b))
@ -191,7 +195,7 @@ func TestSnapshotEmpty(t *testing.T) {
}
func TestSnapshot2(t *testing.T) {
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
stateobjaddr0 := common.BytesToAddress([]byte("so0"))
stateobjaddr1 := common.BytesToAddress([]byte("so1"))

View file

@ -1174,12 +1174,19 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
// Commit objects to the trie, measuring the elapsed time
var (
// Metrics
accountTrieNodesUpdated int
accountTrieNodesDeleted int
storageTrieNodesUpdated int
storageTrieNodesDeleted int
nodes = trienode.NewMergedNodeSet()
codeWriter = s.db.DiskDB().NewBatch()
// Un-flushed contract codes
addresses []common.Address
codeHashes []common.Hash
codes [][]byte
// Un-flushed trie nodes
nodes = trienode.NewMergedNodeSet()
)
// Handle all state deletions first
incomplete, err := s.handleDestruction(nodes)
@ -1194,8 +1201,12 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
}
// Write any contract code associated with the state object
if obj.code != nil && obj.dirtyCode {
rawdb.WriteCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code)
obj.dirtyCode = false
// Collect dirty contract codes for later write in a single batch.
addresses = append(addresses, addr)
codeHashes = append(codeHashes, common.BytesToHash(obj.CodeHash()))
codes = append(codes, obj.code)
}
// Write any storage changes in the state object to its storage trie
set, err := obj.commit()
@ -1214,10 +1225,8 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
storageTrieNodesDeleted += deleted
}
}
if codeWriter.ValueSize() > 0 {
if err := codeWriter.Write(); err != nil {
log.Crit("Failed to commit dirty codes", "error", err)
}
if err := s.db.WriteCodes(addresses, codeHashes, codes); err != nil {
return common.Hash{}, err
}
// Write the account trie changes, measuring the amount of wasted time
var start time.Time

View file

@ -182,7 +182,7 @@ func (test *stateTest) run() bool {
}
disk = rawdb.NewMemoryDatabase()
tdb = trie.NewDatabase(disk, &trie.Config{PathDB: pathdb.Defaults})
sdb = NewDatabaseWithNodeDB(disk, tdb)
sdb = NewDatabase(NewCodeDB(disk), tdb)
byzantium = rand.Intn(2) == 0
)
defer disk.Close()

View file

@ -51,7 +51,7 @@ func TestUpdateLeaks(t *testing.T) {
db = rawdb.NewMemoryDatabase()
tdb = trie.NewDatabase(db, nil)
)
state, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(db, tdb), nil)
state, _ := New(types.EmptyRootHash, NewDatabase(NewCodeDB(db), tdb), nil)
// Update it with some accounts
for i := byte(0); i < 255; i++ {
@ -87,8 +87,8 @@ func TestIntermediateLeaks(t *testing.T) {
finalDb := rawdb.NewMemoryDatabase()
transNdb := trie.NewDatabase(transDb, nil)
finalNdb := trie.NewDatabase(finalDb, nil)
transState, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(transDb, transNdb), nil)
finalState, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(finalDb, finalNdb), nil)
transState, _ := New(types.EmptyRootHash, NewDatabase(NewCodeDB(transDb), transNdb), nil)
finalState, _ := New(types.EmptyRootHash, NewDatabase(NewCodeDB(finalDb), finalNdb), nil)
modify := func(state *StateDB, addr common.Address, i, tweak byte) {
state.SetBalance(addr, big.NewInt(int64(11*i)+int64(tweak)))
@ -163,7 +163,7 @@ func TestIntermediateLeaks(t *testing.T) {
// https://github.com/ethereum/go-ethereum/pull/15549.
func TestCopy(t *testing.T) {
// Create a random state test to copy and modify "independently"
orig, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
orig, _ := New(types.EmptyRootHash, NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
for i := byte(0); i < 255; i++ {
obj := orig.GetOrNewStateObject(common.BytesToAddress([]byte{i}))
@ -423,7 +423,7 @@ func (test *snapshotTest) String() string {
func (test *snapshotTest) run() bool {
// Run all actions and create snapshots.
var (
state, _ = New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ = New(types.EmptyRootHash, NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
snapshotRevs = make([]int, len(test.snapshots))
sindex = 0
)
@ -552,7 +552,7 @@ func TestTouchDelete(t *testing.T) {
// TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy.
// See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512
func TestCopyOfCopy(t *testing.T) {
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
addr := common.HexToAddress("aaaa")
state.SetBalance(addr, big.NewInt(42))
@ -569,7 +569,7 @@ func TestCopyOfCopy(t *testing.T) {
//
// See https://github.com/ethereum/go-ethereum/issues/20106.
func TestCopyCommitCopy(t *testing.T) {
tdb := NewDatabase(rawdb.NewMemoryDatabase())
tdb := NewDatabaseForTesting(rawdb.NewMemoryDatabase())
state, _ := New(types.EmptyRootHash, tdb, nil)
// Create an account and check if the retrieved balance is correct
@ -643,7 +643,7 @@ func TestCopyCommitCopy(t *testing.T) {
//
// See https://github.com/ethereum/go-ethereum/issues/20106.
func TestCopyCopyCommitCopy(t *testing.T) {
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
// Create an account and check if the retrieved balance is correct
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
@ -712,7 +712,7 @@ func TestCopyCopyCommitCopy(t *testing.T) {
// TestCommitCopy tests the copy from a committed state is not functional.
func TestCommitCopy(t *testing.T) {
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
// Create an account and check if the retrieved balance is correct
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
@ -765,7 +765,7 @@ func TestCommitCopy(t *testing.T) {
// first, but the journal wiped the entire state object on create-revert.
func TestDeleteCreateRevert(t *testing.T) {
// Create an initial state with a single contract
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
addr := common.BytesToAddress([]byte("so"))
state.SetBalance(addr, big.NewInt(1))
@ -814,7 +814,7 @@ func testMissingTrieNodes(t *testing.T, scheme string) {
CleanCacheSize: 0,
}}) // disable caching
}
db := NewDatabaseWithNodeDB(memDb, triedb)
db := NewDatabase(NewCodeDB(memDb), triedb)
var root common.Hash
state, _ := New(types.EmptyRootHash, db, nil)
@ -865,7 +865,7 @@ func TestStateDBAccessList(t *testing.T) {
}
memDb := rawdb.NewMemoryDatabase()
db := NewDatabase(memDb)
db := NewDatabaseForTesting(memDb)
state, _ := New(types.EmptyRootHash, db, nil)
state.accessList = newAccessList()
@ -1036,7 +1036,7 @@ func TestFlushOrderDataLoss(t *testing.T) {
var (
memdb = rawdb.NewMemoryDatabase()
triedb = trie.NewDatabase(memdb, nil)
statedb = NewDatabaseWithNodeDB(memdb, triedb)
statedb = NewDatabase(NewCodeDB(memdb), triedb)
state, _ = New(types.EmptyRootHash, statedb, nil)
)
for a := byte(0); a < 10; a++ {
@ -1057,7 +1057,7 @@ func TestFlushOrderDataLoss(t *testing.T) {
t.Fatalf("failed to commit state trie: %v", err)
}
// Reopen the state trie from flushed disk and verify it
state, err = New(root, NewDatabase(memdb), nil)
state, err = New(root, NewDatabaseForTesting(memdb), nil)
if err != nil {
t.Fatalf("failed to reopen state trie: %v", err)
}
@ -1072,7 +1072,7 @@ func TestFlushOrderDataLoss(t *testing.T) {
func TestStateDBTransientStorage(t *testing.T) {
memDb := rawdb.NewMemoryDatabase()
db := NewDatabase(memDb)
db := NewDatabaseForTesting(memDb)
state, _ := New(types.EmptyRootHash, db, nil)
key := common.Hash{0x01}
@ -1108,7 +1108,7 @@ func TestResetObject(t *testing.T) {
var (
disk = rawdb.NewMemoryDatabase()
tdb = trie.NewDatabase(disk, nil)
db = NewDatabaseWithNodeDB(disk, tdb)
db = NewDatabase(NewCodeDB(disk), tdb)
snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash)
state, _ = New(types.EmptyRootHash, db, snaps)
addr = common.HexToAddress("0x1")
@ -1142,7 +1142,7 @@ func TestDeleteStorage(t *testing.T) {
var (
disk = rawdb.NewMemoryDatabase()
tdb = trie.NewDatabase(disk, nil)
db = NewDatabaseWithNodeDB(disk, tdb)
db = NewDatabase(NewCodeDB(disk), tdb)
snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash)
state, _ = New(types.EmptyRootHash, db, snaps)
addr = common.HexToAddress("0x1")

View file

@ -51,7 +51,7 @@ func makeTestState(scheme string) (ethdb.Database, Database, *trie.Database, com
}
db := rawdb.NewMemoryDatabase()
nodeDb := trie.NewDatabase(db, config)
sdb := NewDatabaseWithNodeDB(db, nodeDb)
sdb := NewDatabase(NewCodeDB(db), nodeDb)
state, _ := New(types.EmptyRootHash, sdb, nil)
// Fill it with some arbitrary data
@ -92,7 +92,10 @@ func checkStateAccounts(t *testing.T, db ethdb.Database, scheme string, root com
config.PathDB = pathdb.Defaults
}
// Check root availability and state contents
state, err := New(root, NewDatabaseWithConfig(db, &config), nil)
tdb := trie.NewDatabase(db, &config)
defer tdb.Close()
state, err := New(root, NewDatabase(NewCodeDB(db), tdb), nil)
if err != nil {
t.Fatalf("failed to create state trie at %x: %v", root, err)
}
@ -118,7 +121,10 @@ func checkStateConsistency(db ethdb.Database, scheme string, root common.Hash) e
if scheme == rawdb.PathScheme {
config.PathDB = pathdb.Defaults
}
state, err := New(root, NewDatabaseWithConfig(db, config), nil)
tdb := trie.NewDatabase(db, config)
defer tdb.Close()
state, err := New(root, NewDatabase(NewCodeDB(db), tdb), nil)
if err != nil {
return err
}
@ -215,7 +221,7 @@ func testIterativeStateSync(t *testing.T, count int, commit bool, bypath bool, s
codeResults = make([]trie.CodeSyncResult, len(codeElements))
)
for i, element := range codeElements {
data, err := srcDb.ContractCode(common.Address{}, element.code)
data, err := srcDb.ReadCode(common.Address{}, element.code)
if err != nil {
t.Fatalf("failed to retrieve contract bytecode for hash %x", element.code)
}
@ -335,7 +341,7 @@ func testIterativeDelayedStateSync(t *testing.T, scheme string) {
if len(codeElements) > 0 {
codeResults := make([]trie.CodeSyncResult, len(codeElements)/2+1)
for i, element := range codeElements[:len(codeResults)] {
data, err := srcDb.ContractCode(common.Address{}, element.code)
data, err := srcDb.ReadCode(common.Address{}, element.code)
if err != nil {
t.Fatalf("failed to retrieve contract bytecode for %x", element.code)
}
@ -437,7 +443,7 @@ func testIterativeRandomStateSync(t *testing.T, count int, scheme string) {
if len(codeQueue) > 0 {
results := make([]trie.CodeSyncResult, 0, len(codeQueue))
for hash := range codeQueue {
data, err := srcDb.ContractCode(common.Address{}, hash)
data, err := srcDb.ReadCode(common.Address{}, hash)
if err != nil {
t.Fatalf("failed to retrieve node data for %x", hash)
}
@ -532,7 +538,7 @@ func testIterativeRandomDelayedStateSync(t *testing.T, scheme string) {
for hash := range codeQueue {
delete(codeQueue, hash)
data, err := srcDb.ContractCode(common.Address{}, hash)
data, err := srcDb.ReadCode(common.Address{}, hash)
if err != nil {
t.Fatalf("failed to retrieve node data for %x", hash)
}
@ -648,7 +654,7 @@ func testIncompleteStateSync(t *testing.T, scheme string) {
if len(codeQueue) > 0 {
results := make([]trie.CodeSyncResult, 0, len(codeQueue))
for hash := range codeQueue {
data, err := srcDb.ContractCode(common.Address{}, hash)
data, err := srcDb.ReadCode(common.Address{}, hash)
if err != nil {
t.Fatalf("failed to retrieve node data for %x", hash)
}

View file

@ -27,7 +27,7 @@ import (
)
func filledStateDB() *StateDB {
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
// Create an account and check if the retrieved balance is correct
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")

View file

@ -511,7 +511,7 @@ func TestOpenDrops(t *testing.T) {
store.Close()
// Create a blob pool out of the pre-seeded data
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewDatabase(memorydb.New())), nil)
statedb.AddBalance(crypto.PubkeyToAddress(gapper.PublicKey), big.NewInt(1000000))
statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), big.NewInt(1000000))
statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), big.NewInt(1000000))
@ -636,7 +636,7 @@ func TestOpenIndex(t *testing.T) {
store.Close()
// Create a blob pool out of the pre-seeded data
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewDatabase(memorydb.New())), nil)
statedb.AddBalance(addr, big.NewInt(1_000_000_000))
statedb.Commit(0, true)
@ -736,7 +736,7 @@ func TestOpenHeap(t *testing.T) {
store.Close()
// Create a blob pool out of the pre-seeded data
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewDatabase(memorydb.New())), nil)
statedb.AddBalance(addr1, big.NewInt(1_000_000_000))
statedb.AddBalance(addr2, big.NewInt(1_000_000_000))
statedb.AddBalance(addr3, big.NewInt(1_000_000_000))
@ -816,7 +816,7 @@ func TestOpenCap(t *testing.T) {
// with a high cap to ensure everything was persisted previously
for _, datacap := range []uint64{2 * (txAvgSize + blobSize), 100 * (txAvgSize + blobSize)} {
// Create a blob pool out of the pre-seeded data, but cap it to 2 blob transaction
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewDatabase(memorydb.New())), nil)
statedb.AddBalance(addr1, big.NewInt(1_000_000_000))
statedb.AddBalance(addr2, big.NewInt(1_000_000_000))
statedb.AddBalance(addr3, big.NewInt(1_000_000_000))
@ -1203,7 +1203,7 @@ func TestAdd(t *testing.T) {
keys = make(map[string]*ecdsa.PrivateKey)
addrs = make(map[string]common.Address)
)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewDatabase(memorydb.New())), nil)
for acc, seed := range tt.seeds {
// Generate a new random key/address for the seed account
keys[acc], _ = crypto.GenerateKey()

View file

@ -78,7 +78,7 @@ func TestTransactionFutureAttack(t *testing.T) {
t.Parallel()
// Create the pool to test the limit enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
config := testTxPoolConfig
config.GlobalQueue = 100
@ -115,7 +115,7 @@ func TestTransactionFutureAttack(t *testing.T) {
func TestTransactionFuture1559(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
pool := New(testTxPoolConfig, blockchain)
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), makeAddressReserver())
@ -148,7 +148,7 @@ func TestTransactionFuture1559(t *testing.T) {
func TestTransactionZAttack(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
pool := New(testTxPoolConfig, blockchain)
pool.Init(new(big.Int).SetUint64(testTxPoolConfig.PriceLimit), blockchain.CurrentBlock(), makeAddressReserver())
@ -216,7 +216,7 @@ func TestTransactionZAttack(t *testing.T) {
func BenchmarkFutureAttack(b *testing.B) {
// Create the pool to test the limit enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
config := testTxPoolConfig
config.GlobalQueue = 100

View file

@ -158,7 +158,7 @@ func setupPool() (*LegacyPool, *ecdsa.PrivateKey) {
}
func setupPoolWithConfig(config *params.ChainConfig) (*LegacyPool, *ecdsa.PrivateKey) {
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(config, 10000000, statedb, new(event.Feed))
key, _ := crypto.GenerateKey()
@ -252,7 +252,7 @@ func (c *testChain) State() (*state.StateDB, error) {
// a state change between those fetches.
stdb := c.statedb
if *c.trigger {
c.statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
c.statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
// simulate that the new head block included tx0 and tx1
c.statedb.SetNonce(c.address, 2)
c.statedb.SetBalance(c.address, new(big.Int).SetUint64(params.Ether))
@ -270,7 +270,7 @@ func TestStateChangeDuringReset(t *testing.T) {
var (
key, _ = crypto.GenerateKey()
address = crypto.PubkeyToAddress(key.PublicKey)
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
trigger = false
)
@ -469,7 +469,7 @@ func TestChainFork(t *testing.T) {
addr := crypto.PubkeyToAddress(key.PublicKey)
resetState := func() {
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
statedb.AddBalance(addr, big.NewInt(100000000000000))
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
@ -498,7 +498,7 @@ func TestDoubleNonce(t *testing.T) {
addr := crypto.PubkeyToAddress(key.PublicKey)
resetState := func() {
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
statedb.AddBalance(addr, big.NewInt(100000000000000))
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
@ -698,7 +698,7 @@ func TestPostponing(t *testing.T) {
t.Parallel()
// Create the pool to test the postponing with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
pool := New(testTxPoolConfig, blockchain)
@ -911,7 +911,7 @@ func testQueueGlobalLimiting(t *testing.T, nolocals bool) {
t.Parallel()
// Create the pool to test the limit enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
config := testTxPoolConfig
@ -1004,7 +1004,7 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) {
evictionInterval = time.Millisecond * 100
// Create the pool to test the non-expiration enforcement
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
config := testTxPoolConfig
@ -1190,7 +1190,7 @@ func TestPendingGlobalLimiting(t *testing.T) {
t.Parallel()
// Create the pool to test the limit enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
config := testTxPoolConfig
@ -1292,7 +1292,7 @@ func TestCapClearsFromAll(t *testing.T) {
t.Parallel()
// Create the pool to test the limit enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
config := testTxPoolConfig
@ -1327,7 +1327,7 @@ func TestPendingMinimumAllowance(t *testing.T) {
t.Parallel()
// Create the pool to test the limit enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
config := testTxPoolConfig
@ -1376,7 +1376,7 @@ func TestRepricing(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
pool := New(testTxPoolConfig, blockchain)
@ -1625,7 +1625,7 @@ func TestRepricingKeepsLocals(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
pool := New(testTxPoolConfig, blockchain)
@ -1699,7 +1699,7 @@ func TestUnderpricing(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
config := testTxPoolConfig
@ -1814,7 +1814,7 @@ func TestStableUnderpricing(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
config := testTxPoolConfig
@ -2047,7 +2047,7 @@ func TestDeduplication(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
pool := New(testTxPoolConfig, blockchain)
@ -2114,7 +2114,7 @@ func TestReplacement(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
pool := New(testTxPoolConfig, blockchain)
@ -2320,7 +2320,7 @@ func testJournaling(t *testing.T, nolocals bool) {
os.Remove(journal)
// Create the original pool to inject transaction into the journal
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
config := testTxPoolConfig
@ -2421,7 +2421,7 @@ func TestStatusCheck(t *testing.T) {
t.Parallel()
// Create the pool to test the status retrievals with
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
pool := New(testTxPoolConfig, blockchain)

View file

@ -84,7 +84,7 @@ func TestEIP2200(t *testing.T) {
for i, tt := range eip2200Tests {
address := common.BytesToAddress([]byte("contract"))
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
statedb.CreateAccount(address)
statedb.SetCode(address, hexutil.MustDecode(tt.input))
statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original}))
@ -136,7 +136,7 @@ func TestCreateGas(t *testing.T) {
var gasUsed = uint64(0)
doCheck := func(testGas int) bool {
address := common.BytesToAddress([]byte("contract"))
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
statedb.CreateAccount(address)
statedb.SetCode(address, hexutil.MustDecode(tt.code))
statedb.Finalise(true)

View file

@ -582,7 +582,7 @@ func BenchmarkOpMstore(bench *testing.B) {
func TestOpTstore(t *testing.T) {
var (
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
env = NewEVM(BlockContext{}, TxContext{}, statedb, params.TestChainConfig, Config{})
stack = newstack()
mem = NewMemory()

View file

@ -43,7 +43,7 @@ func TestLoopInterrupt(t *testing.T) {
}
for i, tt := range loopInterruptTests {
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
statedb.CreateAccount(address)
statedb.SetCode(address, common.Hex2Bytes(tt))
statedb.Finalise(true)

View file

@ -109,7 +109,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
setDefaults(cfg)
if cfg.State == nil {
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
}
var (
address = common.BytesToAddress([]byte("contract"))
@ -143,7 +143,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
setDefaults(cfg)
if cfg.State == nil {
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
}
var (
vmenv = NewEnv(cfg)

View file

@ -103,7 +103,7 @@ func TestExecute(t *testing.T) {
}
func TestCall(t *testing.T) {
state, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
address := common.HexToAddress("0x0a")
state.SetCode(address, []byte{
byte(vm.PUSH1), 10,
@ -159,7 +159,7 @@ func BenchmarkCall(b *testing.B) {
}
func benchmarkEVM_Create(bench *testing.B, code string) {
var (
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
sender = common.BytesToAddress([]byte("sender"))
receiver = common.BytesToAddress([]byte("receiver"))
)
@ -327,7 +327,7 @@ func TestBlockhash(t *testing.T) {
func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode string, b *testing.B) {
cfg := new(Config)
setDefaults(cfg)
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
cfg.GasLimit = gas
if len(tracerCode) > 0 {
tracer, err := tracers.DefaultDirectory.New(tracerCode, new(tracers.Context), nil)
@ -818,7 +818,7 @@ func TestRuntimeJSTracer(t *testing.T) {
main := common.HexToAddress("0xaa")
for i, jsTracer := range jsTracers {
for j, tc := range tests {
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
statedb.SetCode(main, tc.code)
statedb.SetCode(common.HexToAddress("0xbb"), calleeCode)
statedb.SetCode(common.HexToAddress("0xcc"), calleeCode)
@ -860,7 +860,7 @@ func TestJSTracerCreateTx(t *testing.T) {
exit: function(res) { this.exits++ }}`
code := []byte{byte(vm.PUSH1), 0, byte(vm.PUSH1), 0, byte(vm.RETURN)}
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting(rawdb.NewMemoryDatabase()), nil)
tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil)
if err != nil {
t.Fatal(err)

View file

@ -35,7 +35,7 @@ import (
var dumper = spew.ConfigState{Indent: " "}
func accountRangeTest(t *testing.T, trie *state.Trie, statedb *state.StateDB, start common.Hash, requestedNum int, expectedNum int) state.IteratorDump {
func accountRangeTest(t *testing.T, statedb *state.StateDB, start common.Hash, requestedNum int, expectedNum int) state.IteratorDump {
result := statedb.IteratorDump(&state.DumpConfig{
SkipCode: true,
SkipStorage: true,
@ -62,11 +62,13 @@ func TestAccountRange(t *testing.T) {
t.Parallel()
var (
statedb = state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), &trie.Config{Preimages: true})
sdb, _ = state.New(types.EmptyRootHash, statedb, nil)
addrs = [AccountRangeMaxResults * 2]common.Address{}
m = map[common.Address]bool{}
disk = rawdb.NewMemoryDatabase()
tdb = trie.NewDatabase(disk, &trie.Config{Preimages: true})
sdb, _ = state.New(types.EmptyRootHash, state.NewDatabase(state.NewCodeDB(disk), tdb), nil)
addrs = [AccountRangeMaxResults * 2]common.Address{}
m = map[common.Address]bool{}
)
defer tdb.Close()
for i := range addrs {
hash := common.HexToHash(fmt.Sprintf("%x", i))
@ -80,16 +82,12 @@ func TestAccountRange(t *testing.T) {
}
}
root, _ := sdb.Commit(0, true)
sdb, _ = state.New(root, statedb, nil)
sdb, _ = state.New(root, state.NewDatabase(state.NewCodeDB(disk), tdb), nil)
trie, err := statedb.OpenTrie(root)
if err != nil {
t.Fatal(err)
}
accountRangeTest(t, &trie, sdb, common.Hash{}, AccountRangeMaxResults/2, AccountRangeMaxResults/2)
accountRangeTest(t, sdb, common.Hash{}, AccountRangeMaxResults/2, AccountRangeMaxResults/2)
// test pagination
firstResult := accountRangeTest(t, &trie, sdb, common.Hash{}, AccountRangeMaxResults, AccountRangeMaxResults)
secondResult := accountRangeTest(t, &trie, sdb, common.BytesToHash(firstResult.Next), AccountRangeMaxResults, AccountRangeMaxResults)
firstResult := accountRangeTest(t, sdb, common.Hash{}, AccountRangeMaxResults, AccountRangeMaxResults)
secondResult := accountRangeTest(t, sdb, common.BytesToHash(firstResult.Next), AccountRangeMaxResults, AccountRangeMaxResults)
hList := make([]common.Hash, 0)
for addr1 := range firstResult.Accounts {
@ -107,7 +105,7 @@ func TestAccountRange(t *testing.T) {
// set and get an even split between the first and second sets.
slices.SortFunc(hList, common.Hash.Cmp)
middleH := hList[AccountRangeMaxResults/2]
middleResult := accountRangeTest(t, &trie, sdb, middleH, AccountRangeMaxResults, AccountRangeMaxResults)
middleResult := accountRangeTest(t, sdb, middleH, AccountRangeMaxResults, AccountRangeMaxResults)
missing, infirst, insecond := 0, 0, 0
for h := range middleResult.Accounts {
if _, ok := firstResult.Accounts[h]; ok {
@ -133,7 +131,7 @@ func TestEmptyAccountRange(t *testing.T) {
t.Parallel()
var (
statedb = state.NewDatabase(rawdb.NewMemoryDatabase())
statedb = state.NewDatabaseForTesting(rawdb.NewMemoryDatabase())
st, _ = state.New(types.EmptyRootHash, statedb, nil)
)
// Commit(although nothing to flush) and re-init the statedb
@ -159,8 +157,9 @@ func TestStorageRangeAt(t *testing.T) {
// Create a state where account 0x010000... has a few storage entries.
var (
db = state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), &trie.Config{Preimages: true})
sdb, _ = state.New(types.EmptyRootHash, db, nil)
disk = rawdb.NewMemoryDatabase()
tdb = trie.NewDatabase(disk, &trie.Config{Preimages: true})
sdb, _ = state.New(types.EmptyRootHash, state.NewDatabase(state.NewCodeDB(disk), tdb), nil)
addr = common.Address{0x01}
keys = []common.Hash{ // hashes of Keys of storage
common.HexToHash("340dd630ad21bf010b4e676dbfa9ba9a02175262d1fa356232cfde6cb5b47ef2"),
@ -175,11 +174,13 @@ func TestStorageRangeAt(t *testing.T) {
keys[3]: {Key: &common.Hash{0x03}, Value: common.Hash{0x04}},
}
)
defer tdb.Close()
for _, entry := range storage {
sdb.SetState(addr, *entry.Key, entry.Value)
}
root, _ := sdb.Commit(0, false)
sdb, _ = state.New(root, db, nil)
sdb, _ = state.New(root, state.NewDatabase(state.NewCodeDB(disk), tdb), nil)
// Check a few combinations of limit and start/end.
tests := []struct {

View file

@ -535,7 +535,7 @@ func testGetNodeData(t *testing.T, protocol uint, drop bool) {
accounts := []common.Address{testAddr, acc1Addr, acc2Addr}
for i := uint64(0); i <= backend.chain.CurrentBlock().Number.Uint64(); i++ {
root := backend.chain.GetBlockByNumber(i).Root()
reconstructed, _ := state.New(root, state.NewDatabase(reconstructDB), nil)
reconstructed, _ := state.New(root, state.NewDatabaseForTesting(reconstructDB), nil)
for j, acc := range accounts {
state, _ := backend.chain.StateAt(root)
bw := state.GetBalance(acc)

View file

@ -67,8 +67,8 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
// the internal junks created by tracing will be persisted into the disk.
// TODO(rjl493456442), clean cache is disabled to prevent memory leak,
// please re-enable it for better performance.
database = state.NewDatabaseWithConfig(eth.chainDb, trie.HashDefaults)
if statedb, err = state.New(block.Root(), database, nil); err == nil {
tdb := trie.NewDatabase(eth.chainDb, trie.HashDefaults)
if statedb, err = state.New(block.Root(), state.NewDatabase(state.NewCodeDB(eth.chainDb), tdb), nil); err == nil {
log.Info("Found disk backend for state trie", "root", block.Root(), "number", block.Number())
return statedb, noopReleaser, nil
}
@ -85,7 +85,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
// TODO(rjl493456442), clean cache is disabled to prevent memory leak,
// please re-enable it for better performance.
triedb = trie.NewDatabase(eth.chainDb, trie.HashDefaults)
database = state.NewDatabaseWithNodeDB(eth.chainDb, triedb)
database = state.NewDatabase(state.NewCodeDB(eth.chainDb), triedb)
// If we didn't check the live database, do check state over ephemeral database,
// otherwise we would rewind past a persisted block (specific corner case is

View file

@ -22,9 +22,9 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/txpool"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/light"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
@ -310,7 +310,7 @@ func handleGetCode(msg Decoder) (serveRequestFn, uint64, uint64, error) {
p.bumpInvalid()
continue
}
code, err := bc.StateCache().ContractCode(address, common.BytesToHash(account.CodeHash))
code, err := bc.CodeDB().ReadCode(address, common.BytesToHash(account.CodeHash))
if err != nil {
p.Log().Warn("Failed to retrieve account code", "block", header.Number, "hash", header.Hash(), "account", address, "codehash", common.BytesToHash(account.CodeHash), "err", err)
continue
@ -409,14 +409,12 @@ func handleGetProofs(msg Decoder) (serveRequestFn, uint64, uint64, error) {
continue
}
// Open the account or storage trie for the request
statedb := bc.StateCache()
var trie state.Trie
var tr *trie.StateTrie
switch len(request.AccountAddress) {
case 0:
// No account key specified, open an account trie
trie, err = statedb.OpenTrie(root)
if trie == nil || err != nil {
tr, err = trie.NewStateTrie(trie.StateTrieID(root), bc.TrieDB())
if err != nil {
p.Log().Warn("Failed to open storage trie for proof", "block", header.Number, "hash", header.Hash(), "root", root, "err", err)
continue
}
@ -429,14 +427,14 @@ func handleGetProofs(msg Decoder) (serveRequestFn, uint64, uint64, error) {
p.bumpInvalid()
continue
}
trie, err = statedb.OpenStorageTrie(root, address, account.Root)
if trie == nil || err != nil {
tr, err = trie.NewStateTrie(trie.StorageTrieID(root, crypto.Keccak256Hash(address.Bytes()), account.Root), bc.TrieDB())
if err != nil {
p.Log().Warn("Failed to open storage trie for proof", "block", header.Number, "hash", header.Hash(), "account", address, "root", account.Root, "err", err)
continue
}
}
// Prove the user's request from the account or storage trie
if err := trie.Prove(request.Key, nodes); err != nil {
if err := tr.Prove(request.Key, nodes); err != nil {
p.Log().Warn("Failed to prove state request", "block", header.Number, "hash", header.Hash(), "err", err)
continue
}

View file

@ -57,7 +57,7 @@ type testOdr struct {
OdrBackend
indexerConfig *IndexerConfig
sdb, ldb ethdb.Database
serverState state.Database
triedb *trie.Database
disable bool
}
@ -88,9 +88,9 @@ func (odr *testOdr) Retrieve(ctx context.Context, req OdrRequest) error {
t state.Trie
)
if len(req.Id.AccountAddress) > 0 {
t, err = odr.serverState.OpenStorageTrie(req.Id.StateRoot, common.BytesToAddress(req.Id.AccountAddress), req.Id.Root)
t, err = trie.NewStateTrie(trie.StorageTrieID(req.Id.StateRoot, crypto.Keccak256Hash(req.Id.AccountAddress), req.Id.Root), odr.triedb)
} else {
t, err = odr.serverState.OpenTrie(req.Id.Root)
t, err = trie.NewStateTrie(trie.StateTrieID(req.Id.StateRoot), odr.triedb)
}
if err != nil {
panic(err)
@ -162,7 +162,7 @@ func odrAccounts(ctx context.Context, db ethdb.Database, bc *core.BlockChain, lc
st = NewState(ctx, header, lc.Odr())
} else {
header := bc.GetHeaderByHash(bhash)
st, _ = state.New(header.Root, bc.StateCache(), nil)
st, _ = state.New(header.Root, state.NewDatabase(bc.CodeDB(), bc.TrieDB()), nil)
}
var res []byte
@ -196,7 +196,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain
} else {
chain = bc
header = bc.GetHeaderByHash(bhash)
st, _ = state.New(header.Root, bc.StateCache(), nil)
st, _ = state.New(header.Root, state.NewDatabase(bc.CodeDB(), bc.TrieDB()), nil)
}
// Perform read-only call.
@ -284,7 +284,7 @@ func testChainOdr(t *testing.T, protocol int, fn odrTestFn) {
}
gspec.MustCommit(ldb, trie.NewDatabase(ldb, trie.HashDefaults))
odr := &testOdr{sdb: sdb, ldb: ldb, serverState: blockchain.StateCache(), indexerConfig: TestClientIndexerConfig}
odr := &testOdr{sdb: sdb, ldb: ldb, triedb: blockchain.TrieDB(), indexerConfig: TestClientIndexerConfig}
lightchain, err := NewLightChain(odr, gspec.Config, ethash.NewFullFaker())
if err != nil {
t.Fatal(err)

View file

@ -72,7 +72,7 @@ func (db *odrDatabase) CopyTrie(t state.Trie) state.Trie {
}
}
func (db *odrDatabase) ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error) {
func (db *odrDatabase) ReadCode(addr common.Address, codeHash common.Hash) ([]byte, error) {
if codeHash == sha3Nil {
return nil, nil
}
@ -87,19 +87,19 @@ func (db *odrDatabase) ContractCode(addr common.Address, codeHash common.Hash) (
return req.Data, err
}
func (db *odrDatabase) ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) {
code, err := db.ContractCode(addr, codeHash)
func (db *odrDatabase) ReadCodeSize(addr common.Address, codeHash common.Hash) (int, error) {
code, err := db.ReadCode(addr, codeHash)
return len(code), err
}
func (db *odrDatabase) WriteCodes(addresses []common.Address, hashes []common.Hash, codes [][]byte) error {
panic("not implemented")
}
func (db *odrDatabase) TrieDB() *trie.Database {
return nil
}
func (db *odrDatabase) DiskDB() ethdb.KeyValueStore {
panic("not implemented")
}
type odrTrie struct {
db *odrDatabase
id *TrieID

View file

@ -52,10 +52,10 @@ func TestNodeIterator(t *testing.T) {
gspec.MustCommit(lightdb, trie.NewDatabase(lightdb, trie.HashDefaults))
ctx := context.Background()
odr := &testOdr{sdb: fulldb, ldb: lightdb, serverState: blockchain.StateCache(), indexerConfig: TestClientIndexerConfig}
odr := &testOdr{sdb: fulldb, ldb: lightdb, triedb: blockchain.TrieDB(), indexerConfig: TestClientIndexerConfig}
head := blockchain.CurrentHeader()
lightTrie, _ := NewStateDatabase(ctx, head, odr).OpenTrie(head.Root)
fullTrie, _ := blockchain.StateCache().OpenTrie(head.Root)
fullTrie, _ := trie.NewStateTrie(trie.StateTrieID(head.Root), blockchain.TrieDB())
if err := diffTries(fullTrie, lightTrie); err != nil {
t.Fatal(err)
}

View file

@ -98,7 +98,7 @@ func TestTxPool(t *testing.T) {
}
gspec.MustCommit(ldb, trie.NewDatabase(ldb, trie.HashDefaults))
odr := &testOdr{sdb: sdb, ldb: ldb, serverState: blockchain.StateCache(), indexerConfig: TestClientIndexerConfig}
odr := &testOdr{sdb: sdb, ldb: ldb, triedb: blockchain.TrieDB(), indexerConfig: TestClientIndexerConfig}
relay := &testTxRelay{
send: make(chan int, 1),
discard: make(chan int, 1),

View file

@ -301,7 +301,7 @@ func createMiner(t *testing.T) (*Miner, *event.TypeMux, func(skipMiner bool)) {
if err != nil {
t.Fatalf("can't create new chain %v", err)
}
statedb, _ := state.New(bc.Genesis().Root(), bc.StateCache(), nil)
statedb, _ := state.New(bc.Genesis().Root(), state.NewDatabase(bc.CodeDB(), bc.TrieDB()), nil)
blockchain := &testBlockChain{chainConfig, statedb, 10000000, new(event.Feed)}
pool := legacypool.New(testTxPoolConfig, blockchain)

View file

@ -314,7 +314,7 @@ func MakePreState(db ethdb.Database, accounts core.GenesisAlloc, snapshotter boo
tconf.PathDB = pathdb.Defaults
}
triedb := trie.NewDatabase(db, tconf)
sdb := state.NewDatabaseWithNodeDB(db, triedb)
sdb := state.NewDatabase(state.NewCodeDB(db), triedb)
statedb, _ := state.New(types.EmptyRootHash, sdb, nil)
for addr, a := range accounts {
statedb.SetCode(addr, a.Code)