Skip to content

Commit

Permalink
fix: handle edgecase where indexer hangs when a block has 0 transacti…
Browse files Browse the repository at this point in the history
…ons (#247)

## Description

Bug fix for a situation observed on holesky where the indexer would hang
when trying to batch fetch 0 transactions. This was only found when
using a direct node rather than a service like quiknode since we
typically dont use the native batch call structure with quiknode.

Fixes # (issue)

## Type of change

- [x] Bug fix (non-breaking change which fixes an issue)

## How Has This Been Tested?

Unit test suite and manually running the sidecar to sync against the
block that had 0 transactions on holesky.

## Checklist:

- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my own code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [x] Any dependent changes have been merged and published in downstream
modules
- [x] I have checked my code and corrected any misspellings
  • Loading branch information
seanmcgary authored Feb 14, 2025
2 parents f0f54a5 + cf87dda commit c649e60
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
12 changes: 12 additions & 0 deletions pkg/clients/ethereum/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,10 @@ func (c *Client) batchCall(ctx context.Context, requests []*RPCRequest) ([]*RPCR
}

func (c *Client) chunkedNativeBatchCall(ctx context.Context, requests []*RPCRequest) ([]*RPCResponse, error) {
if len(requests) == 0 {
c.Logger.Sugar().Warnw("No requests to batch call")
return make([]*RPCResponse, 0), nil
}
batches := [][]*RPCRequest{}

currentIndex := 0
Expand Down Expand Up @@ -414,6 +418,10 @@ type BatchedResponse struct {
//
// This function allows for better retry and error handling over the batch call method.
func (c *Client) chunkedBatchCall(ctx context.Context, requests []*RPCRequest) ([]*RPCResponse, error) {
if len(requests) == 0 {
c.Logger.Sugar().Warnw("No requests to batch call")
return make([]*RPCResponse, 0), nil
}
batches := [][]*IndexedRpcRequestResponse{}

// all requests in a flat list with their index stored
Expand Down Expand Up @@ -497,6 +505,10 @@ func (c *Client) chunkedBatchCall(ctx context.Context, requests []*RPCRequest) (
}

func (c *Client) BatchCall(ctx context.Context, requests []*RPCRequest) ([]*RPCResponse, error) {
if len(requests) == 0 {
c.Logger.Sugar().Warnw("No requests to batch call")
return make([]*RPCResponse, 0), nil
}
if c.clientConfig.UseNativeBatchCall {
return c.chunkedNativeBatchCall(ctx, requests)
}
Expand Down
10 changes: 9 additions & 1 deletion pkg/fetcher/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ func (f *Fetcher) FetchReceiptsForBlock(ctx context.Context, block *ethereum.Eth
zap.Int("count", len(txReceiptRequests)),
zap.Uint64("blockNumber", blockNumber),
)
receipts := make(map[string]*ethereum.EthereumTransactionReceipt)

if len(txReceiptRequests) == 0 {
return receipts, nil
}

receiptResponses, err := f.EthClient.BatchCall(ctx, txReceiptRequests)
if err != nil {
Expand All @@ -80,7 +85,6 @@ func (f *Fetcher) FetchReceiptsForBlock(ctx context.Context, block *ethereum.Eth
return nil, errors.New("failed to fetch all transaction receipts")
}

receipts := make(map[string]*ethereum.EthereumTransactionReceipt)
for _, response := range receiptResponses {
r, err := ethereum.RPCMethod_getTransactionReceipt.ResponseParser(response.Result)
if err != nil {
Expand Down Expand Up @@ -137,6 +141,10 @@ func (f *Fetcher) FetchBlocks(ctx context.Context, startBlockInclusive uint64, e
blockNumbers = append(blockNumbers, i)
}

if len(blockNumbers) == 0 {
return []*FetchedBlock{}, nil
}

blockRequests := make([]*ethereum.RPCRequest, 0)
for i, n := range blockNumbers {
blockRequests = append(blockRequests, ethereum.GetBlockByNumberRequest(n, uint(i)))
Expand Down

0 comments on commit c649e60

Please sign in to comment.