forked from forks/go-ethereum
core/state: revert pending storage updates if they revert to original (#29661)
This commit is contained in:
parent
ad4fb2c729
commit
8d42e115b1
1 changed files with 14 additions and 1 deletions
|
|
@ -27,6 +27,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/core/tracing"
|
"github.com/ethereum/go-ethereum/core/tracing"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
|
|
@ -255,9 +256,16 @@ func (s *stateObject) setState(key common.Hash, value *common.Hash) {
|
||||||
func (s *stateObject) finalise(prefetch bool) {
|
func (s *stateObject) finalise(prefetch bool) {
|
||||||
slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage))
|
slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage))
|
||||||
for key, value := range 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] {
|
if value != s.originStorage[key] {
|
||||||
|
s.pendingStorage[key] = value
|
||||||
slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure
|
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 {
|
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
|
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 {
|
if s.db.prefetcher != nil {
|
||||||
s.db.prefetcher.used(s.addrHash, s.data.Root, usedStorage)
|
s.db.prefetcher.used(s.addrHash, s.data.Root, usedStorage)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue