Skip to content

Commit

Permalink
core, trie: Expose block number to statedb (#593)
Browse files Browse the repository at this point in the history
* core/state: clean up: db already exist in stateObject

* core, trie: statedb also commit the block number
  • Loading branch information
Francesco4203 authored and huyngopt1994 committed Oct 25, 2024
1 parent 6d2fa7a commit bafb899
Show file tree
Hide file tree
Showing 28 changed files with 115 additions and 111 deletions.
4 changes: 2 additions & 2 deletions cmd/evm/internal/t8ntool/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
statedb.AddBalance(pre.Env.Coinbase, minerReward)
}
// Commit block
root, err := statedb.Commit(chainConfig.IsEIP158(vmContext.BlockNumber))
root, err := statedb.Commit(vmContext.BlockNumber.Uint64(), chainConfig.IsEIP158(vmContext.BlockNumber))
if err != nil {
fmt.Fprintf(os.Stderr, "Could not commit state: %v", err)
return nil, nil, NewError(ErrorEVM, fmt.Errorf("could not commit state: %v", err))
Expand Down Expand Up @@ -273,7 +273,7 @@ func MakePreState(db ethdb.Database, accounts core.GenesisAlloc) *state.StateDB
}
}
// Commit and re-open to start with a clean state.
root, _ := statedb.Commit(false)
root, _ := statedb.Commit(0, false)
statedb, _ = state.New(root, sdb, nil)
return statedb
}
Expand Down
7 changes: 4 additions & 3 deletions cmd/evm/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import (
"bytes"
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/eth/tracers/logger"
"github.com/ethereum/go-ethereum/internal/flags"
"io/ioutil"
"math/big"
"os"
Expand All @@ -30,6 +28,9 @@ import (
"testing"
"time"

"github.com/ethereum/go-ethereum/eth/tracers/logger"
"github.com/ethereum/go-ethereum/internal/flags"

"github.com/ethereum/go-ethereum/cmd/evm/internal/compiler"
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -269,7 +270,7 @@ func runCmd(ctx *cli.Context) error {
output, leftOverGas, stats, err := timedExec(bench, execFunc)

if ctx.Bool(DumpFlag.Name) {
statedb.Commit(true)
statedb.Commit(0, true)
statedb.IntermediateRoot(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 @@ -1554,7 +1554,7 @@ func (bc *BlockChain) writeBlockWithState(
}
// Commit all cached state changes into underlying memory database.
dirtyAccounts := state.DirtyAccounts(block.Hash(), block.NumberU64())
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 @@ -180,7 +180,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.GetTd(block.ParentHash(), block.NumberU64()-1)))
rawdb.WriteBlock(blockchain.db, block)
statedb.Commit(false)
statedb.Commit(block.NumberU64(), false)
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 @@ -318,7 +318,7 @@ func generateChain(
}

// 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
4 changes: 2 additions & 2 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (ga *GenesisAlloc) deriveHash() (common.Hash, error) {
statedb.SetState(addr, key, value)
}
}
return statedb.Commit(false)
return statedb.Commit(0, false)
}

// flush is very similar with deriveHash, but the main difference is
Expand All @@ -117,7 +117,7 @@ func (ga *GenesisAlloc) flush(db ethdb.Database, triedb *trie.Database) error {
}
}
// Commit current state, return the root hash.
root, err := statedb.Commit(false)
root, err := statedb.Commit(0, false)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions core/state/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,11 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
addr := common.BytesToAddress(addrBytes)
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)
storageIt := trie.NewIterator(obj.getTrie(s.db).NodeIterator(nil))
storageIt := trie.NewIterator(obj.getTrie().NodeIterator(nil))
for storageIt.Next() {
_, content, _, err := rlp.Split(storageIt.Value)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion core/state/snapshot/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ func (dl *diskLayer) generateRange(trieID *trie.ID, prefix []byte, kind string,
}
root, nodes, _ := snapTrie.Commit(false)
if nodes != nil {
snapTrieDb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes), nil)
snapTrieDb.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), nil)
}
snapTrieDb.Commit(root, false)
}
Expand Down
2 changes: 1 addition & 1 deletion core/state/snapshot/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func (t *testHelper) Commit() common.Hash {
if nodes != nil {
t.nodes.Merge(nodes)
}
t.triedb.Update(root, types.EmptyRootHash, t.nodes, nil)
t.triedb.Update(root, types.EmptyRootHash, 0, t.nodes, nil)
t.triedb.Commit(root, false)
return root
}
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 @@ -155,7 +155,7 @@ func (s *stateObject) touch() {
}
}

