Skip to content

Commit df98ba4

Browse files
committed
all: implement codedb
1 parent e58c785 commit df98ba4

28 files changed

+307
-198
lines changed

cmd/evm/internal/t8ntool/execution.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/ethereum/go-ethereum/core"
3131
"github.com/ethereum/go-ethereum/core/rawdb"
3232
"github.com/ethereum/go-ethereum/core/state"
33+
"github.com/ethereum/go-ethereum/core/state/codedb"
3334
"github.com/ethereum/go-ethereum/core/tracing"
3435
"github.com/ethereum/go-ethereum/core/types"
3536
"github.com/ethereum/go-ethereum/core/vm"
@@ -379,7 +380,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
379380

380381
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, isBintrie bool) *state.StateDB {
381382
tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true, IsVerkle: isBintrie})
382-
sdb := state.NewDatabase(tdb, nil)
383+
sdb := state.NewDatabase(tdb, codedb.New(db))
383384

384385
root := types.EmptyRootHash
385386
if isBintrie {

cmd/evm/runner.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/ethereum/go-ethereum/core"
3636
"github.com/ethereum/go-ethereum/core/rawdb"
3737
"github.com/ethereum/go-ethereum/core/state"
38+
"github.com/ethereum/go-ethereum/core/state/codedb"
3839
"github.com/ethereum/go-ethereum/core/tracing"
3940
"github.com/ethereum/go-ethereum/core/types"
4041
"github.com/ethereum/go-ethereum/core/vm"
@@ -226,8 +227,9 @@ func runCmd(ctx *cli.Context) error {
226227
HashDB: hashdb.Defaults,
227228
})
228229
defer triedb.Close()
230+
229231
genesis := genesisConfig.MustCommit(db, triedb)
230-
sdb := state.NewDatabase(triedb, nil)
232+
sdb := state.NewDatabase(triedb, codedb.New(db))
231233
prestate, _ = state.New(genesis.Root(), sdb)
232234
chainConfig = genesisConfig.Config
233235

cmd/geth/chaincmd.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
"github.com/ethereum/go-ethereum/core/history"
3838
"github.com/ethereum/go-ethereum/core/rawdb"
3939
"github.com/ethereum/go-ethereum/core/state"
40+
"github.com/ethereum/go-ethereum/core/state/codedb"
4041
"github.com/ethereum/go-ethereum/core/types"
4142
"github.com/ethereum/go-ethereum/crypto"
4243
"github.com/ethereum/go-ethereum/ethdb"
@@ -650,7 +651,7 @@ func dump(ctx *cli.Context) error {
650651
triedb := utils.MakeTrieDatabase(ctx, stack, db, true, true, false) // always enable preimage lookup
651652
defer triedb.Close()
652653

653-
state, err := state.New(root, state.NewDatabase(triedb, nil))
654+
state, err := state.New(root, state.NewDatabase(triedb, codedb.New(db)))
654655
if err != nil {
655656
return err
656657
}

core/blockchain.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"github.com/ethereum/go-ethereum/core/history"
4040
"github.com/ethereum/go-ethereum/core/rawdb"
4141
"github.com/ethereum/go-ethereum/core/state"
42+
"github.com/ethereum/go-ethereum/core/state/codedb"
4243
"github.com/ethereum/go-ethereum/core/state/snapshot"
4344
"github.com/ethereum/go-ethereum/core/stateless"
4445
"github.com/ethereum/go-ethereum/core/tracing"
@@ -300,7 +301,7 @@ type BlockChain struct {
300301
lastWrite uint64 // Last block when the state was flushed
301302
flushInterval atomic.Int64 // Time interval (processing time) after which to flush a state
302303
triedb *triedb.Database // The database handler for maintaining trie nodes.
303-
statedb *state.CachingDB // State database to reuse between imports (contains state cache)
304+
codedb *codedb.Database // The database handler for maintaining contract codes
304305
txIndexer *txIndexer // Transaction indexer, might be nil if not enabled
305306

306307
hc *HeaderChain
@@ -381,6 +382,7 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine,
381382
cfg: cfg,
382383
db: db,
383384
triedb: triedb,
385+
codedb: codedb.New(db),
384386
triegc: prque.New[int64, common.Hash](nil),
385387
chainmu: syncx.NewClosableMutex(),
386388
bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit),
@@ -397,7 +399,6 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine,
397399
return nil, err
398400
}
399401
bc.flushInterval.Store(int64(cfg.TrieTimeLimit))
400-
bc.statedb = state.NewDatabase(bc.triedb, nil)
401402
bc.validator = NewBlockValidator(chainConfig, bc)
402403
bc.prefetcher = newStatePrefetcher(chainConfig, bc.hc)
403404
bc.processor = NewStateProcessor(bc.hc)
@@ -574,9 +575,6 @@ func (bc *BlockChain) setupSnapshot() {
574575
AsyncBuild: !bc.cfg.SnapshotWait,
575576
}
576577
bc.snaps, _ = snapshot.New(snapconfig, bc.db, bc.triedb, head.Root)
577-
578-
// Re-initialize the state database with snapshot
579-
bc.statedb = state.NewDatabase(bc.triedb, bc.snaps)
580578
}
581579
}
582580

