core/state: modify how self-destruct journalling works

The self-destruct journalling is a bit strange: we allow the
'selfdestruct' operation to be journalled several times. This makes it
so that we also are forced to store whether the account was
already destructed.
What we can do instead, is to only journal the first destruction, and after
that only journal balance-changes, but not journal the selfdestruct itself.

This simplifies the journalling, so that internals about state management
does not leak into the journal-API.
This commit is contained in:
Martin Holst Swende 2024-01-29 10:57:03 +01:00
parent 36e875a361
commit dad62bc5ab
No known key found for this signature in database
GPG key ID: 683B438C05A5DDF0
2 changed files with 18 additions and 25 deletions

View file

@ -168,12 +168,8 @@ func (j *journal) JournalCreate(addr common.Address) {
j.append(createObjectChange{account: &addr})
}
func (j *journal) JournalDestruct(addr common.Address, previouslyDestructed bool, prevBalance *uint256.Int) {
j.append(selfDestructChange{
account: &addr,
prev: previouslyDestructed,
prevbalance: prevBalance.Clone(),
})
func (j *journal) JournalDestruct(addr common.Address) {
j.append(selfDestructChange{account: &addr})
}
func (j *journal) JournalSetState(addr common.Address, key, prev, origin common.Hash) {
@ -241,8 +237,6 @@ type (
selfDestructChange struct {
account *common.Address
prev bool // whether account had already self-destructed
prevbalance *uint256.Int
}
// Changes to individual accounts.
@ -325,8 +319,7 @@ func (ch createContractChange) copy() journalEntry {
func (ch selfDestructChange) revert(s *StateDB) {
obj := s.getStateObject(*ch.account)
if obj != nil {
obj.selfDestructed = ch.prev
obj.setBalance(ch.prevbalance)
obj.selfDestructed = false
}
}
@ -337,8 +330,6 @@ func (ch selfDestructChange) dirtied() *common.Address {
func (ch selfDestructChange) copy() journalEntry {
return selfDestructChange{
account: ch.account,
prev: ch.prev,
prevbalance: new(uint256.Int).Set(ch.prevbalance),
}
}

View file

@ -498,18 +498,20 @@ func (s *StateDB) SelfDestruct(addr common.Address) {
if stateObject == nil {
return
}
var (
prev = new(uint256.Int).Set(stateObject.Balance())
n = new(uint256.Int)
)
s.journal.JournalDestruct(addr, stateObject.selfDestructed, prev)
if s.logger != nil && s.logger.OnBalanceChange != nil && prev.Sign() > 0 {
s.logger.OnBalanceChange(addr, prev.ToBig(), n.ToBig(), tracing.BalanceDecreaseSelfdestruct)
// Regardless of whether it is already destructed or not, we do have to
// journal the balance-change, if we set it to zero here.
if !stateObject.Balance().IsZero() {
stateObject.SetBalance(new(uint256.Int), tracing.BalanceDecreaseSelfdestruct)
if s.logger != nil && s.logger.OnBalanceChange != nil {
s.logger.OnBalanceChange(addr, stateObject.Balance().ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct)
}
}
// If it is already marked as self-destructed, we do not need to add it
// for journalling a second time.
if !stateObject.selfDestructed {
s.journal.JournalDestruct(addr)
stateObject.markSelfdestructed()
stateObject.data.Balance = n
}
}
func (s *StateDB) Selfdestruct6780(addr common.Address) {