@ -56,14 +56,17 @@ type DumpAccount struct {
Code hexutil . Bytes ` json:"code,omitempty" `
Code hexutil . Bytes ` json:"code,omitempty" `
Storage map [ common . Hash ] string ` json:"storage,omitempty" `
Storage map [ common . Hash ] string ` json:"storage,omitempty" `
Address * common . Address ` json:"address,omitempty" ` // Address only present in iterative (line-by-line) mode
Address * common . Address ` json:"address,omitempty" ` // Address only present in iterative (line-by-line) mode
SecureKey hexutil . Bytes ` json:"key,omitempty" ` // If we don't have address, we can output the key
AddressHash hexutil . Bytes ` json:"key,omitempty" ` // If we don't have address, we can output the key
}
}
// Dump represents the full dump in a collected format, as one large map.
// Dump represents the full dump in a collected format, as one large map.
type Dump struct {
type Dump struct {
Root string ` json:"root" `
Root string ` json:"root" `
Accounts map [ common . Address ] DumpAccount ` json:"accounts" `
Accounts map [ string ] DumpAccount ` json:"accounts" `
// Next can be set to represent that this dump is only partial, and Next
// is where an iterator should be positioned in order to continue the dump.
Next [ ] byte ` json:"next,omitempty" ` // nil if no more accounts
}
}
// OnRoot implements DumpCollector interface
// OnRoot implements DumpCollector interface
@ -73,27 +76,11 @@ func (d *Dump) OnRoot(root common.Hash) {
// OnAccount implements DumpCollector interface
// OnAccount implements DumpCollector interface
func ( d * Dump ) OnAccount ( addr * common . Address , account DumpAccount ) {
func ( d * Dump ) OnAccount ( addr * common . Address , account DumpAccount ) {
if addr ! = nil {
if addr = = nil {
d . Accounts [ * addr ] = account
d . Accounts [ fmt . Sprintf ( "pre(%s)" , account . AddressHash ) ] = account
}
}
}
// IteratorDump is an implementation for iterating over data.
type IteratorDump struct {
Root string ` json:"root" `
Accounts map [ common . Address ] DumpAccount ` json:"accounts" `
Next [ ] byte ` json:"next,omitempty" ` // nil if no more accounts
}
// OnRoot implements DumpCollector interface
func ( d * IteratorDump ) OnRoot ( root common . Hash ) {
d . Root = fmt . Sprintf ( "%x" , root )
}
// OnAccount implements DumpCollector interface
func ( d * IteratorDump ) OnAccount ( addr * common . Address , account DumpAccount ) {
if addr != nil {
if addr != nil {
d . Accounts [ * addr ] = account
d . Accounts [ ( * addr ) . String ( ) ] = account
}
}
}
}
@ -111,7 +98,7 @@ func (d iterativeDump) OnAccount(addr *common.Address, account DumpAccount) {
CodeHash : account . CodeHash ,
CodeHash : account . CodeHash ,
Code : account . Code ,
Code : account . Code ,
Storage : account . Storage ,
Storage : account . Storage ,
SecureKey : account . SecureKey ,
AddressHash : account . AddressHash ,
Address : addr ,
Address : addr ,
}
}
d . Encode ( dumpAccount )
d . Encode ( dumpAccount )
@ -150,26 +137,27 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
if err := rlp . DecodeBytes ( it . Value , & data ) ; err != nil {
if err := rlp . DecodeBytes ( it . Value , & data ) ; err != nil {
panic ( err )
panic ( err )
}
}
account := DumpAccount {
var (
account = DumpAccount {
Balance : data . Balance . String ( ) ,
Balance : data . Balance . String ( ) ,
Nonce : data . Nonce ,
Nonce : data . Nonce ,
Root : data . Root [ : ] ,
Root : data . Root [ : ] ,
CodeHash : data . CodeHash ,
CodeHash : data . CodeHash ,
SecureKey : it . Key ,
AddressHash : it . Key ,
}
}
var (
addrBytes = s . trie . GetKey ( it . Key )
addr = common . BytesToAddress ( addrBytes )
address * common . Address
address * common . Address
addr common . Address
addrBytes = s . trie . GetKey ( it . Key )
)
)
if addrBytes == nil {
if addrBytes == nil {
// Preimage missing
missingPreimages ++
missingPreimages ++
if conf . OnlyWithAddresses {
if conf . OnlyWithAddresses {
continue
continue
}
}
} else {
} else {
addr = common . BytesToAddress ( addrBytes )
address = & addr
address = & addr
account . Address = address
}
}
obj := newObject ( s , addr , & data )
obj := newObject ( s , addr , & data )
if ! conf . SkipCode {
if ! conf . SkipCode {
@ -220,12 +208,13 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []
return nextKey
return nextKey
}
}
// RawDump returns the entire state an a single large object
// RawDump returns the state. If the processing is aborted e.g. due to options
// reaching Max, the `Next` key is set on the returned Dump.
func ( s * StateDB ) RawDump ( opts * DumpConfig ) Dump {
func ( s * StateDB ) RawDump ( opts * DumpConfig ) Dump {
dump := & Dump {
dump := & Dump {
Accounts : make ( map [ common . Address ] DumpAccount ) ,
Accounts : make ( map [ string ] DumpAccount ) ,
}
}
s . DumpToCollector ( dump , opts )
dump . Next = s . DumpToCollector ( dump , opts )
return * dump
return * dump
}
}
@ -234,7 +223,7 @@ func (s *StateDB) Dump(opts *DumpConfig) []byte {
dump := s . RawDump ( opts )
dump := s . RawDump ( opts )
json , err := json . MarshalIndent ( dump , "" , " " )
json , err := json . MarshalIndent ( dump , "" , " " )
if err != nil {
if err != nil {
fmt . Println ( "Dump err", err )
log . Error ( "Error dumping state" , " err", err )
}
}
return json
return json
}
}
@ -243,12 +232,3 @@ func (s *StateDB) Dump(opts *DumpConfig) []byte {
func ( s * StateDB ) IterativeDump ( opts * DumpConfig , output * json . Encoder ) {
func ( s * StateDB ) IterativeDump ( opts * DumpConfig , output * json . Encoder ) {
s . DumpToCollector ( iterativeDump { output } , opts )
s . DumpToCollector ( iterativeDump { output } , opts )
}
}
// IteratorDump dumps out a batch of accounts starts with the given start key
func ( s * StateDB ) IteratorDump ( opts * DumpConfig ) IteratorDump {
iterator := & IteratorDump {
Accounts : make ( map [ common . Address ] DumpAccount ) ,
}
iterator . Next = s . DumpToCollector ( iterator , opts )
return * iterator
}