17
17
package state
18
18
19
19
import (
20
+ "maps"
21
+
20
22
"github.com/ethereum/go-ethereum/common"
21
23
"github.com/holiman/uint256"
22
24
)
@@ -29,6 +31,9 @@ type journalEntry interface {
29
31
30
32
// dirtied returns the Ethereum address modified by this journal entry.
31
33
dirtied () * common.Address
34
+
35
+ // copy returns a deep-copied journal entry.
36
+ copy () journalEntry
32
37
}
33
38
34
39
// journal contains the list of state modifications applied since the last state
@@ -83,22 +88,31 @@ func (j *journal) length() int {
83
88
return len (j .entries )
84
89
}
85
90
91
+ // copy returns a deep-copied journal.
92
+ func (j * journal ) copy () * journal {
93
+ entries := make ([]journalEntry , 0 , j .length ())
94
+ for i := 0 ; i < j .length (); i ++ {
95
+ entries = append (entries , j .entries [i ].copy ())
96
+ }
97
+ return & journal {
98
+ entries : entries ,
99
+ dirties : maps .Clone (j .dirties ),
100
+ }
101
+ }
102
+
86
103
type (
87
104
// Changes to the account trie.
88
105
createObjectChange struct {
89
106
account * common.Address
90
107
}
91
- resetObjectChange struct {
92
- account * common.Address
93
- prev * stateObject
94
- prevdestruct bool
95
- prevAccount []byte
96
- prevStorage map [common.Hash ][]byte
97
108
98
- prevAccountOriginExist bool
99
- prevAccountOrigin []byte
100
- prevStorageOrigin map [common.Hash ][]byte
109
+ // createContractChange represents an account becoming a contract-account.
110
+ // This event happens prior to executing initcode. The journal-event simply
111
+ // manages the created-flag, in order to allow same-tx destruction.
112
+ createContractChange struct {
113
+ account common.Address
101
114
}
115
+
102
116
selfDestructChange struct {
103
117
account * common.Address
104
118
prev bool // whether account had already self-destructed
@@ -136,6 +150,7 @@ type (
136
150
touchChange struct {
137
151
account * common.Address
138
152
}
153
+
139
154
// Changes to the access list
140
155
accessListAddAccountChange struct {
141
156
address * common.Address
@@ -145,6 +160,7 @@ type (
145
160
slot * common.Hash
146
161
}
147
162
163
+ // Changes to transient storage
148
164
transientStorageChange struct {
149
165
account * common.Address
150
166
key , prevalue common.Hash
@@ -153,34 +169,30 @@ type (
153
169
154
170
func (ch createObjectChange ) revert (s * StateDB ) {
155
171
delete (s .stateObjects , * ch .account )
156
- delete (s .stateObjectsDirty , * ch .account )
157
172
}
158
173
159
174
func (ch createObjectChange ) dirtied () * common.Address {
160
175
return ch .account
161
176
}
162
177
163
- func (ch resetObjectChange ) revert (s * StateDB ) {
164
- s .setStateObject (ch .prev )
165
- if ! ch .prevdestruct {
166
- delete (s .stateObjectsDestruct , ch .prev .address )
167
- }
168
- if ch .prevAccount != nil {
169
- s .accounts [ch .prev .addrHash ] = ch .prevAccount
170
- }
171
- if ch .prevStorage != nil {
172
- s .storages [ch .prev .addrHash ] = ch .prevStorage
173
- }
174
- if ch .prevAccountOriginExist {
175
- s .accountsOrigin [ch .prev .address ] = ch .prevAccountOrigin
176
- }
177
- if ch .prevStorageOrigin != nil {
178
- s .storagesOrigin [ch .prev .address ] = ch .prevStorageOrigin
178
+ func (ch createObjectChange ) copy () journalEntry {
179
+ return createObjectChange {
180
+ account : ch .account ,
179
181
}
180
182
}
181
183
182
- func (ch resetObjectChange ) dirtied () * common.Address {
183
- return ch .account
184
+ func (ch createContractChange ) revert (s * StateDB ) {
185
+ s .getStateObject (ch .account ).newContract = false
186
+ }
187
+
188
+ func (ch createContractChange ) dirtied () * common.Address {
189
+ return nil
190
+ }
191
+
192
+ func (ch createContractChange ) copy () journalEntry {
193
+ return createContractChange {
194
+ account : ch .account ,
195
+ }
184
196
}
185
197
186
198
func (ch selfDestructChange ) revert (s * StateDB ) {
@@ -195,6 +207,14 @@ func (ch selfDestructChange) dirtied() *common.Address {
195
207
return ch .account
196
208
}
197
209
210
+ func (ch selfDestructChange ) copy () journalEntry {
211
+ return selfDestructChange {
212
+ account : ch .account ,
213
+ prev : ch .prev ,
214
+ prevbalance : new (uint256.Int ).Set (ch .prevbalance ),
215
+ }
216
+ }
217
+
198
218
var ripemd = common .HexToAddress ("0000000000000000000000000000000000000003" )
199
219
200
220
func (ch touchChange ) revert (s * StateDB ) {
@@ -204,6 +224,12 @@ func (ch touchChange) dirtied() *common.Address {
204
224
return ch .account
205
225
}
206
226
227
+ func (ch touchChange ) copy () journalEntry {
228
+ return touchChange {
229
+ account : ch .account ,
230
+ }
231
+ }
232
+
207
233
func (ch balanceChange ) revert (s * StateDB ) {
208
234
s .getStateObject (* ch .account ).setBalance (ch .prev )
209
235
}
@@ -212,6 +238,13 @@ func (ch balanceChange) dirtied() *common.Address {
212
238
return ch .account
213
239
}
214
240
241
+ func (ch balanceChange ) copy () journalEntry {
242
+ return balanceChange {
243
+ account : ch .account ,
244
+ prev : new (uint256.Int ).Set (ch .prev ),
245
+ }
246
+ }
247
+
215
248
func (ch nonceChange ) revert (s * StateDB ) {
216
249
s .getStateObject (* ch .account ).setNonce (ch .prev )
217
250
}
@@ -220,6 +253,13 @@ func (ch nonceChange) dirtied() *common.Address {
220
253
return ch .account
221
254
}
222
255
256
+ func (ch nonceChange ) copy () journalEntry {
257
+ return nonceChange {
258
+ account : ch .account ,
259
+ prev : ch .prev ,
260
+ }
261
+ }
262
+
223
263
func (ch codeChange ) revert (s * StateDB ) {
224
264
s .getStateObject (* ch .account ).setCode (common .BytesToHash (ch .prevhash ), ch .prevcode )
225
265
}
@@ -228,6 +268,14 @@ func (ch codeChange) dirtied() *common.Address {
228
268
return ch .account
229
269
}
230
270
271
+ func (ch codeChange ) copy () journalEntry {
272
+ return codeChange {
273
+ account : ch .account ,
274
+ prevhash : common .CopyBytes (ch .prevhash ),
275
+ prevcode : common .CopyBytes (ch .prevcode ),
276
+ }
277
+ }
278
+
231
279
func (ch storageChange ) revert (s * StateDB ) {
232
280
s .getStateObject (* ch .account ).setState (ch .key , ch .prevalue )
233
281
}
@@ -236,6 +284,14 @@ func (ch storageChange) dirtied() *common.Address {
236
284
return ch .account
237
285
}
238
286
287
+ func (ch storageChange ) copy () journalEntry {
288
+ return storageChange {
289
+ account : ch .account ,
290
+ key : ch .key ,
291
+ prevalue : ch .prevalue ,
292
+ }
293
+ }
294
+
239
295
func (ch transientStorageChange ) revert (s * StateDB ) {
240
296
s .setTransientState (* ch .account , ch .key , ch .prevalue )
241
297
}
@@ -244,6 +300,14 @@ func (ch transientStorageChange) dirtied() *common.Address {
244
300
return nil
245
301
}
246
302
303
+ func (ch transientStorageChange ) copy () journalEntry {
304
+ return transientStorageChange {
305
+ account : ch .account ,
306
+ key : ch .key ,
307
+ prevalue : ch .prevalue ,
308
+ }
309
+ }
310
+
247
311
func (ch refundChange ) revert (s * StateDB ) {
248
312
s .refund = ch .prev
249
313
}
@@ -252,6 +316,12 @@ func (ch refundChange) dirtied() *common.Address {
252
316
return nil
253
317
}
254
318
319
+ func (ch refundChange ) copy () journalEntry {
320
+ return refundChange {
321
+ prev : ch .prev ,
322
+ }
323
+ }
324
+
255
325
func (ch addLogChange ) revert (s * StateDB ) {
256
326
logs := s .logs [ch .txhash ]
257
327
if len (logs ) == 1 {
@@ -266,6 +336,12 @@ func (ch addLogChange) dirtied() *common.Address {
266
336
return nil
267
337
}
268
338
339
+ func (ch addLogChange ) copy () journalEntry {
340
+ return addLogChange {
341
+ txhash : ch .txhash ,
342
+ }
343
+ }
344
+
269
345
func (ch addPreimageChange ) revert (s * StateDB ) {
270
346
delete (s .preimages , ch .hash )
271
347
}
@@ -274,6 +350,12 @@ func (ch addPreimageChange) dirtied() *common.Address {
274
350
return nil
275
351
}
276
352
353
+ func (ch addPreimageChange ) copy () journalEntry {
354
+ return addPreimageChange {
355
+ hash : ch .hash ,
356
+ }
357
+ }
358
+
277
359
func (ch accessListAddAccountChange ) revert (s * StateDB ) {
278
360
/*
279
361
One important invariant here, is that whenever a (addr, slot) is added, if the
@@ -291,10 +373,23 @@ func (ch accessListAddAccountChange) dirtied() *common.Address {
291
373
return nil
292
374
}
293
375
376
+ func (ch accessListAddAccountChange ) copy () journalEntry {
377
+ return accessListAddAccountChange {
378
+ address : ch .address ,
379
+ }
380
+ }
381
+
294
382
func (ch accessListAddSlotChange ) revert (s * StateDB ) {
295
383
s .accessList .DeleteSlot (* ch .address , * ch .slot )
296
384
}
297
385
298
386
func (ch accessListAddSlotChange ) dirtied () * common.Address {
299
387
return nil
300
388
}
389
+
390
+ func (ch accessListAddSlotChange ) copy () journalEntry {
391
+ return accessListAddSlotChange {
392
+ address : ch .address ,
393
+ slot : ch .slot ,
394
+ }
395
+ }
0 commit comments