Skip to content

Commit dfb8bef

Browse files
authored
296 fix blocks too big (#292)
* fix large block transaction for 296 * minor change
1 parent 1698b1f commit dfb8bef

File tree

1 file changed

+135
-2
lines changed

1 file changed

+135
-2
lines changed

internal/rpc/rpc.go

Lines changed: 135 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,19 @@ func (rpc *Client) GetFullBlocks(ctx context.Context, blockNumbers []*big.Int) [
236236
var receipts []RPCFetchBatchResult[*big.Int, common.RawReceipts]
237237
wg.Add(2)
238238

239+
// Check if we need special handling for chain ID 296
240+
needsSpecialHandling := rpc.needsChain296SpecialHandling(blockNumbers)
241+
239242
go func() {
240243
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+
}
243252
}()
244253

245254
if rpc.supportsBlockReceipts {
@@ -267,6 +276,11 @@ func (rpc *Client) GetFullBlocks(ctx context.Context, blockNumbers []*big.Int) [
267276

268277
wg.Wait()
269278

279+
// If we used special handling, we need to fetch transactions separately
280+
if needsSpecialHandling {
281+
blocks = rpc.fetchTransactionsForChain296(ctx, blocks)
282+
}
283+
270284
return SerializeFullBlocks(rpc.chainID, blocks, logs, traces, receipts)
271285
}
272286

@@ -315,3 +329,122 @@ func (rpc *Client) HasCode(ctx context.Context, address string) (bool, error) {
315329
}
316330
return len(code) > 0, nil
317331
}
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

Comments
 (0)