eth/filters, eth/tracers: add request cancellation checks (#26320)

This ensures that RPC method handlers will react to a timeout or
cancelled request soon after the event occurs.


Co-authored-by: Sina Mahmoodi <itz.s1na@gmail.com>
This commit is contained in:
Felix Lange
2022-12-15 07:52:07 -05:00
committed by GitHub
co-authored by Sina Mahmoodi
parent f51f6edb40
commit f53ff0ff4a
5 changed files with 33 additions and 12 deletions
+16 -5
View File
@@ -549,6 +549,9 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
deleteEmptyObjects = chainConfig.IsEIP158(block.Number())
)
for i, tx := range block.Transactions() {
if err := ctx.Err(); err != nil {
return nil, err
}
var (
msg, _ = tx.AsMessage(signer, block.BaseFee())
txContext = core.NewEVMTxContext(msg)
@@ -609,14 +612,13 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
signer = types.MakeSigner(api.backend.ChainConfig(), block.Number())
txs = block.Transactions()
results = make([]*txTraceResult, len(txs))
pend = new(sync.WaitGroup)
jobs = make(chan *txTraceTask, len(txs))
pend sync.WaitGroup
)
threads := runtime.NumCPU()
if threads > len(txs) {
threads = len(txs)
}
jobs := make(chan *txTraceTask, threads)
blockHash := block.Hash()
for th := 0; th < threads; th++ {
pend.Add(1)
@@ -640,12 +642,20 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
}
}()
}
// Feed the transactions into the tracers and return
var failed error
blockCtx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil)
txloop:
for i, tx := range txs {
// Send the trace task over for execution
jobs <- &txTraceTask{statedb: statedb.Copy(), index: i}
task := &txTraceTask{statedb: statedb.Copy(), index: i}
select {
case <-ctx.Done():
failed = ctx.Err()
break txloop
case jobs <- task:
}
// Generate the next state snapshot fast without tracing
msg, _ := tx.AsMessage(signer, block.BaseFee())
@@ -653,12 +663,13 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{})
if _, err := core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas())); err != nil {
failed = err
break
break txloop
}
// Finalize the state so any modifications are written to the trie
// Only delete empty objects if EIP158/161 (a.k.a Spurious Dragon) is in effect
statedb.Finalise(vmenv.ChainConfig().IsEIP158(block.Number()))
}
close(jobs)
pend.Wait()