core/state: mark account as dirty when resetObject occurs (#27339)

This changes the journal logic to mark the state object dirty immediately when it
is reset. 

We're mostly adding this change to appease the fuzzer. Marking it dirty immediately
makes no difference in practice because accounts will always be modified by EVM
right after creation.
This commit is contained in:
rjl493456442 2023-06-01 17:09:32 +08:00 committed by GitHub
parent 2372fb2781
commit 15bd21f3c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 7 additions and 10 deletions

@ -90,6 +90,7 @@ type (
account *common.Address account *common.Address
} }
resetObjectChange struct { resetObjectChange struct {
account *common.Address
prev *stateObject prev *stateObject
prevdestruct bool prevdestruct bool
} }
@ -162,7 +163,7 @@ func (ch resetObjectChange) revert(s *StateDB) {
} }
func (ch resetObjectChange) dirtied() *common.Address { func (ch resetObjectChange) dirtied() *common.Address {
return nil return ch.account
} }
func (ch suicideChange) revert(s *StateDB) { func (ch suicideChange) revert(s *StateDB) {

@ -623,19 +623,15 @@ func (s *StateDB) GetOrNewStateObject(addr common.Address) *stateObject {
// the given address, it is overwritten and returned as the second return value. // the given address, it is overwritten and returned as the second return value.
func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) { func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) {
prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that! prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that!
var prevdestruct bool
if prev != nil {
_, prevdestruct = s.stateObjectsDestruct[prev.address]
if !prevdestruct {
s.stateObjectsDestruct[prev.address] = struct{}{}
}
}
newobj = newObject(s, addr, types.StateAccount{}) newobj = newObject(s, addr, types.StateAccount{})
if prev == nil { if prev == nil {
s.journal.append(createObjectChange{account: &addr}) s.journal.append(createObjectChange{account: &addr})
} else { } else {
s.journal.append(resetObjectChange{prev: prev, prevdestruct: prevdestruct}) _, prevdestruct := s.stateObjectsDestruct[prev.address]
if !prevdestruct {
s.stateObjectsDestruct[prev.address] = struct{}{}
}
s.journal.append(resetObjectChange{account: &addr, prev: prev, prevdestruct: prevdestruct})
} }
s.setStateObject(newobj) s.setStateObject(newobj)
if prev != nil && !prev.deleted { if prev != nil && !prev.deleted {