@@ -272,6 +272,247 @@ func (env *TraceEnv) GetBlockTrace(block *types.Block) (*types.BlockTrace, error
272
272
return env .fillBlockTrace (block )
273
273
}
274
274
275
+ func (env * TraceEnv ) getSystemResult (state * state.StateDB , block * types.Block ) error {
276
+ //tx := block.Transactions()[index]
277
+ //msg, _ := tx.AsMessage(env.signer, block.BaseFee())
278
+ //from, _ := types.Sender(env.signer, tx)
279
+ //to := tx.To()
280
+
281
+ txctx := & Context {
282
+ BlockHash : block .TxHash (),
283
+ //TxIndex: index,
284
+ //TxHash: tx.Hash(),
285
+ }
286
+
287
+ sender := & types.AccountWrapper {
288
+ Address : from ,
289
+ Nonce : state .GetNonce (from ),
290
+ Balance : (* hexutil .Big )(state .GetBalance (from )),
291
+ KeccakCodeHash : state .GetKeccakCodeHash (from ),
292
+ PoseidonCodeHash : state .GetPoseidonCodeHash (from ),
293
+ CodeSize : state .GetCodeSize (from ),
294
+ }
295
+ var receiver * types.AccountWrapper
296
+ if to != nil {
297
+ receiver = & types.AccountWrapper {
298
+ Address : * to ,
299
+ Nonce : state .GetNonce (* to ),
300
+ Balance : (* hexutil .Big )(state .GetBalance (* to )),
301
+ KeccakCodeHash : state .GetKeccakCodeHash (* to ),
302
+ PoseidonCodeHash : state .GetPoseidonCodeHash (* to ),
303
+ CodeSize : state .GetCodeSize (* to ),
304
+ }
305
+ }
306
+
307
+ txContext := core .NewEVMTxContext (msg )
308
+ tracerContext := tracers.Context {
309
+ BlockHash : block .Hash (),
310
+ //TxIndex: index,
311
+ //TxHash: tx.Hash(),
312
+ }
313
+ callTracer , err := tracers .New ("callTracer" , & tracerContext , nil )
314
+ if err != nil {
315
+ return fmt .Errorf ("failed to create callTracer: %w" , err )
316
+ }
317
+
318
+ applyMessageStart := time .Now ()
319
+ structLogger := vm .NewStructLogger (env .logConfig )
320
+ tracer := NewMuxTracer (structLogger , callTracer )
321
+ // Run the transaction with tracing enabled.
322
+ vmenv := vm .NewEVM (env .blockCtx , txContext , state , env .chainConfig , vm.Config {Debug : true , Tracer : tracer , NoBaseFee : true })
323
+
324
+ // Call Prepare to clear out the statedb access list
325
+ state .SetTxContext (txctx .TxHash , txctx .TxIndex )
326
+
327
+ // Computes the new state by applying the given message.
328
+ //l1DataFee, err := fees.CalculateL1DataFee(tx, state, env.chainConfig, block.Number())
329
+ //if err != nil {
330
+ // return err
331
+ //}
332
+ //result, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), l1DataFee)
333
+ if err != nil {
334
+ getTxResultApplyMessageTimer .UpdateSince (applyMessageStart )
335
+ return err
336
+ }
337
+ getTxResultApplyMessageTimer .UpdateSince (applyMessageStart )
338
+
339
+ // If the result contains a revert reason, return it.
340
+ returnVal := result .Return ()
341
+ if len (result .Revert ()) > 0 {
342
+ returnVal = result .Revert ()
343
+ }
344
+
345
+ createdAcc := structLogger .CreatedAccount ()
346
+ var after []* types.AccountWrapper
347
+ if to == nil {
348
+ if createdAcc == nil {
349
+ return errors .New ("unexpected tx: address for created contract unavailable" )
350
+ }
351
+ to = & createdAcc .Address
352
+ }
353
+ // collect affected account after tx being applied
354
+ for _ , acc := range []common.Address {from , * to , env .coinbase } {
355
+ after = append (after , & types.AccountWrapper {
356
+ Address : acc ,
357
+ Nonce : state .GetNonce (acc ),
358
+ Balance : (* hexutil .Big )(state .GetBalance (acc )),
359
+ KeccakCodeHash : state .GetKeccakCodeHash (acc ),
360
+ PoseidonCodeHash : state .GetPoseidonCodeHash (acc ),
361
+ CodeSize : state .GetCodeSize (acc ),
362
+ })
363
+ }
364
+
365
+ //txStorageTrace := &types.StorageTrace{
366
+ // Proofs: make(map[string][]hexutil.Bytes),
367
+ // StorageProofs: make(map[string]map[string][]hexutil.Bytes),
368
+ //}
369
+ //// still we have no state root for per tx, only set the head and tail
370
+ //if index == 0 {
371
+ // txStorageTrace.RootBefore = state.GetRootHash()
372
+ //}
373
+ //if index == len(block.Transactions())-1 {
374
+ // txStorageTrace.RootAfter = block.Root()
375
+ //}
376
+
377
+ // merge bytecodes
378
+ env .cMu .Lock ()
379
+ for codeHash , codeInfo := range structLogger .TracedBytecodes () {
380
+ if codeHash != (common.Hash {}) {
381
+ env .Codes [codeHash ] = codeInfo
382
+ }
383
+ }
384
+ env .cMu .Unlock ()
385
+
386
+ // merge required proof data
387
+ proofAccounts := structLogger .UpdatedAccounts ()
388
+ proofAccounts [vmenv .FeeRecipient ()] = struct {}{}
389
+ // add from/to address if it does not exist
390
+ if _ , ok := proofAccounts [from ]; ! ok {
391
+ proofAccounts [from ] = struct {}{}
392
+ }
393
+ if _ , ok := proofAccounts [* to ]; ! ok {
394
+ proofAccounts [* to ] = struct {}{}
395
+ }
396
+ for addr := range proofAccounts {
397
+ addrStr := addr .String ()
398
+
399
+ env .pMu .Lock ()
400
+ checkedProof , existed := env .Proofs [addrStr ]
401
+ if existed {
402
+ txStorageTrace .Proofs [addrStr ] = checkedProof
403
+ }
404
+ env .pMu .Unlock ()
405
+ if existed {
406
+ continue
407
+ }
408
+ proof , err := state .GetProof (addr )
409
+ if err != nil {
410
+ log .Error ("Proof not available" , "address" , addrStr , "error" , err )
411
+ // but we still mark the proofs map with nil array
412
+ }
413
+ wrappedProof := types .WrapProof (proof )
414
+ env .pMu .Lock ()
415
+ env .Proofs [addrStr ] = wrappedProof
416
+ txStorageTrace .Proofs [addrStr ] = wrappedProof
417
+ env .pMu .Unlock ()
418
+ }
419
+
420
+ zkTrieBuildStart := time .Now ()
421
+ proofStorages := structLogger .UpdatedStorages ()
422
+ for addr , keys := range proofStorages {
423
+ if _ , existed := txStorageTrace .StorageProofs [addr .String ()]; ! existed {
424
+ txStorageTrace .StorageProofs [addr .String ()] = make (map [string ][]hexutil.Bytes )
425
+ }
426
+
427
+ env .sMu .Lock ()
428
+ trie , err := state .GetStorageTrieForProof (addr )
429
+ if err != nil {
430
+ // but we still continue to next address
431
+ log .Error ("Storage trie not available" , "error" , err , "address" , addr )
432
+ env .sMu .Unlock ()
433
+ continue
434
+ }
435
+ zktrieTracer := state .NewProofTracer (trie )
436
+ env .sMu .Unlock ()
437
+
438
+ for key := range keys {
439
+ addrStr := addr .String ()
440
+ keyStr := key .String ()
441
+ value := state .GetState (addr , key )
442
+ isDelete := bytes .Equal (value .Bytes (), common.Hash {}.Bytes ())
443
+
444
+ txm := txStorageTrace .StorageProofs [addrStr ]
445
+ env .sMu .Lock ()
446
+ m , existed := env .StorageProofs [addrStr ]
447
+ if ! existed {
448
+ m = make (map [string ][]hexutil.Bytes )
449
+ env .StorageProofs [addrStr ] = m
450
+ }
451
+ if zktrieTracer .Available () && ! env .ZkTrieTracer [addrStr ].Available () {
452
+ env .ZkTrieTracer [addrStr ] = state .NewProofTracer (trie )
453
+ }
454
+
455
+ if proof , existed := m [keyStr ]; existed {
456
+ txm [keyStr ] = proof
457
+ // still need to touch tracer for deletion
458
+ if isDelete && zktrieTracer .Available () {
459
+ env .ZkTrieTracer [addrStr ].MarkDeletion (key )
460
+ }
461
+ env .sMu .Unlock ()
462
+ continue
463
+ }
464
+ env .sMu .Unlock ()
465
+
466
+ var proof [][]byte
467
+ var err error
468
+ if zktrieTracer .Available () {
469
+ proof , err = state .GetSecureTrieProof (zktrieTracer , key )
470
+ } else {
471
+ proof , err = state .GetSecureTrieProof (trie , key )
472
+ }
473
+ if err != nil {
474
+ log .Error ("Storage proof not available" , "error" , err , "address" , addrStr , "key" , keyStr )
475
+ // but we still mark the proofs map with nil array
476
+ }
477
+ wrappedProof := types .WrapProof (proof )
478
+ env .sMu .Lock ()
479
+ txm [keyStr ] = wrappedProof
480
+ m [keyStr ] = wrappedProof
481
+ if zktrieTracer .Available () {
482
+ if isDelete {
483
+ zktrieTracer .MarkDeletion (key )
484
+ }
485
+ env .ZkTrieTracer [addrStr ].Merge (zktrieTracer )
486
+ }
487
+ env .sMu .Unlock ()
488
+ }
489
+ }
490
+ getTxResultZkTrieBuildTimer .UpdateSince (zkTrieBuildStart )
491
+
492
+ tracerResultTimer := time .Now ()
493
+ callTrace , err := callTracer .GetResult ()
494
+ if err != nil {
495
+ return fmt .Errorf ("failed to get callTracer result: %w" , err )
496
+ }
497
+ getTxResultTracerResultTimer .UpdateSince (tracerResultTimer )
498
+
499
+ env .ExecutionResults [index ] = & types.ExecutionResult {
500
+ From : sender ,
501
+ To : receiver ,
502
+ AccountCreated : createdAcc ,
503
+ AccountsAfter : after ,
504
+ L1DataFee : (* hexutil .Big )(result .L1DataFee ),
505
+ Gas : result .UsedGas ,
506
+ Failed : result .Failed (),
507
+ ReturnValue : fmt .Sprintf ("%x" , returnVal ),
508
+ StructLogs : vm .FormatLogs (structLogger .StructLogs ()),
509
+ CallTrace : callTrace ,
510
+ }
511
+ env .TxStorageTraces [index ] = txStorageTrace
512
+
513
+ return nil
514
+ }
515
+
275
516
func (env * TraceEnv ) getTxResult (state * state.StateDB , index int , block * types.Block ) error {
276
517
tx := block .Transactions ()[index ]
277
518
msg , _ := tx .AsMessage (env .signer , block .BaseFee ())
0 commit comments