Skip to content

Commit dad62bc

Browse files
committed
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.
1 parent 36e875a commit dad62bc

File tree

2 files changed

+18
-25
lines changed

2 files changed

+18
-25
lines changed

core/state/journal.go

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,8 @@ func (j *journal) JournalCreate(addr common.Address) {
168168
j.append(createObjectChange{account: &addr})
169169
}
170170

171-
func (j *journal) JournalDestruct(addr common.Address, previouslyDestructed bool, prevBalance *uint256.Int) {
172-
j.append(selfDestructChange{
173-
account: &addr,
174-
prev: previouslyDestructed,
175-
prevbalance: prevBalance.Clone(),
176-
})
171+
func (j *journal) JournalDestruct(addr common.Address) {
172+
j.append(selfDestructChange{account: &addr})
177173
}
178174

179175
func (j *journal) JournalSetState(addr common.Address, key, prev, origin common.Hash) {
@@ -240,9 +236,7 @@ type (
240236
}
241237

242238
selfDestructChange struct {
243-
account *common.Address
244-
prev bool // whether account had already self-destructed
245-
prevbalance *uint256.Int
239+
account *common.Address
246240
}
247241

248242
// Changes to individual accounts.
@@ -325,8 +319,7 @@ func (ch createContractChange) copy() journalEntry {
325319
func (ch selfDestructChange) revert(s *StateDB) {
326320
obj := s.getStateObject(*ch.account)
327321
if obj != nil {
328-
obj.selfDestructed = ch.prev
329-
obj.setBalance(ch.prevbalance)
322+
obj.selfDestructed = false
330323
}
331324
}
332325

@@ -336,9 +329,7 @@ func (ch selfDestructChange) dirtied() *common.Address {
336329

337330
func (ch selfDestructChange) copy() journalEntry {
338331
return selfDestructChange{
339-
account: ch.account,
340-
prev: ch.prev,
341-
prevbalance: new(uint256.Int).Set(ch.prevbalance),
332+
account: ch.account,
342333
}
343334
}
344335

core/state/statedb.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -498,18 +498,20 @@ func (s *StateDB) SelfDestruct(addr common.Address) {
498498
if stateObject == nil {
499499
return
500500
}
501-
var (
502-
prev = new(uint256.Int).Set(stateObject.Balance())
503-
n = new(uint256.Int)
504-
)
505-
s.journal.JournalDestruct(addr, stateObject.selfDestructed, prev)
506-
507-
if s.logger != nil && s.logger.OnBalanceChange != nil && prev.Sign() > 0 {
508-
s.logger.OnBalanceChange(addr, prev.ToBig(), n.ToBig(), tracing.BalanceDecreaseSelfdestruct)
501+
// Regardless of whether it is already destructed or not, we do have to
502+
// journal the balance-change, if we set it to zero here.
503+
if !stateObject.Balance().IsZero() {
504+
stateObject.SetBalance(new(uint256.Int), tracing.BalanceDecreaseSelfdestruct)
505+
if s.logger != nil && s.logger.OnBalanceChange != nil {
506+
s.logger.OnBalanceChange(addr, stateObject.Balance().ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct)
507+
}
508+
}
509+
// If it is already marked as self-destructed, we do not need to add it
510+
// for journalling a second time.
511+
if !stateObject.selfDestructed {
512+
s.journal.JournalDestruct(addr)
513+
stateObject.markSelfdestructed()
509514
}
510-
511-
stateObject.markSelfdestructed()
512-
stateObject.data.Balance = n
513515
}
514516

515517
func (s *StateDB) Selfdestruct6780(addr common.Address) {

0 commit comments

Comments
 (0)