Skip to content

Commit bfded65

Browse files
pcw109550holiman
andauthored
core/state: do not ignore null addr while iterative dump (#27320)
fixes bug which caused the zero-address to be ignored during an iterative state-dump. --------- Co-authored-by: Martin Holst Swende <[email protected]>
1 parent a190da9 commit bfded65

File tree

3 files changed

+60
-16
lines changed

3 files changed

+60
-16
lines changed

cmd/evm/internal/t8ntool/transition.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,10 @@ type Alloc map[common.Address]core.GenesisAccount
389389

390390
func (g Alloc) OnRoot(common.Hash) {}
391391

392-
func (g Alloc) OnAccount(addr common.Address, dumpAccount state.DumpAccount) {
392+
func (g Alloc) OnAccount(addr *common.Address, dumpAccount state.DumpAccount) {
393+
if addr == nil {
394+
return
395+
}
393396
balance, _ := new(big.Int).SetString(dumpAccount.Balance, 10)
394397
var storage map[common.Hash]common.Hash
395398
if dumpAccount.Storage != nil {
@@ -404,7 +407,7 @@ func (g Alloc) OnAccount(addr common.Address, dumpAccount state.DumpAccount) {
404407
Balance: balance,
405408
Nonce: dumpAccount.Nonce,
406409
}
407-
g[addr] = genesisAccount
410+
g[*addr] = genesisAccount
408411
}
409412

410413
// saveFile marshals the object to the given file

core/state/dump.go

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type DumpCollector interface {
4444
// OnRoot is called with the state root
4545
OnRoot(common.Hash)
4646
// OnAccount is called once for each account in the trie
47-
OnAccount(common.Address, DumpAccount)
47+
OnAccount(*common.Address, DumpAccount)
4848
}
4949

5050
// DumpAccount represents an account in the state.
@@ -72,8 +72,10 @@ func (d *Dump) OnRoot(root common.Hash) {
7272
}
7373

7474
// OnAccount implements DumpCollector interface
75-
func (d *Dump) OnAccount(addr common.Address, account DumpAccount) {
76-
d.Accounts[addr] = account
75+
func (d *Dump) OnAccount(addr *common.Address, account DumpAccount) {
76+
if addr != nil {
77+
d.Accounts[*addr] = account
78+
}
7779
}
7880

7981
// IteratorDump is an implementation for iterating over data.
@@ -89,8 +91,10 @@ func (d *IteratorDump) OnRoot(root common.Hash) {
8991
}
9092

9193
// OnAccount implements DumpCollector interface
92-
func (d *IteratorDump) OnAccount(addr common.Address, account DumpAccount) {
93-
d.Accounts[addr] = account
94+
func (d *IteratorDump) OnAccount(addr *common.Address, account DumpAccount) {
95+
if addr != nil {
96+
d.Accounts[*addr] = account
97+
}
9498
}
9599

96100
// iterativeDump is a DumpCollector-implementation which dumps output line-by-line iteratively.
@@ -99,7 +103,7 @@ type iterativeDump struct {
99103
}
100104

101105
// OnAccount implements DumpCollector interface
102-
func (d iterativeDump) OnAccount(addr common.Address, account DumpAccount) {
106+
func (d iterativeDump) OnAccount(addr *common.Address, account DumpAccount) {
103107
dumpAccount := &DumpAccount{
104108
Balance: account.Balance,
105109
Nonce: account.Nonce,
@@ -108,10 +112,7 @@ func (d iterativeDump) OnAccount(addr common.Address, account DumpAccount) {
108112
Code: account.Code,
109113
Storage: account.Storage,
110114
SecureKey: account.SecureKey,
111-
Address: nil,
112-
}
113-
if addr != (common.Address{}) {
114-
dumpAccount.Address = &addr
115+
Address: addr,
115116
}
116117
d.Encode(dumpAccount)
117118
}
@@ -152,16 +153,20 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
152153
CodeHash: data.CodeHash,
153154
SecureKey: it.Key,
154155
}
155-
addrBytes := s.trie.GetKey(it.Key)
156+
var (
157+
addrBytes = s.trie.GetKey(it.Key)
158+
addr = common.BytesToAddress(addrBytes)
159+
address *common.Address
160+
)
156161
if addrBytes == nil {
157162
// Preimage missing
158163
missingPreimages++
159164
if conf.OnlyWithAddresses {
160165
continue
161166
}
162-
account.SecureKey = it.Key
167+
} else {
168+
address = &addr
163169
}
164-
addr := common.BytesToAddress(addrBytes)
165170
obj := newObject(s, addr, data)
166171
if !conf.SkipCode {
167172
account.Code = obj.Code(s.db)
@@ -183,7 +188,7 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
183188
account.Storage[common.BytesToHash(s.trie.GetKey(storageIt.Key))] = common.Bytes2Hex(content)
184189
}
185190
}
186-
c.OnAccount(addr, account)
191+
c.OnAccount(address, account)
187192
accounts++
188193
if time.Since(logged) > 8*time.Second {
189194
log.Info("Trie dumping in progress", "at", it.Key, "accounts", accounts,

core/state/state_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package state
1818

1919
import (
2020
"bytes"
21+
"encoding/json"
2122
"math/big"
2223
"testing"
2324

@@ -92,6 +93,41 @@ func TestDump(t *testing.T) {
9293
}
9394
}
9495

96+
func TestIterativeDump(t *testing.T) {
97+
db := rawdb.NewMemoryDatabase()
98+
sdb, _ := New(types.EmptyRootHash, NewDatabaseWithConfig(db, &trie.Config{Preimages: true}), nil)
99+
s := &stateTest{db: db, state: sdb}
100+
101+
// generate a few entries
102+
obj1 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x01}))
103+
obj1.AddBalance(big.NewInt(22))
104+
obj2 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02}))
105+
obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3})
106+
obj3 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x02}))
107+
obj3.SetBalance(big.NewInt(44))
108+
obj4 := s.state.GetOrNewStateObject(common.BytesToAddress([]byte{0x00}))
109+
obj4.AddBalance(big.NewInt(1337))
110+
111+
// write some of them to the trie
112+
s.state.updateStateObject(obj1)
113+
s.state.updateStateObject(obj2)
114+
s.state.Commit(false)
115+
116+
b := &bytes.Buffer{}
117+
s.state.IterativeDump(nil, json.NewEncoder(b))
118+
// check that DumpToCollector contains the state objects that are in trie
119+
got := b.String()
120+
want := `{"root":"0xd5710ea8166b7b04bc2bfb129d7db12931cee82f75ca8e2d075b4884322bf3de"}
121+
{"balance":"22","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x0000000000000000000000000000000000000001","key":"0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d"}
122+
{"balance":"1337","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x0000000000000000000000000000000000000000","key":"0x5380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"}
123+
{"balance":"0","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0x87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3","code":"0x03030303030303","address":"0x0000000000000000000000000000000000000102","key":"0xa17eacbc25cda025e81db9c5c62868822c73ce097cee2a63e33a2e41268358a1"}
124+
{"balance":"44","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","address":"0x0000000000000000000000000000000000000002","key":"0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62"}
125+
`
126+
if got != want {
127+
t.Errorf("DumpToCollector mismatch:\ngot: %s\nwant: %s\n", got, want)
128+
}
129+
}
130+
95131
func TestNull(t *testing.T) {
96132
s := newStateTest()
97133
address := common.HexToAddress("0x823140710bf13990e4500136726d8b55")

0 commit comments

Comments
 (0)