traceBlock configures a new tracer according to the provided configuration, and executes all the transactions contained within. The return value will be one item per transaction, dependent on the requested tracer.
(ctx context.Context, block *types.Block, config *TraceConfig)
| 402 | // executes all the transactions contained within. The return value will be one item |
| 403 | // per transaction, dependent on the requested tracer. |
| 404 | func (api *PrivateDebugAPI) traceBlock(ctx context.Context, block *types.Block, config *TraceConfig) ([]*txTraceResult, error) { |
| 405 | // Create the parent state database |
| 406 | if err := api.cpc.engine.VerifyHeader(api.cpc.blockchain, block.Header(), true, block.RefHeader()); err != nil { |
| 407 | return nil, err |
| 408 | } |
| 409 | parent := api.cpc.blockchain.GetBlock(block.ParentHash(), block.NumberU64()-1) |
| 410 | if parent == nil { |
| 411 | return nil, fmt.Errorf("parent %x not found", block.ParentHash()) |
| 412 | } |
| 413 | reexec := defaultTraceReexec |
| 414 | if config != nil && config.Reexec != nil { |
| 415 | reexec = *config.Reexec |
| 416 | } |
| 417 | statedb, err := api.computeStateDB(parent, reexec) |
| 418 | if err != nil { |
| 419 | return nil, err |
| 420 | } |
| 421 | // Execute all the transaction contained within the block concurrently |
| 422 | var ( |
| 423 | signer = types.MakeSigner(api.config) |
| 424 | |
| 425 | txs = block.Transactions() |
| 426 | results = make([]*txTraceResult, len(txs)) |
| 427 | |
| 428 | pend = new(sync.WaitGroup) |
| 429 | jobs = make(chan *txTraceTask, len(txs)) |
| 430 | ) |
| 431 | threads := runtime.NumCPU() |
| 432 | if threads > len(txs) { |
| 433 | threads = len(txs) |
| 434 | } |
| 435 | for th := 0; th < threads; th++ { |
| 436 | pend.Add(1) |
| 437 | go func() { |
| 438 | defer pend.Done() |
| 439 | |
| 440 | // Fetch and execute the next transaction trace tasks |
| 441 | for task := range jobs { |
| 442 | msg, _ := txs[task.index].AsMessage(signer) |
| 443 | vmctx := core.NewEVMContext(msg, block.Header(), api.cpc.blockchain, nil) |
| 444 | |
| 445 | res, err := api.traceTx(ctx, msg, vmctx, task.statedb, config) |
| 446 | if err != nil { |
| 447 | results[task.index] = &txTraceResult{Error: err.Error()} |
| 448 | continue |
| 449 | } |
| 450 | results[task.index] = &txTraceResult{Result: res} |
| 451 | } |
| 452 | }() |
| 453 | } |
| 454 | // Feed the transactions into the tracers and return |
| 455 | var failed error |
| 456 | for i, tx := range txs { |
| 457 | // Send the trace task over for execution |
| 458 | jobs <- &txTraceTask{statedb: statedb.Copy(), index: i} |
| 459 | |
| 460 | // Generate the next state snapshot fast without tracing |
| 461 | msg, _ := tx.AsMessage(signer) |
no test coverage detected