@@ -24,6 +24,7 @@ const (
2424 // Default retry configuration for RPC calls
2525 RPCDefaultRetryAttempts = 1
2626 RPCDefaultRetryDelay = 1000 * time .Millisecond
27+ RPCDefaultRetryTimeout = 10 * time .Second
2728
2829 // Default retry configuration for dialing RPC endpoints
2930 RPCDefaultDialRetryAttempts = 1
@@ -34,6 +35,7 @@ const (
3435type RetryConfig struct {
3536 Attempts uint
3637 Delay time.Duration
38+ Timeout time.Duration
3739 DialAttempts uint
3840 DialDelay time.Duration
3941 DialTimeout time.Duration
@@ -43,6 +45,7 @@ func defaultRetryConfig() RetryConfig {
4345 return RetryConfig {
4446 Attempts : RPCDefaultRetryAttempts ,
4547 Delay : RPCDefaultRetryDelay ,
48+ Timeout : RPCDefaultRetryTimeout ,
4649 DialAttempts : RPCDefaultDialRetryAttempts ,
4750 DialDelay : RPCDefaultDialRetryDelay ,
4851 DialTimeout : RPCDefaultDialTimeout ,
@@ -98,16 +101,16 @@ func NewMultiClient(lggr logger.Logger, rpcsCfg RPCConfig, opts ...func(client *
98101}
99102
100103func (mc * MultiClient ) SendTransaction (ctx context.Context , tx * types.Transaction ) error {
101- return mc .retryWithBackups ("SendTransaction" , func (client * ethclient.Client ) error {
102- return client .SendTransaction (ctx , tx )
104+ return mc .retryWithBackups (ctx , "SendTransaction" , func (ct context. Context , client * ethclient.Client ) error {
105+ return client .SendTransaction (ct , tx )
103106 })
104107}
105108
106109func (mc * MultiClient ) CallContract (ctx context.Context , msg ethereum.CallMsg , blockNumber * big.Int ) ([]byte , error ) {
107110 var result []byte
108- err := mc .retryWithBackups ("CallContract" , func (client * ethclient.Client ) error {
111+ err := mc .retryWithBackups (ctx , "CallContract" , func (ct context. Context , client * ethclient.Client ) error {
109112 var err error
110- result , err = client .CallContract (ctx , msg , blockNumber )
113+ result , err = client .CallContract (ct , msg , blockNumber )
111114
112115 return err
113116 })
@@ -117,9 +120,9 @@ func (mc *MultiClient) CallContract(ctx context.Context, msg ethereum.CallMsg, b
117120
118121func (mc * MultiClient ) CallContractAtHash (ctx context.Context , msg ethereum.CallMsg , blockHash common.Hash ) ([]byte , error ) {
119122 var result []byte
120- err := mc .retryWithBackups ("CallContractAtHash" , func (client * ethclient.Client ) error {
123+ err := mc .retryWithBackups (ctx , "CallContractAtHash" , func (ct context. Context , client * ethclient.Client ) error {
121124 var err error
122- result , err = client .CallContractAtHash (ctx , msg , blockHash )
125+ result , err = client .CallContractAtHash (ct , msg , blockHash )
123126
124127 return err
125128 })
@@ -129,9 +132,9 @@ func (mc *MultiClient) CallContractAtHash(ctx context.Context, msg ethereum.Call
129132
130133func (mc * MultiClient ) CodeAt (ctx context.Context , account common.Address , blockNumber * big.Int ) ([]byte , error ) {
131134 var code []byte
132- err := mc .retryWithBackups ("CodeAt" , func (client * ethclient.Client ) error {
135+ err := mc .retryWithBackups (ctx , "CodeAt" , func (ct context. Context , client * ethclient.Client ) error {
133136 var err error
134- code , err = client .CodeAt (ctx , account , blockNumber )
137+ code , err = client .CodeAt (ct , account , blockNumber )
135138
136139 return err
137140 })
@@ -141,9 +144,9 @@ func (mc *MultiClient) CodeAt(ctx context.Context, account common.Address, block
141144
142145func (mc * MultiClient ) CodeAtHash (ctx context.Context , account common.Address , blockHash common.Hash ) ([]byte , error ) {
143146 var code []byte
144- err := mc .retryWithBackups ("CodeAtHash" , func (client * ethclient.Client ) error {
147+ err := mc .retryWithBackups (ctx , "CodeAtHash" , func (ct context. Context , client * ethclient.Client ) error {
145148 var err error
146- code , err = client .CodeAtHash (ctx , account , blockHash )
149+ code , err = client .CodeAtHash (ct , account , blockHash )
147150
148151 return err
149152 })
@@ -153,9 +156,9 @@ func (mc *MultiClient) CodeAtHash(ctx context.Context, account common.Address, b
153156
154157func (mc * MultiClient ) NonceAt (ctx context.Context , account common.Address , block * big.Int ) (uint64 , error ) {
155158 var count uint64
156- err := mc .retryWithBackups ("NonceAt" , func (client * ethclient.Client ) error {
159+ err := mc .retryWithBackups (ctx , "NonceAt" , func (ct context. Context , client * ethclient.Client ) error {
157160 var err error
158- count , err = client .NonceAt (ctx , account , block )
161+ count , err = client .NonceAt (ct , account , block )
159162
160163 return err
161164 })
@@ -165,9 +168,9 @@ func (mc *MultiClient) NonceAt(ctx context.Context, account common.Address, bloc
165168
166169func (mc * MultiClient ) NonceAtHash (ctx context.Context , account common.Address , blockHash common.Hash ) (uint64 , error ) {
167170 var count uint64
168- err := mc .retryWithBackups ("NonceAtHash" , func (client * ethclient.Client ) error {
171+ err := mc .retryWithBackups (ctx , "NonceAtHash" , func (ct context. Context , client * ethclient.Client ) error {
169172 var err error
170- count , err = client .NonceAtHash (ctx , account , blockHash )
173+ count , err = client .NonceAtHash (ct , account , blockHash )
171174
172175 return err
173176 })
@@ -177,9 +180,9 @@ func (mc *MultiClient) NonceAtHash(ctx context.Context, account common.Address,
177180
178181func (mc * MultiClient ) HeaderByNumber (ctx context.Context , number * big.Int ) (* types.Header , error ) {
179182 var header * types.Header
180- err := mc .retryWithBackups ("HeaderByNumber" , func (client * ethclient.Client ) error {
183+ err := mc .retryWithBackups (ctx , "HeaderByNumber" , func (ct context. Context , client * ethclient.Client ) error {
181184 var err error
182- header , err = client .HeaderByNumber (ctx , number )
185+ header , err = client .HeaderByNumber (ct , number )
183186
184187 return err
185188 })
@@ -189,9 +192,9 @@ func (mc *MultiClient) HeaderByNumber(ctx context.Context, number *big.Int) (*ty
189192
190193func (mc * MultiClient ) SuggestGasPrice (ctx context.Context ) (* big.Int , error ) {
191194 var gasPrice * big.Int
192- err := mc .retryWithBackups ("SuggestGasPrice" , func (client * ethclient.Client ) error {
195+ err := mc .retryWithBackups (ctx , "SuggestGasPrice" , func (ct context. Context , client * ethclient.Client ) error {
193196 var err error
194- gasPrice , err = client .SuggestGasPrice (ctx )
197+ gasPrice , err = client .SuggestGasPrice (ct )
195198
196199 return err
197200 })
@@ -201,9 +204,9 @@ func (mc *MultiClient) SuggestGasPrice(ctx context.Context) (*big.Int, error) {
201204
202205func (mc * MultiClient ) SuggestGasTipCap (ctx context.Context ) (* big.Int , error ) {
203206 var gasTipCap * big.Int
204- err := mc .retryWithBackups ("SuggestGasTipCap" , func (client * ethclient.Client ) error {
207+ err := mc .retryWithBackups (ctx , "SuggestGasTipCap" , func (ct context. Context , client * ethclient.Client ) error {
205208 var err error
206- gasTipCap , err = client .SuggestGasTipCap (ctx )
209+ gasTipCap , err = client .SuggestGasTipCap (ct )
207210
208211 return err
209212 })
@@ -213,9 +216,9 @@ func (mc *MultiClient) SuggestGasTipCap(ctx context.Context) (*big.Int, error) {
213216
214217func (mc * MultiClient ) PendingCodeAt (ctx context.Context , account common.Address ) ([]byte , error ) {
215218 var code []byte
216- err := mc .retryWithBackups ("PendingCodeAt" , func (client * ethclient.Client ) error {
219+ err := mc .retryWithBackups (ctx , "PendingCodeAt" , func (ct context. Context , client * ethclient.Client ) error {
217220 var err error
218- code , err = client .PendingCodeAt (ctx , account )
221+ code , err = client .PendingCodeAt (ct , account )
219222
220223 return err
221224 })
@@ -225,9 +228,9 @@ func (mc *MultiClient) PendingCodeAt(ctx context.Context, account common.Address
225228
226229func (mc * MultiClient ) PendingNonceAt (ctx context.Context , account common.Address ) (uint64 , error ) {
227230 var count uint64
228- err := mc .retryWithBackups ("PendingNonceAt" , func (client * ethclient.Client ) error {
231+ err := mc .retryWithBackups (ctx , "PendingNonceAt" , func (ct context. Context , client * ethclient.Client ) error {
229232 var err error
230- count , err = client .PendingNonceAt (ctx , account )
233+ count , err = client .PendingNonceAt (ct , account )
231234
232235 return err
233236 })
@@ -237,9 +240,9 @@ func (mc *MultiClient) PendingNonceAt(ctx context.Context, account common.Addres
237240
238241func (mc * MultiClient ) EstimateGas (ctx context.Context , call ethereum.CallMsg ) (uint64 , error ) {
239242 var gas uint64
240- err := mc .retryWithBackups ("EstimateGas" , func (client * ethclient.Client ) error {
243+ err := mc .retryWithBackups (ctx , "EstimateGas" , func (ct context. Context , client * ethclient.Client ) error {
241244 var err error
242- gas , err = client .EstimateGas (ctx , call )
245+ gas , err = client .EstimateGas (ct , call )
243246
244247 return err
245248 })
@@ -249,9 +252,9 @@ func (mc *MultiClient) EstimateGas(ctx context.Context, call ethereum.CallMsg) (
249252
250253func (mc * MultiClient ) BalanceAt (ctx context.Context , account common.Address , blockNumber * big.Int ) (* big.Int , error ) {
251254 var balance * big.Int
252- err := mc .retryWithBackups ("BalanceAt" , func (client * ethclient.Client ) error {
255+ err := mc .retryWithBackups (ctx , "BalanceAt" , func (ct context. Context , client * ethclient.Client ) error {
253256 var err error
254- balance , err = client .BalanceAt (ctx , account , blockNumber )
257+ balance , err = client .BalanceAt (ct , account , blockNumber )
255258
256259 return err
257260 })
@@ -261,9 +264,9 @@ func (mc *MultiClient) BalanceAt(ctx context.Context, account common.Address, bl
261264
262265func (mc * MultiClient ) FilterLogs (ctx context.Context , q ethereum.FilterQuery ) ([]types.Log , error ) {
263266 var logs []types.Log
264- err := mc .retryWithBackups ("FilterLogs" , func (client * ethclient.Client ) error {
267+ err := mc .retryWithBackups (ctx , "FilterLogs" , func (ct context. Context , client * ethclient.Client ) error {
265268 var err error
266- logs , err = client .FilterLogs (ctx , q )
269+ logs , err = client .FilterLogs (ct , q )
267270
268271 return err
269272 })
@@ -273,9 +276,9 @@ func (mc *MultiClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) (
273276
274277func (mc * MultiClient ) SubscribeFilterLogs (ctx context.Context , q ethereum.FilterQuery , ch chan <- types.Log ) (ethereum.Subscription , error ) {
275278 var sub ethereum.Subscription
276- err := mc .retryWithBackups ("SubscribeFilterLogs" , func (client * ethclient.Client ) error {
279+ err := mc .retryWithBackups (ctx , "SubscribeFilterLogs" , func (ct context. Context , client * ethclient.Client ) error {
277280 var err error
278- sub , err = client .SubscribeFilterLogs (ctx , q , ch )
281+ sub , err = client .SubscribeFilterLogs (ct , q , ch )
279282
280283 return err
281284 })
@@ -321,13 +324,16 @@ func (mc *MultiClient) WaitMined(ctx context.Context, tx *types.Transaction) (*t
321324 }
322325}
323326
324- func (mc * MultiClient ) retryWithBackups (opName string , op func (* ethclient.Client ) error ) error {
327+ func (mc * MultiClient ) retryWithBackups (ctx context. Context , opName string , op func (context. Context , * ethclient.Client ) error ) error {
325328 var err error
326329 traceID := uuid .New ()
327330 for i , client := range append ([]* ethclient.Client {mc .Client }, mc .Backups ... ) {
328331 retryCount := 0
329332 err2 := retry .Do (func () error {
330- err = op (client )
333+ timeoutCtx , cancel := context .WithTimeout (ctx , mc .RetryConfig .Timeout )
334+ defer cancel ()
335+
336+ err = op (timeoutCtx , client )
331337 if err != nil {
332338 mc .lggr .Warnf ("traceID %q: chain %q: op: %q: client index %d: failed execution - retryable error '%s'" , traceID .String (), mc .chainName , opName , i , MaybeDataErr (err ))
333339 return err
0 commit comments