@@ -236,10 +236,19 @@ func (rpc *Client) GetFullBlocks(ctx context.Context, blockNumbers []*big.Int) [
236
236
var receipts []RPCFetchBatchResult [* big.Int , common.RawReceipts ]
237
237
wg .Add (2 )
238
238
239
+ // Check if we need special handling for chain ID 296
240
+ needsSpecialHandling := rpc .needsChain296SpecialHandling (blockNumbers )
241
+
239
242
go func () {
240
243
defer wg .Done ()
241
- result := RPCFetchSingleBatch [* big.Int , common.RawBlock ](rpc , ctx , blockNumbers , "eth_getBlockByNumber" , GetBlockWithTransactionsParams )
242
- blocks = result
244
+ if needsSpecialHandling {
245
+ // For chain 296 with block <= 5780915, get blocks without transactions first
246
+ // then fetch transactions separately in batches
247
+ blocks = RPCFetchSingleBatch [* big.Int , common.RawBlock ](rpc , ctx , blockNumbers , "eth_getBlockByNumber" , GetBlockWithoutTransactionsParams )
248
+ } else {
249
+ // Normal flow - get blocks with transactions
250
+ blocks = RPCFetchSingleBatch [* big.Int , common.RawBlock ](rpc , ctx , blockNumbers , "eth_getBlockByNumber" , GetBlockWithTransactionsParams )
251
+ }
243
252
}()
244
253
245
254
if rpc .supportsBlockReceipts {
@@ -267,6 +276,11 @@ func (rpc *Client) GetFullBlocks(ctx context.Context, blockNumbers []*big.Int) [
267
276
268
277
wg .Wait ()
269
278
279
+ // If we used special handling, we need to fetch transactions separately
280
+ if needsSpecialHandling {
281
+ blocks = rpc .fetchTransactionsForChain296 (ctx , blocks )
282
+ }
283
+
270
284
return SerializeFullBlocks (rpc .chainID , blocks , logs , traces , receipts )
271
285
}
272
286
@@ -315,3 +329,122 @@ func (rpc *Client) HasCode(ctx context.Context, address string) (bool, error) {
315
329
}
316
330
return len (code ) > 0 , nil
317
331
}
332
+
333
+ // needsChain296SpecialHandling checks if we need special handling for chain ID 296
334
+ func (rpc * Client ) needsChain296SpecialHandling (blockNumbers []* big.Int ) bool {
335
+ // Check if chain ID is 296
336
+ if rpc .chainID == nil || rpc .chainID .Uint64 () != 296 {
337
+ return false
338
+ }
339
+
340
+ // Check if any block number is <= 5780915 and >= 3853944
341
+ threshold2 := big .NewInt (5780915 )
342
+ threshold1 := big .NewInt (3853944 )
343
+ for _ , blockNum := range blockNumbers {
344
+ if blockNum .Cmp (threshold1 ) > 0 && blockNum .Cmp (threshold2 ) <= 0 {
345
+ return true
346
+ }
347
+ }
348
+ return false
349
+ }
350
+
351
+ // fetchTransactionsForChain296 fetches transactions separately for chain 296 blocks
352
+ func (rpc * Client ) fetchTransactionsForChain296 (ctx context.Context , blocks []RPCFetchBatchResult [* big.Int , common.RawBlock ]) []RPCFetchBatchResult [* big.Int , common.RawBlock ] {
353
+ // Collect all transaction hashes from all blocks
354
+ var allTxHashes []string
355
+ blockTxMap := make (map [string ][]string ) // maps block number to transaction hashes
356
+
357
+ for _ , blockResult := range blocks {
358
+ if blockResult .Error != nil {
359
+ continue
360
+ }
361
+ blockNum := blockResult .Key .String ()
362
+ var txHashes []string
363
+
364
+ // Extract transaction hashes from the block
365
+ if transactions , exists := blockResult .Result ["transactions" ]; exists {
366
+ if txList , ok := transactions .([]interface {}); ok {
367
+ for _ , tx := range txList {
368
+ if txHash , ok := tx .(string ); ok {
369
+ txHashes = append (txHashes , txHash )
370
+ allTxHashes = append (allTxHashes , txHash )
371
+ }
372
+ }
373
+ }
374
+ }
375
+ blockTxMap [blockNum ] = txHashes
376
+ }
377
+
378
+ if len (allTxHashes ) == 0 {
379
+ return blocks
380
+ }
381
+
382
+ // Fetch transactions in batches of 100 with parallel processing
383
+ transactions := rpc .fetchTransactionsInBatches (ctx , allTxHashes , 100 )
384
+
385
+ // Create a map of transaction hash to transaction data
386
+ txMap := make (map [string ]interface {})
387
+ for _ , txResult := range transactions {
388
+ if txResult .Error == nil {
389
+ txMap [txResult .Key ] = txResult .Result
390
+ }
391
+ }
392
+
393
+ // Update blocks with transaction data
394
+ for i , blockResult := range blocks {
395
+ if blockResult .Error != nil {
396
+ continue
397
+ }
398
+ blockNum := blockResult .Key .String ()
399
+ txHashes := blockTxMap [blockNum ]
400
+
401
+ var blockTransactions []interface {}
402
+ for _ , txHash := range txHashes {
403
+ if txData , exists := txMap [txHash ]; exists {
404
+ blockTransactions = append (blockTransactions , txData )
405
+ }
406
+ }
407
+
408
+ // Update the block with the fetched transactions
409
+ blocks [i ].Result ["transactions" ] = blockTransactions
410
+ }
411
+
412
+ return blocks
413
+ }
414
+
415
+ // fetchTransactionsInBatches fetches transactions in batches with parallel processing
416
+ func (rpc * Client ) fetchTransactionsInBatches (ctx context.Context , txHashes []string , batchSize int ) []RPCFetchBatchResult [string , common.RawTransaction ] {
417
+ if len (txHashes ) <= batchSize {
418
+ return RPCFetchSingleBatch [string , common.RawTransaction ](rpc , ctx , txHashes , "eth_getTransactionByHash" , GetTransactionParams )
419
+ }
420
+
421
+ // Split into chunks
422
+ chunks := common .SliceToChunks [string ](txHashes , batchSize )
423
+
424
+ log .Debug ().Msgf ("Fetching %d transactions in %d chunks of max %d requests" , len (txHashes ), len (chunks ), batchSize )
425
+
426
+ var wg sync.WaitGroup
427
+ resultsCh := make (chan []RPCFetchBatchResult [string , common.RawTransaction ], len (chunks ))
428
+
429
+ // Process chunks in parallel
430
+ for _ , chunk := range chunks {
431
+ wg .Add (1 )
432
+ go func (chunk []string ) {
433
+ defer wg .Done ()
434
+ resultsCh <- RPCFetchSingleBatch [string , common.RawTransaction ](rpc , ctx , chunk , "eth_getTransactionByHash" , GetTransactionParams )
435
+ }(chunk )
436
+ }
437
+
438
+ go func () {
439
+ wg .Wait ()
440
+ close (resultsCh )
441
+ }()
442
+
443
+ // Collect results
444
+ results := make ([]RPCFetchBatchResult [string , common.RawTransaction ], 0 , len (txHashes ))
445
+ for batchResults := range resultsCh {
446
+ results = append (results , batchResults ... )
447
+ }
448
+
449
+ return results
450
+ }
0 commit comments