mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 15:16:43 +00:00
core/state, core/vm, light: documented AccountRef, implemented state iterator
This commit is contained in:
parent
9f1bdae638
commit
5f4f75cc47
6 changed files with 64 additions and 4 deletions
|
|
@ -474,6 +474,27 @@ func (self *StateDB) CreateAccount(addr common.Address) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) {
|
||||||
|
so := db.getStateObject(addr)
|
||||||
|
if so == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// When iterating over the storage check the cache first
|
||||||
|
for h, value := range so.cachedStorage {
|
||||||
|
cb(h, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
it := so.getTrie(db.db).Iterator()
|
||||||
|
for it.Next() {
|
||||||
|
// ignore cached values
|
||||||
|
key := common.BytesToHash(db.trie.GetKey(it.Key))
|
||||||
|
if _, ok := so.cachedStorage[key]; !ok {
|
||||||
|
cb(key, common.BytesToHash(it.Value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Copy creates a deep, independent copy of the state.
|
// Copy creates a deep, independent copy of the state.
|
||||||
// Snapshots of the copied state cannot be applied to the copy.
|
// Snapshots of the copied state cannot be applied to the copy.
|
||||||
func (self *StateDB) Copy() *StateDB {
|
func (self *StateDB) Copy() *StateDB {
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,19 @@ type ContractRef interface {
|
||||||
Address() common.Address
|
Address() common.Address
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AccountRef implements ContractRef.
|
||||||
|
//
|
||||||
|
// Account references are used during EVM initialisation and
|
||||||
|
// it's primary use is to fetch addresses. Removing this object
|
||||||
|
// proves difficult because of the cached jump destinations which
|
||||||
|
// are fetched from the parent contract (i.e. the caller), which
|
||||||
|
// is a ContractRef.
|
||||||
type AccountRef common.Address
|
type AccountRef common.Address
|
||||||
|
|
||||||
func (ar AccountRef) Address() common.Address { return (common.Address)(ar) }
|
// Address casts AccountRef to a Address
|
||||||
|
func (ar AccountRef) Address() common.Address { return (common.Address)(ar) }
|
||||||
|
|
||||||
|
// Reference returns a casted Address to AccountRef
|
||||||
func Reference(addr common.Address) AccountRef { return (AccountRef)(addr) }
|
func Reference(addr common.Address) AccountRef { return (AccountRef)(addr) }
|
||||||
|
|
||||||
// Contract represents an ethereum contract in the state database. It contains
|
// Contract represents an ethereum contract in the state database. It contains
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ type StateDB interface {
|
||||||
|
|
||||||
AddLog(*types.Log)
|
AddLog(*types.Log)
|
||||||
AddPreimage(common.Hash, []byte)
|
AddPreimage(common.Hash, []byte)
|
||||||
|
|
||||||
|
ForEachStorage(common.Address, func(common.Hash, common.Hash) bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallContext provides a basic interface for the EVM calling conventions. The EVM EVM
|
// CallContext provides a basic interface for the EVM calling conventions. The EVM EVM
|
||||||
|
|
|
||||||
|
|
@ -145,13 +145,11 @@ func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost *b
|
||||||
// Get the contract account and loop over each storage entry. This may involve looping over
|
// Get the contract account and loop over each storage entry. This may involve looping over
|
||||||
// the trie and is a very expensive process.
|
// the trie and is a very expensive process.
|
||||||
|
|
||||||
/* TODO
|
env.StateDB.ForEachStorage(contract.Address(), func(key, value common.Hash) bool {
|
||||||
env.StateDB.GetAccount(contract.Address()).ForEachStorage(func(key, value common.Hash) bool {
|
|
||||||
storage[key] = value
|
storage[key] = value
|
||||||
// Return true, indicating we'd like to continue.
|
// Return true, indicating we'd like to continue.
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
// copy a snapshot of the current storage to a new container.
|
// copy a snapshot of the current storage to a new container.
|
||||||
storage = l.changedValues[contract.Address()].Copy()
|
storage = l.changedValues[contract.Address()].Copy()
|
||||||
|
|
|
||||||
|
|
@ -268,6 +268,26 @@ func (self *LightState) CreateStateObject(ctx context.Context, addr common.Addre
|
||||||
return newSo, nil
|
return newSo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ForEachStorage calls a callback function for every key/value pair found
|
||||||
|
// in the local storage cache. Note that unlike core/state.StateObject,
|
||||||
|
// light.StateObject only returns cached values and doesn't download the
|
||||||
|
// entire storage tree.
|
||||||
|
func (self *LightState) ForEachStorage(ctx context.Context, addr common.Address, cb func(key, value common.Hash) bool) error {
|
||||||
|
so, err := self.GetStateObject(ctx, addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if so == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for h, v := range so.storage {
|
||||||
|
cb(h, v)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setting, copying of the state methods
|
// Setting, copying of the state methods
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,15 @@ func (s *VMState) SubBalance(addr common.Address, amount *big.Int) {
|
||||||
s.errHandler(err)
|
s.errHandler(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ForEachStorage calls a callback function for every key/value pair found
|
||||||
|
// in the local storage cache. Note that unlike core/state.StateObject,
|
||||||
|
// light.StateObject only returns cached values and doesn't download the
|
||||||
|
// entire storage tree.
|
||||||
|
func (s *VMState) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) {
|
||||||
|
err := s.state.ForEachStorage(s.ctx, addr, cb)
|
||||||
|
s.errHandler(err)
|
||||||
|
}
|
||||||
|
|
||||||
// GetBalance retrieves the balance from the given address or 0 if the account does
|
// GetBalance retrieves the balance from the given address or 0 if the account does
|
||||||
// not exist
|
// not exist
|
||||||
func (s *VMState) GetBalance(addr common.Address) *big.Int {
|
func (s *VMState) GetBalance(addr common.Address) *big.Int {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue