@@ -19,28 +19,28 @@ package state
1919import (
2020 "encoding/json"
2121 "fmt"
22- "os"
2322
2423 "github.com/ethereum/go-ethereum/common"
24+ "github.com/ethereum/go-ethereum/log"
2525 "github.com/ethereum/go-ethereum/rlp"
2626 "github.com/ethereum/go-ethereum/trie"
2727)
2828
2929// DumpAccount represents an account in the state
3030type DumpAccount struct {
31- Balance string `json:"balance"`
32- Nonce uint64 `json:"nonce"`
33- Root string `json:"root"`
34- CodeHash string `json:"codeHash"`
35- Code string `json:"code"`
36- Storage map [string ]string `json:"storage"`
37- Address * string `json:"address,omitempty"` // Address only present in iterative (line-by-line) mode
31+ Balance string `json:"balance"`
32+ Nonce uint64 `json:"nonce"`
33+ Root string `json:"root"`
34+ CodeHash string `json:"codeHash"`
35+ Code string `json:"code"`
36+ Storage map [common. Hash ]string `json:"storage"`
37+ Address * common. Address `json:"address,omitempty"` // Address only present in iterative (line-by-line) mode
3838}
3939
4040// Dump represents the full dump in a collected format, as one large map
4141type Dump struct {
42- Root string `json:"root"`
43- Accounts map [string ]DumpAccount `json:"accounts"`
42+ Root string `json:"root"`
43+ Accounts map [common. Address ]DumpAccount `json:"accounts"`
4444}
4545
4646// iterativeDump is a 'collector'-implementation which dump output line-by-line iteratively
@@ -49,47 +49,57 @@ type iterativeDump json.Encoder
4949// Collector interface which the state trie calls during iteration
5050type collector interface {
5151 onRoot (common.Hash )
52- onAccount (string , DumpAccount )
52+ onAccount (common. Address , DumpAccount )
5353}
5454
5555func (self * Dump ) onRoot (root common.Hash ) {
5656 self .Root = fmt .Sprintf ("%x" , root )
5757}
5858
59- func (self * Dump ) onAccount (addr string , account DumpAccount ) {
59+ func (self * Dump ) onAccount (addr common. Address , account DumpAccount ) {
6060 self .Accounts [addr ] = account
6161}
6262
63- func (self iterativeDump ) onAccount (addr string , account DumpAccount ) {
64- (* json .Encoder )(& self ).Encode (& DumpAccount {
65- account .Balance ,
66- account .Nonce ,
67- account .Root ,
68- account .CodeHash ,
69- account .Code ,
70- account .Storage ,
71- & addr ,
72- })
63+ func (self iterativeDump ) onAccount (addr common.Address , account DumpAccount ) {
64+ dumpAccount := & DumpAccount {
65+ Balance : account .Balance ,
66+ Nonce : account .Nonce ,
67+ Root : account .Root ,
68+ CodeHash : account .CodeHash ,
69+ Code : account .Code ,
70+ Storage : account .Storage ,
71+ Address : nil ,
72+ }
73+ if addr != (common.Address {}) {
74+ dumpAccount .Address = & addr
75+ }
76+ (* json .Encoder )(& self ).Encode (dumpAccount )
7377}
7478func (self iterativeDump ) onRoot (root common.Hash ) {
7579 (* json .Encoder )(& self ).Encode (struct {
76- Root string `json:"root"`
77- }{
78- common .Bytes2Hex (root .Bytes ()),
79- })
80+ Root common.Hash `json:"root"`
81+ }{root })
8082}
8183
8284func (self * StateDB ) dump (c collector , excludeCode , excludeStorage bool ) {
85+ emptyAddress := (common.Address {})
86+ missingPreimages := 0
8387 c .onRoot (self .trie .Hash ())
8488 it := trie .NewIterator (self .trie .NodeIterator (nil ))
8589 for it .Next () {
86- addr := self .trie .GetKey (it .Key )
90+ addr := common .BytesToAddress (self .trie .GetKey (it .Key ))
91+ if emptyAddress == addr {
92+ // We don't have the preimage. All accounts missing preimages
93+ // will be 'mapped' and overwrite the same entry, which is quite useless.
94+ // Make note and continue
95+ missingPreimages ++
96+ continue
97+ }
8798 var data Account
8899 if err := rlp .DecodeBytes (it .Value , & data ); err != nil {
89100 panic (err )
90101 }
91-
92- obj := newObject (nil , common .BytesToAddress (addr ), data )
102+ obj := newObject (nil , addr , data )
93103 account := DumpAccount {
94104 Balance : data .Balance .String (),
95105 Nonce : data .Nonce ,
@@ -100,20 +110,23 @@ func (self *StateDB) dump(c collector, excludeCode, excludeStorage bool) {
100110 account .Code = common .Bytes2Hex (obj .Code (self .db ))
101111 }
102112 if ! excludeStorage {
103- account .Storage = make (map [string ]string )
113+ account .Storage = make (map [common. Hash ]string )
104114 storageIt := trie .NewIterator (obj .getTrie (self .db ).NodeIterator (nil ))
105115 for storageIt .Next () {
106- account .Storage [common .Bytes2Hex (self .trie .GetKey (storageIt .Key ))] = common .Bytes2Hex (storageIt .Value )
116+ account .Storage [common .BytesToHash (self .trie .GetKey (storageIt .Key ))] = common .Bytes2Hex (storageIt .Value )
107117 }
108118 }
109- c .onAccount (common .Bytes2Hex (addr ), account )
119+ c .onAccount (addr , account )
120+ }
121+ if missingPreimages > 0 {
122+ log .Warn ("Dump incomplete due to missing preimages" , "missing" , missingPreimages )
110123 }
111124}
112125
113126// RawDump returns the entire state an a single large object
114127func (self * StateDB ) RawDump (excludeCode , excludeStorage bool ) Dump {
115128 dump := & Dump {
116- Accounts : make (map [string ]DumpAccount ),
129+ Accounts : make (map [common. Address ]DumpAccount ),
117130 }
118131 self .dump (dump , excludeCode , excludeStorage )
119132 return * dump
@@ -122,7 +135,7 @@ func (self *StateDB) RawDump(excludeCode, excludeStorage bool) Dump {
122135// Dump returns a JSON string representing the entire state as a single json-object
123136func (self * StateDB ) Dump (excludeCode , excludeStorage bool ) []byte {
124137 dump := self .RawDump (excludeCode , excludeStorage )
125- json , err := json .MarshalIndent (dump , "" , " " )
138+ json , err := json .MarshalIndent (dump , "" , " " )
126139 if err != nil {
127140 fmt .Println ("dump err" , err )
128141 }
@@ -131,8 +144,5 @@ func (self *StateDB) Dump(excludeCode, excludeStorage bool) []byte {
131144
132145// IterativeDump dumps out accounts as json-objects, delimited by linebreaks on stdout
133146func (self * StateDB ) IterativeDump (excludeCode , excludeStorage bool , output * json.Encoder ) {
134- if output == nil {
135- output = json .NewEncoder (os .Stdout )
136- }
137147 self .dump (iterativeDump (* output ), excludeCode , excludeStorage )
138148}
0 commit comments