@@ -294,6 +294,10 @@ func (rpc *Client) GetFullBlocks(ctx context.Context, blockNumbers []*big.Int) [
294294 blocks = rpc .fetchTransactionsForChain296 (ctx , blocks )
295295 }
296296
297+ if rpc .chainID != nil && rpc .chainID .Uint64 () == 2020 && rpc .supportsBlockReceipts {
298+ receipts = rpc .fallbackBlockReceiptsForChain2020 (ctx , blocks , receipts )
299+ }
300+
297301 return SerializeFullBlocks (rpc .chainID , blocks , logs , traces , receipts )
298302}
299303
@@ -461,3 +465,89 @@ func (rpc *Client) fetchTransactionsInBatches(ctx context.Context, txHashes []st
461465
462466 return results
463467}
468+
469+ func (rpc * Client ) fallbackBlockReceiptsForChain2020 (ctx context.Context , blocks []RPCFetchBatchResult [* big.Int , common.RawBlock ], receipts []RPCFetchBatchResult [* big.Int , common.RawReceipts ]) []RPCFetchBatchResult [* big.Int , common.RawReceipts ] {
470+ blockByNumber := mapBatchResultsByBlockNumber [common.RawBlock ](blocks )
471+
472+ for i := range receipts {
473+ if receipts [i ].Error == nil || ! isChain2020BlockReceiptsError (receipts [i ].Error ) {
474+ continue
475+ }
476+
477+ blockNumber := receipts [i ].Key .String ()
478+ block , ok := blockByNumber [blockNumber ]
479+ if ! ok || block .Error != nil || block .Result == nil {
480+ log .Warn ().
481+ Err (receipts [i ].Error ).
482+ Str ("block_number" , blockNumber ).
483+ Msg ("Skipping chain 2020 eth_getBlockReceipts fallback because block data is unavailable" )
484+ continue
485+ }
486+
487+ txHashes := extractTransactionHashes (block .Result )
488+ if len (txHashes ) == 0 {
489+ receipts [i ].Result = common.RawReceipts {}
490+ receipts [i ].Error = nil
491+ continue
492+ }
493+
494+ txReceiptResults := RPCFetchSingleBatch [string , common.RawReceipt ](rpc , ctx , txHashes , "eth_getTransactionReceipt" , GetTransactionParams )
495+ rawReceipts := make (common.RawReceipts , 0 , len (txReceiptResults ))
496+ var fallbackErr error
497+ for _ , txReceipt := range txReceiptResults {
498+ if txReceipt .Error != nil {
499+ fallbackErr = txReceipt .Error
500+ break
501+ }
502+ rawReceipts = append (rawReceipts , txReceipt .Result )
503+ }
504+ if fallbackErr != nil {
505+ log .Error ().
506+ Err (fallbackErr ).
507+ Str ("block_number" , blockNumber ).
508+ Int ("transaction_count" , len (txHashes )).
509+ Msg ("Chain 2020 eth_getTransactionReceipt fallback failed" )
510+ continue
511+ }
512+
513+ log .Warn ().
514+ Str ("block_number" , blockNumber ).
515+ Int ("receipt_count" , len (rawReceipts )).
516+ Msg ("Recovered chain 2020 block receipts using eth_getTransactionReceipt fallback" )
517+
518+ receipts [i ].Result = rawReceipts
519+ receipts [i ].Error = nil
520+ }
521+
522+ return receipts
523+ }
524+
525+ func isChain2020BlockReceiptsError (err error ) bool {
526+ if err == nil {
527+ return false
528+ }
529+ return strings .Contains (err .Error (), "could not find l1 block info tx in the L2 block" )
530+ }
531+
532+ func extractTransactionHashes (block common.RawBlock ) []string {
533+ rawTransactions , ok := block ["transactions" ].([]interface {})
534+ if ! ok {
535+ return nil
536+ }
537+
538+ txHashes := make ([]string , 0 , len (rawTransactions ))
539+ for _ , rawTx := range rawTransactions {
540+ switch tx := rawTx .(type ) {
541+ case string :
542+ if tx != "" {
543+ txHashes = append (txHashes , tx )
544+ }
545+ case map [string ]interface {}:
546+ if hash , ok := tx ["hash" ].(string ); ok && hash != "" {
547+ txHashes = append (txHashes , hash )
548+ }
549+ }
550+ }
551+
552+ return txHashes
553+ }
0 commit comments