Skip to content

Commit

Permalink
all: introduce state reader interface
Browse files Browse the repository at this point in the history
  • Loading branch information
rjl493456442 committed May 23, 2024
1 parent 4235c05 commit a985ac2
Show file tree
Hide file tree
Showing 31 changed files with 560 additions and 317 deletions.
9 changes: 5 additions & 4 deletions cmd/evm/internal/t8ntool/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
}
// Re-create statedb instance with new root upon the updated database
// for accessing latest states.
statedb, err = state.New(root, statedb.Database(), nil)
statedb, err = state.New(root, statedb.Database())
if err != nil {
return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err))
}
Expand All @@ -379,8 +379,9 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
}

func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB {
sdb := state.NewDatabaseWithConfig(db, &triedb.Config{Preimages: true})
statedb, _ := state.New(types.EmptyRootHash, sdb, nil)
tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
sdb := state.NewDatabase(db, tdb, nil)
statedb, _ := state.New(types.EmptyRootHash, sdb)
for addr, a := range accounts {
statedb.SetCode(addr, a.Code)
statedb.SetNonce(addr, a.Nonce)
Expand All @@ -391,7 +392,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB
}
// Commit and re-open to start with a clean state.
root, _ := statedb.Commit(0, false)
statedb, _ = state.New(root, sdb, nil)
statedb, _ = state.New(root, sdb)
return statedb
}

Expand Down
6 changes: 3 additions & 3 deletions cmd/evm/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ func runCmd(ctx *cli.Context) error {
})
defer triedb.Close()
genesis := genesisConfig.MustCommit(db, triedb)
sdb := state.NewDatabaseWithNodeDB(db, triedb)
statedb, _ = state.New(genesis.Root(), sdb, nil)
sdb := state.NewDatabase(db, triedb, nil)
statedb, _ = state.New(genesis.Root(), sdb)
chainConfig = genesisConfig.Config

if ctx.String(SenderFlag.Name) != "" {
Expand Down Expand Up @@ -277,7 +277,7 @@ func runCmd(ctx *cli.Context) error {
fmt.Printf("Failed to commit changes %v\n", err)
return err
}
dumpdb, err := state.New(root, sdb, nil)
dumpdb, err := state.New(root, sdb)
if err != nil {
fmt.Printf("Failed to open statedb %v\n", err)
return err
Expand Down
2 changes: 1 addition & 1 deletion cmd/geth/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ func dump(ctx *cli.Context) error {
triedb := utils.MakeTrieDatabase(ctx, db, true, true, false) // always enable preimage lookup
defer triedb.Close()

state, err := state.New(root, state.NewDatabaseWithNodeDB(db, triedb), nil)
state, err := state.New(root, state.NewDatabase(db, triedb, nil))
if err != nil {
return err
}
Expand Down
14 changes: 10 additions & 4 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ type BlockChain struct {
lastWrite uint64 // Last block when the state was flushed
flushInterval atomic.Int64 // Time interval (processing time) after which to flush a state
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

hc *HeaderChain
Expand Down Expand Up @@ -304,7 +304,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
}
bc.flushInterval.Store(int64(cacheConfig.TrieTimeLimit))
bc.forker = NewForkChoice(bc, shouldPreserve)
bc.stateCache = state.NewDatabaseWithNodeDB(bc.db, bc.triedb)
bc.stateDb = state.NewDatabase(bc.db, bc.triedb, nil)
bc.validator = NewBlockValidator(chainConfig, bc, engine)
bc.prefetcher = newStatePrefetcher(chainConfig, bc, engine)
bc.processor = NewStateProcessor(chainConfig, bc, engine)
Expand Down Expand Up @@ -447,7 +447,13 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
AsyncBuild: !bc.cacheConfig.SnapshotWait,
}
bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root)

// Register the snapshot into statedb. It's an ugly hack as state snapshot
// is constructed after stateDb. TODO(rjl493456442) improve the construction
// logic.
bc.stateDb.SetSnapshot(bc.snaps)
}

