diff --git a/disperser/cmd/dataapi/config.go b/disperser/cmd/dataapi/config.go index 3cef79fb09..2673b3989a 100644 --- a/disperser/cmd/dataapi/config.go +++ b/disperser/cmd/dataapi/config.go @@ -34,10 +34,10 @@ type Config struct { BLSOperatorStateRetrieverAddr string EigenDAServiceManagerAddr string - AvailabilityCheck bool - DisperserHostname string - ChurnerHostname string - BatcherHealthEndpt string + EigenDASvcAvailabilityCheck bool + DisperserHostname string + ChurnerHostname string + BatcherHealthEndpt string TxnTimeout time.Duration } @@ -83,10 +83,10 @@ func NewConfig(ctx *cli.Context) (Config, error) { HTTPPort: ctx.GlobalString(flags.MetricsHTTPPort.Name), EnableMetrics: ctx.GlobalBool(flags.EnableMetricsFlag.Name), }, - AvailabilityCheck: ctx.GlobalBool(flags.EnableAvailabilityCheckFlag.Name), - DisperserHostname: ctx.GlobalString(flags.DisperserHostnameFlag.Name), - ChurnerHostname: ctx.GlobalString(flags.ChurnerHostnameFlag.Name), - BatcherHealthEndpt: ctx.GlobalString(flags.BatcherHealthEndptFlag.Name), + EigenDASvcAvailabilityCheck: ctx.GlobalBool(flags.EnableDASvcAvailabilityCheckFlag.Name), + DisperserHostname: ctx.GlobalString(flags.DisperserHostnameFlag.Name), + ChurnerHostname: ctx.GlobalString(flags.ChurnerHostnameFlag.Name), + BatcherHealthEndpt: ctx.GlobalString(flags.BatcherHealthEndptFlag.Name), TxnTimeout: ctx.GlobalDuration(flags.TxnTimeoutFlag.Name), } diff --git a/disperser/cmd/dataapi/flags/flags.go b/disperser/cmd/dataapi/flags/flags.go index 0ed3d7235f..e43f5178d6 100644 --- a/disperser/cmd/dataapi/flags/flags.go +++ b/disperser/cmd/dataapi/flags/flags.go @@ -109,9 +109,9 @@ var ( Required: true, EnvVar: common.PrefixEnvVar(envVarPrefix, "ENABLE_METRICS"), } - EnableAvailabilityCheckFlag = cli.BoolFlag{ - Name: common.PrefixFlag(FlagPrefix, "enable-availability-check"), - Usage: "start availability check", + EnableDASvcAvailabilityCheckFlag = cli.BoolFlag{ + Name: common.PrefixFlag(FlagPrefix, "enable-eigenda-svc-availability-check"), + Usage: "start eigenda services availability check", Required: true, EnvVar: common.PrefixEnvVar(envVarPrefix, "CHECK_AVAILABILITY"), } @@ -176,7 +176,7 @@ var requiredFlags = []cli.Flag{ AllowOriginsFlag, EjectionTokenFlag, EnableMetricsFlag, - EnableAvailabilityCheckFlag, + EnableDASvcAvailabilityCheckFlag, DisperserHostnameFlag, ChurnerHostnameFlag, BatcherHealthEndptFlag, diff --git a/disperser/cmd/dataapi/main.go b/disperser/cmd/dataapi/main.go index 846825bbd9..31005cda9f 100644 --- a/disperser/cmd/dataapi/main.go +++ b/disperser/cmd/dataapi/main.go @@ -108,14 +108,14 @@ func RunDataApi(ctx *cli.Context) error { metrics = dataapi.NewMetrics(blobMetadataStore, config.MetricsConfig.HTTPPort, logger) server = dataapi.NewServer( dataapi.Config{ - ServerMode: config.ServerMode, - SocketAddr: config.SocketAddr, - AllowOrigins: config.AllowOrigins, - AvailabilityCheck: config.AvailabilityCheck, - DisperserHostname: config.DisperserHostname, - ChurnerHostname: config.ChurnerHostname, - BatcherHealthEndpt: config.BatcherHealthEndpt, - EjectionToken: config.EjectionToken, + ServerMode: config.ServerMode, + SocketAddr: config.SocketAddr, + AllowOrigins: config.AllowOrigins, + DisperserHostname: config.DisperserHostname, + ChurnerHostname: config.ChurnerHostname, + BatcherHealthEndpt: config.BatcherHealthEndpt, + EjectionToken: config.EjectionToken, + EigenDASvcAvailabilityCheck: config.EigenDASvcAvailabilityCheck, }, sharedStorage, promClient, diff --git a/disperser/dataapi/config.go b/disperser/dataapi/config.go index 186bb8c14f..7b04081b87 100644 --- a/disperser/dataapi/config.go +++ b/disperser/dataapi/config.go @@ -1,12 +1,12 @@ package dataapi type Config struct { - SocketAddr string - ServerMode string - AllowOrigins []string - AvailabilityCheck bool - DisperserHostname string - ChurnerHostname string - BatcherHealthEndpt string - EjectionToken string + SocketAddr string + ServerMode string + AllowOrigins []string + DisperserHostname string + ChurnerHostname string + BatcherHealthEndpt string + EjectionToken string + EigenDASvcAvailabilityCheck bool } diff --git a/disperser/dataapi/docs/docs.go b/disperser/dataapi/docs/docs.go index f4e937dfb4..f6951ea447 100644 --- a/disperser/dataapi/docs/docs.go +++ b/disperser/dataapi/docs/docs.go @@ -252,7 +252,7 @@ const docTemplate = `{ "$ref": "#/definitions/dataapi.ErrorResponse" } }, - "503": { + "501": { "description": "error: Service unavailable or checker not initialized", "schema": { "$ref": "#/definitions/dataapi.ErrorResponse" @@ -296,7 +296,7 @@ const docTemplate = `{ "$ref": "#/definitions/dataapi.ErrorResponse" } }, - "503": { + "501": { "description": "error: Service unavailable or checker not initialized", "schema": { "$ref": "#/definitions/dataapi.ErrorResponse" @@ -340,7 +340,7 @@ const docTemplate = `{ "$ref": "#/definitions/dataapi.ErrorResponse" } }, - "503": { + "501": { "description": "error: Service unavailable or checker not initialized", "schema": { "$ref": "#/definitions/dataapi.ErrorResponse" diff --git a/disperser/dataapi/docs/swagger.json b/disperser/dataapi/docs/swagger.json index 1dc9d145e1..e86a41339b 100644 --- a/disperser/dataapi/docs/swagger.json +++ b/disperser/dataapi/docs/swagger.json @@ -248,7 +248,7 @@ "$ref": "#/definitions/dataapi.ErrorResponse" } }, - "503": { + "501": { "description": "error: Service unavailable or checker not initialized", "schema": { "$ref": "#/definitions/dataapi.ErrorResponse" @@ -292,7 +292,7 @@ "$ref": "#/definitions/dataapi.ErrorResponse" } }, - "503": { + "501": { "description": "error: Service unavailable or checker not initialized", "schema": { "$ref": "#/definitions/dataapi.ErrorResponse" @@ -336,7 +336,7 @@ "$ref": "#/definitions/dataapi.ErrorResponse" } }, - "503": { + "501": { "description": "error: Service unavailable or checker not initialized", "schema": { "$ref": "#/definitions/dataapi.ErrorResponse" diff --git a/disperser/dataapi/docs/swagger.yaml b/disperser/dataapi/docs/swagger.yaml index 3872f05d43..2afdc332a4 100644 --- a/disperser/dataapi/docs/swagger.yaml +++ b/disperser/dataapi/docs/swagger.yaml @@ -395,7 +395,7 @@ paths: description: 'error: Server error' schema: $ref: '#/definitions/dataapi.ErrorResponse' - "503": + "501": description: 'error: Service unavailable or checker not initialized' schema: $ref: '#/definitions/dataapi.ErrorResponse' @@ -425,7 +425,7 @@ paths: description: 'error: Server error' schema: $ref: '#/definitions/dataapi.ErrorResponse' - "503": + "501": description: 'error: Service unavailable or checker not initialized' schema: $ref: '#/definitions/dataapi.ErrorResponse' @@ -455,7 +455,7 @@ paths: description: 'error: Server error' schema: $ref: '#/definitions/dataapi.ErrorResponse' - "503": + "501": description: 'error: Service unavailable or checker not initialized' schema: $ref: '#/definitions/dataapi.ErrorResponse' diff --git a/disperser/dataapi/server.go b/disperser/dataapi/server.go index fd5b583186..261c85d6a8 100644 --- a/disperser/dataapi/server.go +++ b/disperser/dataapi/server.go @@ -197,7 +197,7 @@ func NewServer( grpcConn = &GRPCDialerSkipTLS{} } - if config.AvailabilityCheck { + if config.EigenDASvcAvailabilityCheck { if eigenDAGRPCServiceChecker == nil { @@ -259,7 +259,7 @@ func (s *server) Start() error { metrics.GET("/throughput", s.FetchMetricsThroughputHandler) metrics.GET("/non-signers", s.FetchNonSigners) metrics.GET("/operator-nonsigning-percentage", s.FetchOperatorsNonsigningPercentageHandler) - if s.eigenDAHttpServiceChecker != nil { + if s.eigenDAHttpServiceChecker != nil && s.eigenDAGRPCServiceChecker != nil { metrics.GET("/disperser-service-availability", s.FetchDisperserServiceAvailability) metrics.GET("/churner-service-availability", s.FetchChurnerServiceAvailability) metrics.GET("/batcher-service-availability", s.FetchBatcherAvailability) @@ -721,12 +721,14 @@ func (s *server) OperatorPortCheck(c *gin.Context) { // @Failure 400 {object} ErrorResponse "error: Bad request" // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" -// @Failure 503 {object} ErrorResponse "error: Service unavailable or checker not initialized" +// @Failure 501 {object} ErrorResponse "error: Service unavailable or checker not initialized" // @Router /metrics/disperser-service-availability [get] func (s *server) FetchDisperserServiceAvailability(c *gin.Context) { if s.eigenDAGRPCServiceChecker == nil { - errorResponse(c, errors.New("service availability check is not enabled")) + c.JSON(http.StatusNotImplemented, gin.H{ + "error": "service availability check not enabled", + }) } timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { @@ -782,12 +784,14 @@ func (s *server) FetchDisperserServiceAvailability(c *gin.Context) { // @Failure 400 {object} ErrorResponse "error: Bad request" // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" -// @Failure 503 {object} ErrorResponse "error: Service unavailable or checker not initialized" +// @Failure 501 {object} ErrorResponse "error: Service unavailable or checker not initialized" // @Router /metrics/churner-service-availability [get] func (s *server) FetchChurnerServiceAvailability(c *gin.Context) { if s.eigenDAGRPCServiceChecker == nil { - errorResponse(c, errors.New("service availability check is not enabled")) + c.JSON(http.StatusNotImplemented, gin.H{ + "error": "service availability check not enabled", + }) } timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { @@ -843,12 +847,14 @@ func (s *server) FetchChurnerServiceAvailability(c *gin.Context) { // @Failure 400 {object} ErrorResponse "error: Bad request" // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" -// @Failure 503 {object} ErrorResponse "error: Service unavailable or checker not initialized" +// @Failure 501 {object} ErrorResponse "error: Service unavailable or checker not initialized" // @Router /metrics/batcher-service-availability [get] func (s *server) FetchBatcherAvailability(c *gin.Context) { if s.eigenDAHttpServiceChecker == nil { - errorResponse(c, errors.New("service availability check is not enabled")) + c.JSON(http.StatusNotImplemented, gin.H{ + "error": "service availability check is not enabled", + }) } timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { diff --git a/disperser/dataapi/server_test.go b/disperser/dataapi/server_test.go index 0d62ba3af2..8723936f76 100644 --- a/disperser/dataapi/server_test.go +++ b/disperser/dataapi/server_test.go @@ -55,7 +55,7 @@ var ( mockSubgraphApi = &subgraphmock.MockSubgraphApi{} subgraphClient = dataapi.NewSubgraphClient(mockSubgraphApi, mockLogger) - config = dataapi.Config{ServerMode: "test", SocketAddr: ":8080", AllowOrigins: []string{"*"}, DisperserHostname: "localhost:32007", ChurnerHostname: "localhost:32009", EjectionToken: "deadbeef"} + config = dataapi.Config{ServerMode: "test", SocketAddr: ":8080", AllowOrigins: []string{"*"}, DisperserHostname: "localhost:32007", ChurnerHostname: "localhost:32009", EjectionToken: "deadbeef", EigenDASvcAvailabilityCheck: true} mockTx = &coremock.MockTransactor{} metrics = dataapi.NewMetrics(nil, "9001", mockLogger) @@ -570,6 +570,34 @@ func TestCheckBatcherHealthExpectNotServing(t *testing.T) { assert.Equal(t, "NOT_SERVING", serviceData.ServiceStatus) } +func TestFetchBatcherServiceAvailabilityDisableHandler(t *testing.T) { + r := setUpRouter() + daSvcDisableConfig := dataapi.Config{ServerMode: "test", SocketAddr: ":8080", AllowOrigins: []string{"*"}, DisperserHostname: "localhost:32007", ChurnerHostname: "localhost:32009", EjectionToken: "deadbeef", EigenDASvcAvailabilityCheck: false} + + testDataApiServer = dataapi.NewServer(daSvcDisableConfig, blobstore, prometheusClient, dataapi.NewSubgraphClient(mockSubgraphApi, mockLogger), mockTx, mockChainState, nil, mockLogger, metrics, nil, nil, nil) + + r.GET("/v1/metrics/batcher-service-availability", testDataApiServer.FetchBatcherAvailability) + + w := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodGet, "/v1/metrics/batcher-service-availability", nil) + r.ServeHTTP(w, req) + + res := w.Result() + defer res.Body.Close() + + data, err := io.ReadAll(res.Body) + assert.NoError(t, err) + + var response dataapi.ServiceAvailabilityResponse + err = json.Unmarshal(data, &response) + assert.NoError(t, err) + assert.NotNil(t, response) + + fmt.Printf("Response: %v\n", response) + + assert.Equal(t, http.StatusNotImplemented, res.StatusCode) +} + func TestFetchDisperserServiceAvailabilityHandler(t *testing.T) { r := setUpRouter() @@ -608,6 +636,42 @@ func TestFetchDisperserServiceAvailabilityHandler(t *testing.T) { assert.Equal(t, grpc_health_v1.HealthCheckResponse_SERVING.String(), serviceData.ServiceStatus) } +func TestFetchDisperserServiceAvailabilityDisableHandler(t *testing.T) { + r := setUpRouter() + + mockHealthCheckService := NewMockHealthCheckService() + mockHealthCheckService.AddResponse("Disperser", &grpc_health_v1.HealthCheckResponse{ + Status: grpc_health_v1.HealthCheckResponse_SERVING, + }) + + daSvcDisableConfig := dataapi.Config{ServerMode: "test", SocketAddr: ":8080", AllowOrigins: []string{"*"}, DisperserHostname: "localhost:32007", ChurnerHostname: "localhost:32009", EjectionToken: "deadbeef", EigenDASvcAvailabilityCheck: false} + + testDataApiServer = dataapi.NewServer(daSvcDisableConfig, blobstore, prometheusClient, dataapi.NewSubgraphClient(mockSubgraphApi, mockLogger), mockTx, mockChainState, nil, mockLogger, metrics, nil, nil, nil) + + r.GET("/v1/metrics/disperser-service-availability", testDataApiServer.FetchDisperserServiceAvailability) + + w := httptest.NewRecorder() + req := httptest.NewRequest(http.MethodGet, "/v1/metrics/disperser-service-availability", nil) + r.ServeHTTP(w, req) + + res := w.Result() + defer res.Body.Close() + + data, err := io.ReadAll(res.Body) + assert.NoError(t, err) + + var response dataapi.ServiceAvailabilityResponse + err = json.Unmarshal(data, &response) + assert.NoError(t, err) + assert.NotNil(t, response) + + fmt.Printf("Response: %v\n", response) + + assert.Equal(t, http.StatusNotImplemented, res.StatusCode) + assert.Equal(t, 0, response.Meta.Size) + assert.Equal(t, 0, len(response.Data)) +} + func TestChurnerServiceAvailabilityHandler(t *testing.T) { r := setUpRouter()