Skip to content

Commit b5a08b2

Browse files
committed
core/state: remove account reset operation v2 ethereum#29520
1 parent 71f929d commit b5a08b2

File tree

7 files changed

+470
-317
lines changed

7 files changed

+470
-317
lines changed

core/state/journal.go

Lines changed: 110 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package state
1818

1919
import (
20+
"maps"
2021
"math/big"
2122

2223
"github.com/XinFinOrg/XDPoSChain/common"
@@ -31,6 +32,9 @@ type journalEntry interface {
3132

3233
// dirtied returns the Ethereum address modified by this journal entry.
3334
dirtied() *common.Address
35+
36+
// copy returns a deep-copied journal entry.
37+
copy() journalEntry
3438
}
3539

3640
// journal contains the list of state modifications applied since the last state
@@ -85,6 +89,18 @@ func (j *journal) length() int {
8589
return len(j.entries)
8690
}
8791

92+
// copy returns a deep-copied journal.
93+
func (j *journal) copy() *journal {
94+
entries := make([]journalEntry, 0, j.length())
95+
for i := 0; i < j.length(); i++ {
96+
entries = append(entries, j.entries[i].copy())
97+
}
98+
return &journal{
99+
entries: entries,
100+
dirties: maps.Clone(j.dirties),
101+
}
102+
}
103+
88104
func (j *journal) createContract(addr common.Address) {
89105
j.append(createContractChange{account: addr})
90106
}
@@ -107,11 +123,6 @@ type (
107123
createContractChange struct {
108124
account common.Address
109125
}
110-
resetObjectChange struct {
111-
account common.Address
112-
prev *stateObject
113-
prevdestruct bool
114-
}
115126
selfDestructChange struct {
116127
account common.Address
117128
prev bool // whether account had already self-destructed
@@ -149,6 +160,7 @@ type (
149160
touchChange struct {
150161
account common.Address
151162
}
163+
152164
// Changes to the access list
153165
accessListAddAccountChange struct {
154166
address common.Address
@@ -158,6 +170,7 @@ type (
158170
slot common.Hash
159171
}
160172

173+
// Changes to transient storage
161174
transientStorageChange struct {
162175
account common.Address
163176
key, prevalue common.Hash
@@ -166,32 +179,32 @@ type (
166179

167180
func (ch createObjectChange) revert(s *StateDB) {
168181
delete(s.stateObjects, ch.account)
169-
delete(s.stateObjectsDirty, ch.account)
170182
}
171183

172184
func (ch createObjectChange) dirtied() *common.Address {
173185
return &ch.account
174186
}
175187

188+
func (ch createObjectChange) copy() journalEntry {
189+
return createObjectChange{
190+
account: ch.account,
191+
}
192+
}
193+
176194
func (ch createContractChange) revert(s *StateDB) {
177-
s.getStateObject(ch.account).created = false
195+
s.getStateObject(ch.account).newContract = false
178196
}
179197

180198
func (ch createContractChange) dirtied() *common.Address {
181199
return nil
182200
}
183201

184-
func (ch resetObjectChange) revert(s *StateDB) {
185-
s.setStateObject(ch.prev)
186-
if !ch.prevdestruct {
187-
delete(s.stateObjectsDestruct, ch.prev.address)
202+
func (ch createContractChange) copy() journalEntry {
203+
return createContractChange{
204+
account: ch.account,
188205
}
189206
}
190207

191-
func (ch resetObjectChange) dirtied() *common.Address {
192-
return &ch.account
193-
}
194-
195208
func (ch selfDestructChange) revert(s *StateDB) {
196209
obj := s.getStateObject(ch.account)
197210
if obj != nil {
@@ -204,6 +217,14 @@ func (ch selfDestructChange) dirtied() *common.Address {
204217
return &ch.account
205218
}
206219

220+
func (ch selfDestructChange) copy() journalEntry {
221+
return selfDestructChange{
222+
account: ch.account,
223+
prev: ch.prev,
224+
prevbalance: new(big.Int).Set(ch.prevbalance),
225+
}
226+
}
227+
207228
var ripemd = common.HexToAddress("0000000000000000000000000000000000000003")
208229

209230
func (ch touchChange) revert(s *StateDB) {
@@ -213,6 +234,12 @@ func (ch touchChange) dirtied() *common.Address {
213234
return &ch.account
214235
}
215236

237+
func (ch touchChange) copy() journalEntry {
238+
return touchChange{
239+
account: ch.account,
240+
}
241+
}
242+
216243
func (ch balanceChange) revert(s *StateDB) {
217244
s.getStateObject(ch.account).setBalance(ch.prev)
218245
}
@@ -221,6 +248,13 @@ func (ch balanceChange) dirtied() *common.Address {
221248
return &ch.account
222249
}
223250

251+
func (ch balanceChange) copy() journalEntry {
252+
return balanceChange{
253+
account: ch.account,
254+
prev: new(big.Int).Set(ch.prev),
255+
}
256+
}
257+
224258
func (ch nonceChange) revert(s *StateDB) {
225259
s.getStateObject(ch.account).setNonce(ch.prev)
226260
}
@@ -229,6 +263,13 @@ func (ch nonceChange) dirtied() *common.Address {
229263
return &ch.account
230264
}
231265

266+
func (ch nonceChange) copy() journalEntry {
267+
return nonceChange{
268+
account: ch.account,
269+
prev: ch.prev,
270+
}
271+
}
272+
232273
func (ch codeChange) revert(s *StateDB) {
233274
s.getStateObject(ch.account).setCode(crypto.Keccak256Hash(ch.prevCode), ch.prevCode)
234275
}
@@ -237,6 +278,13 @@ func (ch codeChange) dirtied() *common.Address {
237278
return &ch.account
238279
}
239280

281+
func (ch codeChange) copy() journalEntry {
282+
return codeChange{
283+
account: ch.account,
284+
prevCode: common.CopyBytes(ch.prevCode),
285+
}
286+
}
287+
240288
func (ch storageChange) revert(s *StateDB) {
241289
s.getStateObject(ch.account).setState(ch.key, ch.prevalue)
242290
}
@@ -245,6 +293,14 @@ func (ch storageChange) dirtied() *common.Address {
245293
return &ch.account
246294
}
247295

296+
func (ch storageChange) copy() journalEntry {
297+
return storageChange{
298+
account: ch.account,
299+
key: ch.key,
300+
prevalue: ch.prevalue,
301+
}
302+
}
303+
248304
func (ch transientStorageChange) revert(s *StateDB) {
249305
s.setTransientState(ch.account, ch.key, ch.prevalue)
250306
}
@@ -253,6 +309,14 @@ func (ch transientStorageChange) dirtied() *common.Address {
253309
return nil
254310
}
255311

312+
func (ch transientStorageChange) copy() journalEntry {
313+
return transientStorageChange{
314+
account: ch.account,
315+
key: ch.key,
316+
prevalue: ch.prevalue,
317+
}
318+
}
319+
256320
func (ch refundChange) revert(s *StateDB) {
257321
s.refund = ch.prev
258322
}
@@ -261,6 +325,12 @@ func (ch refundChange) dirtied() *common.Address {
261325
return nil
262326
}
263327

328+
func (ch refundChange) copy() journalEntry {
329+
return refundChange{
330+
prev: ch.prev,
331+
}
332+
}
333+
264334
func (ch addLogChange) revert(s *StateDB) {
265335
logs := s.logs[ch.txhash]
266336
if len(logs) == 1 {
@@ -275,6 +345,12 @@ func (ch addLogChange) dirtied() *common.Address {
275345
return nil
276346
}
277347

348+
func (ch addLogChange) copy() journalEntry {
349+
return addLogChange{
350+
txhash: ch.txhash,
351+
}
352+
}
353+
278354
func (ch addPreimageChange) revert(s *StateDB) {
279355
delete(s.preimages, ch.hash)
280356
}
@@ -283,6 +359,12 @@ func (ch addPreimageChange) dirtied() *common.Address {
283359
return nil
284360
}
285361

362+
func (ch addPreimageChange) copy() journalEntry {
363+
return addPreimageChange{
364+
hash: ch.hash,
365+
}
366+
}
367+
286368
func (ch accessListAddAccountChange) revert(s *StateDB) {
287369
/*
288370
One important invariant here, is that whenever a (addr, slot) is added, if the
@@ -300,10 +382,23 @@ func (ch accessListAddAccountChange) dirtied() *common.Address {
300382
return nil
301383
}
302384

385+
func (ch accessListAddAccountChange) copy() journalEntry {
386+
return accessListAddAccountChange{
387+
address: ch.address,
388+
}
389+
}
390+
303391
func (ch accessListAddSlotChange) revert(s *StateDB) {
304392
s.accessList.DeleteSlot(ch.address, ch.slot)
305393
}
306394

307395
func (ch accessListAddSlotChange) dirtied() *common.Address {
308396
return nil
309397
}
398+
399+
func (ch accessListAddSlotChange) copy() journalEntry {
400+
return accessListAddSlotChange{
401+
address: ch.address,
402+
slot: ch.slot,
403+
}
404+
}

core/state/state_object.go

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,8 @@ import (
3232
"github.com/XinFinOrg/XDPoSChain/trie"
3333
)
3434

35-
type Code []byte
36-
37-
func (c Code) String() string {
38-
return string(c) //strings.Join(Disassemble(c), " ")
39-
}
40-
4135
type Storage map[common.Hash]common.Hash
4236

43-
func (s Storage) String() (str string) {
44-
for key, value := range s {
45-
str += fmt.Sprintf("%X : %X\n", key, value)
46-
}
47-
48-
return
49-
}
50-
5137
func (s Storage) Copy() Storage {
5238
return maps.Clone(s)
5339
}
@@ -60,9 +46,10 @@ func (s Storage) Copy() Storage {
6046
// Finally, call commitTrie to write the modified storage trie into a database.
6147
type stateObject struct {
6248
db *StateDB
63-
address common.Address // address of ethereum account
64-
addrHash common.Hash // hash of ethereum address of the account
65-
data types.StateAccount // Account data with all mutations applied in the scope of block
49+
address common.Address // address of ethereum account
50+
addrHash common.Hash // hash of ethereum address of the account
51+
origin *types.StateAccount // Account original data without any change applied, nil means it was not existent
52+
data types.StateAccount // Account data with all mutations applied in the scope of block
6653

6754
// DB error.
6855
// State objects are used by the consensus core and VM which are
@@ -72,8 +59,8 @@ type stateObject struct {
7259
dbErr error
7360

7461
// Write caches.
75-
trie Trie // storage trie, which becomes non-nil on first access
76-
code Code // contract bytecode, which gets set when code is loaded
62+
trie Trie // storage trie, which becomes non-nil on first access
63+
code []byte // contract bytecode, which gets set when code is loaded
7764

7865
originStorage Storage // Storage cache of original entries to dedup rewrites, reset for every transaction
7966
pendingStorage Storage // Storage entries that need to be flushed to disk, at the end of an entire block
@@ -86,13 +73,12 @@ type stateObject struct {
8673
// account is still accessible in the scope of same transaction.
8774
selfDestructed bool
8875

89-
// Flag whether the account was marked as deleted. A self-destructed account
90-
// or an account that is considered as empty will be marked as deleted at
91-
// the end of transaction and no longer accessible anymore.
92-
deleted bool
93-
94-
// Flag whether the object was created in the current transaction
95-
created bool
76+
// This is an EIP-6780 flag indicating whether the object is eligible for
77+
// self-destruct according to EIP-6780. The flag could be set either when
78+
// the contract is just created within the current transaction, or when the
79+
// object was previously existent and is being deployed as a contract within
80+
// the current transaction.
81+
newContract bool
9682
}
9783

9884
// empty returns whether the account is considered empty.
@@ -248,6 +234,10 @@ func (s *stateObject) finalise() {
248234
if len(s.dirtyStorage) > 0 {
249235
s.dirtyStorage = make(Storage)
250236
}
237+
// Revoke the flag at the end of the transaction. It finalizes the status
238+
// of the newly-created object as it's no longer eligible for self-destruct
239+
// by EIP-6780. For non-newly-created objects, it's a no-op.
240+
s.newContract = false
251241
}
252242

253243
// updateTrie writes cached storage modifications into the object's storage trie.
@@ -371,12 +361,12 @@ func (s *stateObject) deepCopy(db *StateDB) *stateObject {
371361
stateObject.trie = db.db.CopyTrie(s.trie)
372362
}
373363
stateObject.code = s.code
374-
stateObject.dirtyStorage = s.dirtyStorage.Copy()
375364
stateObject.originStorage = s.originStorage.Copy()
376365
stateObject.pendingStorage = s.pendingStorage.Copy()
377-
stateObject.selfDestructed = s.selfDestructed
366+
stateObject.dirtyStorage = s.dirtyStorage.Copy()
378367
stateObject.dirtyCode = s.dirtyCode
379-
stateObject.deleted = s.deleted
368+
stateObject.selfDestructed = s.selfDestructed
369+
stateObject.newContract = s.newContract
380370
return stateObject
381371
}
382372

@@ -391,7 +381,7 @@ func (s *stateObject) Address() common.Address {
391381

392382
// Code returns the contract code associated with this object, if any.
393383
func (s *stateObject) Code(db Database) []byte {
394-
if s.code != nil {
384+
if len(s.code) != 0 {
395385
return s.code
396386
}
397387
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {
@@ -409,7 +399,7 @@ func (s *stateObject) Code(db Database) []byte {
409399
// or zero if none. This method is an almost mirror of Code, but uses a cache
410400
// inside the database to avoid loading codes seen recently.
411401
func (s *stateObject) CodeSize(db Database) int {
412-
if s.code != nil {
402+
if len(s.code) != 0 {
413403
return len(s.code)
414404
}
415405
if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) {

0 commit comments

Comments
 (0)