@@ -185,10 +185,89 @@ func GetValidBlockDataFromRpc(blockNumbers []uint64) []*common.BlockData {
185185}
186186
187187func getValidBlockDataFromRpcBatch (blockNumbers []uint64 ) []* common.BlockData {
188- blockData , err := fetchBlockDataFromRpcBatch (blockNumbers )
189- if err != nil {
190- log .Panic ().Err (err ).Msg ("Failed to fetch block data from RPC" )
188+ var rpcResults []rpc.GetFullBlockResult
189+ var fetchErr error
190+ chainIdStr := libs .ChainIdStr
191+ indexerName := config .Cfg .ZeetProjectName
192+
193+ // Initial fetch
194+ rpcResults = libs .RpcClient .GetFullBlocks (context .Background (), blockNumbersToBigInt (blockNumbers ))
195+
196+ metrics .CommitterRPCRowsToFetch .WithLabelValues (indexerName , chainIdStr ).Set (float64 (len (blockNumbers )))
197+
198+ // Create array of failed block numbers for retry
199+ failedBlockNumbers := make ([]uint64 , 0 )
200+ for i , result := range rpcResults {
201+ if result .Error != nil {
202+ log .Error ().Uint64 ("block_number" , blockNumbers [i ]).Err (result .Error ).Msg ("Failed to fetch block data from RPC" )
203+ failedBlockNumbers = append (failedBlockNumbers , blockNumbers [i ])
204+ }
205+ }
206+
207+ // Retry only failed blocks up to 3 times
208+ for retry := range 3 {
209+ if len (failedBlockNumbers ) == 0 {
210+ break // All blocks succeeded
211+ }
212+
213+ // Track retry metric
214+ metrics .CommitterRPCRetries .WithLabelValues (indexerName , chainIdStr ).Set (float64 (len (failedBlockNumbers )))
215+
216+ log .Warn ().
217+ Int ("retry" , retry + 1 ).
218+ Int ("failed_count" , len (failedBlockNumbers )).
219+ Msg ("Retrying failed block fetches..." )
220+
221+ // Retry only the failed blocks
222+ retryResults := libs .RpcClient .GetFullBlocks (context .Background (), blockNumbersToBigInt (failedBlockNumbers ))
223+
224+ // Update rpcResults with successful ones and create new failed array
225+ newFailedBlockNumbers := make ([]uint64 , 0 )
226+ retryIndex := 0
227+
228+ for i , result := range rpcResults {
229+ if result .Error != nil {
230+ // This was a failed block, check if retry succeeded
231+ if retryIndex < len (retryResults ) && retryResults [retryIndex ].Error == nil {
232+ // Retry succeeded - update the result
233+ rpcResults [i ] = retryResults [retryIndex ]
234+ } else {
235+ // Still failed - add to new failed array
236+ newFailedBlockNumbers = append (newFailedBlockNumbers , blockNumbers [i ])
237+ }
238+ retryIndex ++
239+ }
240+ }
241+
242+ failedBlockNumbers = newFailedBlockNumbers
243+
244+ // Add delay between retries
245+ if len (failedBlockNumbers ) > 0 && retry < 2 {
246+ time .Sleep (time .Duration (retry + 1 ) * 100 * time .Millisecond )
247+ }
191248 }
249+
250+ // Check if any blocks still failed after all retries
251+ if len (failedBlockNumbers ) > 0 {
252+ fetchErr = fmt .Errorf ("failed to fetch %d block(s) from RPC after 3 retries" , len (failedBlockNumbers ))
253+ }
254+
255+ if fetchErr != nil {
256+ log .Panic ().Err (fetchErr ).Msg ("Failed to fetch block data from RPC" )
257+ }
258+
259+ blockData := make ([]* common.BlockData , len (rpcResults ))
260+ for i , result := range rpcResults {
261+ blockData [i ] = & result .Data
262+ rpcResults [i ] = rpc.GetFullBlockResult {} // free memory
263+ }
264+
265+ for i , block := range blockData {
266+ if isValid , _ := Validate (block ); ! isValid {
267+ log .Panic ().Int ("index" , i ).Msg ("Failed to validate block data from rpc" )
268+ }
269+ }
270+
192271 return blockData
193272}
194273
@@ -198,10 +277,12 @@ func fetchBlockDataFromRpcBatch(blockNumbers []uint64) ([]*common.BlockData, err
198277 chainIdStr := libs .ChainIdStr
199278 indexerName := config .Cfg .ZeetProjectName
200279
280+ // Initial fetch
201281 rpcResults = libs .RpcClient .GetFullBlocks (context .Background (), blockNumbersToBigInt (blockNumbers ))
202282
203283 metrics .CommitterRPCRowsToFetch .WithLabelValues (indexerName , chainIdStr ).Set (float64 (len (blockNumbers )))
204284
285+ // Create array of failed block numbers for retry
205286 failedBlockNumbers := make ([]uint64 , 0 )
206287 for i , result := range rpcResults {
207288 if result .Error != nil {
@@ -210,28 +291,35 @@ func fetchBlockDataFromRpcBatch(blockNumbers []uint64) ([]*common.BlockData, err
210291 }
211292 }
212293
294+ // Retry only failed blocks up to 3 times
213295 for retry := range 3 {
214296 if len (failedBlockNumbers ) == 0 {
215- break
297+ break // All blocks succeeded
216298 }
217299
300+ // Track retry metric
218301 metrics .CommitterRPCRetries .WithLabelValues (indexerName , chainIdStr ).Set (float64 (len (failedBlockNumbers )))
219302
220303 log .Warn ().
221304 Int ("retry" , retry + 1 ).
222305 Int ("failed_count" , len (failedBlockNumbers )).
223306 Msg ("Retrying failed block fetches..." )
224307
308+ // Retry only the failed blocks
225309 retryResults := libs .RpcClient .GetFullBlocks (context .Background (), blockNumbersToBigInt (failedBlockNumbers ))
226310
311+ // Update rpcResults with successful ones and create new failed array
227312 newFailedBlockNumbers := make ([]uint64 , 0 )
228313 retryIndex := 0
229314
230315 for i , result := range rpcResults {
231316 if result .Error != nil {
317+ // This was a failed block, check if retry succeeded
232318 if retryIndex < len (retryResults ) && retryResults [retryIndex ].Error == nil {
319+ // Retry succeeded - update the result
233320 rpcResults [i ] = retryResults [retryIndex ]
234321 } else {
322+ // Still failed - add to new failed array
235323 newFailedBlockNumbers = append (newFailedBlockNumbers , blockNumbers [i ])
236324 }
237325 retryIndex ++
@@ -240,19 +328,21 @@ func fetchBlockDataFromRpcBatch(blockNumbers []uint64) ([]*common.BlockData, err
240328
241329 failedBlockNumbers = newFailedBlockNumbers
242330
331+ // Add delay between retries
243332 if len (failedBlockNumbers ) > 0 && retry < 2 {
244333 time .Sleep (time .Duration (retry + 1 ) * 100 * time .Millisecond )
245334 }
246335 }
247336
337+ // Check if any blocks still failed after all retries
248338 if len (failedBlockNumbers ) > 0 {
249339 return nil , fmt .Errorf ("failed to fetch %d block(s) from RPC after 3 retries" , len (failedBlockNumbers ))
250340 }
251341
252342 blockData := make ([]* common.BlockData , len (rpcResults ))
253343 for i , result := range rpcResults {
254344 blockData [i ] = & result .Data
255- rpcResults [i ] = rpc.GetFullBlockResult {}
345+ rpcResults [i ] = rpc.GetFullBlockResult {} // free memory
256346 }
257347
258348 for i , block := range blockData {
0 commit comments