Skip to content

Commit 12fdf94

Browse files
authored
fix: resolve indexer infinite loop (#82) (#83)
on very slow drives or when run with limited resources, a node can have a delay between the block existing & being saved and the block_results getting saved. if the block exists, but the block_results do not, an infinite loop occurs. the indexer will repeatedly request the block and block_results until they both exist. the lack of delay can further constrain the node's resources and result in many calls for block_results before they are committed. this commit updates the condition for waiting to include whenever an error occurred during indexing. if the indexer fails to find the block_results it will bombard the node with requests for it without backing off. this change causes errors to trigger a wait. after waiting for either a new block or for the timeout, the block results are more likely to exist.
1 parent 0d963e7 commit 12fdf94

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

server/indexer_service.go

+18-8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/cenkalti/backoff/v4"
2424
"github.com/cometbft/cometbft/libs/service"
2525
rpcclient "github.com/cometbft/cometbft/rpc/client"
26+
coretypes "github.com/cometbft/cometbft/rpc/core/types"
2627
"github.com/cometbft/cometbft/types"
2728

2829
ethermint "github.com/evmos/ethermint/types"
@@ -111,24 +112,33 @@ func (eis *EVMIndexerService) OnStart() error {
111112
if lastBlock == -1 {
112113
lastBlock = latestBlock
113114
}
115+
// blockErr indicates an error fetching an expected block or its results
116+
var blockErr error
114117
for {
115-
if latestBlock <= lastBlock {
116-
// nothing to index. wait for signal of new block
118+
var block *coretypes.ResultBlock
119+
var blockResult *coretypes.ResultBlockResults
120+
if latestBlock <= lastBlock || blockErr != nil {
121+
// two cases:
122+
// 1. nothing to index (indexer is caught up). wait for signal of new block.
123+
// 2. previous attempt to index errored (failed to fetch the Block or BlockResults).
124+
// in this case, wait before retrying the data fetching, rather than infinite looping
125+
// a failing fetch. this can occur due to drive latency between the block existing and its
126+
// block_results getting saved.
117127
select {
118128
case <-newBlockSignal:
119129
case <-time.After(NewBlockWaitTimeout):
120130
}
121131
continue
122132
}
123133
for i := lastBlock + 1; i <= latestBlock; i++ {
124-
block, err := eis.client.Block(ctx, &i)
125-
if err != nil {
126-
eis.Logger.Error("failed to fetch block", "height", i, "err", err)
134+
block, blockErr = eis.client.Block(ctx, &i)
135+
if blockErr != nil {
136+
eis.Logger.Error("failed to fetch block", "height", i, "err", blockErr)
127137
break
128138
}
129-
blockResult, err := eis.client.BlockResults(ctx, &i)
130-
if err != nil {
131-
eis.Logger.Error("failed to fetch block result", "height", i, "err", err)
139+
blockResult, blockErr = eis.client.BlockResults(ctx, &i)
140+
if blockErr != nil {
141+
eis.Logger.Error("failed to fetch block result", "height", i, "err", blockErr)
132142
break
133143
}
134144
if err := eis.txIdxr.IndexBlock(block.Block, blockResult.TxsResults); err != nil {

0 commit comments

Comments
 (0)