diff --git a/CHANGELOG.md b/CHANGELOG.md index f8b6134b9d..d1ee418e78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Changelog for NeoFS Node - Double voting for validators on IR startup (#2365) - Skip unexpected notary events on notary request parsing step (#2315) - Session inactivity on object PUT request relay (#2460) +- Missing connection retries on IR node startup when the first configured mainnet RPC node is not in sync (#2474) ### Removed - Deprecated `morph.rpc_endpoint` SN and `morph.endpoint.client` IR config sections (#2400) diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index e468997259..6195cfd3ce 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -479,8 +479,13 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper, errChan chan<- return nil, err } - // create mainnet listener - server.mainnetListener, err = createListener(ctx, server.mainnetClient, mainnetChain) + // create mainnet listener, retry with a different node if current one is not up to date + for { + server.mainnetListener, err = createListener(ctx, server.mainnetClient, mainnetChain) + if !errors.Is(err, subscriber.ErrStaleNode) || !server.mainnetClient.SwitchRPC() { + break + } + } if err != nil { return nil, err } diff --git a/pkg/morph/subscriber/subscriber.go b/pkg/morph/subscriber/subscriber.go index e9b3bca21d..4163aaf01c 100644 --- a/pkg/morph/subscriber/subscriber.go +++ b/pkg/morph/subscriber/subscriber.go @@ -68,6 +68,9 @@ func (s *subscriber) NotificationChannels() NotificationChannels { } var ( + // ErrStaleNode is returned from [New] when StartFromBlock requirement + // specified in [Params] is not satisfied by the given node. + ErrStaleNode = errors.New("RPC node is not yet up to date") errNilParams = errors.New("chain/subscriber: config was not provided to the constructor") errNilLogger = errors.New("chain/subscriber: logger was not provided to the constructor") @@ -332,8 +335,8 @@ func awaitHeight(cli *client.Client, startFrom uint32) error { return fmt.Errorf("could not get block height: %w", err) } - if height < startFrom { - return fmt.Errorf("RPC block counter %d didn't reach expected height %d", height, startFrom) + if height < startFrom+1 { + return fmt.Errorf("%w: expected %d height, got %d count", ErrStaleNode, startFrom, height) } return nil