@@ -76,7 +76,6 @@ type StructLog struct {
76
76
Storage map [common.Hash ]common.Hash `json:"-"`
77
77
Depth int `json:"depth"`
78
78
RefundCounter uint64 `json:"refund"`
79
- ExtraData * types.ExtraData `json:"extraData"`
80
79
Err error `json:"-"`
81
80
}
82
81
@@ -96,17 +95,9 @@ func (s *StructLog) clean() {
96
95
s .Stack = s .Stack [:0 ]
97
96
s .ReturnData .Reset ()
98
97
s .Storage = nil
99
- s .ExtraData = nil
100
98
s .Err = nil
101
99
}
102
100
103
- func (s * StructLog ) getOrInitExtraData () * types.ExtraData {
104
- if s .ExtraData == nil {
105
- s .ExtraData = & types.ExtraData {}
106
- }
107
- return s .ExtraData
108
- }
109
-
110
101
// overrides for gencodec
111
102
type structLogMarshaling struct {
112
103
Gas math.HexOrDecimal64
@@ -145,6 +136,13 @@ type EVMLogger interface {
145
136
CaptureEnd (output []byte , gasUsed uint64 , t time.Duration , err error )
146
137
}
147
138
139
+ type CodeInfo struct {
140
+ CodeSize uint64
141
+ KeccakCodeHash common.Hash
142
+ PoseidonCodeHash common.Hash
143
+ Code []byte
144
+ }
145
+
148
146
// StructLogger is an EVM state logger and implements EVMLogger.
149
147
//
150
148
// StructLogger can capture state based on the given Log configuration and also keeps
@@ -154,6 +152,8 @@ type StructLogger struct {
154
152
cfg LogConfig
155
153
env * EVM
156
154
155
+ bytecodes map [common.Hash ]CodeInfo
156
+
157
157
statesAffected map [common.Address ]struct {}
158
158
storage map [common.Address ]Storage
159
159
createdAccount * types.AccountWrapper
@@ -167,6 +167,7 @@ type StructLogger struct {
167
167
// NewStructLogger returns a new logger
168
168
func NewStructLogger (cfg * LogConfig ) * StructLogger {
169
169
logger := & StructLogger {
170
+ bytecodes : make (map [common.Hash ]CodeInfo ),
170
171
storage : make (map [common.Address ]Storage ),
171
172
statesAffected : make (map [common.Address ]struct {}),
172
173
}
@@ -179,6 +180,7 @@ func NewStructLogger(cfg *LogConfig) *StructLogger {
179
180
180
181
// Reset clears the data held by the logger.
181
182
func (l * StructLogger ) Reset () {
183
+ l .bytecodes = make (map [common.Hash ]CodeInfo )
182
184
l .storage = make (map [common.Address ]Storage )
183
185
l .statesAffected = make (map [common.Address ]struct {})
184
186
l .output = make ([]byte , 0 )
@@ -200,6 +202,8 @@ func (l *StructLogger) CaptureStart(env *EVM, from common.Address, to common.Add
200
202
Nonce : env .StateDB .GetNonce (to ),
201
203
Balance : (* hexutil .Big )(value ),
202
204
}
205
+ } else {
206
+ traceCodeWithAddress (l , to )
203
207
}
204
208
205
209
l .statesAffected [from ] = struct {}{}
@@ -260,17 +264,11 @@ func (l *StructLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scop
260
264
if ok {
261
265
// execute trace func list.
262
266
for _ , exec := range execFuncList {
263
- if err := exec (l , scope , structLog . getOrInitExtraData () ); err != nil {
267
+ if err := exec (l , scope ); err != nil {
264
268
log .Error ("Failed to trace data" , "opcode" , op .String (), "err" , err )
265
269
}
266
270
}
267
271
}
268
- // for each "calling" op, pick the caller's state
269
- switch op {
270
- case CALL , CALLCODE , STATICCALL , DELEGATECALL , CREATE , CREATE2 :
271
- extraData := structLog .getOrInitExtraData ()
272
- extraData .Caller = append (extraData .Caller , getWrappedAccountForAddr (l , scope .Contract .Address ()))
273
- }
274
272
275
273
// in reality it is impossible for CREATE to trigger ErrContractAddressCollision
276
274
if op == CREATE2 && opErr == nil {
@@ -288,9 +286,6 @@ func (l *StructLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scop
288
286
289
287
contractHash := l .env .StateDB .GetKeccakCodeHash (address )
290
288
if l .env .StateDB .GetNonce (address ) != 0 || (contractHash != (common.Hash {}) && contractHash != emptyKeccakCodeHash ) {
291
- extraData := structLog .getOrInitExtraData ()
292
- wrappedStatus := getWrappedAccountForAddr (l , address )
293
- extraData .StateList = append (extraData .StateList , wrappedStatus )
294
289
l .statesAffected [address ] = struct {}{}
295
290
}
296
291
}
@@ -331,16 +326,7 @@ func (l *StructLogger) CaptureEnter(typ OpCode, from common.Address, to common.A
331
326
panic ("unexpected evm depth in capture enter" )
332
327
}
333
328
l .statesAffected [to ] = struct {}{}
334
- theLog := l .logs [lastLogPos ]
335
- theLog .getOrInitExtraData ()
336
- // handling additional updating for CALL/STATICCALL/CALLCODE/CREATE/CREATE2 only
337
- // append extraData part for the log, capture the account status (the nonce / balance has been updated in capture enter)
338
- wrappedStatus := getWrappedAccountForAddr (l , to )
339
- theLog .ExtraData .StateList = append (theLog .ExtraData .StateList , wrappedStatus )
340
- // finally we update the caller's status (it is possible that nonce and balance being updated)
341
- if len (theLog .ExtraData .Caller ) == 1 {
342
- theLog .ExtraData .Caller = append (theLog .ExtraData .Caller , getWrappedAccountForAddr (l , from ))
343
- }
329
+
344
330
}
345
331
346
332
// CaptureExit phase, a CREATE has its target address's code being set and queryable
@@ -350,32 +336,7 @@ func (l *StructLogger) CaptureExit(output []byte, gasUsed uint64, err error) {
350
336
panic ("unexpected capture exit occur" )
351
337
}
352
338
353
- theLogPos := l .callStackLogInd [stackH - 1 ]
354
339
l .callStackLogInd = l .callStackLogInd [:stackH - 1 ]
355
- theLog := l .logs [theLogPos ]
356
- // update "forecast" data
357
- if err != nil {
358
- theLog .ExtraData .CallFailed = true
359
- }
360
-
361
- // handling updating for CREATE only
362
- switch theLog .Op {
363
- case CREATE , CREATE2 :
364
- // append extraData part for the log whose op is CREATE(2), capture the account status (the codehash would be updated in capture exit)
365
- dataLen := len (theLog .ExtraData .StateList )
366
- if dataLen == 0 {
367
- panic ("unexpected data capture for target op" )
368
- }
369
-
370
- lastAccData := theLog .ExtraData .StateList [dataLen - 1 ]
371
- wrappedStatus := getWrappedAccountForAddr (l , lastAccData .Address )
372
- theLog .ExtraData .StateList = append (theLog .ExtraData .StateList , wrappedStatus )
373
- code := getCodeForAddr (l , lastAccData .Address )
374
- theLog .ExtraData .CodeList = append (theLog .ExtraData .CodeList , hexutil .Encode (code ))
375
- default :
376
- //do nothing for other op code
377
- return
378
- }
379
340
380
341
}
381
342
@@ -389,6 +350,11 @@ func (l *StructLogger) UpdatedStorages() map[common.Address]Storage {
389
350
return l .storage
390
351
}
391
352
353
+ // TracedBytecodes is used to collect all "touched" bytecodes
354
+ func (l * StructLogger ) TracedBytecodes () map [common.Hash ]CodeInfo {
355
+ return l .bytecodes
356
+ }
357
+
392
358
// CreatedAccount return the account data in case it is a create tx
393
359
func (l * StructLogger ) CreatedAccount () * types.AccountWrapper { return l .createdAccount }
394
360
@@ -540,7 +506,6 @@ func FormatLogs(logs []*StructLog) []*types.StructLogRes {
540
506
}
541
507
logRes .Storage = storage
542
508
}
543
- logRes .ExtraData = trace .ExtraData
544
509
545
510
formatted = append (formatted , logRes )
546
511
}
0 commit comments