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,23 @@ 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
-
98
- prevAccountOriginExist bool
99
- prevAccountOrigin []byte
100
- prevStorageOrigin map [common.Hash ][]byte
101
- }
102
108
selfDestructChange struct {
103
109
account * common.Address
104
110
prev bool // whether account had already self-destructed
@@ -136,6 +142,7 @@ type (
136
142
touchChange struct {
137
143
account * common.Address
138
144
}
145
+
139
146
// Changes to the access list
140
147
accessListAddAccountChange struct {
141
148
address * common.Address
@@ -145,6 +152,7 @@ type (
145
152
slot * common.Hash
146
153
}
147
154
155
+ // Changes to transient storage
148
156
transientStorageChange struct {
149
157
account * common.Address
150
158
key , prevalue common.Hash
@@ -153,36 +161,18 @@ type (
153
161
154
162
func (ch createObjectChange ) revert (s * StateDB ) {
155
163
delete (s .stateObjects , * ch .account )
156
- delete (s .stateObjectsDirty , * ch .account )
157
164
}
158
165
159
166
func (ch createObjectChange ) dirtied () * common.Address {
160
167
return ch .account
161
168
}
162
169
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
170
+ func (ch createObjectChange ) copy () journalEntry {
171
+ return createObjectChange {
172
+ account : ch .account ,
179
173
}
180
174
}
181
175
182
- func (ch resetObjectChange ) dirtied () * common.Address {
183
- return ch .account
184
- }
185
-
186
176
func (ch selfDestructChange ) revert (s * StateDB ) {
187
177
obj := s .getStateObject (* ch .account )
188
178
if obj != nil {
@@ -195,6 +185,14 @@ func (ch selfDestructChange) dirtied() *common.Address {
195
185
return ch .account
196
186
}
197
187
188
+ func (ch selfDestructChange ) copy () journalEntry {
189
+ return selfDestructChange {
190
+ account : ch .account ,
191
+ prev : ch .prev ,
192
+ prevbalance : new (uint256.Int ).Set (ch .prevbalance ),
193
+ }
194
+ }
195
+
198
196
var ripemd = common .HexToAddress ("0000000000000000000000000000000000000003" )
199
197
200
198
func (ch touchChange ) revert (s * StateDB ) {
@@ -204,6 +202,12 @@ func (ch touchChange) dirtied() *common.Address {
204
202
return ch .account
205
203
}
206
204
205
+ func (ch touchChange ) copy () journalEntry {
206
+ return touchChange {
207
+ account : ch .account ,
208
+ }
209
+ }
210
+
207
211
func (ch balanceChange ) revert (s * StateDB ) {
208
212
s .getStateObject (* ch .account ).setBalance (ch .prev )
209
213
}
@@ -212,6 +216,13 @@ func (ch balanceChange) dirtied() *common.Address {
212
216
return ch .account
213
217
}
214
218
219
+ func (ch balanceChange ) copy () journalEntry {
220
+ return balanceChange {
221
+ account : ch .account ,
222
+ prev : new (uint256.Int ).Set (ch .prev ),
223
+ }
224
+ }
225
+
215
226
func (ch nonceChange ) revert (s * StateDB ) {
216
227
s .getStateObject (* ch .account ).setNonce (ch .prev )
217
228
}
@@ -220,6 +231,13 @@ func (ch nonceChange) dirtied() *common.Address {
220
231
return ch .account
221
232
}
222
233
234
+ func (ch nonceChange ) copy () journalEntry {
235
+ return nonceChange {
236
+ account : ch .account ,
237
+ prev : ch .prev ,
238
+ }
239
+ }
240
+
223
241
func (ch codeChange ) revert (s * StateDB ) {
224
242
s .getStateObject (* ch .account ).setCode (common .BytesToHash (ch .prevhash ), ch .prevcode )
225
243
}
@@ -228,6 +246,14 @@ func (ch codeChange) dirtied() *common.Address {
228
246
return ch .account
229
247
}
230
248
249
+ func (ch codeChange ) copy () journalEntry {
250
+ return codeChange {
251
+ account : ch .account ,
252
+ prevhash : common .CopyBytes (ch .prevhash ),
253
+ prevcode : common .CopyBytes (ch .prevcode ),
254
+ }
255
+ }
256
+
231
257
func (ch storageChange ) revert (s * StateDB ) {
232
258
s .getStateObject (* ch .account ).setState (ch .key , ch .prevalue )
233
259
}
@@ -236,6 +262,14 @@ func (ch storageChange) dirtied() *common.Address {
236
262
return ch .account
237
263
}
238
264
265
+ func (ch storageChange ) copy () journalEntry {
266
+ return storageChange {
267
+ account : ch .account ,
268
+ key : ch .key ,
269
+ prevalue : ch .prevalue ,
270
+ }
271
+ }
272
+
239
273
func (ch transientStorageChange ) revert (s * StateDB ) {
240
274
s .setTransientState (* ch .account , ch .key , ch .prevalue )
241
275
}
@@ -244,6 +278,14 @@ func (ch transientStorageChange) dirtied() *common.Address {
244
278
return nil
245
279
}
246
280
281
+ func (ch transientStorageChange ) copy () journalEntry {
282
+ return transientStorageChange {
283
+ account : ch .account ,
284
+ key : ch .key ,
285
+ prevalue : ch .prevalue ,
286
+ }
287
+ }
288
+
247
289
func (ch refundChange ) revert (s * StateDB ) {
248
290
s .refund = ch .prev
249
291
}
@@ -252,6 +294,12 @@ func (ch refundChange) dirtied() *common.Address {
252
294
return nil
253
295
}
254
296
297
+ func (ch refundChange ) copy () journalEntry {
298
+ return refundChange {
299
+ prev : ch .prev ,
300
+ }
301
+ }
302
+
255
303
func (ch addLogChange ) revert (s * StateDB ) {
256
304
logs := s .logs [ch .txhash ]
257
305
if len (logs ) == 1 {
@@ -266,6 +314,12 @@ func (ch addLogChange) dirtied() *common.Address {
266
314
return nil
267
315
}
268
316
317
+ func (ch addLogChange ) copy () journalEntry {
318
+ return addLogChange {
319
+ txhash : ch .txhash ,
320
+ }
321
+ }
322
+
269
323
func (ch addPreimageChange ) revert (s * StateDB ) {
270
324
delete (s .preimages , ch .hash )
271
325
}
@@ -274,6 +328,12 @@ func (ch addPreimageChange) dirtied() *common.Address {
274
328
return nil
275
329
}
276
330
331
+ func (ch addPreimageChange ) copy () journalEntry {
332
+ return addPreimageChange {
333
+ hash : ch .hash ,
334
+ }
335
+ }
336
+
277
337
func (ch accessListAddAccountChange ) revert (s * StateDB ) {
278
338
/*
279
339
One important invariant here, is that whenever a (addr, slot) is added, if the
@@ -291,10 +351,23 @@ func (ch accessListAddAccountChange) dirtied() *common.Address {
291
351
return nil
292
352
}
293
353
354
+ func (ch accessListAddAccountChange ) copy () journalEntry {
355
+ return accessListAddAccountChange {
356
+ address : ch .address ,
357
+ }
358
+ }
359
+
294
360
func (ch accessListAddSlotChange ) revert (s * StateDB ) {
295
361
s .accessList .DeleteSlot (* ch .address , * ch .slot )
296
362
}
297
363
298
364
func (ch accessListAddSlotChange ) dirtied () * common.Address {
299
365
return nil
300
366
}
367
+
368
+ func (ch accessListAddSlotChange ) copy () journalEntry {
369
+ return accessListAddSlotChange {
370
+ address : ch .address ,
371
+ slot : ch .slot ,
372
+ }
373
+ }
0 commit comments