retry.go 3.54 KB
Newer Older
1 2 3 4 5 6
package prefetcher

import (
	"context"
	"math"

7
	"github.com/ethereum-optimism/optimism/op-service/eth"
8
	"github.com/ethereum-optimism/optimism/op-service/retry"
9 10 11 12 13 14 15 16 17 18
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core/types"
	"github.com/ethereum/go-ethereum/log"
)

const maxAttempts = math.MaxInt // Succeed or die trying

type RetryingL1Source struct {
	logger   log.Logger
	source   L1Source
19
	strategy retry.Strategy
20 21 22 23 24 25
}

func NewRetryingL1Source(logger log.Logger, source L1Source) *RetryingL1Source {
	return &RetryingL1Source{
		logger:   logger,
		source:   source,
26
		strategy: retry.Exponential(),
27 28 29 30
	}
}

func (s *RetryingL1Source) InfoByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, error) {
31
	return retry.Do(ctx, maxAttempts, s.strategy, func() (eth.BlockInfo, error) {
32 33 34 35
		res, err := s.source.InfoByHash(ctx, blockHash)
		if err != nil {
			s.logger.Warn("Failed to retrieve info", "hash", blockHash, "err", err)
		}
36
		return res, err
37 38 39 40
	})
}

func (s *RetryingL1Source) InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) {
41
	return retry.Do2(ctx, maxAttempts, s.strategy, func() (eth.BlockInfo, types.Transactions, error) {
42 43 44 45
		i, t, err := s.source.InfoAndTxsByHash(ctx, blockHash)
		if err != nil {
			s.logger.Warn("Failed to retrieve l1 info and txs", "hash", blockHash, "err", err)
		}
46
		return i, t, err
47 48 49 50
	})
}

func (s *RetryingL1Source) FetchReceipts(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Receipts, error) {
51
	return retry.Do2(ctx, maxAttempts, s.strategy, func() (eth.BlockInfo, types.Receipts, error) {
52 53 54 55
		i, r, err := s.source.FetchReceipts(ctx, blockHash)
		if err != nil {
			s.logger.Warn("Failed to fetch receipts", "hash", blockHash, "err", err)
		}
56
		return i, r, err
57 58 59 60 61 62 63 64
	})
}

var _ L1Source = (*RetryingL1Source)(nil)

type RetryingL2Source struct {
	logger   log.Logger
	source   L2Source
65
	strategy retry.Strategy
66 67 68
}

func (s *RetryingL2Source) InfoAndTxsByHash(ctx context.Context, blockHash common.Hash) (eth.BlockInfo, types.Transactions, error) {
69
	return retry.Do2(ctx, maxAttempts, s.strategy, func() (eth.BlockInfo, types.Transactions, error) {
70 71 72 73
		i, t, err := s.source.InfoAndTxsByHash(ctx, blockHash)
		if err != nil {
			s.logger.Warn("Failed to retrieve l2 info and txs", "hash", blockHash, "err", err)
		}
74
		return i, t, err
75 76 77 78
	})
}

func (s *RetryingL2Source) NodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) {
79
	return retry.Do(ctx, maxAttempts, s.strategy, func() ([]byte, error) {
80 81 82 83
		n, err := s.source.NodeByHash(ctx, hash)
		if err != nil {
			s.logger.Warn("Failed to retrieve node", "hash", hash, "err", err)
		}
84
		return n, err
85 86 87 88
	})
}

func (s *RetryingL2Source) CodeByHash(ctx context.Context, hash common.Hash) ([]byte, error) {
89
	return retry.Do(ctx, maxAttempts, s.strategy, func() ([]byte, error) {
90 91 92 93
		c, err := s.source.CodeByHash(ctx, hash)
		if err != nil {
			s.logger.Warn("Failed to retrieve code", "hash", hash, "err", err)
		}
94
		return c, err
95 96 97
	})
}

98
func (s *RetryingL2Source) OutputByRoot(ctx context.Context, root common.Hash) (eth.Output, error) {
99
	return retry.Do(ctx, maxAttempts, s.strategy, func() (eth.Output, error) {
100 101 102
		o, err := s.source.OutputByRoot(ctx, root)
		if err != nil {
			s.logger.Warn("Failed to fetch l2 output", "root", root, "err", err)
Joshua Gutow's avatar
Joshua Gutow committed
103
			return o, err
104
		}
Joshua Gutow's avatar
Joshua Gutow committed
105
		return o, nil
106 107 108
	})
}

109 110 111 112
func NewRetryingL2Source(logger log.Logger, source L2Source) *RetryingL2Source {
	return &RetryingL2Source{
		logger:   logger,
		source:   source,
113
		strategy: retry.Exponential(),
114 115 116 117
	}
}

var _ L2Source = (*RetryingL2Source)(nil)