Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions cmd/evm/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"encoding/json"
"fmt"
"io"
"math/big"
"os"
goruntime "runtime"
"runtime/pprof"
Expand Down Expand Up @@ -81,12 +82,13 @@ func runCmd(ctx *cli.Context) error {
}

var (
tracer *tracing.Hooks
debugLogger *logger.StructLogger
statedb *state.StateDB
chainConfig *params.ChainConfig
sender = common.StringToAddress("sender")
receiver = common.StringToAddress("receiver")
tracer *tracing.Hooks
debugLogger *logger.StructLogger
statedb *state.StateDB
chainConfig *params.ChainConfig
sender = common.StringToAddress("sender")
receiver = common.StringToAddress("receiver")
genesisConfig *core.Genesis
)
if ctx.Bool(MachineFlag.Name) {
tracer = logger.NewJSONLogger(logconfig, os.Stdout)
Expand All @@ -99,13 +101,15 @@ func runCmd(ctx *cli.Context) error {

if ctx.String(GenesisFlag.Name) != "" {
gen := readGenesis(ctx.String(GenesisFlag.Name))
genesisConfig = gen
db := rawdb.NewMemoryDatabase()
genesis := gen.ToBlock(db)
statedb, _ = state.New(genesis.Root(), state.NewDatabase(db))
chainConfig = gen.Config
} else {
db := rawdb.NewMemoryDatabase()
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(db))
genesisConfig = new(core.Genesis)
}
if ctx.String(SenderFlag.Name) != "" {
sender = common.HexToAddress(ctx.String(SenderFlag.Name))
Expand Down Expand Up @@ -156,12 +160,19 @@ func runCmd(ctx *cli.Context) error {
}

initialGas := ctx.Uint64(GasFlag.Name)
if genesisConfig.GasLimit != 0 {
initialGas = genesisConfig.GasLimit
}
runtimeConfig := runtime.Config{
Origin: sender,
State: statedb,
GasLimit: initialGas,
GasPrice: flags.GlobalBig(ctx, PriceFlag.Name),
Value: flags.GlobalBig(ctx, ValueFlag.Name),
Origin: sender,
State: statedb,
GasLimit: initialGas,
GasPrice: flags.GlobalBig(ctx, PriceFlag.Name),
Value: flags.GlobalBig(ctx, ValueFlag.Name),
Difficulty: genesisConfig.Difficulty,
Time: genesisConfig.Timestamp,
Coinbase: genesisConfig.Coinbase,
BlockNumber: new(big.Int).SetUint64(genesisConfig.Number),
EVMConfig: vm.Config{
Tracer: tracer,
},
Expand Down Expand Up @@ -197,7 +208,7 @@ func runCmd(ctx *cli.Context) error {
execTime := time.Since(tstart)

if ctx.Bool(DumpFlag.Name) {
statedb.IntermediateRoot(true)
statedb.Commit(genesisConfig.Number, true)
fmt.Println(string(statedb.Dump(nil)))
}

Expand Down
2 changes: 1 addition & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
log.Crit("Failed to write block into disk", "err", err)
}
// Commit all cached state changes into underlying memory database.
root, err := state.Commit(bc.chainConfig.IsEIP158(block.Number()))
root, err := state.Commit(block.NumberU64(), bc.chainConfig.IsEIP158(block.Number()))
if err != nil {
return NonStatTy, err
}
Expand Down
2 changes: 1 addition & 1 deletion core/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error {
blockchain.chainmu.MustLock()
rawdb.WriteTd(blockchain.db, block.Hash(), block.NumberU64(), new(big.Int).Add(block.Difficulty(), blockchain.GetTdByHash(block.ParentHash())))
rawdb.WriteBlock(blockchain.db, block)
statedb.Commit(true)
statedb.Commit(block.NumberU64(), true)
blockchain.chainmu.Unlock()
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
// Finalize and seal the block
block, _ := b.engine.Finalize(chainReader, b.header, statedb, statedb.Copy(), b.txs, b.uncles, b.receipts)
// Write state changes to db
root, err := statedb.Commit(config.IsEIP158(b.header.Number))
root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number))
if err != nil {
panic(fmt.Sprintf("state write error: %v", err))
}
Expand Down
2 changes: 1 addition & 1 deletion core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
}
}

