From 8d5ceb6cad2b379eac4b5e2489d6628c2358d4ce Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Fri, 26 Jan 2024 14:46:47 +0100 Subject: [PATCH 1/9] core/state: refactor journalling by implementing journal API --- core/state/journal.go | 85 ++++++++++++++++++++++++++++++++++++++ core/state/state_object.go | 38 ++++------------- core/state/statedb.go | 33 ++++++--------- 3 files changed, 105 insertions(+), 51 deletions(-) diff --git a/core/state/journal.go b/core/state/journal.go index ad4a654fc6a2..94f7e0ad39bd 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -100,6 +100,91 @@ func (j *journal) copy() *journal { } } +func (j *journal) JournalAccessListAddAccount(addr common.Address) { + j.append(accessListAddAccountChange{&addr}) +} + +func (j *journal) JournalAccessListAddSlot(addr common.Address, slot common.Hash) { + j.append(accessListAddSlotChange{ + address: &addr, + slot: &slot, + }) +} + +func (j *journal) JournalLog(txHash common.Hash) { + j.append(addLogChange{txhash: txHash}) +} + +func (j *journal) JournalAddPreimage(hash common.Hash) { + j.append(addPreimageChange{hash: hash}) +} + +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) JournalSetState(addr common.Address, key, prev, origin common.Hash) { + j.append(storageChange{ + account: &addr, + key: key, + prevvalue: prev, + origvalue: origin, + }) +} + +func (j *journal) JournalSetTransientState(addr common.Address, key, prev common.Hash) { + j.append(transientStorageChange{ + account: &addr, + key: key, + prevalue: prev, + }) +} + +func (j *journal) JournalRefundChange(previous uint64) { + j.append(refundChange{prev: previous}) +} + +func (j *journal) JournalBalanceChange(addr common.Address, previous *uint256.Int) { + j.append(balanceChange{ + account: &addr, + prev: previous.Clone(), + }) +} + +func (j *journal) JournalSetCode(address common.Address, prevcode, prevHash []byte) { + j.append(codeChange{ + account: &address, + prevhash: prevHash, + prevcode: prevcode, + }) +} + +func (j *journal) JournalNonceChange(address common.Address, prev uint64) { + j.append(nonceChange{ + account: &address, + prev: prev, + }) +} + +func (j *journal) JournalTouch(address common.Address) { + j.append(touchChange{ + account: &address, + }) + if address == ripemd { + // Explicitly put it in the dirty-cache, which is otherwise generated from + // flattened journals. + j.dirty(address) + } +} + type ( // Changes to the account trie. createObjectChange struct { diff --git a/core/state/state_object.go b/core/state/state_object.go index 880b715b4b37..44a628acfc85 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -114,14 +114,7 @@ func (s *stateObject) markSelfdestructed() { } func (s *stateObject) touch() { - s.db.journal.append(touchChange{ - account: &s.address, - }) - if s.address == ripemd { - // Explicitly put it in the dirty-cache, which is otherwise generated from - // flattened journals. - s.db.journal.dirty(s.address) - } + s.db.journal.JournalTouch(s.address) } // getTrie returns the associated storage trie. The trie will be opened if it's @@ -251,16 +244,11 @@ func (s *stateObject) SetState(key, value common.Hash) { return } // New value is different, update and journal the change - s.db.journal.append(storageChange{ - account: &s.address, - key: key, - prevvalue: prev, - origvalue: origin, - }) + s.db.journal.JournalSetState(s.address, key, prev, origin) + s.setState(key, value, origin) if s.db.logger != nil && s.db.logger.OnStorageChange != nil { s.db.logger.OnStorageChange(s.address, key, prev, value) } - s.setState(key, value, origin) } // setState updates a value in account dirty storage. The dirtiness will be @@ -510,10 +498,7 @@ func (s *stateObject) SubBalance(amount *uint256.Int, reason tracing.BalanceChan } func (s *stateObject) SetBalance(amount *uint256.Int, reason tracing.BalanceChangeReason) { - s.db.journal.append(balanceChange{ - account: &s.address, - prev: new(uint256.Int).Set(s.data.Balance), - }) + s.db.journal.JournalBalanceChange(s.address, s.data.Balance) if s.db.logger != nil && s.db.logger.OnBalanceChange != nil { s.db.logger.OnBalanceChange(s.address, s.Balance().ToBig(), amount.ToBig(), reason) } @@ -589,14 +574,10 @@ func (s *stateObject) CodeSize() int { } func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { - prevcode := s.Code() - s.db.journal.append(codeChange{ - account: &s.address, - prevhash: s.CodeHash(), - prevcode: prevcode, - }) + s.db.journal.JournalSetCode(s.address, s.Code(), s.CodeHash()) if s.db.logger != nil && s.db.logger.OnCodeChange != nil { - s.db.logger.OnCodeChange(s.address, common.BytesToHash(s.CodeHash()), prevcode, codeHash, code) + // TODO remove prevcode from this callback + s.db.logger.OnCodeChange(s.address, common.BytesToHash(s.CodeHash()), nil, codeHash, code) } s.setCode(codeHash, code) } @@ -608,10 +589,7 @@ func (s *stateObject) setCode(codeHash common.Hash, code []byte) { } func (s *stateObject) SetNonce(nonce uint64) { - s.db.journal.append(nonceChange{ - account: &s.address, - prev: s.data.Nonce, - }) + s.db.journal.JournalNonceChange(s.address, s.data.Nonce) if s.db.logger != nil && s.db.logger.OnNonceChange != nil { s.db.logger.OnNonceChange(s.address, s.data.Nonce, nonce) } diff --git a/core/state/statedb.go b/core/state/statedb.go index 80a53dbb1772..0457628864ca 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -256,7 +256,7 @@ func (s *StateDB) Error() error { } func (s *StateDB) AddLog(log *types.Log) { - s.journal.append(addLogChange{txhash: s.thash}) + s.journal.JournalLog(s.thash) log.TxHash = s.thash log.TxIndex = uint(s.txIndex) @@ -290,7 +290,7 @@ func (s *StateDB) Logs() []*types.Log { // AddPreimage records a SHA3 preimage seen by the VM. func (s *StateDB) AddPreimage(hash common.Hash, preimage []byte) { if _, ok := s.preimages[hash]; !ok { - s.journal.append(addPreimageChange{hash: hash}) + s.journal.JournalAddPreimage(hash) s.preimages[hash] = slices.Clone(preimage) } } @@ -302,14 +302,14 @@ func (s *StateDB) Preimages() map[common.Hash][]byte { // AddRefund adds gas to the refund counter func (s *StateDB) AddRefund(gas uint64) { - s.journal.append(refundChange{prev: s.refund}) + s.journal.JournalRefundChange(s.refund) s.refund += gas } // SubRefund removes gas from the refund counter. // This method will panic if the refund counter goes below zero func (s *StateDB) SubRefund(gas uint64) { - s.journal.append(refundChange{prev: s.refund}) + s.journal.JournalRefundChange(s.refund) if gas > s.refund { panic(fmt.Sprintf("Refund counter below zero (gas: %d > refund: %d)", gas, s.refund)) } @@ -510,14 +510,12 @@ func (s *StateDB) SelfDestruct(addr common.Address) { prev = new(uint256.Int).Set(stateObject.Balance()) n = new(uint256.Int) ) - s.journal.append(selfDestructChange{ - account: &addr, - prev: stateObject.selfDestructed, - prevbalance: prev, - }) + 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) } + stateObject.markSelfdestructed() stateObject.data.Balance = n } @@ -540,11 +538,7 @@ func (s *StateDB) SetTransientState(addr common.Address, key, value common.Hash) if prev == value { return } - s.journal.append(transientStorageChange{ - account: &addr, - key: key, - prevalue: prev, - }) + s.journal.JournalSetTransientState(addr, key, prev) s.setTransientState(addr, key, value) } @@ -663,7 +657,7 @@ func (s *StateDB) getOrNewStateObject(addr common.Address) *stateObject { // existing account with the given address, otherwise it will be silently overwritten. func (s *StateDB) createObject(addr common.Address) *stateObject { obj := newObject(s, addr, nil) - s.journal.append(createObjectChange{account: &addr}) + s.journal.JournalCreate(addr) s.setStateObject(obj) return obj } @@ -1419,7 +1413,7 @@ func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, d // AddAddressToAccessList adds the given address to the access list func (s *StateDB) AddAddressToAccessList(addr common.Address) { if s.accessList.AddAddress(addr) { - s.journal.append(accessListAddAccountChange{&addr}) + s.journal.JournalAccessListAddAccount(addr) } } @@ -1431,13 +1425,10 @@ func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { // scope of 'address' without having the 'address' become already added // to the access list (via call-variant, create, etc). // Better safe than sorry, though - s.journal.append(accessListAddAccountChange{&addr}) + s.journal.JournalAccessListAddAccount(addr) } if slotMod { - s.journal.append(accessListAddSlotChange{ - address: &addr, - slot: &slot, - }) + s.journal.JournalAccessListAddSlot(addr, slot) } } From 137fdb7fe2d2307f1156abe961b159e1461858ec Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Fri, 26 Jan 2024 15:09:40 +0100 Subject: [PATCH 2/9] core/state: simplify codechange journalling --- core/state/journal.go | 20 ++++++-------------- core/state/state_object.go | 2 +- core/state/statedb_test.go | 6 ++++++ 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/core/state/journal.go b/core/state/journal.go index 94f7e0ad39bd..b042e0cf3f6c 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -20,6 +20,7 @@ import ( "maps" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/holiman/uint256" ) @@ -159,12 +160,8 @@ func (j *journal) JournalBalanceChange(addr common.Address, previous *uint256.In }) } -func (j *journal) JournalSetCode(address common.Address, prevcode, prevHash []byte) { - j.append(codeChange{ - account: &address, - prevhash: prevHash, - prevcode: prevcode, - }) +func (j *journal) JournalSetCode(address common.Address) { + j.append(codeChange{account: &address}) } func (j *journal) JournalNonceChange(address common.Address, prev uint64) { @@ -220,8 +217,7 @@ type ( origvalue common.Hash } codeChange struct { - account *common.Address - prevcode, prevhash []byte + account *common.Address } // Changes to other state values. @@ -348,7 +344,7 @@ func (ch nonceChange) copy() journalEntry { } func (ch codeChange) revert(s *StateDB) { - s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode) + s.getStateObject(*ch.account).setCode(types.EmptyCodeHash, nil) } func (ch codeChange) dirtied() *common.Address { @@ -356,11 +352,7 @@ func (ch codeChange) dirtied() *common.Address { } func (ch codeChange) copy() journalEntry { - return codeChange{ - account: ch.account, - prevhash: common.CopyBytes(ch.prevhash), - prevcode: common.CopyBytes(ch.prevcode), - } + return codeChange{account: ch.account} } func (ch storageChange) revert(s *StateDB) { diff --git a/core/state/state_object.go b/core/state/state_object.go index 44a628acfc85..7a2935a918ec 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -574,7 +574,7 @@ func (s *stateObject) CodeSize() int { } func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { - s.db.journal.JournalSetCode(s.address, s.Code(), s.CodeHash()) + s.db.journal.JournalSetCode(s.address) if s.db.logger != nil && s.db.logger.OnCodeChange != nil { // TODO remove prevcode from this callback s.db.logger.OnCodeChange(s.address, common.BytesToHash(s.CodeHash()), nil, codeHash, code) diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 2ce2b868faa9..9256329ddcec 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -372,6 +372,12 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { { name: "SetCode", fn: func(a testAction, s *StateDB) { + // SetCode can only be performed in case the addr does + // not already hold code + if c := s.GetCode(addr); len(c) > 0 { + // no-op + return + } code := make([]byte, 16) binary.BigEndian.PutUint64(code, uint64(a.args[0])) binary.BigEndian.PutUint64(code[8:], uint64(a.args[1])) From 36e875a3610d23ae8fd11b84296626c6d603eb55 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Fri, 26 Jan 2024 16:43:32 +0100 Subject: [PATCH 3/9] core/state: move revision-handling into journal --- core/state/journal.go | 44 +++++++++++++++++++++++++++++++++++++++++++ core/state/statedb.go | 37 +++++------------------------------- 2 files changed, 49 insertions(+), 32 deletions(-) diff --git a/core/state/journal.go b/core/state/journal.go index b042e0cf3f6c..5fdf59c88b21 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -17,13 +17,20 @@ package state import ( + "fmt" "maps" + "sort" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/holiman/uint256" ) +type revision struct { + id int + journalIndex int +} + // journalEntry is a modification entry in the state change journal that can be // reverted on demand. type journalEntry interface { @@ -43,6 +50,9 @@ type journalEntry interface { type journal struct { entries []journalEntry // Current changes tracked by the journal dirties map[common.Address]int // Dirty accounts and the number of changes + + validRevisions []revision + nextRevisionId int } // newJournal creates a new initialized journal. @@ -52,6 +62,40 @@ func newJournal() *journal { } } +// Reset clears the journal, after this operation the journal can be used +// anew. It is semantically similar to calling 'newJournal', but the underlying +// slices can be reused +func (j *journal) Reset() { + j.entries = j.entries[:0] + j.validRevisions = j.validRevisions[:0] + j.dirties = make(map[common.Address]int) + j.nextRevisionId = 0 +} + +// Snapshot returns an identifier for the current revision of the state. +func (j *journal) Snapshot() int { + id := j.nextRevisionId + j.nextRevisionId++ + j.validRevisions = append(j.validRevisions, revision{id, j.length()}) + return id +} + +// RevertToSnapshot reverts all state changes made since the given revision. +func (j *journal) RevertToSnapshot(revid int, s *StateDB) { + // Find the snapshot in the stack of valid snapshots. + idx := sort.Search(len(j.validRevisions), func(i int) bool { + return j.validRevisions[i].id >= revid + }) + if idx == len(j.validRevisions) || j.validRevisions[idx].id != revid { + panic(fmt.Errorf("revision id %v cannot be reverted", revid)) + } + snapshot := j.validRevisions[idx].journalIndex + + // Replay the journal to undo changes and remove invalidated snapshots + j.revert(s, snapshot) + j.validRevisions = j.validRevisions[:idx] +} + // append inserts a new modification entry to the end of the change journal. func (j *journal) append(entry journalEntry) { j.entries = append(j.entries, entry) diff --git a/core/state/statedb.go b/core/state/statedb.go index 0457628864ca..c553418770a4 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -23,7 +23,6 @@ import ( "maps" "math/big" "slices" - "sort" "sync" "sync/atomic" "time" @@ -48,11 +47,6 @@ import ( // TriesInMemory represents the number of layers that are kept in RAM. const TriesInMemory = 128 -type revision struct { - id int - journalIndex int -} - type mutationType int const ( @@ -143,9 +137,7 @@ type StateDB struct { // Journal of state modifications. This is the backbone of // Snapshot and RevertToSnapshot. - journal *journal - validRevisions []revision - nextRevisionId int + journal *journal // State witness if cross validation is needed witness *stateless.Witness @@ -703,8 +695,6 @@ func (s *StateDB) Copy() *StateDB { logSize: s.logSize, preimages: maps.Clone(s.preimages), journal: s.journal.copy(), - validRevisions: slices.Clone(s.validRevisions), - nextRevisionId: s.nextRevisionId, // In order for the block producer to be able to use and make additions // to the snapshot tree, we need to copy that as well. Otherwise, any @@ -750,26 +740,12 @@ func (s *StateDB) Copy() *StateDB { // Snapshot returns an identifier for the current revision of the state. func (s *StateDB) Snapshot() int { - id := s.nextRevisionId - s.nextRevisionId++ - s.validRevisions = append(s.validRevisions, revision{id, s.journal.length()}) - return id + return s.journal.Snapshot() } // RevertToSnapshot reverts all state changes made since the given revision. func (s *StateDB) RevertToSnapshot(revid int) { - // Find the snapshot in the stack of valid snapshots. - idx := sort.Search(len(s.validRevisions), func(i int) bool { - return s.validRevisions[i].id >= revid - }) - if idx == len(s.validRevisions) || s.validRevisions[idx].id != revid { - panic(fmt.Errorf("revision id %v cannot be reverted", revid)) - } - snapshot := s.validRevisions[idx].journalIndex - - // Replay the journal to undo changes and remove invalidated snapshots - s.journal.revert(s, snapshot) - s.validRevisions = s.validRevisions[:idx] + s.journal.RevertToSnapshot(revid, s) } // GetRefund returns the current value of the refund counter. @@ -983,11 +959,8 @@ func (s *StateDB) SetTxContext(thash common.Hash, ti int) { } func (s *StateDB) clearJournalAndRefund() { - if len(s.journal.entries) > 0 { - s.journal = newJournal() - s.refund = 0 - } - s.validRevisions = s.validRevisions[:0] // Snapshots can be created without journal entries + s.journal.Reset() + s.refund = 0 } // fastDeleteStorage is the function that efficiently deletes the storage trie From dad62bc5ab868f8aeded16aa4da1df00d0f63f07 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 29 Jan 2024 10:57:03 +0100 Subject: [PATCH 4/9] 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. --- core/state/journal.go | 19 +++++-------------- core/state/statedb.go | 24 +++++++++++++----------- 2 files changed, 18 insertions(+), 25 deletions(-) diff --git a/core/state/journal.go b/core/state/journal.go index 5fdf59c88b21..927c5f07cc64 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -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) { @@ -240,9 +236,7 @@ type ( } selfDestructChange struct { - account *common.Address - prev bool // whether account had already self-destructed - prevbalance *uint256.Int + account *common.Address } // 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 } } @@ -336,9 +329,7 @@ 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), + account: ch.account, } } diff --git a/core/state/statedb.go b/core/state/statedb.go index c553418770a4..fedf740f4288 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -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.markSelfdestructed() - stateObject.data.Balance = n } func (s *StateDB) Selfdestruct6780(addr common.Address) { From 66fc14ad584df686ad750f426f4937c7a5a4b363 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 29 Jan 2024 12:55:25 +0100 Subject: [PATCH 5/9] core/state: do not journal preimages We do not strictly need to journal preimages: preimages are stored and served for the benefit of remote RPC users, e.g. for debugging solidity storage. There is no 'consensus requirement' for these keys to be reverted in case of reverted scopes. --- core/state/journal.go | 21 --------------------- core/state/statedb.go | 1 - 2 files changed, 22 deletions(-) diff --git a/core/state/journal.go b/core/state/journal.go index 927c5f07cc64..d5c5eb3525e3 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -160,10 +160,6 @@ func (j *journal) JournalLog(txHash common.Hash) { j.append(addLogChange{txhash: txHash}) } -func (j *journal) JournalAddPreimage(hash common.Hash) { - j.append(addPreimageChange{hash: hash}) -} - func (j *journal) JournalCreate(addr common.Address) { j.append(createObjectChange{account: &addr}) } @@ -265,9 +261,6 @@ type ( addLogChange struct { txhash common.Hash } - addPreimageChange struct { - hash common.Hash - } touchChange struct { account *common.Address } @@ -456,20 +449,6 @@ func (ch addLogChange) copy() journalEntry { } } -func (ch addPreimageChange) revert(s *StateDB) { - delete(s.preimages, ch.hash) -} - -func (ch addPreimageChange) dirtied() *common.Address { - return nil -} - -func (ch addPreimageChange) copy() journalEntry { - return addPreimageChange{ - hash: ch.hash, - } -} - func (ch accessListAddAccountChange) revert(s *StateDB) { /* One important invariant here, is that whenever a (addr, slot) is added, if the diff --git a/core/state/statedb.go b/core/state/statedb.go index fedf740f4288..a5eb7edf4064 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -282,7 +282,6 @@ func (s *StateDB) Logs() []*types.Log { // AddPreimage records a SHA3 preimage seen by the VM. func (s *StateDB) AddPreimage(hash common.Hash, preimage []byte) { if _, ok := s.preimages[hash]; !ok { - s.journal.JournalAddPreimage(hash) s.preimages[hash] = slices.Clone(preimage) } } From 2a2c4324107ac36993e35ba1c8bace40515c2c93 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 14 May 2024 09:38:22 +0200 Subject: [PATCH 6/9] core/state: apply suggestions from review --- core/state/journal.go | 9 ++++++--- core/state/statedb.go | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/core/state/journal.go b/core/state/journal.go index d5c5eb3525e3..0f7d0e61ab33 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -19,6 +19,7 @@ package state import ( "fmt" "maps" + "slices" "sort" "github.com/ethereum/go-ethereum/common" @@ -68,7 +69,7 @@ func newJournal() *journal { func (j *journal) Reset() { j.entries = j.entries[:0] j.validRevisions = j.validRevisions[:0] - j.dirties = make(map[common.Address]int) + clear(j.dirties) j.nextRevisionId = 0 } @@ -140,8 +141,10 @@ func (j *journal) copy() *journal { entries = append(entries, j.entries[i].copy()) } return &journal{ - entries: entries, - dirties: maps.Clone(j.dirties), + entries: entries, + dirties: maps.Clone(j.dirties), + validRevisions: slices.Clone(j.validRevisions), + nextRevisionId: j.nextRevisionId, } } diff --git a/core/state/statedb.go b/core/state/statedb.go index a5eb7edf4064..f43542010768 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -500,10 +500,10 @@ func (s *StateDB) SelfDestruct(addr common.Address) { // 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) } + stateObject.SetBalance(new(uint256.Int), tracing.BalanceDecreaseSelfdestruct) } // If it is already marked as self-destructed, we do not need to add it // for journalling a second time. From d6ee4d95d2ba4bf179e90168047863864e5ebb51 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Wed, 21 Aug 2024 09:18:36 +0200 Subject: [PATCH 7/9] core/state: drop Journal-prefix on journal methods --- core/state/journal.go | 24 ++++++++++++------------ core/state/state_object.go | 10 +++++----- core/state/statedb.go | 18 +++++++++--------- core/state/statedb_fuzz_test.go | 2 +- core/state/statedb_test.go | 2 +- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/core/state/journal.go b/core/state/journal.go index 0f7d0e61ab33..09b72aa45f6d 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -148,30 +148,30 @@ func (j *journal) copy() *journal { } } -func (j *journal) JournalAccessListAddAccount(addr common.Address) { +func (j *journal) AccessListAddAccount(addr common.Address) { j.append(accessListAddAccountChange{&addr}) } -func (j *journal) JournalAccessListAddSlot(addr common.Address, slot common.Hash) { +func (j *journal) AccessListAddSlot(addr common.Address, slot common.Hash) { j.append(accessListAddSlotChange{ address: &addr, slot: &slot, }) } -func (j *journal) JournalLog(txHash common.Hash) { +func (j *journal) Log(txHash common.Hash) { j.append(addLogChange{txhash: txHash}) } -func (j *journal) JournalCreate(addr common.Address) { +func (j *journal) Create(addr common.Address) { j.append(createObjectChange{account: &addr}) } -func (j *journal) JournalDestruct(addr common.Address) { +func (j *journal) Destruct(addr common.Address) { j.append(selfDestructChange{account: &addr}) } -func (j *journal) JournalSetState(addr common.Address, key, prev, origin common.Hash) { +func (j *journal) SetStorage(addr common.Address, key, prev, origin common.Hash) { j.append(storageChange{ account: &addr, key: key, @@ -180,7 +180,7 @@ func (j *journal) JournalSetState(addr common.Address, key, prev, origin common. }) } -func (j *journal) JournalSetTransientState(addr common.Address, key, prev common.Hash) { +func (j *journal) SetTransientState(addr common.Address, key, prev common.Hash) { j.append(transientStorageChange{ account: &addr, key: key, @@ -188,29 +188,29 @@ func (j *journal) JournalSetTransientState(addr common.Address, key, prev common }) } -func (j *journal) JournalRefundChange(previous uint64) { +func (j *journal) RefundChange(previous uint64) { j.append(refundChange{prev: previous}) } -func (j *journal) JournalBalanceChange(addr common.Address, previous *uint256.Int) { +func (j *journal) BalanceChange(addr common.Address, previous *uint256.Int) { j.append(balanceChange{ account: &addr, prev: previous.Clone(), }) } -func (j *journal) JournalSetCode(address common.Address) { +func (j *journal) SetCode(address common.Address) { j.append(codeChange{account: &address}) } -func (j *journal) JournalNonceChange(address common.Address, prev uint64) { +func (j *journal) NonceChange(address common.Address, prev uint64) { j.append(nonceChange{ account: &address, prev: prev, }) } -func (j *journal) JournalTouch(address common.Address) { +func (j *journal) Touch(address common.Address) { j.append(touchChange{ account: &address, }) diff --git a/core/state/state_object.go b/core/state/state_object.go index 7a2935a918ec..18f90f52698c 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -114,7 +114,7 @@ func (s *stateObject) markSelfdestructed() { } func (s *stateObject) touch() { - s.db.journal.JournalTouch(s.address) + s.db.journal.Touch(s.address) } // getTrie returns the associated storage trie. The trie will be opened if it's @@ -244,7 +244,7 @@ func (s *stateObject) SetState(key, value common.Hash) { return } // New value is different, update and journal the change - s.db.journal.JournalSetState(s.address, key, prev, origin) + s.db.journal.SetStorage(s.address, key, prev, origin) s.setState(key, value, origin) if s.db.logger != nil && s.db.logger.OnStorageChange != nil { s.db.logger.OnStorageChange(s.address, key, prev, value) @@ -498,7 +498,7 @@ func (s *stateObject) SubBalance(amount *uint256.Int, reason tracing.BalanceChan } func (s *stateObject) SetBalance(amount *uint256.Int, reason tracing.BalanceChangeReason) { - s.db.journal.JournalBalanceChange(s.address, s.data.Balance) + s.db.journal.BalanceChange(s.address, s.data.Balance) if s.db.logger != nil && s.db.logger.OnBalanceChange != nil { s.db.logger.OnBalanceChange(s.address, s.Balance().ToBig(), amount.ToBig(), reason) } @@ -574,7 +574,7 @@ func (s *stateObject) CodeSize() int { } func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { - s.db.journal.JournalSetCode(s.address) + s.db.journal.SetCode(s.address) if s.db.logger != nil && s.db.logger.OnCodeChange != nil { // TODO remove prevcode from this callback s.db.logger.OnCodeChange(s.address, common.BytesToHash(s.CodeHash()), nil, codeHash, code) @@ -589,7 +589,7 @@ func (s *stateObject) setCode(codeHash common.Hash, code []byte) { } func (s *stateObject) SetNonce(nonce uint64) { - s.db.journal.JournalNonceChange(s.address, s.data.Nonce) + s.db.journal.NonceChange(s.address, s.data.Nonce) if s.db.logger != nil && s.db.logger.OnNonceChange != nil { s.db.logger.OnNonceChange(s.address, s.data.Nonce, nonce) } diff --git a/core/state/statedb.go b/core/state/statedb.go index f43542010768..864dcbd0bbfd 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -248,7 +248,7 @@ func (s *StateDB) Error() error { } func (s *StateDB) AddLog(log *types.Log) { - s.journal.JournalLog(s.thash) + s.journal.Log(s.thash) log.TxHash = s.thash log.TxIndex = uint(s.txIndex) @@ -293,14 +293,14 @@ func (s *StateDB) Preimages() map[common.Hash][]byte { // AddRefund adds gas to the refund counter func (s *StateDB) AddRefund(gas uint64) { - s.journal.JournalRefundChange(s.refund) + s.journal.RefundChange(s.refund) s.refund += gas } // SubRefund removes gas from the refund counter. // This method will panic if the refund counter goes below zero func (s *StateDB) SubRefund(gas uint64) { - s.journal.JournalRefundChange(s.refund) + s.journal.RefundChange(s.refund) if gas > s.refund { panic(fmt.Sprintf("Refund counter below zero (gas: %d > refund: %d)", gas, s.refund)) } @@ -508,7 +508,7 @@ func (s *StateDB) SelfDestruct(addr common.Address) { // 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) + s.journal.Destruct(addr) stateObject.markSelfdestructed() } } @@ -531,7 +531,7 @@ func (s *StateDB) SetTransientState(addr common.Address, key, value common.Hash) if prev == value { return } - s.journal.JournalSetTransientState(addr, key, prev) + s.journal.SetTransientState(addr, key, prev) s.setTransientState(addr, key, value) } @@ -650,7 +650,7 @@ func (s *StateDB) getOrNewStateObject(addr common.Address) *stateObject { // existing account with the given address, otherwise it will be silently overwritten. func (s *StateDB) createObject(addr common.Address) *stateObject { obj := newObject(s, addr, nil) - s.journal.JournalCreate(addr) + s.journal.Create(addr) s.setStateObject(obj) return obj } @@ -1387,7 +1387,7 @@ func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, d // AddAddressToAccessList adds the given address to the access list func (s *StateDB) AddAddressToAccessList(addr common.Address) { if s.accessList.AddAddress(addr) { - s.journal.JournalAccessListAddAccount(addr) + s.journal.AccessListAddAccount(addr) } } @@ -1399,10 +1399,10 @@ func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { // scope of 'address' without having the 'address' become already added // to the access list (via call-variant, create, etc). // Better safe than sorry, though - s.journal.JournalAccessListAddAccount(addr) + s.journal.AccessListAddAccount(addr) } if slotMod { - s.journal.JournalAccessListAddSlot(addr, slot) + s.journal.AccessListAddSlot(addr, slot) } } diff --git a/core/state/statedb_fuzz_test.go b/core/state/statedb_fuzz_test.go index 40b079cd8a43..153035b9c168 100644 --- a/core/state/statedb_fuzz_test.go +++ b/core/state/statedb_fuzz_test.go @@ -73,7 +73,7 @@ func newStateTestAction(addr common.Address, r *rand.Rand, index int) testAction args: make([]int64, 1), }, { - name: "SetState", + name: "SetStorage", fn: func(a testAction, s *StateDB) { var key, val common.Hash binary.BigEndian.PutUint16(key[:], uint16(a.args[0])) diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 9256329ddcec..a8ae6eb6d3f5 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -360,7 +360,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { args: make([]int64, 1), }, { - name: "SetState", + name: "SetStorage", fn: func(a testAction, s *StateDB) { var key, val common.Hash binary.BigEndian.PutUint16(key[:], uint16(a.args[0])) From 542b83ce19819920576b73b19a4e2460c1fb9d8d Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Fri, 23 Aug 2024 15:24:57 +0800 Subject: [PATCH 8/9] core/state: polish code --- core/state/journal.go | 62 ++++++++++++++++++++------------------ core/state/state_object.go | 10 +++--- core/state/statedb.go | 26 ++++++++-------- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/core/state/journal.go b/core/state/journal.go index 09b72aa45f6d..4b69f97caa9f 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -63,26 +63,26 @@ func newJournal() *journal { } } -// Reset clears the journal, after this operation the journal can be used -// anew. It is semantically similar to calling 'newJournal', but the underlying -// slices can be reused -func (j *journal) Reset() { +// reset clears the journal, after this operation the journal can be used +// as new. It is semantically similar to calling 'newJournal', but the underlying +// slices can be reused. +func (j *journal) reset() { j.entries = j.entries[:0] j.validRevisions = j.validRevisions[:0] clear(j.dirties) j.nextRevisionId = 0 } -// Snapshot returns an identifier for the current revision of the state. -func (j *journal) Snapshot() int { +// snapshot returns an identifier for the current revision of the state. +func (j *journal) snapshot() int { id := j.nextRevisionId j.nextRevisionId++ j.validRevisions = append(j.validRevisions, revision{id, j.length()}) return id } -// RevertToSnapshot reverts all state changes made since the given revision. -func (j *journal) RevertToSnapshot(revid int, s *StateDB) { +// revertToSnapshot reverts all state changes made since the given revision. +func (j *journal) revertToSnapshot(revid int, s *StateDB) { // Find the snapshot in the stack of valid snapshots. idx := sort.Search(len(j.validRevisions), func(i int) bool { return j.validRevisions[i].id >= revid @@ -148,30 +148,23 @@ func (j *journal) copy() *journal { } } -func (j *journal) AccessListAddAccount(addr common.Address) { - j.append(accessListAddAccountChange{&addr}) -} - -func (j *journal) AccessListAddSlot(addr common.Address, slot common.Hash) { - j.append(accessListAddSlotChange{ - address: &addr, - slot: &slot, - }) -} - -func (j *journal) Log(txHash common.Hash) { +func (j *journal) logChange(txHash common.Hash) { j.append(addLogChange{txhash: txHash}) } -func (j *journal) Create(addr common.Address) { +func (j *journal) createObject(addr common.Address) { j.append(createObjectChange{account: &addr}) } -func (j *journal) Destruct(addr common.Address) { +func (j *journal) createContract(addr common.Address) { + j.append(createContractChange{account: addr}) +} + +func (j *journal) destruct(addr common.Address) { j.append(selfDestructChange{account: &addr}) } -func (j *journal) SetStorage(addr common.Address, key, prev, origin common.Hash) { +func (j *journal) storageChange(addr common.Address, key, prev, origin common.Hash) { j.append(storageChange{ account: &addr, key: key, @@ -180,7 +173,7 @@ func (j *journal) SetStorage(addr common.Address, key, prev, origin common.Hash) }) } -func (j *journal) SetTransientState(addr common.Address, key, prev common.Hash) { +func (j *journal) transientStateChange(addr common.Address, key, prev common.Hash) { j.append(transientStorageChange{ account: &addr, key: key, @@ -188,29 +181,29 @@ func (j *journal) SetTransientState(addr common.Address, key, prev common.Hash) }) } -func (j *journal) RefundChange(previous uint64) { +func (j *journal) refundChange(previous uint64) { j.append(refundChange{prev: previous}) } -func (j *journal) BalanceChange(addr common.Address, previous *uint256.Int) { +func (j *journal) balanceChange(addr common.Address, previous *uint256.Int) { j.append(balanceChange{ account: &addr, prev: previous.Clone(), }) } -func (j *journal) SetCode(address common.Address) { +func (j *journal) codeChange(address common.Address) { j.append(codeChange{account: &address}) } -func (j *journal) NonceChange(address common.Address, prev uint64) { +func (j *journal) nonceChange(address common.Address, prev uint64) { j.append(nonceChange{ account: &address, prev: prev, }) } -func (j *journal) Touch(address common.Address) { +func (j *journal) touchChange(address common.Address) { j.append(touchChange{ account: &address, }) @@ -221,6 +214,17 @@ func (j *journal) Touch(address common.Address) { } } +func (j *journal) accessListAddAccount(addr common.Address) { + j.append(accessListAddAccountChange{&addr}) +} + +func (j *journal) accessListAddSlot(addr common.Address, slot common.Hash) { + j.append(accessListAddSlotChange{ + address: &addr, + slot: &slot, + }) +} + type ( // Changes to the account trie. createObjectChange struct { diff --git a/core/state/state_object.go b/core/state/state_object.go index 18f90f52698c..87e15e338301 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -114,7 +114,7 @@ func (s *stateObject) markSelfdestructed() { } func (s *stateObject) touch() { - s.db.journal.Touch(s.address) + s.db.journal.touchChange(s.address) } // getTrie returns the associated storage trie. The trie will be opened if it's @@ -244,7 +244,7 @@ func (s *stateObject) SetState(key, value common.Hash) { return } // New value is different, update and journal the change - s.db.journal.SetStorage(s.address, key, prev, origin) + s.db.journal.storageChange(s.address, key, prev, origin) s.setState(key, value, origin) if s.db.logger != nil && s.db.logger.OnStorageChange != nil { s.db.logger.OnStorageChange(s.address, key, prev, value) @@ -498,7 +498,7 @@ func (s *stateObject) SubBalance(amount *uint256.Int, reason tracing.BalanceChan } func (s *stateObject) SetBalance(amount *uint256.Int, reason tracing.BalanceChangeReason) { - s.db.journal.BalanceChange(s.address, s.data.Balance) + s.db.journal.balanceChange(s.address, s.data.Balance) if s.db.logger != nil && s.db.logger.OnBalanceChange != nil { s.db.logger.OnBalanceChange(s.address, s.Balance().ToBig(), amount.ToBig(), reason) } @@ -574,7 +574,7 @@ func (s *stateObject) CodeSize() int { } func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { - s.db.journal.SetCode(s.address) + s.db.journal.codeChange(s.address) if s.db.logger != nil && s.db.logger.OnCodeChange != nil { // TODO remove prevcode from this callback s.db.logger.OnCodeChange(s.address, common.BytesToHash(s.CodeHash()), nil, codeHash, code) @@ -589,7 +589,7 @@ func (s *stateObject) setCode(codeHash common.Hash, code []byte) { } func (s *stateObject) SetNonce(nonce uint64) { - s.db.journal.NonceChange(s.address, s.data.Nonce) + s.db.journal.nonceChange(s.address, s.data.Nonce) if s.db.logger != nil && s.db.logger.OnNonceChange != nil { s.db.logger.OnNonceChange(s.address, s.data.Nonce, nonce) } diff --git a/core/state/statedb.go b/core/state/statedb.go index 864dcbd0bbfd..d9bf8d81265c 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -248,7 +248,7 @@ func (s *StateDB) Error() error { } func (s *StateDB) AddLog(log *types.Log) { - s.journal.Log(s.thash) + s.journal.logChange(s.thash) log.TxHash = s.thash log.TxIndex = uint(s.txIndex) @@ -293,14 +293,14 @@ func (s *StateDB) Preimages() map[common.Hash][]byte { // AddRefund adds gas to the refund counter func (s *StateDB) AddRefund(gas uint64) { - s.journal.RefundChange(s.refund) + s.journal.refundChange(s.refund) s.refund += gas } // SubRefund removes gas from the refund counter. // This method will panic if the refund counter goes below zero func (s *StateDB) SubRefund(gas uint64) { - s.journal.RefundChange(s.refund) + s.journal.refundChange(s.refund) if gas > s.refund { panic(fmt.Sprintf("Refund counter below zero (gas: %d > refund: %d)", gas, s.refund)) } @@ -508,7 +508,7 @@ func (s *StateDB) SelfDestruct(addr common.Address) { // 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.Destruct(addr) + s.journal.destruct(addr) stateObject.markSelfdestructed() } } @@ -531,7 +531,7 @@ func (s *StateDB) SetTransientState(addr common.Address, key, value common.Hash) if prev == value { return } - s.journal.SetTransientState(addr, key, prev) + s.journal.transientStateChange(addr, key, prev) s.setTransientState(addr, key, value) } @@ -650,7 +650,7 @@ func (s *StateDB) getOrNewStateObject(addr common.Address) *stateObject { // existing account with the given address, otherwise it will be silently overwritten. func (s *StateDB) createObject(addr common.Address) *stateObject { obj := newObject(s, addr, nil) - s.journal.Create(addr) + s.journal.createObject(addr) s.setStateObject(obj) return obj } @@ -672,7 +672,7 @@ func (s *StateDB) CreateContract(addr common.Address) { obj := s.getStateObject(addr) if !obj.newContract { obj.newContract = true - s.journal.append(createContractChange{account: addr}) + s.journal.createContract(addr) } } @@ -741,12 +741,12 @@ func (s *StateDB) Copy() *StateDB { // Snapshot returns an identifier for the current revision of the state. func (s *StateDB) Snapshot() int { - return s.journal.Snapshot() + return s.journal.snapshot() } // RevertToSnapshot reverts all state changes made since the given revision. func (s *StateDB) RevertToSnapshot(revid int) { - s.journal.RevertToSnapshot(revid, s) + s.journal.revertToSnapshot(revid, s) } // GetRefund returns the current value of the refund counter. @@ -960,7 +960,7 @@ func (s *StateDB) SetTxContext(thash common.Hash, ti int) { } func (s *StateDB) clearJournalAndRefund() { - s.journal.Reset() + s.journal.reset() s.refund = 0 } @@ -1387,7 +1387,7 @@ func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, d // AddAddressToAccessList adds the given address to the access list func (s *StateDB) AddAddressToAccessList(addr common.Address) { if s.accessList.AddAddress(addr) { - s.journal.AccessListAddAccount(addr) + s.journal.accessListAddAccount(addr) } } @@ -1399,10 +1399,10 @@ func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { // scope of 'address' without having the 'address' become already added // to the access list (via call-variant, create, etc). // Better safe than sorry, though - s.journal.AccessListAddAccount(addr) + s.journal.accessListAddAccount(addr) } if slotMod { - s.journal.AccessListAddSlot(addr, slot) + s.journal.accessListAddSlot(addr, slot) } } From 01f050b96ed5a1c9721107167023e0e64464cb15 Mon Sep 17 00:00:00 2001 From: Gary Rong Date: Tue, 27 Aug 2024 13:54:26 +0800 Subject: [PATCH 9/9] core/state: address comments --- core/state/journal.go | 8 ++++---- core/state/state_object.go | 2 +- core/state/statedb.go | 3 --- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/core/state/journal.go b/core/state/journal.go index 4b69f97caa9f..f180a5dae4b6 100644 --- a/core/state/journal.go +++ b/core/state/journal.go @@ -63,9 +63,9 @@ func newJournal() *journal { } } -// reset clears the journal, after this operation the journal can be used -// as new. It is semantically similar to calling 'newJournal', but the underlying -// slices can be reused. +// reset clears the journal, after this operation the journal can be used anew. +// It is semantically similar to calling 'newJournal', but the underlying slices +// can be reused. func (j *journal) reset() { j.entries = j.entries[:0] j.validRevisions = j.validRevisions[:0] @@ -192,7 +192,7 @@ func (j *journal) balanceChange(addr common.Address, previous *uint256.Int) { }) } -func (j *journal) codeChange(address common.Address) { +func (j *journal) setCode(address common.Address) { j.append(codeChange{account: &address}) } diff --git a/core/state/state_object.go b/core/state/state_object.go index 87e15e338301..366bdc2747b1 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -574,7 +574,7 @@ func (s *stateObject) CodeSize() int { } func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { - s.db.journal.codeChange(s.address) + s.db.journal.setCode(s.address) if s.db.logger != nil && s.db.logger.OnCodeChange != nil { // TODO remove prevcode from this callback s.db.logger.OnCodeChange(s.address, common.BytesToHash(s.CodeHash()), nil, codeHash, code) diff --git a/core/state/statedb.go b/core/state/statedb.go index d9bf8d81265c..29bc830f09c2 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -500,9 +500,6 @@ func (s *StateDB) SelfDestruct(addr common.Address) { // 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() { - if s.logger != nil && s.logger.OnBalanceChange != nil { - s.logger.OnBalanceChange(addr, stateObject.Balance().ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct) - } stateObject.SetBalance(new(uint256.Int), tracing.BalanceDecreaseSelfdestruct) } // If it is already marked as self-destructed, we do not need to add it