diff --git a/apps/evm/cmd/run.go b/apps/evm/cmd/run.go index ce7755ccb6..a88e548d21 100644 --- a/apps/evm/cmd/run.go +++ b/apps/evm/cmd/run.go @@ -59,7 +59,7 @@ var RunCmd = &cobra.Command{ return err } - blobClient, err := blobrpc.NewWSClient(cmd.Context(), nodeConfig.DA.Address, nodeConfig.DA.AuthToken, "") + blobClient, err := blobrpc.NewWSClient(cmd.Context(), logger, nodeConfig.DA.Address, nodeConfig.DA.AuthToken, "") if err != nil { return fmt.Errorf("failed to create blob client: %w", err) } diff --git a/apps/grpc/cmd/run.go b/apps/grpc/cmd/run.go index 3d1d77a6d9..22ca71f587 100644 --- a/apps/grpc/cmd/run.go +++ b/apps/grpc/cmd/run.go @@ -108,7 +108,7 @@ func createSequencer( genesis genesis.Genesis, executor execution.Executor, ) (coresequencer.Sequencer, error) { - blobClient, err := blobrpc.NewWSClient(ctx, nodeConfig.DA.Address, nodeConfig.DA.AuthToken, "") + blobClient, err := blobrpc.NewWSClient(ctx, logger, nodeConfig.DA.Address, nodeConfig.DA.AuthToken, "") if err != nil { return nil, fmt.Errorf("failed to create blob client: %w", err) } diff --git a/apps/testapp/cmd/run.go b/apps/testapp/cmd/run.go index 1022d1bce3..8584882175 100644 --- a/apps/testapp/cmd/run.go +++ b/apps/testapp/cmd/run.go @@ -111,7 +111,7 @@ func createSequencer( genesis genesis.Genesis, executor execution.Executor, ) (coresequencer.Sequencer, error) { - blobClient, err := blobrpc.NewWSClient(ctx, nodeConfig.DA.Address, nodeConfig.DA.AuthToken, "") + blobClient, err := blobrpc.NewWSClient(ctx, logger, nodeConfig.DA.Address, nodeConfig.DA.AuthToken, "") if err != nil { return nil, fmt.Errorf("failed to create blob client: %w", err) } diff --git a/pkg/cmd/run_node.go b/pkg/cmd/run_node.go index b0a36c889a..113a9229ba 100644 --- a/pkg/cmd/run_node.go +++ b/pkg/cmd/run_node.go @@ -149,7 +149,7 @@ func StartNode( } } - blobClient, err := blobrpc.NewWSClient(ctx, nodeConfig.DA.Address, nodeConfig.DA.AuthToken, "") + blobClient, err := blobrpc.NewWSClient(ctx, logger, nodeConfig.DA.Address, nodeConfig.DA.AuthToken, "") if err != nil { return fmt.Errorf("failed to create blob client: %w", err) } diff --git a/pkg/da/jsonrpc/client.go b/pkg/da/jsonrpc/client.go index c856cdd7b9..664da4114b 100644 --- a/pkg/da/jsonrpc/client.go +++ b/pkg/da/jsonrpc/client.go @@ -8,6 +8,7 @@ import ( libshare "github.com/celestiaorg/go-square/v3/share" "github.com/filecoin-project/go-jsonrpc" + "github.com/rs/zerolog" ) // Client dials the celestia-node RPC "blob" and "header" namespaces. @@ -72,9 +73,15 @@ func NewClient(ctx context.Context, addr, token string, authHeaderName string) ( // Automatically converts http:// to ws:// (and https:// to wss://). // Supports channel-based subscriptions (e.g. Subscribe). // Note: WebSocket connections are eager — they connect at creation time -// and will fail immediately if the server is unavailable. -func NewWSClient(ctx context.Context, addr, token string, authHeaderName string) (*Client, error) { - return NewClient(ctx, httpToWS(addr), token, authHeaderName) +// if the initial WS dial fails, falls back to HTTP polling for the entire session. +func NewWSClient(ctx context.Context, logger zerolog.Logger, addr, token string, authHeaderName string) (*Client, error) { + client, err := NewClient(ctx, httpToWS(addr), token, authHeaderName) + if err != nil { + logger.Warn().Err(err).Msg("DA websocket connection failed, falling back to DA polling") + return NewClient(ctx, addr, token, authHeaderName) + } + + return client, nil } // BlobAPI mirrors celestia-node's blob module (nodebuilder/blob/blob.go).