diff --git a/ethapi/api.go b/ethapi/api.go index 3149c6700..4165a47ac 100644 --- a/ethapi/api.go +++ b/ethapi/api.go @@ -22,9 +22,7 @@ import ( "fmt" "math/big" "math/rand" - "runtime" "strings" - "sync" "time" "github.com/Fantom-foundation/lachesis-base/hash" @@ -2180,6 +2178,9 @@ func (api *PublicDebugAPI) traceTx(ctx context.Context, message evmcore.Message, return nil, fmt.Errorf("tracing failed: %w", err) } + // Finalize the state so any modifications are written to the trie + statedb.Finalise(vmenv.ChainConfig().IsByzantium(vmctx.BlockNumber) || vmenv.ChainConfig().IsEIP158(vmctx.BlockNumber)) + // Depending on the tracer type, format and return the output. switch tracer := tracer.(type) { case *vm.StructLogger: @@ -2222,13 +2223,6 @@ type txTraceResult struct { Error string `json:"error,omitempty"` // Trace failure produced by the tracer } -// txTraceTask represents a single transaction trace task when an entire block -// is being traced. -type txTraceTask struct { - statedb *state.StateDB // Intermediate state prepped for tracing - index int // Transaction offset in the block -} - // TraceBlockByNumber returns the structured logs created during the execution of // EVM and returns them as a JSON object. func (api *PublicDebugAPI) TraceBlockByNumber(ctx context.Context, number rpc.BlockNumber, config *TraceConfig) ([]*txTraceResult, error) { @@ -2291,64 +2285,27 @@ func (api *PublicDebugAPI) traceBlock(ctx context.Context, block *evmcore.EvmBlo signer = types.MakeSigner(api.b.ChainConfig(), block.Number) txs = block.Transactions results = make([]*txTraceResult, len(txs)) - - pend = new(sync.WaitGroup) - jobs = make(chan *txTraceTask, len(txs)) ) - threads := runtime.NumCPU() - if threads > len(txs) { - threads = len(txs) - } blockHeader := block.Header() blockHash := block.Hash - for th := 0; th < threads; th++ { - pend.Add(1) - go func() { - defer pend.Done() - blockCtx := api.b.GetBlockContext(blockHeader) - - // Fetch and execute the next transaction trace tasks - for task := range jobs { - msg, _ := txs[task.index].AsMessage(signer, block.BaseFee) - txctx := &tracers.Context{ - BlockHash: blockHash, - TxIndex: task.index, - TxHash: txs[task.index].Hash(), - } - res, err := api.traceTx(ctx, msg, txctx, blockCtx, task.statedb, config) - if err != nil { - results[task.index] = &txTraceResult{Error: err.Error()} - continue - } - results[task.index] = &txTraceResult{Result: res} - } - }() - } + // Feed the transactions into the tracers and return blockCtx := api.b.GetBlockContext(blockHeader) - var failed error for i, tx := range txs { - // Send the trace task over for execution - jobs <- &txTraceTask{statedb: statedb.Copy(), index: i} - // Generate the next state snapshot fast without tracing + txctx := &tracers.Context{ + BlockHash: blockHash, + TxIndex: i, + TxHash: txs[i].Hash(), + } msg, _ := tx.AsMessage(signer, block.BaseFee) - statedb.Prepare(tx.Hash(), i) - vmenv := vm.NewEVM(blockCtx, evmcore.NewEVMTxContext(msg), statedb, api.b.ChainConfig(), opera.DefaultVMConfig) - if _, err := evmcore.ApplyMessage(vmenv, msg, new(evmcore.GasPool).AddGas(msg.Gas())); err != nil { - failed = err - break + res, err := api.traceTx(ctx, msg, txctx, blockCtx, statedb, config) + if err != nil { + results[i] = &txTraceResult{Error: err.Error()} + continue } - // Finalize the state so any modifications are written to the trie - statedb.Finalise(vmenv.ChainConfig().IsByzantium(block.Number) || vmenv.ChainConfig().IsEIP158(block.Number)) - } - close(jobs) - pend.Wait() - - // If execution failed in between, abort - if failed != nil { - return nil, failed + results[i] = &txTraceResult{Result: res} } return results, nil }