From c142a59eb68ce813bbde9f8500262988ae707eaa Mon Sep 17 00:00:00 2001 From: HonzaDajc Date: Tue, 31 Oct 2023 11:24:42 +0100 Subject: [PATCH] Remove parallel procesing for debug_traceBlock Because of preparing data for replaying transaction with EVM which is slower with javascript tracer execution, deep copy of stateDB is created and every transaction is replayed twice. So this is contra productive. --- ethapi/api.go | 71 ++++++++++----------------------------------------- 1 file changed, 14 insertions(+), 57 deletions(-) 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 }