statedb.Commit(false)
statedb.Commit(0, false)
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The block number parameter should be g.Number instead of hardcoded 0. The Genesis struct supports non-zero Number values for consensus tests (as documented in the struct comments), and ToBlock should respect this value when committing state. Using a hardcoded 0 will cause incorrect block context for consensus tests that use non-zero genesis block numbers.

Suggested change
statedb.Commit(0, false)
statedb.Commit(g.Number, false)

Copilot uses AI. Check for mistakes.
statedb.Database().TrieDB().Commit(root, true)

return types.NewBlock(head, nil, nil, trie.NewStackTrie(nil))
Expand Down
4 changes: 2 additions & 2 deletions core/state/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,11 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
}
obj := newObject(s, addr, data)
if !conf.SkipCode {
account.Code = obj.Code(s.db)
account.Code = obj.Code()
}
if !conf.SkipStorage {
account.Storage = make(map[common.Hash]string)
tr, err := obj.getTrie(s.db)
tr, err := obj.getTrie()
if err != nil {
log.Error("Failed to load storage trie", "err", err)
continue
Expand Down
36 changes: 18 additions & 18 deletions core/state/state_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ func (s *stateObject) touch() {
// getTrie returns the associated storage trie. The trie will be opened
// if it's not loaded previously. An error will be returned if trie can't
// be loaded.
func (s *stateObject) getTrie(db Database) (Trie, error) {
func (s *stateObject) getTrie() (Trie, error) {
if s.trie == nil {
tr, err := db.OpenStorageTrie(s.db.originalRoot, s.addrHash, s.data.Root)
tr, err := s.db.db.OpenStorageTrie(s.db.originalRoot, s.addrHash, s.data.Root)
if err != nil {
return nil, err
}
Expand All @@ -164,17 +164,17 @@ func (s *stateObject) getTrie(db Database) (Trie, error) {
}

// GetState retrieves a value from the account storage trie.
func (s *stateObject) GetState(db Database, key common.Hash) common.Hash {
func (s *stateObject) GetState(key common.Hash) common.Hash {
// If we have a dirty value for this state entry, return it
value, dirty := s.dirtyStorage[key]
if dirty {
return value
}
// Otherwise return the entry's original value
return s.GetCommittedState(db, key)
return s.GetCommittedState(key)
}

func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash {
func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
// If we have a pending write or clean cached, return that
if value, pending := s.pendingStorage[key]; pending {
return value
Expand All @@ -194,7 +194,7 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has
// Track the amount of time wasted on reading the storage trie
start := time.Now()
// Otherwise load the value from the database
tr, err := s.getTrie(db)
tr, err := s.getTrie()
if err != nil {
s.setError(err)
return common.Hash{}
Expand All @@ -218,10 +218,10 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has
}

// SetState updates a value in account storage.
func (s *stateObject) SetState(db Database, key, value common.Hash) common.Hash {
func (s *stateObject) SetState(key, value common.Hash) common.Hash {
// If the new value is the same as old, don't set. Otherwise, track only the
// dirty changes, supporting reverting all of it back to no change.
prev := s.GetState(db, key)
prev := s.GetState(key)
if prev == value {
return prev
}
Expand Down Expand Up @@ -253,15 +253,15 @@ func (s *stateObject) finalise() {
// updateTrie writes cached storage modifications into the object's storage trie.
// It will return nil if the trie has not been loaded and no changes have been
// made. An error will be returned if the trie can't be loaded/updated correctly.
func (s *stateObject) updateTrie(db Database) (Trie, error) {
func (s *stateObject) updateTrie() (Trie, error) {
// Make sure all dirty slots are finalized into the pending storage area
s.finalise()
if len(s.pendingStorage) == 0 {
return s.trie, nil
}
// Track the amount of time wasted on updating the storage trie
defer func(start time.Time) { s.db.StorageUpdates += time.Since(start) }(time.Now())
tr, err := s.getTrie(db)
tr, err := s.getTrie()
if err != nil {
s.setError(err)
return nil, err
Expand Down Expand Up @@ -298,8 +298,8 @@ func (s *stateObject) updateTrie(db Database) (Trie, error) {

// UpdateRoot sets the trie root to the current root hash of. An error
// will be returned if trie root hash is not computed correctly.
func (s *stateObject) updateRoot(db Database) {
tr, err := s.updateTrie(db)
func (s *stateObject) updateRoot() {
tr, err := s.updateTrie()
if err != nil {
s.setError(fmt.Errorf("updateRoot (%x) error: %w", s.address, err))
return
Expand All @@ -315,9 +315,9 @@ func (s *stateObject) updateRoot(db Database) {

// CommitTrie the storage trie of the object to dwb.
// This updates the trie root.
func (s *stateObject) commitTrie(db Database) (*trie.NodeSet, error) {
func (s *stateObject) commitTrie() (*trie.NodeSet, error) {
// If nothing changed, don't bother with hashing anything
tr, err := s.updateTrie(db)
tr, err := s.updateTrie()
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -390,14 +390,14 @@ func (s *stateObject) Address() common.Address {
}

// Code returns the contract code associated with this object, if any.
func (s *stateObject) Code(db Database) []byte {
func (s *stateObject) Code() []byte {
if s.code != nil {
return s.code
}
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
return nil
}
code, err := db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash()))
code, err := s.db.db.ContractCode(s.addrHash, common.BytesToHash(s.CodeHash()))
if err != nil {
s.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err))
}
Expand All @@ -408,14 +408,14 @@ func (s *stateObject) Code(db Database) []byte {
// CodeSize returns the size of the contract code associated with this object,
// or zero if none. This method is an almost mirror of Code, but uses a cache
// inside the database to avoid loading codes seen recently.
func (s *stateObject) CodeSize(db Database) int {
func (s *stateObject) CodeSize() int {
if s.code != nil {
return len(s.code)
}
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
return 0
}
size, err := db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash()))
size, err := s.db.db.ContractCodeSize(s.addrHash, common.BytesToHash(s.CodeHash()))
if err != nil {
s.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err))
}
Expand Down
12 changes: 6 additions & 6 deletions core/state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestDump(t *testing.T) {
// write some of them to the trie
s.state.updateStateObject(obj1)
s.state.updateStateObject(obj2)
s.state.Commit(false)
s.state.Commit(0, false)

// check that DumpToCollector contains the state objects that are in trie
got := string(s.state.Dump(nil))
Expand Down Expand Up @@ -111,7 +111,7 @@ func TestIterativeDump(t *testing.T) {
// write some of them to the trie
s.state.updateStateObject(obj1)
s.state.updateStateObject(obj2)
s.state.Commit(false)
s.state.Commit(0, false)

b := &bytes.Buffer{}
s.state.IterativeDump(nil, json.NewEncoder(b))
Expand All @@ -136,7 +136,7 @@ func TestNull(t *testing.T) {
var value common.Hash

s.state.SetState(address, common.Hash{}, value)
s.state.Commit(false)
s.state.Commit(0, false)

if value := s.state.GetState(address, common.Hash{}); value != (common.Hash{}) {
t.Errorf("expected empty current value, got %x", value)
Expand Down Expand Up @@ -209,7 +209,7 @@ func TestSnapshot2(t *testing.T) {
so0.deleted = false
state.setStateObject(so0)

root, _ := state.Commit(false)
root, _ := state.Commit(0, false)
state.Reset(root)

// and one with deleted == true
Expand All @@ -231,8 +231,8 @@ func TestSnapshot2(t *testing.T) {

so0Restored := state.getStateObject(stateobjaddr0)
// Update lazily-loaded values before comparing.
so0Restored.GetState(state.db, storageaddr)
so0Restored.Code(state.db)
so0Restored.GetState(storageaddr)
so0Restored.Code()
// non-deleted is equal (restored)
compareStateObjects(so0Restored, so0, t)

Expand Down
Loading
Loading