@@ -30,6 +30,9 @@ type journalEntry interface {
30
30
31
31
// dirtied returns the Ethereum address modified by this journal entry.
32
32
dirtied () * common.Address
33
+
34
+ // copy returns a deep-copied journal entry.
35
+ copy () journalEntry
33
36
}
34
37
35
38
// journal contains the list of state modifications applied since the last state
@@ -84,6 +87,22 @@ func (j *journal) length() int {
84
87
return len (j .entries )
85
88
}
86
89
90
+ // copy returns a deep-copied journal.
91
+ func (j * journal ) copy () * journal {
92
+ entries := make ([]journalEntry , 0 , j .length ())
93
+ for i := 0 ; i < j .length (); i ++ {
94
+ entries = append (entries , j .entries [i ].copy ())
95
+ }
96
+ dirties := make (map [common.Address ]int )
97
+ for addr , count := range j .dirties {
98
+ dirties [addr ] = count
99
+ }
100
+ return & journal {
101
+ entries : entries ,
102
+ dirties : dirties ,
103
+ }
104
+ }
105
+
87
106
type (
88
107
// Changes to the account trie.
89
108
createObjectChange struct {
@@ -137,6 +156,7 @@ type (
137
156
touchChange struct {
138
157
account * common.Address
139
158
}
159
+
140
160
// Changes to the access list
141
161
accessListAddAccountChange struct {
142
162
address * common.Address
@@ -146,6 +166,7 @@ type (
146
166
slot * common.Hash
147
167
}
148
168
169
+ // Changes to transient storage
149
170
transientStorageChange struct {
150
171
account * common.Address
151
172
key , prevalue common.Hash
@@ -154,13 +175,18 @@ type (
154
175
155
176
func (ch createObjectChange ) revert (s * StateDB ) {
156
177
delete (s .stateObjects , * ch .account )
157
- delete (s .stateObjectsDirty , * ch .account )
158
178
}
159
179
160
180
func (ch createObjectChange ) dirtied () * common.Address {
161
181
return ch .account
162
182
}
163
183
184
+ func (ch createObjectChange ) copy () journalEntry {
185
+ return createObjectChange {
186
+ account : ch .account ,
187
+ }
188
+ }
189
+
164
190
func (ch resetObjectChange ) revert (s * StateDB ) {
165
191
s .setStateObject (ch .prev )
166
192
if ! ch .prevdestruct {
@@ -184,6 +210,27 @@ func (ch resetObjectChange) dirtied() *common.Address {
184
210
return ch .account
185
211
}
186
212
213
+ func (ch resetObjectChange ) copy () journalEntry {
214
+ prevStorage := make (map [common.Hash ][]byte )
215
+ for key , slot := range ch .prevStorage {
216
+ prevStorage [key ] = common .CopyBytes (slot )
217
+ }
218
+ prevStorageOrigin := make (map [common.Hash ][]byte )
219
+ for key , slot := range ch .prevStorageOrigin {
220
+ prevStorageOrigin [key ] = common .CopyBytes (slot )
221
+ }
222
+ return resetObjectChange {
223
+ account : ch .account ,
224
+ prev : ch .prev .deepCopy (),
225
+ prevdestruct : ch .prevdestruct ,
226
+ prevAccount : common .CopyBytes (ch .prevAccount ),
227
+ prevStorage : prevStorage ,
228
+ prevAccountOriginExist : ch .prevAccountOriginExist ,
229
+ prevAccountOrigin : common .CopyBytes (ch .prevAccountOrigin ),
230
+ prevStorageOrigin : prevStorageOrigin ,
231
+ }
232
+ }
233
+
187
234
func (ch selfDestructChange ) revert (s * StateDB ) {
188
235
obj := s .getStateObject (* ch .account )
189
236
if obj != nil {
@@ -196,6 +243,14 @@ func (ch selfDestructChange) dirtied() *common.Address {
196
243
return ch .account
197
244
}
198
245
246
+ func (ch selfDestructChange ) copy () journalEntry {
247
+ return selfDestructChange {
248
+ account : ch .account ,
249
+ prev : ch .prev ,
250
+ prevbalance : new (big.Int ).Set (ch .prevbalance ),
251
+ }
252
+ }
253
+
199
254
var ripemd = common .HexToAddress ("0000000000000000000000000000000000000003" )
200
255
201
256
func (ch touchChange ) revert (s * StateDB ) {
@@ -205,6 +260,12 @@ func (ch touchChange) dirtied() *common.Address {
205
260
return ch .account
206
261
}
207
262
263
+ func (ch touchChange ) copy () journalEntry {
264
+ return touchChange {
265
+ account : ch .account ,
266
+ }
267
+ }
268
+
208
269
func (ch balanceChange ) revert (s * StateDB ) {
209
270
s .getStateObject (* ch .account ).setBalance (ch .prev )
210
271
}
@@ -213,6 +274,13 @@ func (ch balanceChange) dirtied() *common.Address {
213
274
return ch .account
214
275
}
215
276
277
+ func (ch balanceChange ) copy () journalEntry {
278
+ return balanceChange {
279
+ account : ch .account ,
280
+ prev : new (big.Int ).Set (ch .prev ),
281
+ }
282
+ }
283
+
216
284
func (ch nonceChange ) revert (s * StateDB ) {
217
285
s .getStateObject (* ch .account ).setNonce (ch .prev )
218
286
}
@@ -221,6 +289,13 @@ func (ch nonceChange) dirtied() *common.Address {
221
289
return ch .account
222
290
}
223
291
292
+ func (ch nonceChange ) copy () journalEntry {
293
+ return nonceChange {
294
+ account : ch .account ,
295
+ prev : ch .prev ,
296
+ }
297
+ }
298
+
224
299
func (ch codeChange ) revert (s * StateDB ) {
225
300
s .getStateObject (* ch .account ).setCode (common .BytesToHash (ch .prevhash ), ch .prevcode )
226
301
}
@@ -229,6 +304,14 @@ func (ch codeChange) dirtied() *common.Address {
229
304
return ch .account
230
305
}
231
306
307
+ func (ch codeChange ) copy () journalEntry {
308
+ return codeChange {
309
+ account : ch .account ,
310
+ prevhash : common .CopyBytes (ch .prevhash ),
311
+ prevcode : common .CopyBytes (ch .prevcode ),
312
+ }
313
+ }
314
+
232
315
func (ch storageChange ) revert (s * StateDB ) {
233
316
s .getStateObject (* ch .account ).setState (ch .key , ch .prevalue )
234
317
}
@@ -237,6 +320,14 @@ func (ch storageChange) dirtied() *common.Address {
237
320
return ch .account
238
321
}
239
322
323
+ func (ch storageChange ) copy () journalEntry {
324
+ return storageChange {
325
+ account : ch .account ,
326
+ key : ch .key ,
327
+ prevalue : ch .prevalue ,
328
+ }
329
+ }
330
+
240
331
func (ch transientStorageChange ) revert (s * StateDB ) {
241
332
s .setTransientState (* ch .account , ch .key , ch .prevalue )
242
333
}
@@ -245,6 +336,14 @@ func (ch transientStorageChange) dirtied() *common.Address {
245
336
return nil
246
337
}
247
338
339
+ func (ch transientStorageChange ) copy () journalEntry {
340
+ return transientStorageChange {
341
+ account : ch .account ,
342
+ key : ch .key ,
343
+ prevalue : ch .prevalue ,
344
+ }
345
+ }
346
+
248
347
func (ch refundChange ) revert (s * StateDB ) {
249
348
s .refund = ch .prev
250
349
}
@@ -253,6 +352,12 @@ func (ch refundChange) dirtied() *common.Address {
253
352
return nil
254
353
}
255
354
355
+ func (ch refundChange ) copy () journalEntry {
356
+ return refundChange {
357
+ prev : ch .prev ,
358
+ }
359
+ }
360
+
256
361
func (ch addLogChange ) revert (s * StateDB ) {
257
362
logs := s .logs [ch .txhash ]
258
363
if len (logs ) == 1 {
@@ -267,6 +372,12 @@ func (ch addLogChange) dirtied() *common.Address {
267
372
return nil
268
373
}
269
374
375
+ func (ch addLogChange ) copy () journalEntry {
376
+ return addLogChange {
377
+ txhash : ch .txhash ,
378
+ }
379
+ }
380
+
270
381
func (ch addPreimageChange ) revert (s * StateDB ) {
271
382
delete (s .preimages , ch .hash )
272
383
}
@@ -275,6 +386,12 @@ func (ch addPreimageChange) dirtied() *common.Address {
275
386
return nil
276
387
}
277
388
389
+ func (ch addPreimageChange ) copy () journalEntry {
390
+ return addPreimageChange {
391
+ hash : ch .hash ,
392
+ }
393
+ }
394
+
278
395
func (ch accessListAddAccountChange ) revert (s * StateDB ) {
279
396
/*
280
397
One important invariant here, is that whenever a (addr, slot) is added, if the
@@ -292,10 +409,23 @@ func (ch accessListAddAccountChange) dirtied() *common.Address {
292
409
return nil
293
410
}
294
411
412
+ func (ch accessListAddAccountChange ) copy () journalEntry {
413
+ return accessListAddAccountChange {
414
+ address : ch .address ,
415
+ }
416
+ }
417
+
295
418
func (ch accessListAddSlotChange ) revert (s * StateDB ) {
296
419
s .accessList .DeleteSlot (* ch .address , * ch .slot )
297
420
}
298
421
299
422
func (ch accessListAddSlotChange ) dirtied () * common.Address {
300
423
return nil
301
424
}
425
+
426
+ func (ch accessListAddSlotChange ) copy () journalEntry {
427
+ return accessListAddSlotChange {
428
+ address : ch .address ,
429
+ slot : ch .slot ,
430
+ }
431
+ }
0 commit comments