func (s *stateObject) getTrie(db Database) Trie {
func (s *stateObject) getTrie() Trie {
if s.trie == nil {
// Try fetching from prefetcher first
// We don't prefetch empty tries
Expand All @@ -166,9 +166,9 @@ func (s *stateObject) getTrie(db Database) Trie {
}
if s.trie == nil {
var err error
s.trie, err = db.OpenStorageTrie(s.db.originalRoot, s.addrHash, s.data.Root)
s.trie, err = s.db.db.OpenStorageTrie(s.db.originalRoot, s.addrHash, s.data.Root)
if err != nil {
s.trie, _ = db.OpenStorageTrie(s.db.originalRoot, s.addrHash, common.Hash{})
s.trie, _ = s.db.db.OpenStorageTrie(s.db.originalRoot, s.addrHash, common.Hash{})
s.setError(fmt.Errorf("can't create storage trie: %v", err))
}
}
Expand All @@ -177,7 +177,7 @@ func (s *stateObject) getTrie(db Database) Trie {
}

// 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 the fake storage is set, only lookup the state here(in the debugging mode)
if s.fakeStorage != nil {
return s.fakeStorage[key]
Expand All @@ -188,11 +188,11 @@ func (s *stateObject) GetState(db Database, key common.Hash) common.Hash {
return value
}
// Otherwise return the entry's original value
return s.GetCommittedState(db, key)
return s.GetCommittedState(key)
}

// GetCommittedState retrieves a value from the committed account storage trie.
func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Hash {
func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
// If the fake storage is set, only lookup the state here(in the debugging mode)
if s.fakeStorage != nil {
return s.fakeStorage[key]
Expand Down Expand Up @@ -247,7 +247,7 @@ func (s *stateObject) GetCommittedState(db Database, key common.Hash) common.Has
if metrics.EnabledExpensive {
meter = &s.db.StorageReads
}
if enc, err = s.getTrie(db).TryGet(key.Bytes()); err != nil {
if enc, err = s.getTrie().TryGet(key.Bytes()); err != nil {
s.setError(err)
return common.Hash{}
}
Expand All @@ -265,14 +265,14 @@ 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) {
func (s *stateObject) SetState(key, value common.Hash) {
// If the fake storage is set, put the temporary state update here.
if s.fakeStorage != nil {
s.fakeStorage[key] = value
return
}
// If the new value is the same as old, don't set
prev := s.GetState(db, key)
prev := s.GetState(key)
if prev == value {
return
}
Expand Down Expand Up @@ -327,7 +327,7 @@ func (s *stateObject) finalise(prefetch bool) {

// 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
func (s *stateObject) updateTrie(db Database) Trie {
func (s *stateObject) updateTrie() Trie {
// Make sure all dirty slots are finalized into the pending storage area
s.finalise(false) // Don't prefetch anymore, pull directly if need be
if len(s.pendingStorage) == 0 {
Expand All @@ -343,7 +343,7 @@ func (s *stateObject) updateTrie(db Database) Trie {
origin map[common.Hash][]byte
)
// Insert all the pending updates into the trie
tr := s.getTrie(db)
tr := s.getTrie()
hasher := s.db.hasher

usedStorage := make([][]byte, 0, len(s.pendingStorage))
Expand Down Expand Up @@ -406,9 +406,9 @@ func (s *stateObject) updateTrie(db Database) Trie {
}

// UpdateRoot sets the trie root to the current root hash of
func (s *stateObject) updateRoot(db Database) {
func (s *stateObject) updateRoot() {
// If nothing changed, don't bother with hashing anything
if s.updateTrie(db) == nil {
if s.updateTrie() == nil {
return
}
// Track the amount of time wasted on hashing the storage trie
Expand All @@ -419,9 +419,9 @@ func (s *stateObject) updateRoot(db Database) {
}

// commit returns the changes made in storage trie and updates the account data.
func (s *stateObject) commit(db Database) (*trienode.NodeSet, error) {
func (s *stateObject) commit() (*trienode.NodeSet, error) {
// If nothing changed, don't bother with hashing anything
if s.updateTrie(db) == nil {
if s.updateTrie() == nil {
s.origin = s.data.Copy() // Update original account data after commit
return nil, nil
}
Expand Down Expand Up @@ -507,14 +507,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(), emptyCodeHash) {
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 @@ -540,7 +540,7 @@ func (s *stateObject) CodeSize(db Database) int {
}

func (s *stateObject) SetCode(codeHash common.Hash, code []byte) {
prevcode := s.Code(s.db.db)
prevcode := s.Code()
s.db.journal.append(codeChange{
account: &s.address,
prevhash: s.CodeHash(),
Expand Down
10 changes: 5 additions & 5 deletions core/state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,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 @@ -99,7 +99,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 @@ -171,7 +171,7 @@ func TestSnapshot2(t *testing.T) {
so0.deleted = false
state.setStateObject(so0)

root, _ := state.Commit(false)
root, _ := state.Commit(0, false)
state, _ = New(root, state.db, state.snaps)

// and one with deleted == true
Expand All @@ -193,8 +193,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
25 changes: 14 additions & 11 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ func (s *StateDB) TxIndex() int {
func (s *StateDB) GetCode(addr common.Address) []byte {
stateObject := s.getStateObject(addr)
if stateObject != nil {
return stateObject.Code(s.db)
return stateObject.Code()
}
return nil
}
Expand All @@ -325,7 +325,7 @@ func (s *StateDB) GetCodeHash(addr common.Address) common.Hash {
func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash {
stateObject := s.getStateObject(addr)
if stateObject != nil {
return stateObject.GetState(s.db, hash)
return stateObject.GetState(hash)
}
return common.Hash{}
}
Expand Down Expand Up @@ -357,7 +357,7 @@ func (s *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte,
func (s *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
stateObject := s.getStateObject(addr)
if stateObject != nil {
return stateObject.GetCommittedState(s.db, hash)
return stateObject.GetCommittedState(hash)
}
return common.Hash{}
}
Expand All @@ -375,8 +375,8 @@ func (s *StateDB) StorageTrie(addr common.Address) Trie {
return nil
}
cpy := stateObject.deepCopy(s)
cpy.updateTrie(s.db)
return cpy.getTrie(s.db)
cpy.updateTrie()
return cpy.getTrie()
}

func (s *StateDB) HasSelfDestructed(addr common.Address) bool {
Expand Down Expand Up @@ -431,7 +431,7 @@ func (s *StateDB) SetCode(addr common.Address, code []byte) {
func (s *StateDB) SetState(addr common.Address, key, value common.Hash) {
stateObject := s.GetOrNewStateObject(addr)
if stateObject != nil {
stateObject.SetState(s.db, key, value)
stateObject.SetState(key, value)
}
}

Expand Down Expand Up @@ -712,7 +712,7 @@ func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common
if so == nil {
return nil
}
it := trie.NewIterator(so.getTrie(db.db).NodeIterator(nil))
it := trie.NewIterator(so.getTrie().NodeIterator(nil))

for it.Next() {
key := common.BytesToHash(db.trie.GetKey(it.Key))
Expand Down Expand Up @@ -954,7 +954,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash {
// to pull useful data from disk.
for addr := range s.stateObjectsPending {
if obj := s.stateObjects[addr]; !obj.deleted {
obj.updateRoot(s.db)
obj.updateRoot()
}
}
// Now we're about to start to write changes to the trie. The trie is so far
Expand Down Expand Up @@ -1134,7 +1134,10 @@ func (s *StateDB) clearJournalAndRefund() {
}

// Commit writes the state to the underlying in-memory trie database.
func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
//
// The associated block number of the state transition is also provided
// for more chain context.
func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, error) {
if s.dbErr != nil {
return common.Hash{}, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr)
}
Expand Down Expand Up @@ -1164,7 +1167,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
obj.dirtyCode = false
}
// Write any storage changes in the state object to its storage trie
nodeSet, err := obj.commit(s.db)
nodeSet, err := obj.commit()
if err != nil {
return common.Hash{}, err
}
Expand Down Expand Up @@ -1253,7 +1256,7 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
Storages: s.storagesOrigin,
Incomplete: incomplete,
}
if err := s.db.TrieDB().Update(root, origin, nodes, set); err != nil {
if err := s.db.TrieDB().Update(root, origin, block, nodes, set); err != nil {
return common.Hash{}, err
}
s.originalRoot = root
Expand Down
Loading

0 comments on commit bafb899

Please sign in to comment.