From 36f81118f6d00713dbf8d1caf168ad937e0f1a90 Mon Sep 17 00:00:00 2001 From: gary rong Date: Fri, 5 Apr 2019 14:44:02 +0800 Subject: [PATCH] core/state: fix state iterator (#19127) * core/state: fix state iterator * core: fix state iterator more elegant --- core/state/statedb.go | 21 +++++++++++++++++---- core/vm/interface.go | 2 +- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/core/state/statedb.go b/core/state/statedb.go index db2e0d5e0..3bb9862ed 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -515,20 +515,33 @@ func (self *StateDB) CreateAccount(addr common.Address) { } } -func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) { +func (db *StateDB) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) error { so := db.getStateObject(addr) if so == nil { - return + return nil } it := trie.NewIterator(so.getTrie(db.db).NodeIterator(nil)) + for it.Next() { key := common.BytesToHash(db.trie.GetKey(it.Key)) if value, dirty := so.dirtyStorage[key]; dirty { - cb(key, value) + if !cb(key, value) { + return nil + } continue } - cb(key, common.BytesToHash(it.Value)) + + if len(it.Value) > 0 { + _, content, _, err := rlp.Split(it.Value) + if err != nil { + return err + } + if !cb(key, common.BytesToHash(content)) { + return nil + } + } } + return nil } // Copy creates a deep, independent copy of the state. diff --git a/core/vm/interface.go b/core/vm/interface.go index fc15082f1..dd401466a 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -63,7 +63,7 @@ type StateDB interface { AddLog(*types.Log) AddPreimage(common.Hash, []byte) - ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) + ForEachStorage(common.Address, func(common.Hash, common.Hash) bool) error } // CallContext provides a basic interface for the EVM calling conventions. The EVM