mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
ots: stop at ctx.Done() (#8790)
This commit is contained in:
parent
57bcbaa21f
commit
e390b0e182
@ -5,9 +5,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sync"
|
||||
|
||||
hexutil2 "github.com/ledgerwatch/erigon-lib/common/hexutil"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
"github.com/ledgerwatch/log/v3"
|
||||
@ -435,8 +435,6 @@ func (api *OtterscanAPIImpl) SearchTransactionsAfter(ctx context.Context, addr c
|
||||
}
|
||||
|
||||
func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Address, chainConfig *chain.Config, pageSize, resultCount uint16, callFromToProvider BlockProvider) ([]*TransactionsWithReceipts, bool, error) {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// Estimate the common case of user address having at most 1 interaction/block and
|
||||
// trace N := remaining page matches as number of blocks to trace concurrently.
|
||||
// TODO: this is not optimimal for big contract addresses; implement some better heuristics.
|
||||
@ -445,7 +443,11 @@ func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Addres
|
||||
totalBlocksTraced := 0
|
||||
hasMore := true
|
||||
|
||||
eg, ctx := errgroup.WithContext(ctx)
|
||||
eg.SetLimit(1024) // we don't want limit much here, but protecting from infinity attack
|
||||
for i := 0; i < int(estBlocksToTrace); i++ {
|
||||
i := i // we will pass it to goroutine
|
||||
|
||||
var nextBlock uint64
|
||||
var err error
|
||||
nextBlock, hasMore, err = callFromToProvider()
|
||||
@ -457,11 +459,19 @@ func (api *OtterscanAPIImpl) traceBlocks(ctx context.Context, addr common.Addres
|
||||
break
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
totalBlocksTraced++
|
||||
go api.searchTraceBlock(ctx, &wg, addr, chainConfig, i, nextBlock, results)
|
||||
|
||||
eg.Go(func() error {
|
||||
// don't return error from searchTraceBlock - to avoid 1 block fail impact to other blocks
|
||||
// if return error - `errgroup` will interrupt all other goroutines
|
||||
// but passing `ctx` - then user still can cancel request
|
||||
api.searchTraceBlock(ctx, addr, chainConfig, i, nextBlock, results)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
if err := eg.Wait(); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
wg.Wait()
|
||||
|
||||
return results[:totalBlocksTraced], hasMore, nil
|
||||
}
|
||||
|
@ -211,6 +211,12 @@ func (api *OtterscanAPIImpl) GetContractCreator(ctx context.Context, addr common
|
||||
defer bitmapdb.ReturnToPool64(bm)
|
||||
prevShardMaxBl := uint64(0)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
_, err := bm.ReadFrom(bytes.NewReader(v))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -84,6 +84,12 @@ func (api *OtterscanAPIImpl) genericTracer(dbtx kv.Tx, ctx context.Context, bloc
|
||||
rules := chainConfig.Rules(block.NumberU64(), header.Time)
|
||||
signer := types.MakeSigner(chainConfig, blockNum, header.Time)
|
||||
for idx, tx := range block.Transactions() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
ibs.SetTxContext(tx.Hash(), block.Hash(), idx)
|
||||
|
||||
msg, _ := tx.AsMessage(*signer, header.BaseFee, rules)
|
||||
|
@ -2,7 +2,7 @@ package jsonrpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"fmt"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/chain"
|
||||
"github.com/ledgerwatch/erigon-lib/common"
|
||||
@ -18,9 +18,7 @@ import (
|
||||
"github.com/ledgerwatch/erigon/turbo/shards"
|
||||
)
|
||||
|
||||
func (api *OtterscanAPIImpl) searchTraceBlock(ctx context.Context, wg *sync.WaitGroup, addr common.Address, chainConfig *chain.Config, idx int, bNum uint64, results []*TransactionsWithReceipts) {
|
||||
defer wg.Done()
|
||||
|
||||
func (api *OtterscanAPIImpl) searchTraceBlock(ctx context.Context, addr common.Address, chainConfig *chain.Config, idx int, bNum uint64, results []*TransactionsWithReceipts) {
|
||||
// Trace block for Txs
|
||||
newdbtx, err := api.db.BeginRo(ctx)
|
||||
if err != nil {
|
||||
@ -80,6 +78,11 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu
|
||||
rules := chainConfig.Rules(block.NumberU64(), header.Time)
|
||||
found := false
|
||||
for idx, tx := range block.Transactions() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return false, nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
ibs.SetTxContext(tx.Hash(), block.Hash(), idx)
|
||||
|
||||
msg, _ := tx.AsMessage(*signer, header.BaseFee, rules)
|
||||
@ -95,6 +98,14 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu
|
||||
_ = ibs.FinalizeTx(rules, cachedWriter)
|
||||
|
||||
if tracer.Found {
|
||||
if idx > len(blockReceipts) {
|
||||
select { // it may happen because request canceled, then return canelation error
|
||||
case <-ctx.Done():
|
||||
return false, nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
return false, nil, fmt.Errorf("requested receipt idx %d, but have only %d", idx, len(blockReceipts)) // otherwise return some error for debugging
|
||||
}
|
||||
rpcTx := NewRPCTransaction(tx, block.Hash(), blockNum, uint64(idx), block.BaseFee())
|
||||
mReceipt := marshalReceipt(blockReceipts[idx], tx, chainConfig, block.HeaderNoCopy(), tx.Hash(), true)
|
||||
mReceipt["timestamp"] = block.Time()
|
||||
|
@ -173,6 +173,12 @@ func (api *OtterscanAPIImpl) GetTransactionBySenderAndNonce(ctx context.Context,
|
||||
maxBlPrevChunk := uint64(0)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
default:
|
||||
}
|
||||
|
||||
if k == nil || !bytes.HasPrefix(k, addr.Bytes()) {
|
||||
// Check plain state
|
||||
data, err := tx.GetOne(kv.PlainState, addr.Bytes())
|
||||
|
Loading…
Reference in New Issue
Block a user