|
|
|
@ -27,6 +27,7 @@ import ( |
|
|
|
|
"github.com/ethereum/go-ethereum/core/tracing" |
|
|
|
|
"github.com/ethereum/go-ethereum/core/types" |
|
|
|
|
"github.com/ethereum/go-ethereum/crypto" |
|
|
|
|
"github.com/ethereum/go-ethereum/log" |
|
|
|
|
"github.com/ethereum/go-ethereum/rlp" |
|
|
|
|
"github.com/ethereum/go-ethereum/trie/trienode" |
|
|
|
|
"github.com/holiman/uint256" |
|
|
|
@ -255,9 +256,16 @@ func (s *stateObject) setState(key common.Hash, value *common.Hash) { |
|
|
|
|
func (s *stateObject) finalise(prefetch bool) { |
|
|
|
|
slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage)) |
|
|
|
|
for key, value := range s.dirtyStorage { |
|
|
|
|
s.pendingStorage[key] = value |
|
|
|
|
// If the slot is different from its original value, move it into the
|
|
|
|
|
// pending area to be committed at the end of the block (and prefetch
|
|
|
|
|
// the pathways).
|
|
|
|
|
if value != s.originStorage[key] { |
|
|
|
|
s.pendingStorage[key] = value |
|
|
|
|
slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure
|
|
|
|
|
} else { |
|
|
|
|
// Otherwise, the slot was reverted to its original value, remove it
|
|
|
|
|
// from the pending area to avoid thrashing the data strutures.
|
|
|
|
|
delete(s.pendingStorage, key) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if s.db.prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != types.EmptyRootHash { |
|
|
|
@ -371,6 +379,11 @@ func (s *stateObject) updateTrie() (Trie, error) { |
|
|
|
|
} |
|
|
|
|
s.db.StorageDeleted += 1 |
|
|
|
|
} |
|
|
|
|
// If no slots were touched, issue a warning as we shouldn't have done all
|
|
|
|
|
// the above work in the first place
|
|
|
|
|
if len(usedStorage) == 0 { |
|
|
|
|
log.Error("State object update was noop", "addr", s.address, "slots", len(s.pendingStorage)) |
|
|
|
|
} |
|
|
|
|
if s.db.prefetcher != nil { |
|
|
|
|
s.db.prefetcher.used(s.addrHash, s.data.Root, usedStorage) |
|
|
|
|
} |
|
|
|
|