// Rewind the chain in case of an incompatible config upgrade.
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
Expand Down Expand Up @@ -1799,7 +1805,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
if parent == nil {
parent = bc.GetHeader(block.ParentHash(), block.NumberU64()-1)
}
statedb, err := state.New(parent.Root, bc.stateCache, bc.snaps)
statedb, err := state.New(parent.Root, bc.stateDb)
if err != nil {
return it.index, err
}
Expand All @@ -1818,7 +1824,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
var followupInterrupt atomic.Bool
if !bc.cacheConfig.TrieCleanNoPrefetch {
if followup, err := it.peek(); followup != nil && err == nil {
throwaway, _ := state.New(parent.Root, bc.stateCache, bc.snaps)
throwaway, _ := state.New(parent.Root, bc.stateDb)

go func(start time.Time, followup *types.Block, throwaway *state.StateDB) {
// Disable tracing for prefetcher executions.
Expand Down
11 changes: 4 additions & 7 deletions core/blockchain_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
func (bc *BlockChain) HasState(hash common.Hash) bool {
_, err := bc.stateCache.OpenTrie(hash)
_, err := bc.stateDb.OpenTrie(hash)
return err == nil
}

Expand Down Expand Up @@ -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
// new code scheme.
func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) ([]byte, error) {
type codeReader interface {
ContractCodeWithPrefix(address common.Address, codeHash common.Hash) ([]byte, error)
}
// TODO(rjl493456442) The associated account address is also required
// in Verkle scheme. Fix it once snap-sync is supported for Verkle.
return bc.stateCache.(codeReader).ContractCodeWithPrefix(common.Address{}, hash)
return bc.stateDb.ContractCodeWithPrefix(common.Address{}, hash)
}

// State returns a new mutable state based on the current HEAD block.
Expand All @@ -356,7 +353,7 @@ func (bc *BlockChain) State() (*state.StateDB, error) {

// StateAt returns a new mutable state based on a particular point in time.
func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
return state.New(root, bc.stateCache, bc.snaps)
return state.New(root, bc.stateDb)
}

// Config retrieves the chain's fork configuration.
Expand All @@ -382,7 +379,7 @@ func (bc *BlockChain) Processor() Processor {

// StateCache returns the caching database underpinning the blockchain instance.
func (bc *BlockChain) StateCache() state.Database {
return bc.stateCache
return bc.stateDb
}

// GasLimit returns the gas limit of the current HEAD block.
Expand Down
4 changes: 2 additions & 2 deletions core/blockchain_sethead_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package core

import (
"fmt"
"github.com/ethereum/go-ethereum/core/state"
"math/big"
"path/filepath"
"strings"
Expand All @@ -30,7 +31,6 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -2040,7 +2040,7 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme
dbconfig.HashDB = hashdb.Defaults
}
chain.triedb = triedb.NewDatabase(chain.db, dbconfig)
chain.stateCache = state.NewDatabaseWithNodeDB(chain.db, chain.triedb)
chain.stateDb = state.NewDatabase(chain.db, chain.triedb, chain.snaps)

// Force run a freeze cycle
type freezer interface {
Expand Down
2 changes: 1 addition & 1 deletion core/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
}
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 {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
defer triedb.Close()

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(db, triedb, nil))
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -475,7 +475,7 @@ func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine
}

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(db, trdb, nil))
if err != nil {
panic(err)
}
Expand Down
6 changes: 3 additions & 3 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
}
// Create an ephemeral in-memory database for computing hash,
// all the derived states will be discarded to not pollute disk.
db := state.NewDatabaseWithConfig(rawdb.NewMemoryDatabase(), config)
statedb, err := state.New(types.EmptyRootHash, db, nil)
db := rawdb.NewMemoryDatabase()
statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(db, triedb.NewDatabase(db, config), nil))
if err != nil {
return common.Hash{}, err
}
Expand All @@ -149,7 +149,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
// states will be persisted into the given database. Also, the genesis state
// specification will be flushed as well.
func flushAlloc(ga *types.GenesisAlloc, db ethdb.Database, triedb *triedb.Database, blockhash common.Hash) error {
statedb, err := state.New(types.EmptyRootHash, state.NewDatabaseWithNodeDB(db, triedb), nil)
statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(db, triedb, nil))
if err != nil {
return err
}
Expand Down

0 comments on commit a985ac2

Please sign in to comment.