@@ -56,6 +56,13 @@ var _ cctypes.OracleCreator = &pluginOracleCreator{}
5656const (
5757 defaultCommitGasLimit = 500_000
5858 defaultExecGasLimit = 6_500_000
59+
60+ // readerWriterCreationTimeout bounds the per-chain contract reader/writer creation,
61+ // binding, and startup during oracle creation.
62+ // Applied per chain, so it must stay small: a DON can span many chains and the timeout
63+ // is spent serially in the worst case. 10s matches the other blockchain-facing timeouts
64+ // in defaultLocalConfig and rpctimeout.Default.
65+ readerWriterCreationTimeout = 10 * time .Second
5966)
6067
6168// pluginOracleCreator creates oracles that reference plugins running
@@ -684,76 +691,87 @@ func (i *pluginOracleCreator) createReadersAndWriters(
684691 extendedReaders := make (map [cciptypes.ChainSelector ]contractreader.Extended )
685692 chainWriters := make (map [cciptypes.ChainSelector ]types.ContractWriter )
686693 for relayID , relayer := range i .relayers {
687- chainID := relayID .ChainID
688- relayChainFamily := relayID .Network
689- chainDetails , err1 := chainsel .GetChainDetailsByChainIDAndFamily (chainID , relayChainFamily )
690- chainSelector := cciptypes .ChainSelector (chainDetails .ChainSelector )
691- if err1 != nil {
692- return nil , nil , nil , fmt .Errorf ("failed to get chain selector from chain ID %s: %w" , chainID , err1 )
693- }
694-
695- cr , err1 := crcw .GetChainReader (ctx , ccipcommon.ChainReaderProviderOpts {
696- Lggr : i .lggr ,
697- Relayer : relayer ,
698- ChainID : chainID ,
699- DestChainID : destChainID ,
700- HomeChainID : homeChainID ,
701- Ofc : ofc ,
702- ChainSelector : chainSelector ,
703- ChainFamily : relayChainFamily ,
704- DestChainFamily : destChainFamily ,
705- Transmitters : i .transmitters ,
706- })
707- if err1 != nil {
708- // Some Chain family might not need crcw to be created, and if createChainAccessorsAndContractTransmitters will catch error if it does
709- i .lggr .Debugf ("skipping creating reader and writers for chain %s, reader creation: %v" , chainID , err1 )
710- continue
711- }
694+ if err := func () error {
695+ // Bound each chain's reader/writer creation with its own deadline so an unavailable
696+ // chain LOOPP fails fast instead of blocking the launcher context
697+ // forever.
698+ chainCtx , cancel := context .WithTimeout (ctx , readerWriterCreationTimeout )
699+ defer cancel ()
700+
701+ chainID := relayID .ChainID
702+ relayChainFamily := relayID .Network
703+ chainDetails , err1 := chainsel .GetChainDetailsByChainIDAndFamily (chainID , relayChainFamily )
704+ chainSelector := cciptypes .ChainSelector (chainDetails .ChainSelector )
705+ if err1 != nil {
706+ return fmt .Errorf ("failed to get chain selector from chain ID %s: %w" , chainID , err1 )
707+ }
712708
713- if chainID == destChainID && destChainFamily == relayChainFamily {
714- offrampAddress := destAddrStr
715- err2 := cr .Bind (ctx , []types.BoundContract {
716- {
717- Address : offrampAddress ,
718- Name : consts .ContractNameOffRamp ,
719- },
709+ cr , err1 := crcw .GetChainReader (chainCtx , ccipcommon.ChainReaderProviderOpts {
710+ Lggr : i .lggr ,
711+ Relayer : relayer ,
712+ ChainID : chainID ,
713+ DestChainID : destChainID ,
714+ HomeChainID : homeChainID ,
715+ Ofc : ofc ,
716+ ChainSelector : chainSelector ,
717+ ChainFamily : relayChainFamily ,
718+ DestChainFamily : destChainFamily ,
719+ Transmitters : i .transmitters ,
720720 })
721- if err2 != nil {
722- return nil , nil , nil , fmt .Errorf ("failed to bind chain reader for dest chain %s's offramp at %s: %w" , chainID , offrampAddress , err2 )
721+ if err1 != nil {
722+ // Some Chain family might not need crcw to be created, and if createChainAccessorsAndContractTransmitters will catch error if it does
723+ i .lggr .Debugf ("skipping creating reader and writers for chain %s, reader creation: %v" , chainID , err1 )
724+ return nil
723725 }
724- }
725726
726- if err2 := cr .Start (ctx ); err2 != nil {
727- return nil , nil , nil , fmt .Errorf ("failed to start contract reader for chain %s: %w" , chainID , err2 )
728- }
727+ if chainID == destChainID && destChainFamily == relayChainFamily {
728+ offrampAddress := destAddrStr
729+ err2 := cr .Bind (chainCtx , []types.BoundContract {
730+ {
731+ Address : offrampAddress ,
732+ Name : consts .ContractNameOffRamp ,
733+ },
734+ })
735+ if err2 != nil {
736+ return fmt .Errorf ("failed to bind chain reader for dest chain %s's offramp at %s: %w" , chainID , offrampAddress , err2 )
737+ }
738+ }
729739
730- cw , err1 := crcw .GetChainWriter (ctx , ccipcommon.ChainWriterProviderOpts {
731- ChainID : chainID ,
732- Relayer : relayer ,
733- Transmitters : i .transmitters ,
734- ExecBatchGasLimit : execBatchGasLimit ,
735- CommitEvmBatchGasLimit : commitEvmGasLimit ,
736- ChainFamily : relayChainFamily ,
737- OfframpProgramAddress : config .Config .OfframpAddress ,
738- })
739- if err1 != nil {
740- // Some Chain family might not need crcw to be created, and if createChainAccessorsAndContractTransmitters will catch error if it does
741- i .lggr .Debugf ("skipping creating chain writer for chain %s, writer creation: %v" , chainID , err1 )
742- continue
743- }
740+ if err2 := cr .Start (chainCtx ); err2 != nil {
741+ return fmt .Errorf ("failed to start contract reader for chain %s: %w" , chainID , err2 )
742+ }
744743
745- if err4 := cw .Start (ctx ); err4 != nil {
746- return nil , nil , nil , fmt .Errorf ("failed to start chain writer for chain %s: %w" , chainID , err4 )
747- }
744+ cw , err1 := crcw .GetChainWriter (chainCtx , ccipcommon.ChainWriterProviderOpts {
745+ ChainID : chainID ,
746+ Relayer : relayer ,
747+ Transmitters : i .transmitters ,
748+ ExecBatchGasLimit : execBatchGasLimit ,
749+ CommitEvmBatchGasLimit : commitEvmGasLimit ,
750+ ChainFamily : relayChainFamily ,
751+ OfframpProgramAddress : config .Config .OfframpAddress ,
752+ })
753+ if err1 != nil {
754+ // Some Chain family might not need crcw to be created, and if createChainAccessorsAndContractTransmitters will catch error if it does
755+ i .lggr .Debugf ("skipping creating chain writer for chain %s, writer creation: %v" , chainID , err1 )
756+ return nil
757+ }
748758
749- extendedCr , err := wrapContractReaderInObservedExtended (i .lggr , cr , chainSelector )
750- if err != nil {
751- return nil , nil , nil , fmt .Errorf ("failed to wrap contract reader for chain %s: %w" , chainID , err )
752- }
759+ if err4 := cw .Start (chainCtx ); err4 != nil {
760+ return fmt .Errorf ("failed to start chain writer for chain %s: %w" , chainID , err4 )
761+ }
762+
763+ extendedCr , err := wrapContractReaderInObservedExtended (i .lggr , cr , chainSelector )
764+ if err != nil {
765+ return fmt .Errorf ("failed to wrap contract reader for chain %s: %w" , chainID , err )
766+ }
753767
754- contractReaders [chainSelector ] = cr
755- extendedReaders [chainSelector ] = extendedCr
756- chainWriters [chainSelector ] = cw
768+ contractReaders [chainSelector ] = cr
769+ extendedReaders [chainSelector ] = extendedCr
770+ chainWriters [chainSelector ] = cw
771+ return nil
772+ }(); err != nil {
773+ return nil , nil , nil , err
774+ }
757775 }
758776 return contractReaders , extendedReaders , chainWriters , nil
759777}
0 commit comments