@@ -2008,11 +2006,12 @@ func (bc *BlockChain) ProcessBlock(parentRoot common.Hash, block *types.Block, s
20082006
startTime = time.Now()
20092007
statedb *state.StateDB
20102008
interrupt atomic.Bool
2009+
sdb = state.NewDatabase(bc.triedb, bc.codedb).WithSnapshot(bc.snaps)
20112010
)
20122011
defer interrupt.Store(true) // terminate the prefetch at the end
20132012

20142013
if bc.cfg.NoPrefetch {
2015-
statedb, err = state.New(parentRoot, bc.statedb)
2014+
statedb, err = state.New(parentRoot, sdb)
20162015
if err != nil {
20172016
return nil, err
20182017
}
@@ -2022,15 +2021,15 @@ func (bc *BlockChain) ProcessBlock(parentRoot common.Hash, block *types.Block, s
20222021
//
20232022
// Note: the main processor and prefetcher share the same reader with a local
20242023
// cache for mitigating the overhead of state access.
2025-
prefetch, process, err := bc.statedb.ReadersWithCacheStats(parentRoot)
2024+
prefetch, process, err := sdb.ReadersWithCacheStats(parentRoot)
20262025
if err != nil {
20272026
return nil, err
20282027
}
2029-
throwaway, err := state.NewWithReader(parentRoot, bc.statedb, prefetch)
2028+
throwaway, err := state.NewWithReader(parentRoot, sdb, prefetch)
20302029
if err != nil {
20312030
return nil, err
20322031
}
2033-
statedb, err = state.NewWithReader(parentRoot, bc.statedb, process)
2032+
statedb, err = state.NewWithReader(parentRoot, sdb, process)
20342033
if err != nil {
20352034
return nil, err
20362035
}

core/blockchain_reader.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
2727
"github.com/ethereum/go-ethereum/core/rawdb"
2828
"github.com/ethereum/go-ethereum/core/state"
29+
"github.com/ethereum/go-ethereum/core/state/codedb"
2930
"github.com/ethereum/go-ethereum/core/state/snapshot"
3031
"github.com/ethereum/go-ethereum/core/types"
3132
"github.com/ethereum/go-ethereum/core/vm"
@@ -371,7 +372,7 @@ func (bc *BlockChain) TxIndexDone() bool {
371372

372373
// HasState checks if state trie is fully present in the database or not.
373374
func (bc *BlockChain) HasState(hash common.Hash) bool {
374-
_, err := bc.statedb.OpenTrie(hash)
375+
_, err := bc.triedb.NodeReader(hash)
375376
return err == nil
376377
}
377378

@@ -403,7 +404,7 @@ func (bc *BlockChain) stateRecoverable(root common.Hash) bool {
403404
func (bc *BlockChain) ContractCodeWithPrefix(hash common.Hash) []byte {
404405
// TODO(rjl493456442) The associated account address is also required
405406
// in Verkle scheme. Fix it once snap-sync is supported for Verkle.
406-
return bc.statedb.ContractCodeWithPrefix(common.Address{}, hash)
407+
return bc.codedb.Reader().CodeWithPrefix(common.Address{}, hash)
407408
}
408409

409410
// State returns a new mutable state based on the current HEAD block.
@@ -413,14 +414,14 @@ func (bc *BlockChain) State() (*state.StateDB, error) {
413414

414415
// StateAt returns a new mutable state based on a particular point in time.
415416
func (bc *BlockChain) StateAt(root common.Hash) (*state.StateDB, error) {
416-
return state.New(root, bc.statedb)
417+
return state.New(root, state.NewDatabase(bc.triedb, bc.codedb).WithSnapshot(bc.snaps))
417418
}
418419

419420
// HistoricState returns a historic state specified by the given root.
420421
// Live states are not available and won't be served, please use `State`
421422
// or `StateAt` instead.
422423
func (bc *BlockChain) HistoricState(root common.Hash) (*state.StateDB, error) {
423-
return state.New(root, state.NewHistoricDatabase(bc.db, bc.triedb))
424+
return state.New(root, state.NewHistoricDatabase(bc.triedb, bc.codedb))
424425
}
425426

426427
// Config retrieves the chain's fork configuration.
@@ -444,11 +445,6 @@ func (bc *BlockChain) Processor() Processor {
444445
return bc.processor
445446
}
446447

447-
// StateCache returns the caching database underpinning the blockchain instance.
448-
func (bc *BlockChain) StateCache() state.Database {
449-
return bc.statedb
450-
}
451-
452448
// GasLimit returns the gas limit of the current HEAD block.
453449
func (bc *BlockChain) GasLimit() uint64 {
454450
return bc.CurrentBlock().GasLimit
@@ -492,6 +488,11 @@ func (bc *BlockChain) TrieDB() *triedb.Database {
492488
return bc.triedb
493489
}
494490

491+
// CodeDB retrieves the low level contract code database used for data storage.
492+
func (bc *BlockChain) CodeDB() *codedb.Database {
493+
return bc.codedb
494+
}
495+
495496
// HeaderChain returns the underlying header chain.
496497
func (bc *BlockChain) HeaderChain() *HeaderChain {
497498
return bc.hc

core/blockchain_sethead_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030
"github.com/ethereum/go-ethereum/common"
3131
"github.com/ethereum/go-ethereum/consensus/ethash"
3232
"github.com/ethereum/go-ethereum/core/rawdb"
33-
"github.com/ethereum/go-ethereum/core/state"
3433
"github.com/ethereum/go-ethereum/core/types"
3534
"github.com/ethereum/go-ethereum/ethdb/pebble"
3635
"github.com/ethereum/go-ethereum/params"
@@ -2041,7 +2040,6 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme
20412040
dbconfig.HashDB = hashdb.Defaults
20422041
}
20432042
chain.triedb = triedb.NewDatabase(chain.db, dbconfig)
2044-
chain.statedb = state.NewDatabase(chain.triedb, chain.snaps)
20452043

20462044
// Force run a freeze cycle
20472045
type freezer interface {

core/blockchain_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
156156
}
157157
return err
158158
}
159-
statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), blockchain.statedb)
159+
sdb := state.NewDatabase(blockchain.triedb, blockchain.codedb)
160+
statedb, err := state.New(blockchain.GetBlockByHash(block.ParentHash()).Root(), sdb)
160161
if err != nil {
161162
return err
162163
}

core/chain_makers.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"github.com/ethereum/go-ethereum/consensus/misc/eip4844"
2828
"github.com/ethereum/go-ethereum/core/rawdb"
2929
"github.com/ethereum/go-ethereum/core/state"
30+
"github.com/ethereum/go-ethereum/core/state/codedb"
3031
"github.com/ethereum/go-ethereum/core/types"
3132
"github.com/ethereum/go-ethereum/core/vm"
3233
"github.com/ethereum/go-ethereum/ethdb"
@@ -432,9 +433,10 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
432433
}
433434
triedb := triedb.NewDatabase(db, triedbConfig)
434435
defer triedb.Close()
436+
codedb := codedb.New(db)
435437

436438
for i := 0; i < n; i++ {
437-
statedb, err := state.New(parent.Root(), state.NewDatabase(triedb, nil))
439+
statedb, err := state.New(parent.Root(), state.NewDatabase(triedb, codedb))
438440
if err != nil {
439441
panic(err)
440442
}

core/genesis.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/ethereum/go-ethereum/common/math"
3030
"github.com/ethereum/go-ethereum/core/rawdb"
3131
"github.com/ethereum/go-ethereum/core/state"
32+
"github.com/ethereum/go-ethereum/core/state/codedb"
3233
"github.com/ethereum/go-ethereum/core/tracing"
3334
"github.com/ethereum/go-ethereum/core/types"
3435
"github.com/ethereum/go-ethereum/crypto"
@@ -145,7 +146,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
145146
emptyRoot = types.EmptyVerkleHash
146147
}
147148
db := rawdb.NewMemoryDatabase()
148-
statedb, err := state.New(emptyRoot, state.NewDatabase(triedb.NewDatabase(db, config), nil))
149+
statedb, err := state.New(emptyRoot, state.NewDatabase(triedb.NewDatabase(db, config), codedb.New(db)))
149150
if err != nil {
150151
return common.Hash{}, err
151152
}
@@ -164,12 +165,12 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
164165

165166
// flushAlloc is very similar with hash, but the main difference is all the
166167
// generated states will be persisted into the given database.
167-
func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, error) {
168+
func flushAlloc(ga *types.GenesisAlloc, db ethdb.KeyValueStore, triedb *triedb.Database) (common.Hash, error) {
168169
emptyRoot := types.EmptyRootHash
169170
if triedb.IsVerkle() {
170171
emptyRoot = types.EmptyVerkleHash
171172
}
172-
statedb, err := state.New(emptyRoot, state.NewDatabase(triedb, nil))
173+
statedb, err := state.New(emptyRoot, state.NewDatabase(triedb, codedb.New(db)))
173174
if err != nil {
174175
return common.Hash{}, err
175176
}
@@ -552,7 +553,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo
552553
return nil, errors.New("can't start clique chain without signers")
553554
}
554555
// flush the data to disk and compute the state root
555-
root, err := flushAlloc(&g.Alloc, triedb)
556+
root, err := flushAlloc(&g.Alloc, db, triedb)
556557
if err != nil {
557558
return nil, err
558559
}

0 commit comments

Comments
 (0)