Skip to content

Commit ad91cc2

Browse files
committed
2020 receipt fallback
1 parent af5040e commit ad91cc2

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

internal/rpc/rpc.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)