mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 02:12:23 +00:00
Merge branch 'master' into multicall
This commit is contained in:
commit
9da10f9a70
36 changed files with 667 additions and 420 deletions
|
|
@ -304,7 +304,7 @@ func doTest(cmdline []string) {
|
||||||
gotest := tc.Go("test")
|
gotest := tc.Go("test")
|
||||||
|
|
||||||
// CI needs a bit more time for the statetests (default 10m).
|
// CI needs a bit more time for the statetests (default 10m).
|
||||||
gotest.Args = append(gotest.Args, "-timeout=20m")
|
gotest.Args = append(gotest.Args, "-timeout=30m")
|
||||||
|
|
||||||
// Enable CKZG backend in CI.
|
// Enable CKZG backend in CI.
|
||||||
gotest.Args = append(gotest.Args, "-tags=ckzg")
|
gotest.Args = append(gotest.Args, "-tags=ckzg")
|
||||||
|
|
|
||||||
|
|
@ -403,7 +403,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
}
|
}
|
||||||
// Re-create statedb instance with new root upon the updated database
|
// Re-create statedb instance with new root upon the updated database
|
||||||
// for accessing latest states.
|
// for accessing latest states.
|
||||||
statedb, err = state.New(root, statedb.Database(), nil)
|
statedb, err = state.New(root, statedb.Database())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err))
|
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err))
|
||||||
}
|
}
|
||||||
|
|
@ -412,8 +412,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB {
|
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB {
|
||||||
sdb := state.NewDatabaseWithConfig(db, &triedb.Config{Preimages: true})
|
tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
||||||
statedb, _ := state.New(types.EmptyRootHash, sdb, nil)
|
sdb := state.NewDatabase(tdb, nil)
|
||||||
|
statedb, _ := state.New(types.EmptyRootHash, sdb)
|
||||||
for addr, a := range accounts {
|
for addr, a := range accounts {
|
||||||
statedb.SetCode(addr, a.Code)
|
statedb.SetCode(addr, a.Code)
|
||||||
statedb.SetNonce(addr, a.Nonce)
|
statedb.SetNonce(addr, a.Nonce)
|
||||||
|
|
@ -424,7 +425,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB
|
||||||
}
|
}
|
||||||
// Commit and re-open to start with a clean state.
|
// Commit and re-open to start with a clean state.
|
||||||
root, _ := statedb.Commit(0, false)
|
root, _ := statedb.Commit(0, false)
|
||||||
statedb, _ = state.New(root, sdb, nil)
|
statedb, _ = state.New(root, sdb)
|
||||||
return statedb
|
return statedb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -155,8 +155,8 @@ func runCmd(ctx *cli.Context) error {
|
||||||
})
|
})
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
genesis := genesisConfig.MustCommit(db, triedb)
|
genesis := genesisConfig.MustCommit(db, triedb)
|
||||||
sdb := state.NewDatabaseWithNodeDB(db, triedb)
|
sdb := state.NewDatabase(triedb, nil)
|
||||||
statedb, _ = state.New(genesis.Root(), sdb, nil)
|
statedb, _ = state.New(genesis.Root(), sdb)
|
||||||
chainConfig = genesisConfig.Config
|
chainConfig = genesisConfig.Config
|
||||||
|
|
||||||
if ctx.String(SenderFlag.Name) != "" {
|
if ctx.String(SenderFlag.Name) != "" {
|
||||||
|
|
@ -277,7 +277,7 @@ func runCmd(ctx *cli.Context) error {
|
||||||
fmt.Printf("Failed to commit changes %v\n", err)
|
fmt.Printf("Failed to commit changes %v\n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dumpdb, err := state.New(root, sdb, nil)
|
dumpdb, err := state.New(root, sdb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Failed to open statedb %v\n", err)
|
fmt.Printf("Failed to open statedb %v\n", err)
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ func runStateTest(fname string, cfg vm.Config, dump bool) error {
|
||||||
result.Root = &root
|
result.Root = &root
|
||||||
fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
|
fmt.Fprintf(os.Stderr, "{\"stateRoot\": \"%#x\"}\n", root)
|
||||||
if dump { // Dump any state to aid debugging
|
if dump { // Dump any state to aid debugging
|
||||||
cpy, _ := state.New(root, tstate.StateDB.Database(), nil)
|
cpy, _ := state.New(root, tstate.StateDB.Database())
|
||||||
dump := cpy.RawDump(nil)
|
dump := cpy.RawDump(nil)
|
||||||
result.State = &dump
|
result.State = &dump
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -584,7 +584,7 @@ func dump(ctx *cli.Context) error {
|
||||||
triedb := utils.MakeTrieDatabase(ctx, db, true, true, false) // always enable preimage lookup
|
triedb := utils.MakeTrieDatabase(ctx, db, true, true, false) // always enable preimage lookup
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
state, err := state.New(root, state.NewDatabaseWithNodeDB(db, triedb), nil)
|
state, err := state.New(root, state.NewDatabase(triedb, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,14 +72,11 @@ var (
|
||||||
storageUpdateTimer = metrics.NewRegisteredResettingTimer("chain/storage/updates", nil)
|
storageUpdateTimer = metrics.NewRegisteredResettingTimer("chain/storage/updates", nil)
|
||||||
storageCommitTimer = metrics.NewRegisteredResettingTimer("chain/storage/commits", nil)
|
storageCommitTimer = metrics.NewRegisteredResettingTimer("chain/storage/commits", nil)
|
||||||
|
|
||||||
snapshotAccountReadTimer = metrics.NewRegisteredResettingTimer("chain/snapshot/account/reads", nil)
|
|
||||||
snapshotStorageReadTimer = metrics.NewRegisteredResettingTimer("chain/snapshot/storage/reads", nil)
|
|
||||||
snapshotCommitTimer = metrics.NewRegisteredResettingTimer("chain/snapshot/commits", nil)
|
|
||||||
|
|
||||||
accountReadSingleTimer = metrics.NewRegisteredResettingTimer("chain/account/single/reads", nil)
|
accountReadSingleTimer = metrics.NewRegisteredResettingTimer("chain/account/single/reads", nil)
|
||||||
storageReadSingleTimer = metrics.NewRegisteredResettingTimer("chain/storage/single/reads", nil)
|
storageReadSingleTimer = metrics.NewRegisteredResettingTimer("chain/storage/single/reads", nil)
|
||||||
|
|
||||||
triedbCommitTimer = metrics.NewRegisteredResettingTimer("chain/triedb/commits", nil)
|
snapshotCommitTimer = metrics.NewRegisteredResettingTimer("chain/snapshot/commits", nil)
|
||||||
|
triedbCommitTimer = metrics.NewRegisteredResettingTimer("chain/triedb/commits", nil)
|
||||||
|
|
||||||
blockInsertTimer = metrics.NewRegisteredResettingTimer("chain/inserts", nil)
|
blockInsertTimer = metrics.NewRegisteredResettingTimer("chain/inserts", nil)
|
||||||
blockValidationTimer = metrics.NewRegisteredResettingTimer("chain/validation", nil)
|
blockValidationTimer = metrics.NewRegisteredResettingTimer("chain/validation", nil)
|
||||||
|
|
@ -220,7 +217,7 @@ type BlockChain struct {
|
||||||
lastWrite uint64 // Last block when the state was flushed
|
lastWrite uint64 // Last block when the state was flushed
|
||||||
flushInterval atomic.Int64 // Time interval (processing time) after which to flush a state
|
flushInterval atomic.Int64 // Time interval (processing time) after which to flush a state
|
||||||
triedb *triedb.Database // The database handler for maintaining trie nodes.
|
triedb *triedb.Database // The database handler for maintaining trie nodes.
|
||||||
stateCache state.Database // State database to reuse between imports (contains state cache)
|
statedb *state.CachingDB // State database to reuse between imports (contains state cache)
|
||||||
txIndexer *txIndexer // Transaction indexer, might be nil if not enabled
|
txIndexer *txIndexer // Transaction indexer, might be nil if not enabled
|
||||||
|
|
||||||
hc *HeaderChain
|
hc *HeaderChain
|
||||||
|
|
@ -311,7 +308,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit))
|
bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit))
|
||||||
bc.stateCache = state.NewDatabaseWithNodeDB(bc.db, bc.triedb)
|
bc.statedb = state.NewDatabase(bc.triedb, nil)
|
||||||
bc.validator = NewBlockValidator(chainConfig, bc)
|
bc.validator = NewBlockValidator(chainConfig, bc)
|
||||||
bc.prefetcher = newStatePrefetcher(chainConfig, bc.hc)
|
bc.prefetcher = newStatePrefetcher(chainConfig, bc.hc)
|
||||||
bc.processor = NewStateProcessor(chainConfig, bc.hc)
|
bc.processor = NewStateProcessor(chainConfig, bc.hc)
|
||||||
|
|
@ -449,7 +446,11 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
|
||||||
AsyncBuild: !bc.cacheConfig.SnapshotWait,
|
AsyncBuild: !bc.cacheConfig.SnapshotWait,
|
||||||
}
|
}
|
||||||
bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root)
|
bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root)
|
||||||
|
|
||||||
|
// Re-initialize the state database with snapshot
|
||||||
|
bc.statedb = state.NewDatabase(bc.triedb, bc.snaps)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewind the chain in case of an incompatible config upgrade.
|
// Rewind the chain in case of an incompatible config upgrade.
|
||||||
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
|
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
|
||||||
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
|
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
|
||||||
|
|
@ -1767,7 +1768,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
||||||
if parent == nil {
|
if parent == nil {
|
||||||
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
|
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
|
||||||
}
|
}
|
||||||
statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps)
|
statedb, err := state.New(parent.Root, bc.statedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return it.index, err
|
return it.index, err
|
||||||
}
|
}
|
||||||
|
|
@ -1793,7 +1794,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
||||||
var followupInterrupt atomic.Bool
|
var followupInterrupt atomic.Bool
|
||||||
if !bc.cacheConfig.TrieCleanNoPrefetch {
|
if !bc.cacheConfig.TrieCleanNoPrefetch {
|
||||||
if followup, err := it.peek(); followup != nil && err == nil {
|
if followup, err := it.peek(); followup != nil && err == nil {
|
||||||
throwaway, _ := state.New(parent.Root, bc.stateCache, bc.snaps)
|
throwaway, _ := state.New(parent.Root, bc.statedb)
|
||||||
|
|
||||||
go func(start time.Time, followup *types.Block, throwaway *state.StateDB) {
|
go func(start time.Time, followup *types.Block, throwaway *state.StateDB) {
|
||||||
// Disable tracing for prefetcher executions.
|
// Disable tracing for prefetcher executions.
|
||||||
|
|
@ -1914,26 +1915,21 @@ func (bc *BlockChain) processBlock(block *types.Block, statedb *state.StateDB, s
|
||||||
proctime := time.Since(start) // processing + validation
|
proctime := time.Since(start) // processing + validation
|
||||||
|
|
||||||
// Update the metrics touched during block processing and validation
|
// Update the metrics touched during block processing and validation
|
||||||
accountReadTimer.Update(statedb.AccountReads) // Account reads are complete(in processing)
|
accountReadTimer.Update(statedb.AccountReads) // Account reads are complete(in processing)
|
||||||
storageReadTimer.Update(statedb.StorageReads) // Storage reads are complete(in processing)
|
storageReadTimer.Update(statedb.StorageReads) // Storage reads are complete(in processing)
|
||||||
snapshotAccountReadTimer.Update(statedb.SnapshotAccountReads) // Account reads are complete(in processing)
|
|
||||||
snapshotStorageReadTimer.Update(statedb.SnapshotStorageReads) // Storage reads are complete(in processing)
|
|
||||||
|
|
||||||
accountRead := statedb.SnapshotAccountReads + statedb.AccountReads // The time spent on account read
|
|
||||||
storageRead := statedb.SnapshotStorageReads + statedb.StorageReads // The time spent on storage read
|
|
||||||
if statedb.AccountLoaded != 0 {
|
if statedb.AccountLoaded != 0 {
|
||||||
accountReadSingleTimer.Update(accountRead / time.Duration(statedb.AccountLoaded))
|
accountReadSingleTimer.Update(statedb.AccountReads / time.Duration(statedb.AccountLoaded))
|
||||||
}
|
}
|
||||||
if statedb.StorageLoaded != 0 {
|
if statedb.StorageLoaded != 0 {
|
||||||
storageReadSingleTimer.Update(storageRead / time.Duration(statedb.StorageLoaded))
|
storageReadSingleTimer.Update(statedb.StorageReads / time.Duration(statedb.StorageLoaded))
|
||||||
}
|
}
|
||||||
accountUpdateTimer.Update(statedb.AccountUpdates) // Account updates are complete(in validation)
|
accountUpdateTimer.Update(statedb.AccountUpdates) // Account updates are complete(in validation)
|
||||||
storageUpdateTimer.Update(statedb.StorageUpdates) // Storage updates are complete(in validation)
|
storageUpdateTimer.Update(statedb.StorageUpdates) // Storage updates are complete(in validation)
|
||||||
accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete(in validation)
|
accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete(in validation)
|
||||||
triehash := statedb.AccountHashes // The time spent on tries hashing
|
triehash := statedb.AccountHashes // The time spent on tries hashing
|
||||||
trieUpdate := statedb.AccountUpdates + statedb.StorageUpdates // The time spent on tries update
|
trieUpdate := statedb.AccountUpdates + statedb.StorageUpdates // The time spent on tries update
|
||||||
blockExecutionTimer.Update(ptime - (accountRead + storageRead)) // The time spent on EVM processing
|
blockExecutionTimer.Update(ptime - (statedb.AccountReads + statedb.StorageReads)) // The time spent on EVM processing
|
||||||
blockValidationTimer.Update(vtime - (triehash + trieUpdate)) // The time spent on block validation
|
blockValidationTimer.Update(vtime - (triehash + trieUpdate)) // The time spent on block validation
|
||||||
|
|
||||||
// Write the block to the chain and get the status.
|
// Write the block to the chain and get the status.
|
||||||
var (
|
var (
|
||||||
|
|
|
||||||
|
|
@ -308,7 +308,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.
|
// HasState checks if state trie is fully present in the database or not.
|
||||||
func (bc *BlockChain) HasState(hash common.Hash) bool {
|
func (bc *BlockChain) HasState(hash common.Hash) bool {
|
||||||
_, err := bc.stateCache.OpenTrie(hash)
|
_, err := bc.statedb.OpenTrie(hash)
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -341,12 +341,9 @@ func (bc *BlockChain) stateRecoverable(root common.Hash) bool {
|
||||||
// If the code doesn't exist in the in-memory cache, check the storage with
|
// If the code doesn't exist in the in-memory cache, check the storage with
|
||||||
// new code scheme.
|
// new code scheme.
|
||||||
func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
|
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
|
// TODO(rjl493456442) The associated account address is also required
|
||||||
// in Verkle scheme. Fix it once snap-sync is supported for Verkle.
|
// in Verkle scheme. Fix it once snap-sync is supported for Verkle.
|
||||||
return bc.stateCache.(codeReader).ContractCodeWithPrefix(common.Address{}, hash)
|
return bc.statedb.ContractCodeWithPrefix(common.Address{}, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// State returns a new mutable state based on the current HEAD block.
|
// State returns a new mutable state based on the current HEAD block.
|
||||||
|
|
@ -356,7 +353,7 @@ func (bc *BlockChain) State() (*state.StateDB, error) {
|
||||||
|
|
||||||
// StateAt returns a new mutable state based on a particular point in time.
|
// StateAt returns a new mutable state based on a particular point in time.
|
||||||
func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
|
func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
|
||||||
return state.New(root, bc.stateCache, bc.snaps)
|
return state.New(root, bc.statedb)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config retrieves the chain's fork configuration.
|
// Config retrieves the chain's fork configuration.
|
||||||
|
|
@ -382,7 +379,7 @@ func (bc *BlockChain) Processor() Processor {
|
||||||
|
|
||||||
// StateCache returns the caching database underpinning the blockchain instance.
|
// StateCache returns the caching database underpinning the blockchain instance.
|
||||||
func (bc *BlockChain) StateCache() state.Database {
|
func (bc *BlockChain) StateCache() state.Database {
|
||||||
return bc.stateCache
|
return bc.statedb
|
||||||
}
|
}
|
||||||
|
|
||||||
// GasLimit returns the gas limit of the current HEAD block.
|
// GasLimit returns the gas limit of the current HEAD block.
|
||||||
|
|
|
||||||
|
|
@ -2040,7 +2040,7 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme
|
||||||
dbconfig.HashDB = hashdb.Defaults
|
dbconfig.HashDB = hashdb.Defaults
|
||||||
}
|
}
|
||||||
chain.triedb = triedb.NewDatabase(chain.db, dbconfig)
|
chain.triedb = triedb.NewDatabase(chain.db, dbconfig)
|
||||||
chain.stateCache = state.NewDatabaseWithNodeDB(chain.db, chain.triedb)
|
chain.statedb = state.NewDatabase(chain.triedb, chain.snaps)
|
||||||
|
|
||||||
// Force run a freeze cycle
|
// Force run a freeze cycle
|
||||||
type freezer interface {
|
type freezer interface {
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.stateCache, nil)
|
statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.statedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -379,7 +379,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
|
||||||
defer triedb.Close()
|
defer triedb.Close()
|
||||||
|
|
||||||
for i := 0; i < n; i++ {
|
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(triedb, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
@ -485,7 +485,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
statedb, err := state.New(parent.Root(), state.NewDatabaseWithNodeDB(db, trdb), nil)
|
statedb, err := state.New(parent.Root(), state.NewDatabase(trdb, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,8 +127,8 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
|
||||||
}
|
}
|
||||||
// Create an ephemeral in-memory database for computing hash,
|
// Create an ephemeral in-memory database for computing hash,
|
||||||
// all the derived states will be discarded to not pollute disk.
|
// all the derived states will be discarded to not pollute disk.
|
||||||
db := state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), config)
|
db := rawdb.NewMemoryDatabase()
|
||||||
statedb, err := state.New(types.EmptyRootHash, db, nil)
|
statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(triedb.NewDatabase(db, config), nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -147,8 +147,8 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
|
||||||
|
|
||||||
// flushAlloc is very similar with hash, but the main difference is all the
|
// flushAlloc is very similar with hash, but the main difference is all the
|
||||||
// generated states will be persisted into the given database.
|
// generated states will be persisted into the given database.
|
||||||
func flushAlloc(ga *types.GenesisAlloc, db ethdb.Database, triedb *triedb.Database) (common.Hash, error) {
|
func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, error) {
|
||||||
statedb, err := state.New(types.EmptyRootHash, state.NewDatabaseWithNodeDB(db, triedb), nil)
|
statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(triedb, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -497,7 +497,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo
|
||||||
return nil, errors.New("can't start clique chain without signers")
|
return nil, errors.New("can't start clique chain without signers")
|
||||||
}
|
}
|
||||||
// flush the data to disk and compute the state root
|
// flush the data to disk and compute the state root
|
||||||
root, err := flushAlloc(&g.Alloc, db, triedb)
|
root, err := flushAlloc(&g.Alloc, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/lru"
|
"github.com/ethereum/go-ethereum/common/lru"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
|
@ -45,29 +46,29 @@ const (
|
||||||
|
|
||||||
// Database wraps access to tries and contract code.
|
// Database wraps access to tries and contract code.
|
||||||
type Database interface {
|
type Database interface {
|
||||||
|
// Reader returns a state reader associated with the specified state root.
|
||||||
|
Reader(root common.Hash) (Reader, error)
|
||||||
|
|
||||||
// OpenTrie opens the main account trie.
|
// OpenTrie opens the main account trie.
|
||||||
OpenTrie(root common.Hash) (Trie, error)
|
OpenTrie(root common.Hash) (Trie, error)
|
||||||
|
|
||||||
// OpenStorageTrie opens the storage trie of an account.
|
// OpenStorageTrie opens the storage trie of an account.
|
||||||
OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, trie Trie) (Trie, error)
|
OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, trie Trie) (Trie, error)
|
||||||
|
|
||||||
// CopyTrie returns an independent copy of the given trie.
|
|
||||||
CopyTrie(Trie) Trie
|
|
||||||
|
|
||||||
// ContractCode retrieves a particular contract's code.
|
// ContractCode retrieves a particular contract's code.
|
||||||
ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error)
|
ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error)
|
||||||
|
|
||||||
// ContractCodeSize retrieves a particular contracts code's size.
|
// ContractCodeSize retrieves a particular contracts code's size.
|
||||||
ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error)
|
ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error)
|
||||||
|
|
||||||
// DiskDB returns the underlying key-value disk database.
|
|
||||||
DiskDB() ethdb.KeyValueStore
|
|
||||||
|
|
||||||
// PointCache returns the cache holding points used in verkle tree key computation
|
// PointCache returns the cache holding points used in verkle tree key computation
|
||||||
PointCache() *utils.PointCache
|
PointCache() *utils.PointCache
|
||||||
|
|
||||||
// TrieDB returns the underlying trie database for managing trie nodes.
|
// TrieDB returns the underlying trie database for managing trie nodes.
|
||||||
TrieDB() *triedb.Database
|
TrieDB() *triedb.Database
|
||||||
|
|
||||||
|
// Snapshot returns the underlying state snapshot.
|
||||||
|
Snapshot() *snapshot.Tree
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trie is a Ethereum Merkle Patricia trie.
|
// Trie is a Ethereum Merkle Patricia trie.
|
||||||
|
|
@ -147,47 +148,62 @@ type Trie interface {
|
||||||
IsVerkle() bool
|
IsVerkle() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDatabase creates a backing store for state. The returned database is safe for
|
// CachingDB is an implementation of Database interface. It leverages both trie and
|
||||||
// concurrent use, but does not retain any recent trie nodes in memory. To keep some
|
// state snapshot to provide functionalities for state access. It's meant to be a
|
||||||
// historical state in memory, use the NewDatabaseWithConfig constructor.
|
// long-live object and has a few caches inside for sharing between blocks.
|
||||||
func NewDatabase(db ethdb.Database) Database {
|
type CachingDB struct {
|
||||||
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 *triedb.Config) Database {
|
|
||||||
return &cachingDB{
|
|
||||||
disk: db,
|
|
||||||
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
|
|
||||||
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
|
|
||||||
triedb: triedb.NewDatabase(db, config),
|
|
||||||
pointCache: utils.NewPointCache(pointCacheSize),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDatabaseWithNodeDB creates a state database with an already initialized node database.
|
|
||||||
func NewDatabaseWithNodeDB(db ethdb.Database, triedb *triedb.Database) Database {
|
|
||||||
return &cachingDB{
|
|
||||||
disk: db,
|
|
||||||
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
|
|
||||||
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
|
|
||||||
triedb: triedb,
|
|
||||||
pointCache: utils.NewPointCache(pointCacheSize),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type cachingDB struct {
|
|
||||||
disk ethdb.KeyValueStore
|
disk ethdb.KeyValueStore
|
||||||
codeSizeCache *lru.Cache[common.Hash, int]
|
|
||||||
codeCache *lru.SizeConstrainedCache[common.Hash, []byte]
|
|
||||||
triedb *triedb.Database
|
triedb *triedb.Database
|
||||||
|
snap *snapshot.Tree
|
||||||
|
codeCache *lru.SizeConstrainedCache[common.Hash, []byte]
|
||||||
|
codeSizeCache *lru.Cache[common.Hash, int]
|
||||||
pointCache *utils.PointCache
|
pointCache *utils.PointCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDatabase creates a state database with the provided data sources.
|
||||||
|
func NewDatabase(triedb *triedb.Database, snap *snapshot.Tree) *CachingDB {
|
||||||
|
return &CachingDB{
|
||||||
|
disk: triedb.Disk(),
|
||||||
|
triedb: triedb,
|
||||||
|
snap: snap,
|
||||||
|
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
|
||||||
|
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
|
||||||
|
pointCache: utils.NewPointCache(pointCacheSize),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDatabaseForTesting is similar to NewDatabase, but it initializes the caching
|
||||||
|
// db by using an ephemeral memory db with default config for testing.
|
||||||
|
func NewDatabaseForTesting() *CachingDB {
|
||||||
|
return NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reader returns a state reader associated with the specified state root.
|
||||||
|
func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) {
|
||||||
|
var readers []Reader
|
||||||
|
|
||||||
|
// Set up the state snapshot reader if available. This feature
|
||||||
|
// is optional and may be partially useful if it's not fully
|
||||||
|
// generated.
|
||||||
|
if db.snap != nil {
|
||||||
|
sr, err := newStateReader(stateRoot, db.snap)
|
||||||
|
if err == nil {
|
||||||
|
readers = append(readers, sr) // snap reader is optional
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Set up the trie reader, which is expected to always be available
|
||||||
|
// as the gatekeeper unless the state is corrupted.
|
||||||
|
tr, err := newTrieReader(stateRoot, db.triedb, db.pointCache)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
readers = append(readers, tr)
|
||||||
|
|
||||||
|
return newMultiReader(readers...)
|
||||||
|
}
|
||||||
|
|
||||||
// OpenTrie opens the main account trie at a specific root hash.
|
// OpenTrie opens the main account trie at a specific root hash.
|
||||||
func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
|
func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) {
|
||||||
if db.triedb.IsVerkle() {
|
if db.triedb.IsVerkle() {
|
||||||
return trie.NewVerkleTrie(root, db.triedb, db.pointCache)
|
return trie.NewVerkleTrie(root, db.triedb, db.pointCache)
|
||||||
}
|
}
|
||||||
|
|
@ -199,7 +215,7 @@ func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenStorageTrie opens the storage trie of an account.
|
// OpenStorageTrie opens the storage trie of an account.
|
||||||
func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) {
|
func (db *CachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) {
|
||||||
// In the verkle case, there is only one tree. But the two-tree structure
|
// In the verkle case, there is only one tree. But the two-tree structure
|
||||||
// is hardcoded in the codebase. So we need to return the same trie in this
|
// is hardcoded in the codebase. So we need to return the same trie in this
|
||||||
// case.
|
// case.
|
||||||
|
|
@ -213,20 +229,8 @@ func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Addre
|
||||||
return tr, nil
|
return tr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CopyTrie returns an independent copy of the given trie.
|
|
||||||
func (db *cachingDB) CopyTrie(t Trie) Trie {
|
|
||||||
switch t := t.(type) {
|
|
||||||
case *trie.StateTrie:
|
|
||||||
return t.Copy()
|
|
||||||
case *trie.VerkleTrie:
|
|
||||||
return t.Copy()
|
|
||||||
default:
|
|
||||||
panic(fmt.Errorf("unknown trie type %T", t))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ContractCode retrieves a particular contract's code.
|
// ContractCode retrieves a particular contract's code.
|
||||||
func (db *cachingDB) ContractCode(address common.Address, codeHash common.Hash) ([]byte, error) {
|
func (db *CachingDB) ContractCode(address common.Address, codeHash common.Hash) ([]byte, error) {
|
||||||
code, _ := db.codeCache.Get(codeHash)
|
code, _ := db.codeCache.Get(codeHash)
|
||||||
if len(code) > 0 {
|
if len(code) > 0 {
|
||||||
return code, nil
|
return code, nil
|
||||||
|
|
@ -243,7 +247,7 @@ func (db *cachingDB) ContractCode(address common.Address, codeHash common.Hash)
|
||||||
// ContractCodeWithPrefix retrieves a particular contract's code. If the
|
// ContractCodeWithPrefix retrieves a particular contract's code. If the
|
||||||
// code can't be found in the cache, then check the existence with **new**
|
// code can't be found in the cache, then check the existence with **new**
|
||||||
// db scheme.
|
// db scheme.
|
||||||
func (db *cachingDB) ContractCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error) {
|
func (db *CachingDB) ContractCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error) {
|
||||||
code, _ := db.codeCache.Get(codeHash)
|
code, _ := db.codeCache.Get(codeHash)
|
||||||
if len(code) > 0 {
|
if len(code) > 0 {
|
||||||
return code, nil
|
return code, nil
|
||||||
|
|
@ -258,7 +262,7 @@ func (db *cachingDB) ContractCodeWithPrefix(address common.Address, codeHash com
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContractCodeSize retrieves a particular contracts code's size.
|
// ContractCodeSize retrieves a particular contracts code's size.
|
||||||
func (db *cachingDB) ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) {
|
func (db *CachingDB) ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) {
|
||||||
if cached, ok := db.codeSizeCache.Get(codeHash); ok {
|
if cached, ok := db.codeSizeCache.Get(codeHash); ok {
|
||||||
return cached, nil
|
return cached, nil
|
||||||
}
|
}
|
||||||
|
|
@ -266,17 +270,29 @@ func (db *cachingDB) ContractCodeSize(addr common.Address, codeHash common.Hash)
|
||||||
return len(code), err
|
return len(code), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DiskDB returns the underlying key-value disk database.
|
|
||||||
func (db *cachingDB) DiskDB() ethdb.KeyValueStore {
|
|
||||||
return db.disk
|
|
||||||
}
|
|
||||||
|
|
||||||
// TrieDB retrieves any intermediate trie-node caching layer.
|
// TrieDB retrieves any intermediate trie-node caching layer.
|
||||||
func (db *cachingDB) TrieDB() *triedb.Database {
|
func (db *CachingDB) TrieDB() *triedb.Database {
|
||||||
return db.triedb
|
return db.triedb
|
||||||
}
|
}
|
||||||
|
|
||||||
// PointCache returns the cache of evaluated curve points.
|
// PointCache returns the cache of evaluated curve points.
|
||||||
func (db *cachingDB) PointCache() *utils.PointCache {
|
func (db *CachingDB) PointCache() *utils.PointCache {
|
||||||
return db.pointCache
|
return db.pointCache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Snapshot returns the underlying state snapshot.
|
||||||
|
func (db *CachingDB) Snapshot() *snapshot.Tree {
|
||||||
|
return db.snap
|
||||||
|
}
|
||||||
|
|
||||||
|
// mustCopyTrie returns a deep-copied trie.
|
||||||
|
func mustCopyTrie(t Trie) Trie {
|
||||||
|
switch t := t.(type) {
|
||||||
|
case *trie.StateTrie:
|
||||||
|
return t.Copy()
|
||||||
|
case *trie.VerkleTrie:
|
||||||
|
return t.Copy()
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("unknown trie type %T", t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ func testNodeIteratorCoverage(t *testing.T, scheme string) {
|
||||||
db, sdb, ndb, root, _ := makeTestState(scheme)
|
db, sdb, ndb, root, _ := makeTestState(scheme)
|
||||||
ndb.Commit(root, false)
|
ndb.Commit(root, false)
|
||||||
|
|
||||||
state, err := New(root, sdb, nil)
|
state, err := New(root, sdb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create state trie at %x: %v", root, err)
|
t.Fatalf("failed to create state trie at %x: %v", root, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
313
core/state/reader.go
Normal file
313
core/state/reader.go
Normal file
|
|
@ -0,0 +1,313 @@
|
||||||
|
// Copyright 2024 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"
|
||||||
|
"maps"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
|
"github.com/ethereum/go-ethereum/trie/utils"
|
||||||
|
"github.com/ethereum/go-ethereum/triedb"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Reader defines the interface for accessing accounts and storage slots
|
||||||
|
// associated with a specific state.
|
||||||
|
type Reader interface {
|
||||||
|
// Account retrieves the account associated with a particular address.
|
||||||
|
//
|
||||||
|
// - Returns a nil account if it does not exist
|
||||||
|
// - Returns an error only if an unexpected issue occurs
|
||||||
|
// - The returned account is safe to modify after the call
|
||||||
|
Account(addr common.Address) (*types.StateAccount, error)
|
||||||
|
|
||||||
|
// Storage retrieves the storage slot associated with a particular account
|
||||||
|
// address and slot key.
|
||||||
|
//
|
||||||
|
// - Returns an empty slot if it does not exist
|
||||||
|
// - Returns an error only if an unexpected issue occurs
|
||||||
|
// - The returned storage slot is safe to modify after the call
|
||||||
|
Storage(addr common.Address, slot common.Hash) (common.Hash, error)
|
||||||
|
|
||||||
|
// Copy returns a deep-copied state reader.
|
||||||
|
Copy() Reader
|
||||||
|
}
|
||||||
|
|
||||||
|
// stateReader is a wrapper over the state snapshot and implements the Reader
|
||||||
|
// interface. It provides an efficient way to access flat state.
|
||||||
|
type stateReader struct {
|
||||||
|
snap snapshot.Snapshot
|
||||||
|
buff crypto.KeccakState
|
||||||
|
}
|
||||||
|
|
||||||
|
// newStateReader constructs a flat state reader with on the specified state root.
|
||||||
|
func newStateReader(root common.Hash, snaps *snapshot.Tree) (*stateReader, error) {
|
||||||
|
snap := snaps.Snapshot(root)
|
||||||
|
if snap == nil {
|
||||||
|
return nil, errors.New("snapshot is not available")
|
||||||
|
}
|
||||||
|
return &stateReader{
|
||||||
|
snap: snap,
|
||||||
|
buff: crypto.NewKeccakState(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Account implements Reader, retrieving the account specified by the address.
|
||||||
|
//
|
||||||
|
// An error will be returned if the associated snapshot is already stale or
|
||||||
|
// the requested account is not yet covered by the snapshot.
|
||||||
|
//
|
||||||
|
// The returned account might be nil if it's not existent.
|
||||||
|
func (r *stateReader) Account(addr common.Address) (*types.StateAccount, error) {
|
||||||
|
ret, err := r.snap.Account(crypto.HashData(r.buff, addr.Bytes()))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if ret == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
acct := &types.StateAccount{
|
||||||
|
Nonce: ret.Nonce,
|
||||||
|
Balance: ret.Balance,
|
||||||
|
CodeHash: ret.CodeHash,
|
||||||
|
Root: common.BytesToHash(ret.Root),
|
||||||
|
}
|
||||||
|
if len(acct.CodeHash) == 0 {
|
||||||
|
acct.CodeHash = types.EmptyCodeHash.Bytes()
|
||||||
|
}
|
||||||
|
if acct.Root == (common.Hash{}) {
|
||||||
|
acct.Root = types.EmptyRootHash
|
||||||
|
}
|
||||||
|
return acct, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Storage implements Reader, retrieving the storage slot specified by the
|
||||||
|
// address and slot key.
|
||||||
|
//
|
||||||
|
// An error will be returned if the associated snapshot is already stale or
|
||||||
|
// the requested storage slot is not yet covered by the snapshot.
|
||||||
|
//
|
||||||
|
// The returned storage slot might be empty if it's not existent.
|
||||||
|
func (r *stateReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) {
|
||||||
|
addrHash := crypto.HashData(r.buff, addr.Bytes())
|
||||||
|
slotHash := crypto.HashData(r.buff, key.Bytes())
|
||||||
|
ret, err := r.snap.Storage(addrHash, slotHash)
|
||||||
|
if err != nil {
|
||||||
|
return common.Hash{}, err
|
||||||
|
}
|
||||||
|
if len(ret) == 0 {
|
||||||
|
return common.Hash{}, nil
|
||||||
|
}
|
||||||
|
// Perform the rlp-decode as the slot value is RLP-encoded in the state
|
||||||
|
// snapshot.
|
||||||
|
_, content, _, err := rlp.Split(ret)
|
||||||
|
if err != nil {
|
||||||
|
return common.Hash{}, err
|
||||||
|
}
|
||||||
|
var value common.Hash
|
||||||
|
value.SetBytes(content)
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy implements Reader, returning a deep-copied snap reader.
|
||||||
|
func (r *stateReader) Copy() Reader {
|
||||||
|
return &stateReader{
|
||||||
|
snap: r.snap,
|
||||||
|
buff: crypto.NewKeccakState(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trieReader implements the Reader interface, providing functions to access
|
||||||
|
// state from the referenced trie.
|
||||||
|
type trieReader struct {
|
||||||
|
root common.Hash // State root which uniquely represent a state
|
||||||
|
db *triedb.Database // Database for loading trie
|
||||||
|
buff crypto.KeccakState // Buffer for keccak256 hashing
|
||||||
|
mainTrie Trie // Main trie, resolved in constructor
|
||||||
|
subRoots map[common.Address]common.Hash // Set of storage roots, cached when the account is resolved
|
||||||
|
subTries map[common.Address]Trie // Group of storage tries, cached when it's resolved
|
||||||
|
}
|
||||||
|
|
||||||
|
// trieReader constructs a trie reader of the specific state. An error will be
|
||||||
|
// returned if the associated trie specified by root is not existent.
|
||||||
|
func newTrieReader(root common.Hash, db *triedb.Database, cache *utils.PointCache) (*trieReader, error) {
|
||||||
|
var (
|
||||||
|
tr Trie
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if !db.IsVerkle() {
|
||||||
|
tr, err = trie.NewStateTrie(trie.StateTrieID(root), db)
|
||||||
|
} else {
|
||||||
|
tr, err = trie.NewVerkleTrie(root, db, cache)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &trieReader{
|
||||||
|
root: root,
|
||||||
|
db: db,
|
||||||
|
buff: crypto.NewKeccakState(),
|
||||||
|
mainTrie: tr,
|
||||||
|
subRoots: make(map[common.Address]common.Hash),
|
||||||
|
subTries: make(map[common.Address]Trie),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Account implements Reader, retrieving the account specified by the address.
|
||||||
|
//
|
||||||
|
// An error will be returned if the trie state is corrupted. An nil account
|
||||||
|
// will be returned if it's not existent in the trie.
|
||||||
|
func (r *trieReader) Account(addr common.Address) (*types.StateAccount, error) {
|
||||||
|
account, err := r.mainTrie.GetAccount(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if account == nil {
|
||||||
|
r.subRoots[addr] = types.EmptyRootHash
|
||||||
|
} else {
|
||||||
|
r.subRoots[addr] = account.Root
|
||||||
|
}
|
||||||
|
return account, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Storage implements Reader, retrieving the storage slot specified by the
|
||||||
|
// address and slot key.
|
||||||
|
//
|
||||||
|
// An error will be returned if the trie state is corrupted. An empty storage
|
||||||
|
// slot will be returned if it's not existent in the trie.
|
||||||
|
func (r *trieReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) {
|
||||||
|
var (
|
||||||
|
tr Trie
|
||||||
|
found bool
|
||||||
|
value common.Hash
|
||||||
|
)
|
||||||
|
if r.db.IsVerkle() {
|
||||||
|
tr = r.mainTrie
|
||||||
|
} else {
|
||||||
|
tr, found = r.subTries[addr]
|
||||||
|
if !found {
|
||||||
|
root, ok := r.subRoots[addr]
|
||||||
|
|
||||||
|
// The storage slot is accessed without account caching. It's unexpected
|
||||||
|
// behavior but try to resolve the account first anyway.
|
||||||
|
if !ok {
|
||||||
|
_, err := r.Account(addr)
|
||||||
|
if err != nil {
|
||||||
|
return common.Hash{}, err
|
||||||
|
}
|
||||||
|
root = r.subRoots[addr]
|
||||||
|
}
|
||||||
|
var err error
|
||||||
|
tr, err = trie.NewStateTrie(trie.StorageTrieID(r.root, crypto.HashData(r.buff, addr.Bytes()), root), r.db)
|
||||||
|
if err != nil {
|
||||||
|
return common.Hash{}, err
|
||||||
|
}
|
||||||
|
r.subTries[addr] = tr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret, err := tr.GetStorage(addr, key.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
return common.Hash{}, err
|
||||||
|
}
|
||||||
|
value.SetBytes(ret)
|
||||||
|
return value, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy implements Reader, returning a deep-copied trie reader.
|
||||||
|
func (r *trieReader) Copy() Reader {
|
||||||
|
tries := make(map[common.Address]Trie)
|
||||||
|
for addr, tr := range r.subTries {
|
||||||
|
tries[addr] = mustCopyTrie(tr)
|
||||||
|
}
|
||||||
|
return &trieReader{
|
||||||
|
root: r.root,
|
||||||
|
db: r.db,
|
||||||
|
buff: crypto.NewKeccakState(),
|
||||||
|
mainTrie: mustCopyTrie(r.mainTrie),
|
||||||
|
subRoots: maps.Clone(r.subRoots),
|
||||||
|
subTries: tries,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiReader is the aggregation of a list of Reader interface, providing state
|
||||||
|
// access by leveraging all readers. The checking priority is determined by the
|
||||||
|
// position in the reader list.
|
||||||
|
type multiReader struct {
|
||||||
|
readers []Reader // List of readers, sorted by checking priority
|
||||||
|
}
|
||||||
|
|
||||||
|
// newMultiReader constructs a multiReader instance with the given readers. The
|
||||||
|
// priority among readers is assumed to be sorted. Note, it must contain at least
|
||||||
|
// one reader for constructing a multiReader.
|
||||||
|
func newMultiReader(readers ...Reader) (*multiReader, error) {
|
||||||
|
if len(readers) == 0 {
|
||||||
|
return nil, errors.New("empty reader set")
|
||||||
|
}
|
||||||
|
return &multiReader{
|
||||||
|
readers: readers,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Account implementing Reader interface, retrieving the account associated with
|
||||||
|
// a particular address.
|
||||||
|
//
|
||||||
|
// - Returns a nil account if it does not exist
|
||||||
|
// - Returns an error only if an unexpected issue occurs
|
||||||
|
// - The returned account is safe to modify after the call
|
||||||
|
func (r *multiReader) Account(addr common.Address) (*types.StateAccount, error) {
|
||||||
|
var errs []error
|
||||||
|
for _, reader := range r.readers {
|
||||||
|
acct, err := reader.Account(addr)
|
||||||
|
if err == nil {
|
||||||
|
return acct, nil
|
||||||
|
}
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
return nil, errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Storage implementing Reader interface, retrieving the storage slot associated
|
||||||
|
// with a particular account address and slot key.
|
||||||
|
//
|
||||||
|
// - Returns an empty slot if it does not exist
|
||||||
|
// - Returns an error only if an unexpected issue occurs
|
||||||
|
// - The returned storage slot is safe to modify after the call
|
||||||
|
func (r *multiReader) Storage(addr common.Address, slot common.Hash) (common.Hash, error) {
|
||||||
|
var errs []error
|
||||||
|
for _, reader := range r.readers {
|
||||||
|
slot, err := reader.Storage(addr, slot)
|
||||||
|
if err == nil {
|
||||||
|
return slot, nil
|
||||||
|
}
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
return common.Hash{}, errors.Join(errs...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy implementing Reader interface, returning a deep-copied state reader.
|
||||||
|
func (r *multiReader) Copy() Reader {
|
||||||
|
var readers []Reader
|
||||||
|
for _, reader := range r.readers {
|
||||||
|
readers = append(readers, reader.Copy())
|
||||||
|
}
|
||||||
|
return &multiReader{readers: readers}
|
||||||
|
}
|
||||||
|
|
@ -187,52 +187,23 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
|
||||||
s.originStorage[key] = common.Hash{} // track the empty slot as origin value
|
s.originStorage[key] = common.Hash{} // track the empty slot as origin value
|
||||||
return common.Hash{}
|
return common.Hash{}
|
||||||
}
|
}
|
||||||
// If no live objects are available, attempt to use snapshots
|
s.db.StorageLoaded++
|
||||||
var (
|
|
||||||
enc []byte
|
|
||||||
err error
|
|
||||||
value common.Hash
|
|
||||||
)
|
|
||||||
if s.db.snap != nil {
|
|
||||||
start := time.Now()
|
|
||||||
enc, err = s.db.snap.Storage(s.addrHash, crypto.Keccak256Hash(key.Bytes()))
|
|
||||||
s.db.SnapshotStorageReads += time.Since(start)
|
|
||||||
|
|
||||||
if len(enc) > 0 {
|
start := time.Now()
|
||||||
_, content, _, err := rlp.Split(enc)
|
value, err := s.db.reader.Storage(s.address, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.db.setError(err)
|
s.db.setError(err)
|
||||||
}
|
return common.Hash{}
|
||||||
value.SetBytes(content)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// If the snapshot is unavailable or reading from it fails, load from the database.
|
s.db.StorageReads += time.Since(start)
|
||||||
if s.db.snap == nil || err != nil {
|
|
||||||
start := time.Now()
|
|
||||||
tr, err := s.getTrie()
|
|
||||||
if err != nil {
|
|
||||||
s.db.setError(err)
|
|
||||||
return common.Hash{}
|
|
||||||
}
|
|
||||||
val, err := tr.GetStorage(s.address, key.Bytes())
|
|
||||||
s.db.StorageReads += time.Since(start)
|
|
||||||
|
|
||||||
if err != nil {
|
// Schedule the resolved storage slots for prefetching if it's enabled.
|
||||||
s.db.setError(err)
|
|
||||||
return common.Hash{}
|
|
||||||
}
|
|
||||||
value.SetBytes(val)
|
|
||||||
}
|
|
||||||
// Independent of where we loaded the data from, add it to the prefetcher.
|
|
||||||
// Whilst this would be a bit weird if snapshots are disabled, but we still
|
|
||||||
// want the trie nodes to end up in the prefetcher too, so just push through.
|
|
||||||
if s.db.prefetcher != nil && s.data.Root != types.EmptyRootHash {
|
if s.db.prefetcher != nil && s.data.Root != types.EmptyRootHash {
|
||||||
if err = s.db.prefetcher.prefetch(s.addrHash, s.origin.Root, s.address, [][]byte{key[:]}, true); err != nil {
|
if err = s.db.prefetcher.prefetch(s.addrHash, s.origin.Root, s.address, [][]byte{key[:]}, true); err != nil {
|
||||||
log.Error("Failed to prefetch storage slot", "addr", s.address, "key", key, "err", err)
|
log.Error("Failed to prefetch storage slot", "addr", s.address, "key", key, "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.originStorage[key] = value
|
s.originStorage[key] = value
|
||||||
s.db.StorageLoaded++
|
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -527,7 +498,7 @@ func (s *stateObject) deepCopy(db *StateDB) *stateObject {
|
||||||
newContract: s.newContract,
|
newContract: s.newContract,
|
||||||
}
|
}
|
||||||
if s.trie != nil {
|
if s.trie != nil {
|
||||||
obj.trie = db.db.CopyTrie(s.trie)
|
obj.trie = mustCopyTrie(s.trie)
|
||||||
}
|
}
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,27 +26,25 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
|
||||||
"github.com/ethereum/go-ethereum/triedb"
|
"github.com/ethereum/go-ethereum/triedb"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
type stateEnv struct {
|
type stateEnv struct {
|
||||||
db ethdb.Database
|
|
||||||
state *StateDB
|
state *StateDB
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStateEnv() *stateEnv {
|
func newStateEnv() *stateEnv {
|
||||||
db := rawdb.NewMemoryDatabase()
|
sdb, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
||||||
sdb, _ := New(types.EmptyRootHash, NewDatabase(db), nil)
|
return &stateEnv{state: sdb}
|
||||||
return &stateEnv{db: db, state: sdb}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDump(t *testing.T) {
|
func TestDump(t *testing.T) {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
tdb := NewDatabaseWithConfig(db, &triedb.Config{Preimages: true})
|
triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
||||||
sdb, _ := New(types.EmptyRootHash, tdb, nil)
|
tdb := NewDatabase(triedb, nil)
|
||||||
s := &stateEnv{db: db, state: sdb}
|
sdb, _ := New(types.EmptyRootHash, tdb)
|
||||||
|
s := &stateEnv{state: sdb}
|
||||||
|
|
||||||
// generate a few entries
|
// generate a few entries
|
||||||
obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01}))
|
obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01}))
|
||||||
|
|
@ -62,7 +60,7 @@ func TestDump(t *testing.T) {
|
||||||
root, _ := s.state.Commit(0, false)
|
root, _ := s.state.Commit(0, false)
|
||||||
|
|
||||||
// check that DumpToCollector contains the state objects that are in trie
|
// check that DumpToCollector contains the state objects that are in trie
|
||||||
s.state, _ = New(root, tdb, nil)
|
s.state, _ = New(root, tdb)
|
||||||
got := string(s.state.Dump(nil))
|
got := string(s.state.Dump(nil))
|
||||||
want := `{
|
want := `{
|
||||||
"root": "71edff0130dd2385947095001c73d9e28d862fc286fca2b922ca6f6f3cddfdd2",
|
"root": "71edff0130dd2385947095001c73d9e28d862fc286fca2b922ca6f6f3cddfdd2",
|
||||||
|
|
@ -101,9 +99,10 @@ func TestDump(t *testing.T) {
|
||||||
|
|
||||||
func TestIterativeDump(t *testing.T) {
|
func TestIterativeDump(t *testing.T) {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
tdb := NewDatabaseWithConfig(db, &triedb.Config{Preimages: true})
|
triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
||||||
sdb, _ := New(types.EmptyRootHash, tdb, nil)
|
tdb := NewDatabase(triedb, nil)
|
||||||
s := &stateEnv{db: db, state: sdb}
|
sdb, _ := New(types.EmptyRootHash, tdb)
|
||||||
|
s := &stateEnv{state: sdb}
|
||||||
|
|
||||||
// generate a few entries
|
// generate a few entries
|
||||||
obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01}))
|
obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01}))
|
||||||
|
|
@ -119,7 +118,7 @@ func TestIterativeDump(t *testing.T) {
|
||||||
s.state.updateStateObject(obj1)
|
s.state.updateStateObject(obj1)
|
||||||
s.state.updateStateObject(obj2)
|
s.state.updateStateObject(obj2)
|
||||||
root, _ := s.state.Commit(0, false)
|
root, _ := s.state.Commit(0, false)
|
||||||
s.state, _ = New(root, tdb, nil)
|
s.state, _ = New(root, tdb)
|
||||||
|
|
||||||
b := &bytes.Buffer{}
|
b := &bytes.Buffer{}
|
||||||
s.state.IterativeDump(nil, json.NewEncoder(b))
|
s.state.IterativeDump(nil, json.NewEncoder(b))
|
||||||
|
|
@ -195,7 +194,7 @@ func TestSnapshotEmpty(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateObjectRevert(t *testing.T) {
|
func TestCreateObjectRevert(t *testing.T) {
|
||||||
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
||||||
addr := common.BytesToAddress([]byte("so0"))
|
addr := common.BytesToAddress([]byte("so0"))
|
||||||
snap := state.Snapshot()
|
snap := state.Snapshot()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,10 +82,8 @@ type StateDB struct {
|
||||||
db Database
|
db Database
|
||||||
prefetcher *triePrefetcher
|
prefetcher *triePrefetcher
|
||||||
trie Trie
|
trie Trie
|
||||||
hasher crypto.KeccakState
|
|
||||||
logger *tracing.Hooks
|
logger *tracing.Hooks
|
||||||
snaps *snapshot.Tree // Nil if snapshot is not available
|
reader Reader
|
||||||
snap snapshot.Snapshot // Nil if snapshot is not available
|
|
||||||
|
|
||||||
// originalRoot is the pre-state root, before any changes were made.
|
// originalRoot is the pre-state root, before any changes were made.
|
||||||
// It will be updated when the Commit is called.
|
// It will be updated when the Commit is called.
|
||||||
|
|
@ -144,17 +142,15 @@ type StateDB struct {
|
||||||
witness *stateless.Witness
|
witness *stateless.Witness
|
||||||
|
|
||||||
// Measurements gathered during execution for debugging purposes
|
// Measurements gathered during execution for debugging purposes
|
||||||
AccountReads time.Duration
|
AccountReads time.Duration
|
||||||
AccountHashes time.Duration
|
AccountHashes time.Duration
|
||||||
AccountUpdates time.Duration
|
AccountUpdates time.Duration
|
||||||
AccountCommits time.Duration
|
AccountCommits time.Duration
|
||||||
StorageReads time.Duration
|
StorageReads time.Duration
|
||||||
StorageUpdates time.Duration
|
StorageUpdates time.Duration
|
||||||
StorageCommits time.Duration
|
StorageCommits time.Duration
|
||||||
SnapshotAccountReads time.Duration
|
SnapshotCommits time.Duration
|
||||||
SnapshotStorageReads time.Duration
|
TrieDBCommits time.Duration
|
||||||
SnapshotCommits time.Duration
|
|
||||||
TrieDBCommits time.Duration
|
|
||||||
|
|
||||||
AccountLoaded int // Number of accounts retrieved from the database during the state transition
|
AccountLoaded int // Number of accounts retrieved from the database during the state transition
|
||||||
AccountUpdated int // Number of accounts updated during the state transition
|
AccountUpdated int // Number of accounts updated during the state transition
|
||||||
|
|
@ -165,16 +161,20 @@ type StateDB struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new state from a given trie.
|
// New creates a new state from a given trie.
|
||||||
func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) {
|
func New(root common.Hash, db Database) (*StateDB, error) {
|
||||||
tr, err := db.OpenTrie(root)
|
tr, err := db.OpenTrie(root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
reader, err := db.Reader(root)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
sdb := &StateDB{
|
sdb := &StateDB{
|
||||||
db: db,
|
db: db,
|
||||||
trie: tr,
|
trie: tr,
|
||||||
originalRoot: root,
|
originalRoot: root,
|
||||||
snaps: snaps,
|
reader: reader,
|
||||||
stateObjects: make(map[common.Address]*stateObject),
|
stateObjects: make(map[common.Address]*stateObject),
|
||||||
stateObjectsDestruct: make(map[common.Address]*stateObject),
|
stateObjectsDestruct: make(map[common.Address]*stateObject),
|
||||||
mutations: make(map[common.Address]*mutation),
|
mutations: make(map[common.Address]*mutation),
|
||||||
|
|
@ -183,13 +183,9 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
|
||||||
journal: newJournal(),
|
journal: newJournal(),
|
||||||
accessList: newAccessList(),
|
accessList: newAccessList(),
|
||||||
transientStorage: newTransientStorage(),
|
transientStorage: newTransientStorage(),
|
||||||
hasher: crypto.NewKeccakState(),
|
|
||||||
}
|
}
|
||||||
if db.TrieDB().IsVerkle() {
|
if db.TrieDB().IsVerkle() {
|
||||||
sdb.accessEvents = NewAccessEvents(db.(*cachingDB).pointCache)
|
sdb.accessEvents = NewAccessEvents(db.PointCache())
|
||||||
}
|
|
||||||
if sdb.snaps != nil {
|
|
||||||
sdb.snap = sdb.snaps.Snapshot(root)
|
|
||||||
}
|
}
|
||||||
return sdb, nil
|
return sdb, nil
|
||||||
}
|
}
|
||||||
|
|
@ -204,30 +200,23 @@ func (s *StateDB) SetLogger(l *tracing.Hooks) {
|
||||||
// commit phase, most of the needed data is already hot.
|
// commit phase, most of the needed data is already hot.
|
||||||
func (s *StateDB) StartPrefetcher(namespace string, witness *stateless.Witness) {
|
func (s *StateDB) StartPrefetcher(namespace string, witness *stateless.Witness) {
|
||||||
// Terminate any previously running prefetcher
|
// Terminate any previously running prefetcher
|
||||||
if s.prefetcher != nil {
|
s.StopPrefetcher()
|
||||||
s.prefetcher.terminate(false)
|
|
||||||
s.prefetcher.report()
|
|
||||||
s.prefetcher = nil
|
|
||||||
}
|
|
||||||
// Enable witness collection if requested
|
// Enable witness collection if requested
|
||||||
s.witness = witness
|
s.witness = witness
|
||||||
|
|
||||||
// If snapshots are enabled, start prefethers explicitly
|
// With the switch to the Proof-of-Stake consensus algorithm, block production
|
||||||
if s.snap != nil {
|
// rewards are now handled at the consensus layer. Consequently, a block may
|
||||||
s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, namespace, witness == nil)
|
// have no state transitions if it contains no transactions and no withdrawals.
|
||||||
|
// In such cases, the account trie won't be scheduled for prefetching, leading
|
||||||
// With the switch to the Proof-of-Stake consensus algorithm, block production
|
// to unnecessary error logs.
|
||||||
// rewards are now handled at the consensus layer. Consequently, a block may
|
//
|
||||||
// have no state transitions if it contains no transactions and no withdrawals.
|
// To prevent this, the account trie is always scheduled for prefetching once
|
||||||
// In such cases, the account trie won't be scheduled for prefetching, leading
|
// the prefetcher is constructed. For more details, see:
|
||||||
// to unnecessary error logs.
|
// https://github.com/ethereum/go-ethereum/issues/29880
|
||||||
//
|
s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, namespace, witness == nil)
|
||||||
// To prevent this, the account trie is always scheduled for prefetching once
|
if err := s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, nil, false); err != nil {
|
||||||
// the prefetcher is constructed. For more details, see:
|
log.Error("Failed to prefetch account trie", "root", s.originalRoot, "err", err)
|
||||||
// https://github.com/ethereum/go-ethereum/issues/29880
|
|
||||||
if err := s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, nil, false); err != nil {
|
|
||||||
log.Error("Failed to prefetch account trie", "root", s.originalRoot, "err", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -583,57 +572,28 @@ func (s *StateDB) getStateObject(addr common.Address) *stateObject {
|
||||||
if _, ok := s.stateObjectsDestruct[addr]; ok {
|
if _, ok := s.stateObjectsDestruct[addr]; ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// If no live objects are available, attempt to use snapshots
|
s.AccountLoaded++
|
||||||
var data *types.StateAccount
|
|
||||||
if s.snap != nil {
|
|
||||||
start := time.Now()
|
|
||||||
acc, err := s.snap.Account(crypto.HashData(s.hasher, addr.Bytes()))
|
|
||||||
s.SnapshotAccountReads += time.Since(start)
|
|
||||||
if err == nil {
|
|
||||||
if acc == nil {
|
|
||||||
s.AccountLoaded++
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
data = &types.StateAccount{
|
|
||||||
Nonce: acc.Nonce,
|
|
||||||
Balance: acc.Balance,
|
|
||||||
CodeHash: acc.CodeHash,
|
|
||||||
Root: common.BytesToHash(acc.Root),
|
|
||||||
}
|
|
||||||
if len(data.CodeHash) == 0 {
|
|
||||||
data.CodeHash = types.EmptyCodeHash.Bytes()
|
|
||||||
}
|
|
||||||
if data.Root == (common.Hash{}) {
|
|
||||||
data.Root = types.EmptyRootHash
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If snapshot unavailable or reading from it failed, load from the database
|
|
||||||
if data == nil {
|
|
||||||
start := time.Now()
|
|
||||||
var err error
|
|
||||||
data, err = s.trie.GetAccount(addr)
|
|
||||||
s.AccountReads += time.Since(start)
|
|
||||||
|
|
||||||
if err != nil {
|
start := time.Now()
|
||||||
s.setError(fmt.Errorf("getDeleteStateObject (%x) error: %w", addr.Bytes(), err))
|
acct, err := s.reader.Account(addr)
|
||||||
return nil
|
if err != nil {
|
||||||
}
|
s.setError(fmt.Errorf("getStateObject (%x) error: %w", addr.Bytes(), err))
|
||||||
if data == nil {
|
return nil
|
||||||
s.AccountLoaded++
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Independent of where we loaded the data from, add it to the prefetcher.
|
s.AccountReads += time.Since(start)
|
||||||
// Whilst this would be a bit weird if snapshots are disabled, but we still
|
|
||||||
// want the trie nodes to end up in the prefetcher too, so just push through.
|
// Short circuit if the account is not found
|
||||||
|
if acct == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Schedule the resolved account for prefetching if it's enabled.
|
||||||
if s.prefetcher != nil {
|
if s.prefetcher != nil {
|
||||||
if err := s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, [][]byte{addr[:]}, true); err != nil {
|
if err := s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, [][]byte{addr[:]}, true); err != nil {
|
||||||
log.Error("Failed to prefetch account", "addr", addr, "err", err)
|
log.Error("Failed to prefetch account", "addr", addr, "err", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Insert into the live set
|
// Insert into the live set
|
||||||
obj := newObject(s, addr, data)
|
obj := newObject(s, addr, acct)
|
||||||
s.setStateObject(obj)
|
s.setStateObject(obj)
|
||||||
s.AccountLoaded++
|
s.AccountLoaded++
|
||||||
return obj
|
return obj
|
||||||
|
|
@ -688,8 +648,8 @@ func (s *StateDB) Copy() *StateDB {
|
||||||
// Copy all the basic fields, initialize the memory ones
|
// Copy all the basic fields, initialize the memory ones
|
||||||
state := &StateDB{
|
state := &StateDB{
|
||||||
db: s.db,
|
db: s.db,
|
||||||
trie: s.db.CopyTrie(s.trie),
|
trie: mustCopyTrie(s.trie),
|
||||||
hasher: crypto.NewKeccakState(),
|
reader: s.reader.Copy(),
|
||||||
originalRoot: s.originalRoot,
|
originalRoot: s.originalRoot,
|
||||||
stateObjects: make(map[common.Address]*stateObject, len(s.stateObjects)),
|
stateObjects: make(map[common.Address]*stateObject, len(s.stateObjects)),
|
||||||
stateObjectsDestruct: make(map[common.Address]*stateObject, len(s.stateObjectsDestruct)),
|
stateObjectsDestruct: make(map[common.Address]*stateObject, len(s.stateObjectsDestruct)),
|
||||||
|
|
@ -701,14 +661,16 @@ func (s *StateDB) Copy() *StateDB {
|
||||||
logs: make(map[common.Hash][]*types.Log, len(s.logs)),
|
logs: make(map[common.Hash][]*types.Log, len(s.logs)),
|
||||||
logSize: s.logSize,
|
logSize: s.logSize,
|
||||||
preimages: maps.Clone(s.preimages),
|
preimages: maps.Clone(s.preimages),
|
||||||
journal: s.journal.copy(),
|
|
||||||
|
|
||||||
// In order for the block producer to be able to use and make additions
|
// Do we need to copy the access list and transient storage?
|
||||||
// to the snapshot tree, we need to copy that as well. Otherwise, any
|
// In practice: No. At the start of a transaction, these two lists are empty.
|
||||||
// block mined by ourselves will cause gaps in the tree, and force the
|
// In practice, we only ever copy state _between_ transactions/blocks, never
|
||||||
// miner to operate trie-backed only.
|
// in the middle of a transaction. However, it doesn't cost us much to copy
|
||||||
snaps: s.snaps,
|
// empty lists, so we do it anyway to not blow up if we ever decide copy them
|
||||||
snap: s.snap,
|
// in the middle of a transaction.
|
||||||
|
accessList: s.accessList.Copy(),
|
||||||
|
transientStorage: s.transientStorage.Copy(),
|
||||||
|
journal: s.journal.copy(),
|
||||||
}
|
}
|
||||||
if s.witness != nil {
|
if s.witness != nil {
|
||||||
state.witness = s.witness.Copy()
|
state.witness = s.witness.Copy()
|
||||||
|
|
@ -737,14 +699,6 @@ func (s *StateDB) Copy() *StateDB {
|
||||||
}
|
}
|
||||||
state.logs[hash] = cpy
|
state.logs[hash] = cpy
|
||||||
}
|
}
|
||||||
// Do we need to copy the access list and transient storage?
|
|
||||||
// In practice: No. At the start of a transaction, these two lists are empty.
|
|
||||||
// In practice, we only ever copy state _between_ transactions/blocks, never
|
|
||||||
// in the middle of a transaction. However, it doesn't cost us much to copy
|
|
||||||
// empty lists, so we do it anyway to not blow up if we ever decide copy them
|
|
||||||
// in the middle of a transaction.
|
|
||||||
state.accessList = s.accessList.Copy()
|
|
||||||
state.transientStorage = s.transientStorage.Copy()
|
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -979,8 +933,8 @@ func (s *StateDB) clearJournalAndRefund() {
|
||||||
// of a specific account. It leverages the associated state snapshot for fast
|
// of a specific account. It leverages the associated state snapshot for fast
|
||||||
// storage iteration and constructs trie node deletion markers by creating
|
// storage iteration and constructs trie node deletion markers by creating
|
||||||
// stack trie with iterated slots.
|
// stack trie with iterated slots.
|
||||||
func (s *StateDB) fastDeleteStorage(addrHash common.Hash, root common.Hash) (map[common.Hash][]byte, *trienode.NodeSet, error) {
|
func (s *StateDB) fastDeleteStorage(snaps *snapshot.Tree, addrHash common.Hash, root common.Hash) (map[common.Hash][]byte, *trienode.NodeSet, error) {
|
||||||
iter, err := s.snaps.StorageIterator(s.originalRoot, addrHash, common.Hash{})
|
iter, err := snaps.StorageIterator(s.originalRoot, addrHash, common.Hash{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -1058,10 +1012,11 @@ func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root
|
||||||
// The fast approach can be failed if the snapshot is not fully
|
// The fast approach can be failed if the snapshot is not fully
|
||||||
// generated, or it's internally corrupted. Fallback to the slow
|
// generated, or it's internally corrupted. Fallback to the slow
|
||||||
// one just in case.
|
// one just in case.
|
||||||
if s.snap != nil {
|
snaps := s.db.Snapshot()
|
||||||
slots, nodes, err = s.fastDeleteStorage(addrHash, root)
|
if snaps != nil {
|
||||||
|
slots, nodes, err = s.fastDeleteStorage(snaps, addrHash, root)
|
||||||
}
|
}
|
||||||
if s.snap == nil || err != nil {
|
if snaps == nil || err != nil {
|
||||||
slots, nodes, err = s.slowDeleteStorage(addr, addrHash, root)
|
slots, nodes, err = s.slowDeleteStorage(addr, addrHash, root)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -1299,7 +1254,7 @@ func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool) (*stateU
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Commit dirty contract code if any exists
|
// Commit dirty contract code if any exists
|
||||||
if db := s.db.DiskDB(); db != nil && len(ret.codes) > 0 {
|
if db := s.db.TrieDB().Disk(); db != nil && len(ret.codes) > 0 {
|
||||||
batch := db.NewBatch()
|
batch := db.NewBatch()
|
||||||
for _, code := range ret.codes {
|
for _, code := range ret.codes {
|
||||||
rawdb.WriteCode(batch, code.hash, code.blob)
|
rawdb.WriteCode(batch, code.hash, code.blob)
|
||||||
|
|
@ -1310,18 +1265,16 @@ func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool) (*stateU
|
||||||
}
|
}
|
||||||
if !ret.empty() {
|
if !ret.empty() {
|
||||||
// If snapshotting is enabled, update the snapshot tree with this new version
|
// If snapshotting is enabled, update the snapshot tree with this new version
|
||||||
if s.snap != nil {
|
if snap := s.db.Snapshot(); snap != nil {
|
||||||
s.snap = nil
|
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
if err := s.snaps.Update(ret.root, ret.originRoot, ret.destructs, ret.accounts, ret.storages); err != nil {
|
if err := snap.Update(ret.root, ret.originRoot, ret.destructs, ret.accounts, ret.storages); err != nil {
|
||||||
log.Warn("Failed to update snapshot tree", "from", ret.originRoot, "to", ret.root, "err", err)
|
log.Warn("Failed to update snapshot tree", "from", ret.originRoot, "to", ret.root, "err", err)
|
||||||
}
|
}
|
||||||
// Keep 128 diff layers in the memory, persistent layer is 129th.
|
// Keep 128 diff layers in the memory, persistent layer is 129th.
|
||||||
// - head layer is paired with HEAD state
|
// - head layer is paired with HEAD state
|
||||||
// - head-1 layer is paired with HEAD-1 state
|
// - head-1 layer is paired with HEAD-1 state
|
||||||
// - head-127 layer(bottom-most diff layer) is paired with HEAD-127 state
|
// - head-127 layer(bottom-most diff layer) is paired with HEAD-127 state
|
||||||
if err := s.snaps.Cap(ret.root, TriesInMemory); err != nil {
|
if err := snap.Cap(ret.root, TriesInMemory); err != nil {
|
||||||
log.Warn("Failed to cap snapshot tree", "root", ret.root, "layers", TriesInMemory, "err", err)
|
log.Warn("Failed to cap snapshot tree", "root", ret.root, "layers", TriesInMemory, "err", err)
|
||||||
}
|
}
|
||||||
s.SnapshotCommits += time.Since(start)
|
s.SnapshotCommits += time.Since(start)
|
||||||
|
|
@ -1336,6 +1289,7 @@ func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool) (*stateU
|
||||||
s.TrieDBCommits += time.Since(start)
|
s.TrieDBCommits += time.Since(start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s.reader, _ = s.db.Reader(s.originalRoot)
|
||||||
return ret, err
|
return ret, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1451,6 +1405,7 @@ func (s *StateDB) markUpdate(addr common.Address) {
|
||||||
s.mutations[addr].typ = update
|
s.mutations[addr].typ = update
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PointCache returns the point cache used by verkle tree.
|
||||||
func (s *StateDB) PointCache() *utils.PointCache {
|
func (s *StateDB) PointCache() *utils.PointCache {
|
||||||
return s.db.PointCache()
|
return s.db.PointCache()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,6 @@ func (test *stateTest) run() bool {
|
||||||
}
|
}
|
||||||
disk = rawdb.NewMemoryDatabase()
|
disk = rawdb.NewMemoryDatabase()
|
||||||
tdb = triedb.NewDatabase(disk, &triedb.Config{PathDB: pathdb.Defaults})
|
tdb = triedb.NewDatabase(disk, &triedb.Config{PathDB: pathdb.Defaults})
|
||||||
sdb = NewDatabaseWithNodeDB(disk, tdb)
|
|
||||||
byzantium = rand.Intn(2) == 0
|
byzantium = rand.Intn(2) == 0
|
||||||
)
|
)
|
||||||
defer disk.Close()
|
defer disk.Close()
|
||||||
|
|
@ -217,7 +216,7 @@ func (test *stateTest) run() bool {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
root = roots[len(roots)-1]
|
root = roots[len(roots)-1]
|
||||||
}
|
}
|
||||||
state, err := New(root, sdb, snaps)
|
state, err := New(root, NewDatabase(tdb, snaps))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ package state
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"maps"
|
"maps"
|
||||||
"math"
|
"math"
|
||||||
|
|
@ -53,8 +52,9 @@ func TestUpdateLeaks(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
db = rawdb.NewMemoryDatabase()
|
db = rawdb.NewMemoryDatabase()
|
||||||
tdb = triedb.NewDatabase(db, nil)
|
tdb = triedb.NewDatabase(db, nil)
|
||||||
|
sdb = NewDatabase(tdb, nil)
|
||||||
)
|
)
|
||||||
state, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(db, tdb), nil)
|
state, _ := New(types.EmptyRootHash, sdb)
|
||||||
|
|
||||||
// Update it with some accounts
|
// Update it with some accounts
|
||||||
for i := byte(0); i < 255; i++ {
|
for i := byte(0); i < 255; i++ {
|
||||||
|
|
@ -90,8 +90,8 @@ func TestIntermediateLeaks(t *testing.T) {
|
||||||
finalDb := rawdb.NewMemoryDatabase()
|
finalDb := rawdb.NewMemoryDatabase()
|
||||||
transNdb := triedb.NewDatabase(transDb, nil)
|
transNdb := triedb.NewDatabase(transDb, nil)
|
||||||
finalNdb := triedb.NewDatabase(finalDb, nil)
|
finalNdb := triedb.NewDatabase(finalDb, nil)
|
||||||
transState, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(transDb, transNdb), nil)
|
transState, _ := New(types.EmptyRootHash, NewDatabase(transNdb, nil))
|
||||||
finalState, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(finalDb, finalNdb), nil)
|
finalState, _ := New(types.EmptyRootHash, NewDatabase(finalNdb, nil))
|
||||||
|
|
||||||
modify := func(state *StateDB, addr common.Address, i, tweak byte) {
|
modify := func(state *StateDB, addr common.Address, i, tweak byte) {
|
||||||
state.SetBalance(addr, uint256.NewInt(uint64(11*i)+uint64(tweak)), tracing.BalanceChangeUnspecified)
|
state.SetBalance(addr, uint256.NewInt(uint64(11*i)+uint64(tweak)), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -166,7 +166,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
||||||
// https://github.com/ethereum/go-ethereum/pull/15549.
|
// https://github.com/ethereum/go-ethereum/pull/15549.
|
||||||
func TestCopy(t *testing.T) {
|
func TestCopy(t *testing.T) {
|
||||||
// Create a random state test to copy and modify "independently"
|
// Create a random state test to copy and modify "independently"
|
||||||
orig, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
orig, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
||||||
|
|
||||||
for i := byte(0); i < 255; i++ {
|
for i := byte(0); i < 255; i++ {
|
||||||
obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
||||||
|
|
@ -230,8 +230,8 @@ func TestCopy(t *testing.T) {
|
||||||
// TestCopyWithDirtyJournal tests if Copy can correct create a equal copied
|
// TestCopyWithDirtyJournal tests if Copy can correct create a equal copied
|
||||||
// stateDB with dirty journal present.
|
// stateDB with dirty journal present.
|
||||||
func TestCopyWithDirtyJournal(t *testing.T) {
|
func TestCopyWithDirtyJournal(t *testing.T) {
|
||||||
db := NewDatabase(rawdb.NewMemoryDatabase())
|
db := NewDatabaseForTesting()
|
||||||
orig, _ := New(types.EmptyRootHash, db, nil)
|
orig, _ := New(types.EmptyRootHash, db)
|
||||||
|
|
||||||
// Fill up the initial states
|
// Fill up the initial states
|
||||||
for i := byte(0); i < 255; i++ {
|
for i := byte(0); i < 255; i++ {
|
||||||
|
|
@ -241,7 +241,7 @@ func TestCopyWithDirtyJournal(t *testing.T) {
|
||||||
orig.updateStateObject(obj)
|
orig.updateStateObject(obj)
|
||||||
}
|
}
|
||||||
root, _ := orig.Commit(0, true)
|
root, _ := orig.Commit(0, true)
|
||||||
orig, _ = New(root, db, nil)
|
orig, _ = New(root, db)
|
||||||
|
|
||||||
// modify all in memory without finalizing
|
// modify all in memory without finalizing
|
||||||
for i := byte(0); i < 255; i++ {
|
for i := byte(0); i < 255; i++ {
|
||||||
|
|
@ -274,8 +274,8 @@ func TestCopyWithDirtyJournal(t *testing.T) {
|
||||||
// It then proceeds to make changes to S1. Those changes are _not_ supposed
|
// It then proceeds to make changes to S1. Those changes are _not_ supposed
|
||||||
// to affect S2. This test checks that the copy properly deep-copies the objectstate
|
// to affect S2. This test checks that the copy properly deep-copies the objectstate
|
||||||
func TestCopyObjectState(t *testing.T) {
|
func TestCopyObjectState(t *testing.T) {
|
||||||
db := NewDatabase(rawdb.NewMemoryDatabase())
|
db := NewDatabaseForTesting()
|
||||||
orig, _ := New(types.EmptyRootHash, db, nil)
|
orig, _ := New(types.EmptyRootHash, db)
|
||||||
|
|
||||||
// Fill up the initial states
|
// Fill up the initial states
|
||||||
for i := byte(0); i < 5; i++ {
|
for i := byte(0); i < 5; i++ {
|
||||||
|
|
@ -527,7 +527,7 @@ func (test *snapshotTest) String() string {
|
||||||
func (test *snapshotTest) run() bool {
|
func (test *snapshotTest) run() bool {
|
||||||
// Run all actions and create snapshots.
|
// Run all actions and create snapshots.
|
||||||
var (
|
var (
|
||||||
state, _ = New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
state, _ = New(types.EmptyRootHash, NewDatabaseForTesting())
|
||||||
snapshotRevs = make([]int, len(test.snapshots))
|
snapshotRevs = make([]int, len(test.snapshots))
|
||||||
sindex = 0
|
sindex = 0
|
||||||
checkstates = make([]*StateDB, len(test.snapshots))
|
checkstates = make([]*StateDB, len(test.snapshots))
|
||||||
|
|
@ -699,7 +699,7 @@ func TestTouchDelete(t *testing.T) {
|
||||||
s := newStateEnv()
|
s := newStateEnv()
|
||||||
s.state.getOrNewStateObject(common.Address{})
|
s.state.getOrNewStateObject(common.Address{})
|
||||||
root, _ := s.state.Commit(0, false)
|
root, _ := s.state.Commit(0, false)
|
||||||
s.state, _ = New(root, s.state.db, s.state.snaps)
|
s.state, _ = New(root, s.state.db)
|
||||||
|
|
||||||
snapshot := s.state.Snapshot()
|
snapshot := s.state.Snapshot()
|
||||||
s.state.AddBalance(common.Address{}, new(uint256.Int), tracing.BalanceChangeUnspecified)
|
s.state.AddBalance(common.Address{}, new(uint256.Int), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -716,7 +716,7 @@ func TestTouchDelete(t *testing.T) {
|
||||||
// TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy.
|
// 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
|
// See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512
|
||||||
func TestCopyOfCopy(t *testing.T) {
|
func TestCopyOfCopy(t *testing.T) {
|
||||||
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
||||||
addr := common.HexToAddress("aaaa")
|
addr := common.HexToAddress("aaaa")
|
||||||
state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified)
|
state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified)
|
||||||
|
|
||||||
|
|
@ -733,8 +733,8 @@ func TestCopyOfCopy(t *testing.T) {
|
||||||
//
|
//
|
||||||
// See https://github.com/ethereum/go-ethereum/issues/20106.
|
// See https://github.com/ethereum/go-ethereum/issues/20106.
|
||||||
func TestCopyCommitCopy(t *testing.T) {
|
func TestCopyCommitCopy(t *testing.T) {
|
||||||
tdb := NewDatabase(rawdb.NewMemoryDatabase())
|
tdb := NewDatabaseForTesting()
|
||||||
state, _ := New(types.EmptyRootHash, tdb, nil)
|
state, _ := New(types.EmptyRootHash, tdb)
|
||||||
|
|
||||||
// Create an account and check if the retrieved balance is correct
|
// Create an account and check if the retrieved balance is correct
|
||||||
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
||||||
|
|
@ -787,7 +787,7 @@ func TestCopyCommitCopy(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Commit state, ensure states can be loaded from disk
|
// Commit state, ensure states can be loaded from disk
|
||||||
root, _ := state.Commit(0, false)
|
root, _ := state.Commit(0, false)
|
||||||
state, _ = New(root, tdb, nil)
|
state, _ = New(root, tdb)
|
||||||
if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 {
|
if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 {
|
||||||
t.Fatalf("state post-commit balance mismatch: have %v, want %v", balance, 42)
|
t.Fatalf("state post-commit balance mismatch: have %v, want %v", balance, 42)
|
||||||
}
|
}
|
||||||
|
|
@ -807,7 +807,7 @@ func TestCopyCommitCopy(t *testing.T) {
|
||||||
//
|
//
|
||||||
// See https://github.com/ethereum/go-ethereum/issues/20106.
|
// See https://github.com/ethereum/go-ethereum/issues/20106.
|
||||||
func TestCopyCopyCommitCopy(t *testing.T) {
|
func TestCopyCopyCommitCopy(t *testing.T) {
|
||||||
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
||||||
|
|
||||||
// Create an account and check if the retrieved balance is correct
|
// Create an account and check if the retrieved balance is correct
|
||||||
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
||||||
|
|
@ -876,8 +876,8 @@ func TestCopyCopyCommitCopy(t *testing.T) {
|
||||||
|
|
||||||
// TestCommitCopy tests the copy from a committed state is not fully functional.
|
// TestCommitCopy tests the copy from a committed state is not fully functional.
|
||||||
func TestCommitCopy(t *testing.T) {
|
func TestCommitCopy(t *testing.T) {
|
||||||
db := NewDatabase(rawdb.NewMemoryDatabase())
|
db := NewDatabaseForTesting()
|
||||||
state, _ := New(types.EmptyRootHash, db, nil)
|
state, _ := New(types.EmptyRootHash, db)
|
||||||
|
|
||||||
// Create an account and check if the retrieved balance is correct
|
// Create an account and check if the retrieved balance is correct
|
||||||
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
||||||
|
|
@ -902,7 +902,7 @@ func TestCommitCopy(t *testing.T) {
|
||||||
}
|
}
|
||||||
root, _ := state.Commit(0, true)
|
root, _ := state.Commit(0, true)
|
||||||
|
|
||||||
state, _ = New(root, db, nil)
|
state, _ = New(root, db)
|
||||||
state.SetState(addr, skey2, sval2)
|
state.SetState(addr, skey2, sval2)
|
||||||
state.Commit(1, true)
|
state.Commit(1, true)
|
||||||
|
|
||||||
|
|
@ -915,10 +915,10 @@ func TestCommitCopy(t *testing.T) {
|
||||||
t.Fatalf("unexpected code: have %x", code)
|
t.Fatalf("unexpected code: have %x", code)
|
||||||
}
|
}
|
||||||
// Miss slots because of non-functional trie after commit
|
// Miss slots because of non-functional trie after commit
|
||||||
if val := copied.GetState(addr, skey1); val != (common.Hash{}) {
|
if val := copied.GetState(addr, skey1); val != sval1 {
|
||||||
t.Fatalf("unexpected storage slot: have %x", sval1)
|
t.Fatalf("unexpected storage slot: have %x", val)
|
||||||
}
|
}
|
||||||
if val := copied.GetCommittedState(addr, skey1); val != (common.Hash{}) {
|
if val := copied.GetCommittedState(addr, skey1); val != sval1 {
|
||||||
t.Fatalf("unexpected storage slot: have %x", val)
|
t.Fatalf("unexpected storage slot: have %x", val)
|
||||||
}
|
}
|
||||||
// Slots cached in the stateDB, available after commit
|
// Slots cached in the stateDB, available after commit
|
||||||
|
|
@ -928,9 +928,6 @@ func TestCommitCopy(t *testing.T) {
|
||||||
if val := copied.GetCommittedState(addr, skey2); val != sval2 {
|
if val := copied.GetCommittedState(addr, skey2); val != sval2 {
|
||||||
t.Fatalf("unexpected storage slot: have %x", val)
|
t.Fatalf("unexpected storage slot: have %x", val)
|
||||||
}
|
}
|
||||||
if !errors.Is(copied.Error(), trie.ErrCommitted) {
|
|
||||||
t.Fatalf("unexpected state error, %v", copied.Error())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestDeleteCreateRevert tests a weird state transition corner case that we hit
|
// TestDeleteCreateRevert tests a weird state transition corner case that we hit
|
||||||
|
|
@ -943,13 +940,13 @@ func TestCommitCopy(t *testing.T) {
|
||||||
// first, but the journal wiped the entire state object on create-revert.
|
// first, but the journal wiped the entire state object on create-revert.
|
||||||
func TestDeleteCreateRevert(t *testing.T) {
|
func TestDeleteCreateRevert(t *testing.T) {
|
||||||
// Create an initial state with a single contract
|
// Create an initial state with a single contract
|
||||||
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
||||||
|
|
||||||
addr := common.BytesToAddress([]byte("so"))
|
addr := common.BytesToAddress([]byte("so"))
|
||||||
state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified)
|
state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified)
|
||||||
|
|
||||||
root, _ := state.Commit(0, false)
|
root, _ := state.Commit(0, false)
|
||||||
state, _ = New(root, state.db, state.snaps)
|
state, _ = New(root, state.db)
|
||||||
|
|
||||||
// Simulate self-destructing in one transaction, then create-reverting in another
|
// Simulate self-destructing in one transaction, then create-reverting in another
|
||||||
state.SelfDestruct(addr)
|
state.SelfDestruct(addr)
|
||||||
|
|
@ -961,7 +958,7 @@ func TestDeleteCreateRevert(t *testing.T) {
|
||||||
|
|
||||||
// Commit the entire state and make sure we don't crash and have the correct state
|
// Commit the entire state and make sure we don't crash and have the correct state
|
||||||
root, _ = state.Commit(0, true)
|
root, _ = state.Commit(0, true)
|
||||||
state, _ = New(root, state.db, state.snaps)
|
state, _ = New(root, state.db)
|
||||||
|
|
||||||
if state.getStateObject(addr) != nil {
|
if state.getStateObject(addr) != nil {
|
||||||
t.Fatalf("self-destructed contract came alive")
|
t.Fatalf("self-destructed contract came alive")
|
||||||
|
|
@ -992,10 +989,10 @@ func testMissingTrieNodes(t *testing.T, scheme string) {
|
||||||
CleanCacheSize: 0,
|
CleanCacheSize: 0,
|
||||||
}}) // disable caching
|
}}) // disable caching
|
||||||
}
|
}
|
||||||
db := NewDatabaseWithNodeDB(memDb, tdb)
|
db := NewDatabase(tdb, nil)
|
||||||
|
|
||||||
var root common.Hash
|
var root common.Hash
|
||||||
state, _ := New(types.EmptyRootHash, db, nil)
|
state, _ := New(types.EmptyRootHash, db)
|
||||||
addr := common.BytesToAddress([]byte("so"))
|
addr := common.BytesToAddress([]byte("so"))
|
||||||
{
|
{
|
||||||
state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified)
|
state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -1009,7 +1006,7 @@ func testMissingTrieNodes(t *testing.T, scheme string) {
|
||||||
tdb.Commit(root, false)
|
tdb.Commit(root, false)
|
||||||
}
|
}
|
||||||
// Create a new state on the old root
|
// Create a new state on the old root
|
||||||
state, _ = New(root, db, nil)
|
state, _ = New(root, db)
|
||||||
// Now we clear out the memdb
|
// Now we clear out the memdb
|
||||||
it := memDb.NewIterator(nil, nil)
|
it := memDb.NewIterator(nil, nil)
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
|
|
@ -1042,9 +1039,8 @@ func TestStateDBAccessList(t *testing.T) {
|
||||||
return common.HexToHash(a)
|
return common.HexToHash(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
memDb := rawdb.NewMemoryDatabase()
|
db := NewDatabaseForTesting()
|
||||||
db := NewDatabase(memDb)
|
state, _ := New(types.EmptyRootHash, db)
|
||||||
state, _ := New(types.EmptyRootHash, db, nil)
|
|
||||||
state.accessList = newAccessList()
|
state.accessList = newAccessList()
|
||||||
|
|
||||||
verifyAddrs := func(astrings ...string) {
|
verifyAddrs := func(astrings ...string) {
|
||||||
|
|
@ -1213,9 +1209,9 @@ func TestFlushOrderDataLoss(t *testing.T) {
|
||||||
// Create a state trie with many accounts and slots
|
// Create a state trie with many accounts and slots
|
||||||
var (
|
var (
|
||||||
memdb = rawdb.NewMemoryDatabase()
|
memdb = rawdb.NewMemoryDatabase()
|
||||||
triedb = triedb.NewDatabase(memdb, nil)
|
tdb = triedb.NewDatabase(memdb, triedb.HashDefaults)
|
||||||
statedb = NewDatabaseWithNodeDB(memdb, triedb)
|
statedb = NewDatabase(tdb, nil)
|
||||||
state, _ = New(types.EmptyRootHash, statedb, nil)
|
state, _ = New(types.EmptyRootHash, statedb)
|
||||||
)
|
)
|
||||||
for a := byte(0); a < 10; a++ {
|
for a := byte(0); a < 10; a++ {
|
||||||
state.CreateAccount(common.Address{a})
|
state.CreateAccount(common.Address{a})
|
||||||
|
|
@ -1227,15 +1223,15 @@ func TestFlushOrderDataLoss(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to commit state trie: %v", err)
|
t.Fatalf("failed to commit state trie: %v", err)
|
||||||
}
|
}
|
||||||
triedb.Reference(root, common.Hash{})
|
tdb.Reference(root, common.Hash{})
|
||||||
if err := triedb.Cap(1024); err != nil {
|
if err := tdb.Cap(1024); err != nil {
|
||||||
t.Fatalf("failed to cap trie dirty cache: %v", err)
|
t.Fatalf("failed to cap trie dirty cache: %v", err)
|
||||||
}
|
}
|
||||||
if err := triedb.Commit(root, false); err != nil {
|
if err := tdb.Commit(root, false); err != nil {
|
||||||
t.Fatalf("failed to commit state trie: %v", err)
|
t.Fatalf("failed to commit state trie: %v", err)
|
||||||
}
|
}
|
||||||
// Reopen the state trie from flushed disk and verify it
|
// Reopen the state trie from flushed disk and verify it
|
||||||
state, err = New(root, NewDatabase(memdb), nil)
|
state, err = New(root, NewDatabase(triedb.NewDatabase(memdb, triedb.HashDefaults), nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to reopen state trie: %v", err)
|
t.Fatalf("failed to reopen state trie: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -1249,9 +1245,8 @@ func TestFlushOrderDataLoss(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStateDBTransientStorage(t *testing.T) {
|
func TestStateDBTransientStorage(t *testing.T) {
|
||||||
memDb := rawdb.NewMemoryDatabase()
|
db := NewDatabaseForTesting()
|
||||||
db := NewDatabase(memDb)
|
state, _ := New(types.EmptyRootHash, db)
|
||||||
state, _ := New(types.EmptyRootHash, db, nil)
|
|
||||||
|
|
||||||
key := common.Hash{0x01}
|
key := common.Hash{0x01}
|
||||||
value := common.Hash{0x02}
|
value := common.Hash{0x02}
|
||||||
|
|
@ -1286,9 +1281,9 @@ func TestDeleteStorage(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
disk = rawdb.NewMemoryDatabase()
|
disk = rawdb.NewMemoryDatabase()
|
||||||
tdb = triedb.NewDatabase(disk, nil)
|
tdb = triedb.NewDatabase(disk, nil)
|
||||||
db = NewDatabaseWithNodeDB(disk, tdb)
|
|
||||||
snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash)
|
snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash)
|
||||||
state, _ = New(types.EmptyRootHash, db, snaps)
|
db = NewDatabase(tdb, snaps)
|
||||||
|
state, _ = New(types.EmptyRootHash, db)
|
||||||
addr = common.HexToAddress("0x1")
|
addr = common.HexToAddress("0x1")
|
||||||
)
|
)
|
||||||
// Initialize account and populate storage
|
// Initialize account and populate storage
|
||||||
|
|
@ -1300,9 +1295,10 @@ func TestDeleteStorage(t *testing.T) {
|
||||||
state.SetState(addr, slot, value)
|
state.SetState(addr, slot, value)
|
||||||
}
|
}
|
||||||
root, _ := state.Commit(0, true)
|
root, _ := state.Commit(0, true)
|
||||||
|
|
||||||
// Init phase done, create two states, one with snap and one without
|
// Init phase done, create two states, one with snap and one without
|
||||||
fastState, _ := New(root, db, snaps)
|
fastState, _ := New(root, NewDatabase(tdb, snaps))
|
||||||
slowState, _ := New(root, db, nil)
|
slowState, _ := New(root, NewDatabase(tdb, nil))
|
||||||
|
|
||||||
obj := fastState.getOrNewStateObject(addr)
|
obj := fastState.getOrNewStateObject(addr)
|
||||||
storageRoot := obj.data.Root
|
storageRoot := obj.data.Root
|
||||||
|
|
@ -1340,8 +1336,8 @@ func TestStorageDirtiness(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
disk = rawdb.NewMemoryDatabase()
|
disk = rawdb.NewMemoryDatabase()
|
||||||
tdb = triedb.NewDatabase(disk, nil)
|
tdb = triedb.NewDatabase(disk, nil)
|
||||||
db = NewDatabaseWithNodeDB(disk, tdb)
|
db = NewDatabase(tdb, nil)
|
||||||
state, _ = New(types.EmptyRootHash, db, nil)
|
state, _ = New(types.EmptyRootHash, db)
|
||||||
addr = common.HexToAddress("0x1")
|
addr = common.HexToAddress("0x1")
|
||||||
checkDirty = func(key common.Hash, value common.Hash, dirty bool) {
|
checkDirty = func(key common.Hash, value common.Hash, dirty bool) {
|
||||||
obj := state.getStateObject(addr)
|
obj := state.getStateObject(addr)
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,8 @@ func makeTestState(scheme string) (ethdb.Database, Database, *triedb.Database, c
|
||||||
}
|
}
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
nodeDb := triedb.NewDatabase(db, config)
|
nodeDb := triedb.NewDatabase(db, config)
|
||||||
sdb := NewDatabaseWithNodeDB(db, nodeDb)
|
sdb := NewDatabase(nodeDb, nil)
|
||||||
state, _ := New(types.EmptyRootHash, sdb, nil)
|
state, _ := New(types.EmptyRootHash, sdb)
|
||||||
|
|
||||||
// Fill it with some arbitrary data
|
// Fill it with some arbitrary data
|
||||||
var accounts []*testAccount
|
var accounts []*testAccount
|
||||||
|
|
@ -94,7 +94,7 @@ func checkStateAccounts(t *testing.T, db ethdb.Database, scheme string, root com
|
||||||
config.PathDB = pathdb.Defaults
|
config.PathDB = pathdb.Defaults
|
||||||
}
|
}
|
||||||
// Check root availability and state contents
|
// Check root availability and state contents
|
||||||
state, err := New(root, NewDatabaseWithConfig(db, &config), nil)
|
state, err := New(root, NewDatabase(triedb.NewDatabase(db, &config), nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create state trie at %x: %v", root, err)
|
t.Fatalf("failed to create state trie at %x: %v", root, err)
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +120,7 @@ func checkStateConsistency(db ethdb.Database, scheme string, root common.Hash) e
|
||||||
if scheme == rawdb.PathScheme {
|
if scheme == rawdb.PathScheme {
|
||||||
config.PathDB = pathdb.Defaults
|
config.PathDB = pathdb.Defaults
|
||||||
}
|
}
|
||||||
state, err := New(root, NewDatabaseWithConfig(db, config), nil)
|
state, err := New(root, NewDatabase(triedb.NewDatabase(db, config), nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func filledStateDB() *StateDB {
|
func filledStateDB() *StateDB {
|
||||||
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
||||||
|
|
||||||
// Create an account and check if the retrieved balance is correct
|
// Create an account and check if the retrieved balance is correct
|
||||||
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
||||||
|
|
@ -67,8 +67,11 @@ func TestUseAfterTerminate(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestVerklePrefetcher(t *testing.T) {
|
func TestVerklePrefetcher(t *testing.T) {
|
||||||
db := NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), triedb.VerkleDefaults)
|
disk := rawdb.NewMemoryDatabase()
|
||||||
state, err := New(types.EmptyRootHash, db, nil)
|
db := triedb.NewDatabase(disk, triedb.VerkleDefaults)
|
||||||
|
sdb := NewDatabase(db, nil)
|
||||||
|
|
||||||
|
state, err := New(types.EmptyRootHash, sdb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to initialize state: %v", err)
|
t.Fatalf("failed to initialize state: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -82,9 +85,9 @@ func TestVerklePrefetcher(t *testing.T) {
|
||||||
state.SetState(addr, skey, sval) // Change the storage trie
|
state.SetState(addr, skey, sval) // Change the storage trie
|
||||||
root, _ := state.Commit(0, true)
|
root, _ := state.Commit(0, true)
|
||||||
|
|
||||||
state, _ = New(root, db, nil)
|
state, _ = New(root, sdb)
|
||||||
sRoot := state.GetStorageRoot(addr)
|
sRoot := state.GetStorageRoot(addr)
|
||||||
fetcher := newTriePrefetcher(db, root, "", false)
|
fetcher := newTriePrefetcher(sdb, root, "", false)
|
||||||
|
|
||||||
// Read account
|
// Read account
|
||||||
fetcher.prefetch(common.Hash{}, root, common.Address{}, [][]byte{
|
fetcher.prefetch(common.Hash{}, root, common.Address{}, [][]byte{
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/trie"
|
"github.com/ethereum/go-ethereum/trie"
|
||||||
"github.com/ethereum/go-ethereum/triedb"
|
"github.com/ethereum/go-ethereum/triedb"
|
||||||
|
|
@ -602,7 +601,7 @@ func TestProcessParentBlockHash(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Run("MPT", func(t *testing.T) {
|
t.Run("MPT", func(t *testing.T) {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
test(statedb)
|
test(statedb)
|
||||||
})
|
})
|
||||||
t.Run("Verkle", func(t *testing.T) {
|
t.Run("Verkle", func(t *testing.T) {
|
||||||
|
|
@ -610,7 +609,7 @@ func TestProcessParentBlockHash(t *testing.T) {
|
||||||
cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme)
|
cacheConfig := DefaultCacheConfigWithScheme(rawdb.PathScheme)
|
||||||
cacheConfig.SnapshotLimit = 0
|
cacheConfig.SnapshotLimit = 0
|
||||||
triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true))
|
triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true))
|
||||||
statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabaseWithNodeDB(db, triedb), nil)
|
statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, nil))
|
||||||
test(statedb)
|
test(statedb)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,7 @@ import (
|
||||||
func ExecuteStateless(config *params.ChainConfig, witness *stateless.Witness) (common.Hash, common.Hash, error) {
|
func ExecuteStateless(config *params.ChainConfig, witness *stateless.Witness) (common.Hash, common.Hash, error) {
|
||||||
// Create and populate the state database to serve as the stateless backend
|
// Create and populate the state database to serve as the stateless backend
|
||||||
memdb := witness.MakeHashDB()
|
memdb := witness.MakeHashDB()
|
||||||
|
db, err := state.New(witness.Root(), state.NewDatabase(triedb.NewDatabase(memdb, triedb.HashDefaults), nil))
|
||||||
db, err := state.New(witness.Root(), state.NewDatabaseWithConfig(memdb, triedb.HashDefaults), nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, common.Hash{}, err
|
return common.Hash{}, common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,14 +33,12 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
"github.com/ethereum/go-ethereum/consensus/misc/eip1559"
|
||||||
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/txpool"
|
"github.com/ethereum/go-ethereum/core/txpool"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
"github.com/ethereum/go-ethereum/crypto/kzg4844"
|
||||||
"github.com/ethereum/go-ethereum/ethdb/memorydb"
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
|
|
@ -545,7 +543,7 @@ func TestOpenDrops(t *testing.T) {
|
||||||
store.Close()
|
store.Close()
|
||||||
|
|
||||||
// Create a blob pool out of the pre-seeded data
|
// 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())
|
||||||
statedb.AddBalance(crypto.PubkeyToAddress(gapper.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(crypto.PubkeyToAddress(gapper.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -676,7 +674,7 @@ func TestOpenIndex(t *testing.T) {
|
||||||
store.Close()
|
store.Close()
|
||||||
|
|
||||||
// Create a blob pool out of the pre-seeded data
|
// 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())
|
||||||
statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.Commit(0, true)
|
statedb.Commit(0, true)
|
||||||
|
|
||||||
|
|
@ -776,7 +774,7 @@ func TestOpenHeap(t *testing.T) {
|
||||||
store.Close()
|
store.Close()
|
||||||
|
|
||||||
// Create a blob pool out of the pre-seeded data
|
// 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())
|
||||||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -856,7 +854,7 @@ func TestOpenCap(t *testing.T) {
|
||||||
// with a high cap to ensure everything was persisted previously
|
// with a high cap to ensure everything was persisted previously
|
||||||
for _, datacap := range []uint64{2 * (txAvgSize + blobSize), 100 * (txAvgSize + blobSize)} {
|
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
|
// 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())
|
||||||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -1266,7 +1264,7 @@ func TestAdd(t *testing.T) {
|
||||||
keys = make(map[string]*ecdsa.PrivateKey)
|
keys = make(map[string]*ecdsa.PrivateKey)
|
||||||
addrs = make(map[string]common.Address)
|
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())
|
||||||
for acc, seed := range tt.seeds {
|
for acc, seed := range tt.seeds {
|
||||||
// Generate a new random key/address for the seed account
|
// Generate a new random key/address for the seed account
|
||||||
keys[acc], _ = crypto.GenerateKey()
|
keys[acc], _ = crypto.GenerateKey()
|
||||||
|
|
@ -1328,7 +1326,7 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) {
|
||||||
basefee = uint64(1050)
|
basefee = uint64(1050)
|
||||||
blobfee = uint64(105)
|
blobfee = uint64(105)
|
||||||
signer = types.LatestSigner(testChainConfig)
|
signer = types.LatestSigner(testChainConfig)
|
||||||
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewDatabase(memorydb.New())), nil)
|
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
chain = &testBlockChain{
|
chain = &testBlockChain{
|
||||||
config: testChainConfig,
|
config: testChainConfig,
|
||||||
basefee: uint256.NewInt(basefee),
|
basefee: uint256.NewInt(basefee),
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
|
@ -80,7 +79,7 @@ func TestTransactionFutureAttack(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
config.GlobalQueue = 100
|
config.GlobalQueue = 100
|
||||||
|
|
@ -117,7 +116,7 @@ func TestTransactionFutureAttack(t *testing.T) {
|
||||||
func TestTransactionFuture1559(t *testing.T) {
|
func TestTransactionFuture1559(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
// Create the pool to test the pricing enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver())
|
||||||
|
|
@ -150,7 +149,7 @@ func TestTransactionFuture1559(t *testing.T) {
|
||||||
func TestTransactionZAttack(t *testing.T) {
|
func TestTransactionZAttack(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
// Create the pool to test the pricing enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver())
|
||||||
|
|
@ -218,7 +217,7 @@ func TestTransactionZAttack(t *testing.T) {
|
||||||
|
|
||||||
func BenchmarkFutureAttack(b *testing.B) {
|
func BenchmarkFutureAttack(b *testing.B) {
|
||||||
// Create the pool to test the limit enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
config.GlobalQueue = 100
|
config.GlobalQueue = 100
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/txpool"
|
"github.com/ethereum/go-ethereum/core/txpool"
|
||||||
|
|
@ -160,7 +159,7 @@ func setupPool() (*LegacyPool, *ecdsa.PrivateKey) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupPoolWithConfig(config *params.ChainConfig) (*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())
|
||||||
blockchain := newTestBlockChain(config, 10000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(config, 10000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
|
|
@ -251,7 +250,7 @@ func (c *testChain) State() (*state.StateDB, error) {
|
||||||
// a state change between those fetches.
|
// a state change between those fetches.
|
||||||
stdb := c.statedb
|
stdb := c.statedb
|
||||||
if *c.trigger {
|
if *c.trigger {
|
||||||
c.statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
c.statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
// simulate that the new head block included tx0 and tx1
|
// simulate that the new head block included tx0 and tx1
|
||||||
c.statedb.SetNonce(c.address, 2)
|
c.statedb.SetNonce(c.address, 2)
|
||||||
c.statedb.SetBalance(c.address, new(uint256.Int).SetUint64(params.Ether), tracing.BalanceChangeUnspecified)
|
c.statedb.SetBalance(c.address, new(uint256.Int).SetUint64(params.Ether), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -269,7 +268,7 @@ func TestStateChangeDuringReset(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
key, _ = crypto.GenerateKey()
|
key, _ = crypto.GenerateKey()
|
||||||
address = crypto.PubkeyToAddress(key.PublicKey)
|
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||||
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
trigger = false
|
trigger = false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -468,7 +467,7 @@ func TestChainFork(t *testing.T) {
|
||||||
|
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
statedb.AddBalance(addr, uint256.NewInt(100000000000000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr, uint256.NewInt(100000000000000), tracing.BalanceChangeUnspecified)
|
||||||
|
|
||||||
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
@ -497,7 +496,7 @@ func TestDoubleNonce(t *testing.T) {
|
||||||
|
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
statedb.AddBalance(addr, uint256.NewInt(100000000000000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr, uint256.NewInt(100000000000000), tracing.BalanceChangeUnspecified)
|
||||||
|
|
||||||
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
@ -697,7 +696,7 @@ func TestPostponing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the postponing with
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
@ -910,7 +909,7 @@ func testQueueGlobalLimiting(t *testing.T, nolocals bool) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1003,7 +1002,7 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) {
|
||||||
evictionInterval = time.Millisecond * 100
|
evictionInterval = time.Millisecond * 100
|
||||||
|
|
||||||
// Create the pool to test the non-expiration enforcement
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1189,7 +1188,7 @@ func TestPendingGlobalLimiting(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1291,7 +1290,7 @@ func TestCapClearsFromAll(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1326,7 +1325,7 @@ func TestPendingMinimumAllowance(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1375,7 +1374,7 @@ func TestRepricing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
@ -1495,7 +1494,7 @@ func TestMinGasPriceEnforced(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 10000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 10000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
txPoolConfig := DefaultConfig
|
txPoolConfig := DefaultConfig
|
||||||
|
|
@ -1668,7 +1667,7 @@ func TestRepricingKeepsLocals(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
@ -1742,7 +1741,7 @@ func TestUnderpricing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1857,7 +1856,7 @@ func TestStableUnderpricing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -2090,7 +2089,7 @@ func TestDeduplication(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
@ -2157,7 +2156,7 @@ func TestReplacement(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
@ -2363,7 +2362,7 @@ func testJournaling(t *testing.T, nolocals bool) {
|
||||||
os.Remove(journal)
|
os.Remove(journal)
|
||||||
|
|
||||||
// Create the original pool to inject transaction into the 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -2464,7 +2463,7 @@ func TestStatusCheck(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the status retrievals with
|
// 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())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
@ -86,7 +85,7 @@ func TestEIP2200(t *testing.T) {
|
||||||
for i, tt := range eip2200Tests {
|
for i, tt := range eip2200Tests {
|
||||||
address := common.BytesToAddress([]byte("contract"))
|
address := common.BytesToAddress([]byte("contract"))
|
||||||
|
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
statedb.CreateAccount(address)
|
statedb.CreateAccount(address)
|
||||||
statedb.SetCode(address, hexutil.MustDecode(tt.input))
|
statedb.SetCode(address, hexutil.MustDecode(tt.input))
|
||||||
statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original}))
|
statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original}))
|
||||||
|
|
@ -138,7 +137,7 @@ func TestCreateGas(t *testing.T) {
|
||||||
var gasUsed = uint64(0)
|
var gasUsed = uint64(0)
|
||||||
doCheck := func(testGas int) bool {
|
doCheck := func(testGas int) bool {
|
||||||
address := common.BytesToAddress([]byte("contract"))
|
address := common.BytesToAddress([]byte("contract"))
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
statedb.CreateAccount(address)
|
statedb.CreateAccount(address)
|
||||||
statedb.SetCode(address, hexutil.MustDecode(tt.code))
|
statedb.SetCode(address, hexutil.MustDecode(tt.code))
|
||||||
statedb.Finalise(true)
|
statedb.Finalise(true)
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/math"
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
|
@ -582,7 +581,7 @@ func BenchmarkOpMstore(bench *testing.B) {
|
||||||
|
|
||||||
func TestOpTstore(t *testing.T) {
|
func TestOpTstore(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
env = NewEVM(BlockContext{}, TxContext{}, statedb, params.TestChainConfig, Config{})
|
env = NewEVM(BlockContext{}, TxContext{}, statedb, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import (
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/math"
|
"github.com/ethereum/go-ethereum/common/math"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
@ -43,7 +42,7 @@ func TestLoopInterrupt(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range loopInterruptTests {
|
for i, tt := range loopInterruptTests {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
statedb.CreateAccount(address)
|
statedb.CreateAccount(address)
|
||||||
statedb.SetCode(address, common.Hex2Bytes(tt))
|
statedb.SetCode(address, common.Hex2Bytes(tt))
|
||||||
statedb.Finalise(true)
|
statedb.Finalise(true)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
|
@ -128,7 +127,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
||||||
setDefaults(cfg)
|
setDefaults(cfg)
|
||||||
|
|
||||||
if cfg.State == nil {
|
if cfg.State == nil {
|
||||||
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
address = common.BytesToAddress([]byte("contract"))
|
address = common.BytesToAddress([]byte("contract"))
|
||||||
|
|
@ -165,7 +164,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
||||||
setDefaults(cfg)
|
setDefaults(cfg)
|
||||||
|
|
||||||
if cfg.State == nil {
|
if cfg.State == nil {
|
||||||
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
vmenv = NewEnv(cfg)
|
vmenv = NewEnv(cfg)
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/asm"
|
"github.com/ethereum/go-ethereum/core/asm"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
|
@ -105,7 +104,7 @@ func TestExecute(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCall(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())
|
||||||
address := common.HexToAddress("0xaa")
|
address := common.HexToAddress("0xaa")
|
||||||
state.SetCode(address, []byte{
|
state.SetCode(address, []byte{
|
||||||
byte(vm.PUSH1), 10,
|
byte(vm.PUSH1), 10,
|
||||||
|
|
@ -161,7 +160,7 @@ func BenchmarkCall(b *testing.B) {
|
||||||
}
|
}
|
||||||
func benchmarkEVM_Create(bench *testing.B, code string) {
|
func benchmarkEVM_Create(bench *testing.B, code string) {
|
||||||
var (
|
var (
|
||||||
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
sender = common.BytesToAddress([]byte("sender"))
|
sender = common.BytesToAddress([]byte("sender"))
|
||||||
receiver = common.BytesToAddress([]byte("receiver"))
|
receiver = common.BytesToAddress([]byte("receiver"))
|
||||||
)
|
)
|
||||||
|
|
@ -227,7 +226,7 @@ func BenchmarkEVM_SWAP1(b *testing.B) {
|
||||||
return contract
|
return contract
|
||||||
}
|
}
|
||||||
|
|
||||||
state, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
state, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
contractAddr := common.BytesToAddress([]byte("contract"))
|
contractAddr := common.BytesToAddress([]byte("contract"))
|
||||||
|
|
||||||
b.Run("10k", func(b *testing.B) {
|
b.Run("10k", func(b *testing.B) {
|
||||||
|
|
@ -255,7 +254,7 @@ func BenchmarkEVM_RETURN(b *testing.B) {
|
||||||
return contract
|
return contract
|
||||||
}
|
}
|
||||||
|
|
||||||
state, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
state, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
contractAddr := common.BytesToAddress([]byte("contract"))
|
contractAddr := common.BytesToAddress([]byte("contract"))
|
||||||
|
|
||||||
for _, n := range []uint64{1_000, 10_000, 100_000, 1_000_000} {
|
for _, n := range []uint64{1_000, 10_000, 100_000, 1_000_000} {
|
||||||
|
|
@ -393,7 +392,7 @@ func TestBlockhash(t *testing.T) {
|
||||||
func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode string, b *testing.B) {
|
func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode string, b *testing.B) {
|
||||||
cfg := new(Config)
|
cfg := new(Config)
|
||||||
setDefaults(cfg)
|
setDefaults(cfg)
|
||||||
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
cfg.GasLimit = gas
|
cfg.GasLimit = gas
|
||||||
if len(tracerCode) > 0 {
|
if len(tracerCode) > 0 {
|
||||||
tracer, err := tracers.DefaultDirectory.New(tracerCode, new(tracers.Context), nil)
|
tracer, err := tracers.DefaultDirectory.New(tracerCode, new(tracers.Context), nil)
|
||||||
|
|
@ -880,7 +879,7 @@ func TestRuntimeJSTracer(t *testing.T) {
|
||||||
main := common.HexToAddress("0xaa")
|
main := common.HexToAddress("0xaa")
|
||||||
for i, jsTracer := range jsTracers {
|
for i, jsTracer := range jsTracers {
|
||||||
for j, tc := range tests {
|
for j, tc := range tests {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
|
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
||||||
statedb.SetCode(main, tc.code)
|
statedb.SetCode(main, tc.code)
|
||||||
statedb.SetCode(common.HexToAddress("0xbb"), calleeCode)
|
statedb.SetCode(common.HexToAddress("0xbb"), calleeCode)
|
||||||
statedb.SetCode(common.HexToAddress("0xcc"), calleeCode)
|
statedb.SetCode(common.HexToAddress("0xcc"), calleeCode)
|
||||||
|
|
@ -922,7 +921,7 @@ func TestJSTracerCreateTx(t *testing.T) {
|
||||||
exit: function(res) { this.exits++ }}`
|
exit: function(res) { this.exits++ }}`
|
||||||
code := []byte{byte(vm.PUSH1), 0, byte(vm.PUSH1), 0, byte(vm.RETURN)}
|
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())
|
||||||
tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil)
|
tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,9 @@ func TestAccountRange(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
statedb = state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), &triedb.Config{Preimages: true})
|
mdb = rawdb.NewMemoryDatabase()
|
||||||
sdb, _ = state.New(types.EmptyRootHash, statedb, nil)
|
statedb = state.NewDatabase(triedb.NewDatabase(mdb, &triedb.Config{Preimages: true}), nil)
|
||||||
|
sdb, _ = state.New(types.EmptyRootHash, statedb)
|
||||||
addrs = [AccountRangeMaxResults * 2]common.Address{}
|
addrs = [AccountRangeMaxResults * 2]common.Address{}
|
||||||
m = map[common.Address]bool{}
|
m = map[common.Address]bool{}
|
||||||
)
|
)
|
||||||
|
|
@ -82,7 +83,7 @@ func TestAccountRange(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root, _ := sdb.Commit(0, true)
|
root, _ := sdb.Commit(0, true)
|
||||||
sdb, _ = state.New(root, statedb, nil)
|
sdb, _ = state.New(root, statedb)
|
||||||
|
|
||||||
trie, err := statedb.OpenTrie(root)
|
trie, err := statedb.OpenTrie(root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -135,12 +136,12 @@ func TestEmptyAccountRange(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
statedb = state.NewDatabase(rawdb.NewMemoryDatabase())
|
statedb = state.NewDatabaseForTesting()
|
||||||
st, _ = state.New(types.EmptyRootHash, statedb, nil)
|
st, _ = state.New(types.EmptyRootHash, statedb)
|
||||||
)
|
)
|
||||||
// Commit(although nothing to flush) and re-init the statedb
|
// Commit(although nothing to flush) and re-init the statedb
|
||||||
st.Commit(0, true)
|
st.Commit(0, true)
|
||||||
st, _ = state.New(types.EmptyRootHash, statedb, nil)
|
st, _ = state.New(types.EmptyRootHash, statedb)
|
||||||
|
|
||||||
results := st.RawDump(&state.DumpConfig{
|
results := st.RawDump(&state.DumpConfig{
|
||||||
SkipCode: true,
|
SkipCode: true,
|
||||||
|
|
@ -161,8 +162,10 @@ func TestStorageRangeAt(t *testing.T) {
|
||||||
|
|
||||||
// Create a state where account 0x010000... has a few storage entries.
|
// Create a state where account 0x010000... has a few storage entries.
|
||||||
var (
|
var (
|
||||||
db = state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), &triedb.Config{Preimages: true})
|
mdb = rawdb.NewMemoryDatabase()
|
||||||
sdb, _ = state.New(types.EmptyRootHash, db, nil)
|
tdb = triedb.NewDatabase(mdb, &triedb.Config{Preimages: true})
|
||||||
|
db = state.NewDatabase(tdb, nil)
|
||||||
|
sdb, _ = state.New(types.EmptyRootHash, db)
|
||||||
addr = common.Address{0x01}
|
addr = common.Address{0x01}
|
||||||
keys = []common.Hash{ // hashes of Keys of storage
|
keys = []common.Hash{ // hashes of Keys of storage
|
||||||
common.HexToHash("340dd630ad21bf010b4e676dbfa9ba9a02175262d1fa356232cfde6cb5b47ef2"),
|
common.HexToHash("340dd630ad21bf010b4e676dbfa9ba9a02175262d1fa356232cfde6cb5b47ef2"),
|
||||||
|
|
@ -181,7 +184,7 @@ func TestStorageRangeAt(t *testing.T) {
|
||||||
sdb.SetState(addr, *entry.Key, entry.Value)
|
sdb.SetState(addr, *entry.Key, entry.Value)
|
||||||
}
|
}
|
||||||
root, _ := sdb.Commit(0, false)
|
root, _ := sdb.Commit(0, false)
|
||||||
sdb, _ = state.New(root, db, nil)
|
sdb, _ = state.New(root, db)
|
||||||
|
|
||||||
// Check a few combinations of limit and start/end.
|
// Check a few combinations of limit and start/end.
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,9 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
|
||||||
// the internal junks created by tracing will be persisted into the disk.
|
// the internal junks created by tracing will be persisted into the disk.
|
||||||
// TODO(rjl493456442), clean cache is disabled to prevent memory leak,
|
// TODO(rjl493456442), clean cache is disabled to prevent memory leak,
|
||||||
// please re-enable it for better performance.
|
// please re-enable it for better performance.
|
||||||
database = state.NewDatabaseWithConfig(eth.chainDb, triedb.HashDefaults)
|
tdb := triedb.NewDatabase(eth.chainDb, triedb.HashDefaults)
|
||||||
if statedb, err = state.New(block.Root(), database, nil); err == nil {
|
database = state.NewDatabase(tdb, nil)
|
||||||
|
if statedb, err = state.New(block.Root(), database); err == nil {
|
||||||
log.Info("Found disk backend for state trie", "root", block.Root(), "number", block.Number())
|
log.Info("Found disk backend for state trie", "root", block.Root(), "number", block.Number())
|
||||||
return statedb, noopReleaser, nil
|
return statedb, noopReleaser, nil
|
||||||
}
|
}
|
||||||
|
|
@ -86,13 +87,13 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
|
||||||
// TODO(rjl493456442), clean cache is disabled to prevent memory leak,
|
// TODO(rjl493456442), clean cache is disabled to prevent memory leak,
|
||||||
// please re-enable it for better performance.
|
// please re-enable it for better performance.
|
||||||
tdb = triedb.NewDatabase(eth.chainDb, triedb.HashDefaults)
|
tdb = triedb.NewDatabase(eth.chainDb, triedb.HashDefaults)
|
||||||
database = state.NewDatabaseWithNodeDB(eth.chainDb, tdb)
|
database = state.NewDatabase(tdb, nil)
|
||||||
|
|
||||||
// If we didn't check the live database, do check state over ephemeral database,
|
// 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
|
// otherwise we would rewind past a persisted block (specific corner case is
|
||||||
// chain tracing from the genesis).
|
// chain tracing from the genesis).
|
||||||
if !readOnly {
|
if !readOnly {
|
||||||
statedb, err = state.New(current.Root(), database, nil)
|
statedb, err = state.New(current.Root(), database)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return statedb, noopReleaser, nil
|
return statedb, noopReleaser, nil
|
||||||
}
|
}
|
||||||
|
|
@ -111,7 +112,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
|
||||||
}
|
}
|
||||||
current = parent
|
current = parent
|
||||||
|
|
||||||
statedb, err = state.New(current.Root(), database, nil)
|
statedb, err = state.New(current.Root(), database)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +157,7 @@ func (eth *Ethereum) hashState(ctx context.Context, block *types.Block, reexec u
|
||||||
return nil, nil, fmt.Errorf("stateAtBlock commit failed, number %d root %v: %w",
|
return nil, nil, fmt.Errorf("stateAtBlock commit failed, number %d root %v: %w",
|
||||||
current.NumberU64(), current.Root().Hex(), err)
|
current.NumberU64(), current.Root().Hex(), err)
|
||||||
}
|
}
|
||||||
statedb, err = state.New(root, database, nil)
|
statedb, err = state.New(root, database)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("state reset after block %d failed: %v", current.NumberU64(), err)
|
return nil, nil, fmt.Errorf("state reset after block %d failed: %v", current.NumberU64(), err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ func createMiner(t *testing.T) *Miner {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("can't create new chain %v", err)
|
t.Fatalf("can't create new chain %v", err)
|
||||||
}
|
}
|
||||||
statedb, _ := state.New(bc.Genesis().Root(), bc.StateCache(), nil)
|
statedb, _ := state.New(bc.Genesis().Root(), bc.StateCache())
|
||||||
blockchain := &testBlockChain{bc.Genesis().Root(), chainConfig, statedb, 10000000, new(event.Feed)}
|
blockchain := &testBlockChain{bc.Genesis().Root(), chainConfig, statedb, 10000000, new(event.Feed)}
|
||||||
|
|
||||||
pool := legacypool.New(testTxPoolConfig, blockchain)
|
pool := legacypool.New(testTxPoolConfig, blockchain)
|
||||||
|
|
|
||||||
|
|
@ -222,7 +222,7 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bo
|
||||||
if logs := rlpHash(st.StateDB.Logs()); logs != common.Hash(post.Logs) {
|
if logs := rlpHash(st.StateDB.Logs()); logs != common.Hash(post.Logs) {
|
||||||
return fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, post.Logs)
|
return fmt.Errorf("post state logs hash mismatch: got %x, want %x", logs, post.Logs)
|
||||||
}
|
}
|
||||||
st.StateDB, _ = state.New(root, st.StateDB.Database(), st.Snapshots)
|
st.StateDB, _ = state.New(root, st.StateDB.Database())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -462,8 +462,8 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo
|
||||||
tconf.PathDB = pathdb.Defaults
|
tconf.PathDB = pathdb.Defaults
|
||||||
}
|
}
|
||||||
triedb := triedb.NewDatabase(db, tconf)
|
triedb := triedb.NewDatabase(db, tconf)
|
||||||
sdb := state.NewDatabaseWithNodeDB(db, triedb)
|
sdb := state.NewDatabase(triedb, nil)
|
||||||
statedb, _ := state.New(types.EmptyRootHash, sdb, nil)
|
statedb, _ := state.New(types.EmptyRootHash, sdb)
|
||||||
for addr, a := range accounts {
|
for addr, a := range accounts {
|
||||||
statedb.SetCode(addr, a.Code)
|
statedb.SetCode(addr, a.Code)
|
||||||
statedb.SetNonce(addr, a.Nonce)
|
statedb.SetNonce(addr, a.Nonce)
|
||||||
|
|
@ -486,7 +486,8 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo
|
||||||
}
|
}
|
||||||
snaps, _ = snapshot.New(snapconfig, db, triedb, root)
|
snaps, _ = snapshot.New(snapconfig, db, triedb, root)
|
||||||
}
|
}
|
||||||
statedb, _ = state.New(root, sdb, snaps)
|
sdb = state.NewDatabase(triedb, snaps)
|
||||||
|
statedb, _ = state.New(root, sdb)
|
||||||
return StateTestState{statedb, triedb, snaps}
|
return StateTestState{statedb, triedb, snaps}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ type backend interface {
|
||||||
// types of node backend as an entrypoint. It's responsible for all interactions
|
// types of node backend as an entrypoint. It's responsible for all interactions
|
||||||
// relevant with trie nodes and node preimages.
|
// relevant with trie nodes and node preimages.
|
||||||
type Database struct {
|
type Database struct {
|
||||||
|
disk ethdb.Database
|
||||||
config *Config // Configuration for trie database
|
config *Config // Configuration for trie database
|
||||||
preimages *preimageStore // The store for caching preimages
|
preimages *preimageStore // The store for caching preimages
|
||||||
backend backend // The backend for managing trie nodes
|
backend backend // The backend for managing trie nodes
|
||||||
|
|
@ -109,6 +110,7 @@ func NewDatabase(diskdb ethdb.Database, config *Config) *Database {
|
||||||
preimages = newPreimageStore(diskdb)
|
preimages = newPreimageStore(diskdb)
|
||||||
}
|
}
|
||||||
db := &Database{
|
db := &Database{
|
||||||
|
disk: diskdb,
|
||||||
config: config,
|
config: config,
|
||||||
preimages: preimages,
|
preimages: preimages,
|
||||||
}
|
}
|
||||||
|
|
@ -327,3 +329,8 @@ func (db *Database) SetBufferSize(size int) error {
|
||||||
func (db *Database) IsVerkle() bool {
|
func (db *Database) IsVerkle() bool {
|
||||||
return db.config.IsVerkle
|
return db.config.IsVerkle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disk returns the underlying disk database.
|
||||||
|
func (db *Database) Disk() ethdb.Database {
|
||||||
|
return db.disk
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue