@@ -286,6 +286,9 @@ func (mc *MultiClient) SubscribeFilterLogs(ctx context.Context, q ethereum.Filte
286286 return sub , err
287287}
288288
289+ // WaitMined waits for a transaction to be mined and returns the receipt.
290+ // A timeout for this operation must be set in the context.
291+ // Note: retryConfig timeout settings are not used for this operation.
289292func (mc * MultiClient ) WaitMined (ctx context.Context , tx * types.Transaction ) (* types.Receipt , error ) {
290293 mc .lggr .Debugf ("Waiting for tx %s to be mined for chain %s" , tx .Hash ().Hex (), mc .chainName )
291294 // no retries here because we want to wait for the tx to be mined
@@ -330,7 +333,7 @@ func (mc *MultiClient) retryWithBackups(ctx context.Context, opName string, op f
330333 for i , client := range append ([]* ethclient.Client {mc .Client }, mc .Backups ... ) {
331334 retryCount := 0
332335 err2 := retry .Do (func () error {
333- timeoutCtx , cancel := context . WithTimeout (ctx , mc .RetryConfig .Timeout )
336+ timeoutCtx , cancel := ensureTimeout (ctx , mc .RetryConfig .Timeout )
334337 defer cancel ()
335338
336339 err = op (timeoutCtx , client )
@@ -389,3 +392,17 @@ func (mc *MultiClient) dialWithRetry(rpc RPC, lggr logger.Logger) (*ethclient.Cl
389392
390393 return client , nil
391394}
395+
396+ // ensureTimeout checks if the parent context has a deadline.
397+ // If it does, it returns a new cancelable context using the parent's deadline.
398+ // If it doesn't, it creates a new context with the specified timeout.
399+ func ensureTimeout (parent context.Context , timeout time.Duration ) (context.Context , context.CancelFunc ) {
400+ // check if the parent context already has a deadline
401+ if _ , hasDeadline := parent .Deadline (); hasDeadline {
402+ // derive a new cancelable context from the parent context with the same deadline
403+ return context .WithCancel (parent )
404+ }
405+
406+ // create a new context with the specified timeout
407+ return context .WithTimeout (parent , timeout )
408+ }
0 commit comments