diff --git a/disperser/dataapi/docs/docs.go b/disperser/dataapi/docs/docs.go index bbc26fc7e..8628e5843 100644 --- a/disperser/dataapi/docs/docs.go +++ b/disperser/dataapi/docs/docs.go @@ -107,756 +107,34 @@ const docTemplate = `{ } } }, - "/feed/batches/{batch_header_hash}/blobs": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Feed" - ], - "summary": "Fetch blob metadata by batch header hash", - "parameters": [ - { - "type": "string", - "description": "Batch Header Hash", - "name": "batch_header_hash", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Limit [default: 10]", - "name": "limit", - "in": "query" - }, - { - "type": "string", - "description": "Next page token", - "name": "next_token", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.BlobsResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/feed/blobs": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Feed" - ], - "summary": "Fetch blobs metadata list", - "parameters": [ - { - "type": "integer", - "description": "Limit [default: 10]", - "name": "limit", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.BlobsResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/feed/blobs/{blob_key}": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Feed" - ], - "summary": "Fetch blob metadata by blob key", - "parameters": [ - { - "type": "string", - "description": "Blob Key", - "name": "blob_key", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.BlobMetadataResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch metrics", - "parameters": [ - { - "type": "integer", - "description": "Start unix timestamp [default: 1 hour ago]", - "name": "start", - "in": "query" - }, - { - "type": "integer", - "description": "End unix timestamp [default: unix time now]", - "name": "end", - "in": "query" - }, - { - "type": "integer", - "description": "Limit [default: 10]", - "name": "limit", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.Metric" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/batcher-service-availability": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Batcher Availability" - ], - "summary": "Get status of EigenDA batcher.", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.ServiceAvailabilityResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/churner-service-availability": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Churner ServiceAvailability" - ], - "summary": "Get status of EigenDA churner service.", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.ServiceAvailabilityResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/disperser-service-availability": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "ServiceAvailability" - ], - "summary": "Get status of EigenDA Disperser service.", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.ServiceAvailabilityResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/non-signers": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch non signers", - "parameters": [ - { - "type": "integer", - "description": "Interval to query for non signers in seconds [default: 3600]", - "name": "interval", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.NonSigner" - } - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/operator-nonsigning-percentage": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch operators non signing percentage", - "parameters": [ - { - "type": "integer", - "description": "Interval to query for operators nonsigning percentage [default: 3600]", - "name": "interval", - "in": "query" - }, - { - "type": "string", - "description": "End time (2006-01-02T15:04:05Z) to query for operators nonsigning percentage [default: now]", - "name": "end", - "in": "query" - }, - { - "type": "string", - "description": "Whether return only live nonsigners [default: true]", - "name": "live_only", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.OperatorsNonsigningPercentage" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/summary": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch metrics summary", - "parameters": [ - { - "type": "integer", - "description": "Start unix timestamp [default: 1 hour ago]", - "name": "start", - "in": "query" - }, - { - "type": "integer", - "description": "End unix timestamp [default: unix time now]", - "name": "end", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.Metric" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/throughput": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch throughput time series", - "parameters": [ - { - "type": "integer", - "description": "Start unix timestamp [default: 1 hour ago]", - "name": "start", - "in": "query" - }, - { - "type": "integer", - "description": "End unix timestamp [default: unix time now]", - "name": "end", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.Throughput" - } - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/timeseries/throughput": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch throughput time series", - "parameters": [ - { - "type": "integer", - "description": "Start unix timestamp [default: 1 hour ago]", - "name": "start", - "in": "query" - }, - { - "type": "integer", - "description": "End unix timestamp [default: unix time now]", - "name": "end", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.Throughput" - } - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/operators-info/deregistered-operators": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "OperatorsInfo" - ], - "summary": "Fetch list of operators that have been deregistered for days. Days is a query parameter with a default value of 14 and max value of 30.", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.QueriedStateOperatorsResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/operators-info/operator-ejections": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "OperatorsInfo" - ], - "summary": "Fetch list of operator ejections over last N days.", - "parameters": [ - { - "type": "integer", - "description": "Lookback in days [default: 1]", - "name": "days", - "in": "query" - }, - { - "type": "string", - "description": "Operator ID filter [default: all operators]", - "name": "operator_id", - "in": "query" - }, - { - "type": "integer", - "description": "Return first N ejections [default: 1000]", - "name": "first", - "in": "query" - }, - { - "type": "integer", - "description": "Skip first N ejections [default: 0]", - "name": "skip", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.QueriedOperatorEjectionsResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/operators-info/operators-stake": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "OperatorsStake" - ], - "summary": "Operator stake distribution query", - "parameters": [ - { - "type": "string", - "description": "Operator ID", - "name": "operator_id", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.OperatorsStakeResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/operators-info/port-check": { + "/metrics/summary": { "get": { "produces": [ "application/json" ], "tags": [ - "OperatorsInfo" + "Metrics" ], - "summary": "Operator node reachability port check", + "summary": "Fetch metrics summary", "parameters": [ { - "type": "string", - "description": "Operator ID", - "name": "operator_id", - "in": "query", - "required": true + "type": "integer", + "description": "Start unix timestamp [default: 1 hour ago]", + "name": "start", + "in": "query" + }, + { + "type": "integer", + "description": "End unix timestamp [default: unix time now]", + "name": "end", + "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dataapi.OperatorPortCheckResponse" + "$ref": "#/definitions/dataapi.Metric" } }, "400": { @@ -880,20 +158,37 @@ const docTemplate = `{ } } }, - "/operators-info/registered-operators": { + "/metrics/timeseries/throughput": { "get": { "produces": [ "application/json" ], "tags": [ - "OperatorsInfo" + "Metrics" + ], + "summary": "Fetch throughput time series", + "parameters": [ + { + "type": "integer", + "description": "Start unix timestamp [default: 1 hour ago]", + "name": "start", + "in": "query" + }, + { + "type": "integer", + "description": "End unix timestamp [default: unix time now]", + "name": "end", + "in": "query" + } ], - "summary": "Fetch list of operators that have been registered for days. Days is a query parameter with a default value of 14 and max value of 30.", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dataapi.QueriedStateOperatorsResponse" + "type": "array", + "items": { + "$ref": "#/definitions/dataapi.Throughput" + } } }, "400": { @@ -917,31 +212,6 @@ const docTemplate = `{ } } }, - "/operators-info/semver-scan": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "OperatorsInfo" - ], - "summary": "Active operator semver scan", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.SemverReportResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, "/operators/nodeinfo": { "get": { "produces": [ @@ -1087,79 +357,6 @@ const docTemplate = `{ } } }, - "core.SecurityParam": { - "type": "object", - "properties": { - "adversaryThreshold": { - "description": "AdversaryThreshold is the maximum amount of stake that can be controlled by an adversary in the quorum as a percentage of the total stake in the quorum", - "type": "integer" - }, - "confirmationThreshold": { - "description": "ConfirmationThreshold is the amount of stake that must sign a message for it to be considered valid as a percentage of the total stake in the quorum", - "type": "integer" - }, - "quorumID": { - "type": "integer" - }, - "quorumRate": { - "description": "Rate Limit. This is a temporary measure until the node can derive rates on its own using rollup authentication. This is used\nfor restricting the rate at which retrievers are able to download data from the DA node to a multiple of the rate at which the\ndata was posted to the DA node.", - "type": "integer" - } - } - }, - "dataapi.BlobMetadataResponse": { - "type": "object", - "properties": { - "batch_header_hash": { - "type": "string" - }, - "batch_id": { - "type": "integer" - }, - "batch_root": { - "type": "string" - }, - "blob_commitment": { - "$ref": "#/definitions/encoding.BlobCommitments" - }, - "blob_inclusion_proof": { - "type": "string" - }, - "blob_index": { - "type": "integer" - }, - "blob_key": { - "type": "string" - }, - "blob_status": { - "$ref": "#/definitions/github_com_Layr-Labs_eigenda_disperser.BlobStatus" - }, - "confirmation_block_number": { - "type": "integer" - }, - "confirmation_txn_hash": { - "type": "string" - }, - "fee": { - "type": "string" - }, - "reference_block_number": { - "type": "integer" - }, - "requested_at": { - "type": "integer" - }, - "security_params": { - "type": "array", - "items": { - "$ref": "#/definitions/core.SecurityParam" - } - }, - "signatory_record_hash": { - "type": "string" - } - } - }, "dataapi.BlobResponse": { "type": "object", "properties": { @@ -1177,20 +374,6 @@ const docTemplate = `{ } } }, - "dataapi.BlobsResponse": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.BlobMetadataResponse" - } - }, - "meta": { - "$ref": "#/definitions/dataapi.Meta" - } - } - }, "dataapi.ErrorResponse": { "type": "object", "properties": { @@ -1199,17 +382,6 @@ const docTemplate = `{ } } }, - "dataapi.Meta": { - "type": "object", - "properties": { - "next_token": { - "type": "string" - }, - "size": { - "type": "integer" - } - } - }, "dataapi.Metric": { "type": "object", "properties": { @@ -1235,43 +407,6 @@ const docTemplate = `{ } } }, - "dataapi.NonSigner": { - "type": "object", - "properties": { - "count": { - "type": "integer" - }, - "operatorId": { - "type": "string" - } - } - }, - "dataapi.OperatorNonsigningPercentageMetrics": { - "type": "object", - "properties": { - "operator_address": { - "type": "string" - }, - "operator_id": { - "type": "string" - }, - "percentage": { - "type": "number" - }, - "quorum_id": { - "type": "integer" - }, - "stake_percentage": { - "type": "number" - }, - "total_batches": { - "type": "integer" - }, - "total_unsigned_batches": { - "type": "integer" - } - } - }, "dataapi.OperatorPortCheckResponse": { "type": "object", "properties": { @@ -1309,20 +444,6 @@ const docTemplate = `{ } } }, - "dataapi.OperatorsNonsigningPercentage": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.OperatorNonsigningPercentageMetrics" - } - }, - "meta": { - "$ref": "#/definitions/dataapi.Meta" - } - } - }, "dataapi.OperatorsStakeResponse": { "type": "object", "properties": { @@ -1337,77 +458,6 @@ const docTemplate = `{ } } }, - "dataapi.QueriedOperatorEjections": { - "type": "object", - "properties": { - "block_number": { - "type": "integer" - }, - "block_timestamp": { - "type": "string" - }, - "operator_address": { - "type": "string" - }, - "operator_id": { - "type": "string" - }, - "quorum": { - "type": "integer" - }, - "stake_percentage": { - "type": "number" - }, - "transaction_hash": { - "type": "string" - } - } - }, - "dataapi.QueriedOperatorEjectionsResponse": { - "type": "object", - "properties": { - "ejections": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.QueriedOperatorEjections" - } - } - } - }, - "dataapi.QueriedStateOperatorMetadata": { - "type": "object", - "properties": { - "block_number": { - "type": "integer" - }, - "is_online": { - "type": "boolean" - }, - "operator_id": { - "type": "string" - }, - "operator_process_error": { - "type": "string" - }, - "socket": { - "type": "string" - } - } - }, - "dataapi.QueriedStateOperatorsResponse": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.QueriedStateOperatorMetadata" - } - }, - "meta": { - "$ref": "#/definitions/dataapi.Meta" - } - } - }, "dataapi.SemverReportResponse": { "type": "object", "properties": { @@ -1419,31 +469,6 @@ const docTemplate = `{ } } }, - "dataapi.ServiceAvailability": { - "type": "object", - "properties": { - "service_name": { - "type": "string" - }, - "service_status": { - "type": "string" - } - } - }, - "dataapi.ServiceAvailabilityResponse": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.ServiceAvailability" - } - }, - "meta": { - "$ref": "#/definitions/dataapi.Meta" - } - } - }, "dataapi.Throughput": { "type": "object", "properties": { @@ -1480,6 +505,12 @@ const docTemplate = `{ "items": { "type": "integer" } + }, + "y": { + "type": "array", + "items": { + "type": "integer" + } } } }, @@ -1488,6 +519,9 @@ const docTemplate = `{ "properties": { "x": { "$ref": "#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2" + }, + "y": { + "$ref": "#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2" } } }, @@ -1496,6 +530,9 @@ const docTemplate = `{ "properties": { "x": { "$ref": "#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2" + }, + "y": { + "$ref": "#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2" } } }, @@ -1532,25 +569,6 @@ const docTemplate = `{ } } }, - "github_com_Layr-Labs_eigenda_disperser.BlobStatus": { - "type": "integer", - "enum": [ - 0, - 1, - 2, - 3, - 4, - 5 - ], - "x-enum-varnames": [ - "Processing", - "Confirmed", - "Failed", - "Finalized", - "InsufficientSignatures", - "Dispersing" - ] - }, "github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2": { "type": "object", "properties": { @@ -1559,6 +577,12 @@ const docTemplate = `{ "items": { "type": "integer" } + }, + "a1": { + "type": "array", + "items": { + "type": "integer" + } } } }, diff --git a/disperser/dataapi/docs/swagger.json b/disperser/dataapi/docs/swagger.json index 9f8e09c67..4b4b4962b 100644 --- a/disperser/dataapi/docs/swagger.json +++ b/disperser/dataapi/docs/swagger.json @@ -103,756 +103,34 @@ } } }, - "/feed/batches/{batch_header_hash}/blobs": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Feed" - ], - "summary": "Fetch blob metadata by batch header hash", - "parameters": [ - { - "type": "string", - "description": "Batch Header Hash", - "name": "batch_header_hash", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Limit [default: 10]", - "name": "limit", - "in": "query" - }, - { - "type": "string", - "description": "Next page token", - "name": "next_token", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.BlobsResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/feed/blobs": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Feed" - ], - "summary": "Fetch blobs metadata list", - "parameters": [ - { - "type": "integer", - "description": "Limit [default: 10]", - "name": "limit", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.BlobsResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/feed/blobs/{blob_key}": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Feed" - ], - "summary": "Fetch blob metadata by blob key", - "parameters": [ - { - "type": "string", - "description": "Blob Key", - "name": "blob_key", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.BlobMetadataResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch metrics", - "parameters": [ - { - "type": "integer", - "description": "Start unix timestamp [default: 1 hour ago]", - "name": "start", - "in": "query" - }, - { - "type": "integer", - "description": "End unix timestamp [default: unix time now]", - "name": "end", - "in": "query" - }, - { - "type": "integer", - "description": "Limit [default: 10]", - "name": "limit", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.Metric" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/batcher-service-availability": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Batcher Availability" - ], - "summary": "Get status of EigenDA batcher.", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.ServiceAvailabilityResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/churner-service-availability": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Churner ServiceAvailability" - ], - "summary": "Get status of EigenDA churner service.", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.ServiceAvailabilityResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/disperser-service-availability": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "ServiceAvailability" - ], - "summary": "Get status of EigenDA Disperser service.", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.ServiceAvailabilityResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/non-signers": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch non signers", - "parameters": [ - { - "type": "integer", - "description": "Interval to query for non signers in seconds [default: 3600]", - "name": "interval", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.NonSigner" - } - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/operator-nonsigning-percentage": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch operators non signing percentage", - "parameters": [ - { - "type": "integer", - "description": "Interval to query for operators nonsigning percentage [default: 3600]", - "name": "interval", - "in": "query" - }, - { - "type": "string", - "description": "End time (2006-01-02T15:04:05Z) to query for operators nonsigning percentage [default: now]", - "name": "end", - "in": "query" - }, - { - "type": "string", - "description": "Whether return only live nonsigners [default: true]", - "name": "live_only", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.OperatorsNonsigningPercentage" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/summary": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch metrics summary", - "parameters": [ - { - "type": "integer", - "description": "Start unix timestamp [default: 1 hour ago]", - "name": "start", - "in": "query" - }, - { - "type": "integer", - "description": "End unix timestamp [default: unix time now]", - "name": "end", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.Metric" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/throughput": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch throughput time series", - "parameters": [ - { - "type": "integer", - "description": "Start unix timestamp [default: 1 hour ago]", - "name": "start", - "in": "query" - }, - { - "type": "integer", - "description": "End unix timestamp [default: unix time now]", - "name": "end", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.Throughput" - } - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/metrics/timeseries/throughput": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "Metrics" - ], - "summary": "Fetch throughput time series", - "parameters": [ - { - "type": "integer", - "description": "Start unix timestamp [default: 1 hour ago]", - "name": "start", - "in": "query" - }, - { - "type": "integer", - "description": "End unix timestamp [default: unix time now]", - "name": "end", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.Throughput" - } - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/operators-info/deregistered-operators": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "OperatorsInfo" - ], - "summary": "Fetch list of operators that have been deregistered for days. Days is a query parameter with a default value of 14 and max value of 30.", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.QueriedStateOperatorsResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/operators-info/operator-ejections": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "OperatorsInfo" - ], - "summary": "Fetch list of operator ejections over last N days.", - "parameters": [ - { - "type": "integer", - "description": "Lookback in days [default: 1]", - "name": "days", - "in": "query" - }, - { - "type": "string", - "description": "Operator ID filter [default: all operators]", - "name": "operator_id", - "in": "query" - }, - { - "type": "integer", - "description": "Return first N ejections [default: 1000]", - "name": "first", - "in": "query" - }, - { - "type": "integer", - "description": "Skip first N ejections [default: 0]", - "name": "skip", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.QueriedOperatorEjectionsResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/operators-info/operators-stake": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "OperatorsStake" - ], - "summary": "Operator stake distribution query", - "parameters": [ - { - "type": "string", - "description": "Operator ID", - "name": "operator_id", - "in": "query", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.OperatorsStakeResponse" - } - }, - "400": { - "description": "error: Bad request", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "404": { - "description": "error: Not found", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, - "/operators-info/port-check": { + "/metrics/summary": { "get": { "produces": [ "application/json" ], "tags": [ - "OperatorsInfo" + "Metrics" ], - "summary": "Operator node reachability port check", + "summary": "Fetch metrics summary", "parameters": [ { - "type": "string", - "description": "Operator ID", - "name": "operator_id", - "in": "query", - "required": true + "type": "integer", + "description": "Start unix timestamp [default: 1 hour ago]", + "name": "start", + "in": "query" + }, + { + "type": "integer", + "description": "End unix timestamp [default: unix time now]", + "name": "end", + "in": "query" } ], "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dataapi.OperatorPortCheckResponse" + "$ref": "#/definitions/dataapi.Metric" } }, "400": { @@ -876,20 +154,37 @@ } } }, - "/operators-info/registered-operators": { + "/metrics/timeseries/throughput": { "get": { "produces": [ "application/json" ], "tags": [ - "OperatorsInfo" + "Metrics" + ], + "summary": "Fetch throughput time series", + "parameters": [ + { + "type": "integer", + "description": "Start unix timestamp [default: 1 hour ago]", + "name": "start", + "in": "query" + }, + { + "type": "integer", + "description": "End unix timestamp [default: unix time now]", + "name": "end", + "in": "query" + } ], - "summary": "Fetch list of operators that have been registered for days. Days is a query parameter with a default value of 14 and max value of 30.", "responses": { "200": { "description": "OK", "schema": { - "$ref": "#/definitions/dataapi.QueriedStateOperatorsResponse" + "type": "array", + "items": { + "$ref": "#/definitions/dataapi.Throughput" + } } }, "400": { @@ -913,31 +208,6 @@ } } }, - "/operators-info/semver-scan": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "OperatorsInfo" - ], - "summary": "Active operator semver scan", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/dataapi.SemverReportResponse" - } - }, - "500": { - "description": "error: Server error", - "schema": { - "$ref": "#/definitions/dataapi.ErrorResponse" - } - } - } - } - }, "/operators/nodeinfo": { "get": { "produces": [ @@ -1083,79 +353,6 @@ } } }, - "core.SecurityParam": { - "type": "object", - "properties": { - "adversaryThreshold": { - "description": "AdversaryThreshold is the maximum amount of stake that can be controlled by an adversary in the quorum as a percentage of the total stake in the quorum", - "type": "integer" - }, - "confirmationThreshold": { - "description": "ConfirmationThreshold is the amount of stake that must sign a message for it to be considered valid as a percentage of the total stake in the quorum", - "type": "integer" - }, - "quorumID": { - "type": "integer" - }, - "quorumRate": { - "description": "Rate Limit. This is a temporary measure until the node can derive rates on its own using rollup authentication. This is used\nfor restricting the rate at which retrievers are able to download data from the DA node to a multiple of the rate at which the\ndata was posted to the DA node.", - "type": "integer" - } - } - }, - "dataapi.BlobMetadataResponse": { - "type": "object", - "properties": { - "batch_header_hash": { - "type": "string" - }, - "batch_id": { - "type": "integer" - }, - "batch_root": { - "type": "string" - }, - "blob_commitment": { - "$ref": "#/definitions/encoding.BlobCommitments" - }, - "blob_inclusion_proof": { - "type": "string" - }, - "blob_index": { - "type": "integer" - }, - "blob_key": { - "type": "string" - }, - "blob_status": { - "$ref": "#/definitions/github_com_Layr-Labs_eigenda_disperser.BlobStatus" - }, - "confirmation_block_number": { - "type": "integer" - }, - "confirmation_txn_hash": { - "type": "string" - }, - "fee": { - "type": "string" - }, - "reference_block_number": { - "type": "integer" - }, - "requested_at": { - "type": "integer" - }, - "security_params": { - "type": "array", - "items": { - "$ref": "#/definitions/core.SecurityParam" - } - }, - "signatory_record_hash": { - "type": "string" - } - } - }, "dataapi.BlobResponse": { "type": "object", "properties": { @@ -1173,20 +370,6 @@ } } }, - "dataapi.BlobsResponse": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.BlobMetadataResponse" - } - }, - "meta": { - "$ref": "#/definitions/dataapi.Meta" - } - } - }, "dataapi.ErrorResponse": { "type": "object", "properties": { @@ -1195,17 +378,6 @@ } } }, - "dataapi.Meta": { - "type": "object", - "properties": { - "next_token": { - "type": "string" - }, - "size": { - "type": "integer" - } - } - }, "dataapi.Metric": { "type": "object", "properties": { @@ -1231,43 +403,6 @@ } } }, - "dataapi.NonSigner": { - "type": "object", - "properties": { - "count": { - "type": "integer" - }, - "operatorId": { - "type": "string" - } - } - }, - "dataapi.OperatorNonsigningPercentageMetrics": { - "type": "object", - "properties": { - "operator_address": { - "type": "string" - }, - "operator_id": { - "type": "string" - }, - "percentage": { - "type": "number" - }, - "quorum_id": { - "type": "integer" - }, - "stake_percentage": { - "type": "number" - }, - "total_batches": { - "type": "integer" - }, - "total_unsigned_batches": { - "type": "integer" - } - } - }, "dataapi.OperatorPortCheckResponse": { "type": "object", "properties": { @@ -1305,20 +440,6 @@ } } }, - "dataapi.OperatorsNonsigningPercentage": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.OperatorNonsigningPercentageMetrics" - } - }, - "meta": { - "$ref": "#/definitions/dataapi.Meta" - } - } - }, "dataapi.OperatorsStakeResponse": { "type": "object", "properties": { @@ -1333,77 +454,6 @@ } } }, - "dataapi.QueriedOperatorEjections": { - "type": "object", - "properties": { - "block_number": { - "type": "integer" - }, - "block_timestamp": { - "type": "string" - }, - "operator_address": { - "type": "string" - }, - "operator_id": { - "type": "string" - }, - "quorum": { - "type": "integer" - }, - "stake_percentage": { - "type": "number" - }, - "transaction_hash": { - "type": "string" - } - } - }, - "dataapi.QueriedOperatorEjectionsResponse": { - "type": "object", - "properties": { - "ejections": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.QueriedOperatorEjections" - } - } - } - }, - "dataapi.QueriedStateOperatorMetadata": { - "type": "object", - "properties": { - "block_number": { - "type": "integer" - }, - "is_online": { - "type": "boolean" - }, - "operator_id": { - "type": "string" - }, - "operator_process_error": { - "type": "string" - }, - "socket": { - "type": "string" - } - } - }, - "dataapi.QueriedStateOperatorsResponse": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.QueriedStateOperatorMetadata" - } - }, - "meta": { - "$ref": "#/definitions/dataapi.Meta" - } - } - }, "dataapi.SemverReportResponse": { "type": "object", "properties": { @@ -1415,31 +465,6 @@ } } }, - "dataapi.ServiceAvailability": { - "type": "object", - "properties": { - "service_name": { - "type": "string" - }, - "service_status": { - "type": "string" - } - } - }, - "dataapi.ServiceAvailabilityResponse": { - "type": "object", - "properties": { - "data": { - "type": "array", - "items": { - "$ref": "#/definitions/dataapi.ServiceAvailability" - } - }, - "meta": { - "$ref": "#/definitions/dataapi.Meta" - } - } - }, "dataapi.Throughput": { "type": "object", "properties": { @@ -1476,6 +501,12 @@ "items": { "type": "integer" } + }, + "y": { + "type": "array", + "items": { + "type": "integer" + } } } }, @@ -1484,6 +515,9 @@ "properties": { "x": { "$ref": "#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2" + }, + "y": { + "$ref": "#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2" } } }, @@ -1492,6 +526,9 @@ "properties": { "x": { "$ref": "#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2" + }, + "y": { + "$ref": "#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2" } } }, @@ -1528,25 +565,6 @@ } } }, - "github_com_Layr-Labs_eigenda_disperser.BlobStatus": { - "type": "integer", - "enum": [ - 0, - 1, - 2, - 3, - 4, - 5 - ], - "x-enum-varnames": [ - "Processing", - "Confirmed", - "Failed", - "Finalized", - "InsufficientSignatures", - "Dispersing" - ] - }, "github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2": { "type": "object", "properties": { @@ -1555,6 +573,12 @@ "items": { "type": "integer" } + }, + "a1": { + "type": "array", + "items": { + "type": "integer" + } } } }, diff --git a/disperser/dataapi/docs/swagger.yaml b/disperser/dataapi/docs/swagger.yaml index c479f789d..b173e32b2 100644 --- a/disperser/dataapi/docs/swagger.yaml +++ b/disperser/dataapi/docs/swagger.yaml @@ -21,62 +21,6 @@ definitions: reservation period type: integer type: object - core.SecurityParam: - properties: - adversaryThreshold: - description: AdversaryThreshold is the maximum amount of stake that can be - controlled by an adversary in the quorum as a percentage of the total stake - in the quorum - type: integer - confirmationThreshold: - description: ConfirmationThreshold is the amount of stake that must sign a - message for it to be considered valid as a percentage of the total stake - in the quorum - type: integer - quorumID: - type: integer - quorumRate: - description: |- - Rate Limit. This is a temporary measure until the node can derive rates on its own using rollup authentication. This is used - for restricting the rate at which retrievers are able to download data from the DA node to a multiple of the rate at which the - data was posted to the DA node. - type: integer - type: object - dataapi.BlobMetadataResponse: - properties: - batch_header_hash: - type: string - batch_id: - type: integer - batch_root: - type: string - blob_commitment: - $ref: '#/definitions/encoding.BlobCommitments' - blob_inclusion_proof: - type: string - blob_index: - type: integer - blob_key: - type: string - blob_status: - $ref: '#/definitions/github_com_Layr-Labs_eigenda_disperser.BlobStatus' - confirmation_block_number: - type: integer - confirmation_txn_hash: - type: string - fee: - type: string - reference_block_number: - type: integer - requested_at: - type: integer - security_params: - items: - $ref: '#/definitions/core.SecurityParam' - type: array - signatory_record_hash: - type: string - type: object dataapi.BlobResponse: properties: blob_header: @@ -88,27 +32,11 @@ definitions: status: type: string type: object - dataapi.BlobsResponse: - properties: - data: - items: - $ref: '#/definitions/dataapi.BlobMetadataResponse' - type: array - meta: - $ref: '#/definitions/dataapi.Meta' - type: object dataapi.ErrorResponse: properties: error: type: string type: object - dataapi.Meta: - properties: - next_token: - type: string - size: - type: integer - type: object dataapi.Metric: properties: cost_in_gas: @@ -125,30 +53,6 @@ definitions: $ref: '#/definitions/big.Int' type: object type: object - dataapi.NonSigner: - properties: - count: - type: integer - operatorId: - type: string - type: object - dataapi.OperatorNonsigningPercentageMetrics: - properties: - operator_address: - type: string - operator_id: - type: string - percentage: - type: number - quorum_id: - type: integer - stake_percentage: - type: number - total_batches: - type: integer - total_unsigned_batches: - type: integer - type: object dataapi.OperatorPortCheckResponse: properties: dispersal_online: @@ -173,15 +77,6 @@ definitions: stake_percentage: type: number type: object - dataapi.OperatorsNonsigningPercentage: - properties: - data: - items: - $ref: '#/definitions/dataapi.OperatorNonsigningPercentageMetrics' - type: array - meta: - $ref: '#/definitions/dataapi.Meta' - type: object dataapi.OperatorsStakeResponse: properties: stake_ranked_operators: @@ -191,52 +86,6 @@ definitions: type: array type: object type: object - dataapi.QueriedOperatorEjections: - properties: - block_number: - type: integer - block_timestamp: - type: string - operator_address: - type: string - operator_id: - type: string - quorum: - type: integer - stake_percentage: - type: number - transaction_hash: - type: string - type: object - dataapi.QueriedOperatorEjectionsResponse: - properties: - ejections: - items: - $ref: '#/definitions/dataapi.QueriedOperatorEjections' - type: array - type: object - dataapi.QueriedStateOperatorMetadata: - properties: - block_number: - type: integer - is_online: - type: boolean - operator_id: - type: string - operator_process_error: - type: string - socket: - type: string - type: object - dataapi.QueriedStateOperatorsResponse: - properties: - data: - items: - $ref: '#/definitions/dataapi.QueriedStateOperatorMetadata' - type: array - meta: - $ref: '#/definitions/dataapi.Meta' - type: object dataapi.SemverReportResponse: properties: semver: @@ -244,22 +93,6 @@ definitions: $ref: '#/definitions/semver.SemverMetrics' type: object type: object - dataapi.ServiceAvailability: - properties: - service_name: - type: string - service_status: - type: string - type: object - dataapi.ServiceAvailabilityResponse: - properties: - data: - items: - $ref: '#/definitions/dataapi.ServiceAvailability' - type: array - meta: - $ref: '#/definitions/dataapi.Meta' - type: object dataapi.Throughput: properties: throughput: @@ -284,16 +117,24 @@ definitions: items: type: integer type: array + "y": + items: + type: integer + type: array type: object encoding.G2Commitment: properties: x: $ref: '#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2' + "y": + $ref: '#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2' type: object encoding.LengthProof: properties: x: $ref: '#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2' + "y": + $ref: '#/definitions/github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2' type: object github_com_Layr-Labs_eigenda_core_v2.BlobHeader: properties: @@ -317,28 +158,16 @@ definitions: type: integer type: array type: object - github_com_Layr-Labs_eigenda_disperser.BlobStatus: - enum: - - 0 - - 1 - - 2 - - 3 - - 4 - - 5 - type: integer - x-enum-varnames: - - Processing - - Confirmed - - Failed - - Finalized - - InsufficientSignatures - - Dispersing github_com_consensys_gnark-crypto_ecc_bn254_internal_fptower.E2: properties: a0: items: type: integer type: array + a1: + items: + type: integer + type: array type: object semver.SemverMetrics: properties: @@ -421,282 +250,6 @@ paths: summary: Fetch blob metadata by blob key tags: - Feed - /feed/batches/{batch_header_hash}/blobs: - get: - parameters: - - description: Batch Header Hash - in: path - name: batch_header_hash - required: true - type: string - - description: 'Limit [default: 10]' - in: query - name: limit - type: integer - - description: Next page token - in: query - name: next_token - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.BlobsResponse' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Fetch blob metadata by batch header hash - tags: - - Feed - /feed/blobs: - get: - parameters: - - description: 'Limit [default: 10]' - in: query - name: limit - type: integer - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.BlobsResponse' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Fetch blobs metadata list - tags: - - Feed - /feed/blobs/{blob_key}: - get: - parameters: - - description: Blob Key - in: path - name: blob_key - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.BlobMetadataResponse' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Fetch blob metadata by blob key - tags: - - Feed - /metrics: - get: - parameters: - - description: 'Start unix timestamp [default: 1 hour ago]' - in: query - name: start - type: integer - - description: 'End unix timestamp [default: unix time now]' - in: query - name: end - type: integer - - description: 'Limit [default: 10]' - in: query - name: limit - type: integer - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.Metric' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Fetch metrics - tags: - - Metrics - /metrics/batcher-service-availability: - get: - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.ServiceAvailabilityResponse' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Get status of EigenDA batcher. - tags: - - Batcher Availability - /metrics/churner-service-availability: - get: - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.ServiceAvailabilityResponse' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Get status of EigenDA churner service. - tags: - - Churner ServiceAvailability - /metrics/disperser-service-availability: - get: - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.ServiceAvailabilityResponse' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Get status of EigenDA Disperser service. - tags: - - ServiceAvailability - /metrics/non-signers: - get: - parameters: - - description: 'Interval to query for non signers in seconds [default: 3600]' - in: query - name: interval - type: integer - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/dataapi.NonSigner' - type: array - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Fetch non signers - tags: - - Metrics - /metrics/operator-nonsigning-percentage: - get: - parameters: - - description: 'Interval to query for operators nonsigning percentage [default: - 3600]' - in: query - name: interval - type: integer - - description: 'End time (2006-01-02T15:04:05Z) to query for operators nonsigning - percentage [default: now]' - in: query - name: end - type: string - - description: 'Whether return only live nonsigners [default: true]' - in: query - name: live_only - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.OperatorsNonsigningPercentage' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Fetch operators non signing percentage - tags: - - Metrics /metrics/summary: get: parameters: @@ -730,41 +283,6 @@ paths: summary: Fetch metrics summary tags: - Metrics - /metrics/throughput: - get: - parameters: - - description: 'Start unix timestamp [default: 1 hour ago]' - in: query - name: start - type: integer - - description: 'End unix timestamp [default: unix time now]' - in: query - name: end - type: integer - produces: - - application/json - responses: - "200": - description: OK - schema: - items: - $ref: '#/definitions/dataapi.Throughput' - type: array - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Fetch throughput time series - tags: - - Metrics /metrics/timeseries/throughput: get: parameters: @@ -800,173 +318,6 @@ paths: summary: Fetch throughput time series tags: - Metrics - /operators-info/deregistered-operators: - get: - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.QueriedStateOperatorsResponse' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Fetch list of operators that have been deregistered for days. Days - is a query parameter with a default value of 14 and max value of 30. - tags: - - OperatorsInfo - /operators-info/operator-ejections: - get: - parameters: - - description: 'Lookback in days [default: 1]' - in: query - name: days - type: integer - - description: 'Operator ID filter [default: all operators]' - in: query - name: operator_id - type: string - - description: 'Return first N ejections [default: 1000]' - in: query - name: first - type: integer - - description: 'Skip first N ejections [default: 0]' - in: query - name: skip - type: integer - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.QueriedOperatorEjectionsResponse' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Fetch list of operator ejections over last N days. - tags: - - OperatorsInfo - /operators-info/operators-stake: - get: - parameters: - - description: Operator ID - in: query - name: operator_id - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.OperatorsStakeResponse' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Operator stake distribution query - tags: - - OperatorsStake - /operators-info/port-check: - get: - parameters: - - description: Operator ID - in: query - name: operator_id - required: true - type: string - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.OperatorPortCheckResponse' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Operator node reachability port check - tags: - - OperatorsInfo - /operators-info/registered-operators: - get: - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.QueriedStateOperatorsResponse' - "400": - description: 'error: Bad request' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "404": - description: 'error: Not found' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Fetch list of operators that have been registered for days. Days is - a query parameter with a default value of 14 and max value of 30. - tags: - - OperatorsInfo - /operators-info/semver-scan: - get: - produces: - - application/json - responses: - "200": - description: OK - schema: - $ref: '#/definitions/dataapi.SemverReportResponse' - "500": - description: 'error: Server error' - schema: - $ref: '#/definitions/dataapi.ErrorResponse' - summary: Active operator semver scan - tags: - - OperatorsInfo /operators/nodeinfo: get: produces: diff --git a/disperser/dataapi/server.go b/disperser/dataapi/server.go index a04e3d3e8..ae0cf0f19 100644 --- a/disperser/dataapi/server.go +++ b/disperser/dataapi/server.go @@ -2,17 +2,11 @@ package dataapi import ( "context" - "encoding/base64" - "encoding/json" "errors" - "fmt" - "math" "math/big" "net/http" "os" "os/signal" - "strconv" - "strings" "syscall" "time" @@ -23,13 +17,12 @@ import ( "github.com/Layr-Labs/eigenda/disperser" "github.com/Layr-Labs/eigenda/disperser/common/semver" - "github.com/Layr-Labs/eigenda/disperser/dataapi/docs" + "github.com/gin-contrib/cors" "github.com/gin-contrib/logger" "github.com/gin-gonic/gin" - "github.com/prometheus/client_golang/prometheus" - swaggerfiles "github.com/swaggo/files" // swagger embed files - ginswagger "github.com/swaggo/gin-swagger" // gin-swagger middleware + // swagger embed files + // gin-swagger middleware ) const ( @@ -272,41 +265,43 @@ func (s *server) Start() error { } router := gin.New() - basePath := "/api/v1" - docs.SwaggerInfo.BasePath = basePath - docs.SwaggerInfo.Host = os.Getenv("SWAGGER_HOST") - v1 := router.Group(basePath) - { - feed := v1.Group("/feed") - { - feed.GET("/blobs", s.FetchBlobsHandler) - feed.GET("/blobs/:blob_key", s.FetchBlobHandler) - feed.GET("/batches/:batch_header_hash/blobs", s.FetchBlobsFromBatchHeaderHash) - } - operatorsInfo := v1.Group("/operators-info") - { - operatorsInfo.GET("/deregistered-operators", s.FetchDeregisteredOperators) - operatorsInfo.GET("/operator-ejections", s.FetchOperatorEjections) - operatorsInfo.GET("/registered-operators", s.FetchRegisteredOperators) - operatorsInfo.GET("/port-check", s.OperatorPortCheck) - operatorsInfo.GET("/semver-scan", s.SemverScan) - operatorsInfo.GET("/operators-stake", s.OperatorsStake) - } - metrics := v1.Group("/metrics") - { - metrics.GET("/", s.FetchMetricsHandler) - metrics.GET("/throughput", s.FetchMetricsThroughputHandler) - metrics.GET("/non-signers", s.FetchNonSigners) - metrics.GET("/operator-nonsigning-percentage", s.FetchOperatorsNonsigningPercentageHandler) - metrics.GET("/disperser-service-availability", s.FetchDisperserServiceAvailability) - metrics.GET("/churner-service-availability", s.FetchChurnerServiceAvailability) - metrics.GET("/batcher-service-availability", s.FetchBatcherAvailability) - } - swagger := v1.Group("/swagger") + /* + basePath := "/api/v1" + docs.SwaggerInfo.BasePath = basePath + docs.SwaggerInfo.Host = os.Getenv("SWAGGER_HOST") + v1 := router.Group(basePath) { - swagger.GET("/*any", ginswagger.WrapHandler(swaggerfiles.Handler)) + feed := v1.Group("/feed") + { + feed.GET("/blobs", s.FetchBlobsHandler) + feed.GET("/blobs/:blob_key", s.FetchBlobHandler) + feed.GET("/batches/:batch_header_hash/blobs", s.FetchBlobsFromBatchHeaderHash) + } + operatorsInfo := v1.Group("/operators-info") + { + operatorsInfo.GET("/deregistered-operators", s.FetchDeregisteredOperators) + operatorsInfo.GET("/operator-ejections", s.FetchOperatorEjections) + operatorsInfo.GET("/registered-operators", s.FetchRegisteredOperators) + operatorsInfo.GET("/port-check", s.OperatorPortCheck) + operatorsInfo.GET("/semver-scan", s.SemverScan) + operatorsInfo.GET("/operators-stake", s.OperatorsStake) + } + metrics := v1.Group("/metrics") + { + metrics.GET("/", s.FetchMetricsHandler) + metrics.GET("/throughput", s.FetchMetricsThroughputHandler) + metrics.GET("/non-signers", s.FetchNonSigners) + metrics.GET("/operator-nonsigning-percentage", s.FetchOperatorsNonsigningPercentageHandler) + metrics.GET("/disperser-service-availability", s.FetchDisperserServiceAvailability) + metrics.GET("/churner-service-availability", s.FetchChurnerServiceAvailability) + metrics.GET("/batcher-service-availability", s.FetchBatcherAvailability) + } + swagger := v1.Group("/swagger") + { + swagger.GET("/*any", ginswagger.WrapHandler(swaggerfiles.Handler)) + } } - } + */ router.GET("/", func(g *gin.Context) { g.JSON(http.StatusAccepted, gin.H{"status": "OK"}) @@ -353,6 +348,7 @@ func (s *server) Shutdown() error { return nil } +/* // FetchBlobHandler godoc // // @Summary Fetch blob metadata by blob key @@ -364,25 +360,26 @@ func (s *server) Shutdown() error { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /feed/blobs/{blob_key} [get] -func (s *server) FetchBlobHandler(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchBlob", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - blobKey := c.Param("blob_key") - - metadata, err := s.getBlob(c.Request.Context(), blobKey) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchBlob") - errorResponse(c, err) - return - } - s.metrics.IncrementSuccessfulRequestNum("FetchBlob") - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxFeedBlobAge)) - c.JSON(http.StatusOK, metadata) -} + func (s *server) FetchBlobHandler(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchBlob", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() + + blobKey := c.Param("blob_key") + + metadata, err := s.getBlob(c.Request.Context(), blobKey) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchBlob") + errorResponse(c, err) + return + } + + s.metrics.IncrementSuccessfulRequestNum("FetchBlob") + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxFeedBlobAge)) + c.JSON(http.StatusOK, metadata) + } // FetchBlobsFromBatchHeaderHash godoc // @@ -397,100 +394,101 @@ func (s *server) FetchBlobHandler(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /feed/batches/{batch_header_hash}/blobs [get] -func (s *server) FetchBlobsFromBatchHeaderHash(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchBlobsFromBatchHeaderHash", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - batchHeaderHash := c.Param("batch_header_hash") - batchHeaderHashBytes, err := ConvertHexadecimalToBytes([]byte(batchHeaderHash)) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") - errorResponse(c, fmt.Errorf("invalid batch header hash")) - return - } - limit, err := strconv.Atoi(c.DefaultQuery("limit", "10")) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") - errorResponse(c, fmt.Errorf("invalid limit parameter")) - return - } - if limit <= 0 || limit > 1000 { - s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") - errorResponse(c, fmt.Errorf("limit must be between 0 and 1000")) - return - } + func (s *server) FetchBlobsFromBatchHeaderHash(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchBlobsFromBatchHeaderHash", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() - var exclusiveStartKey *disperser.BatchIndexExclusiveStartKey - nextToken := c.Query("next_token") - if nextToken != "" { - exclusiveStartKey, err = decodeNextToken(nextToken) + batchHeaderHash := c.Param("batch_header_hash") + batchHeaderHashBytes, err := ConvertHexadecimalToBytes([]byte(batchHeaderHash)) if err != nil { s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") - errorResponse(c, fmt.Errorf("invalid next_token")) + errorResponse(c, fmt.Errorf("invalid batch header hash")) return } - } - metadatas, newExclusiveStartKey, err := s.getBlobsFromBatchHeaderHash(c.Request.Context(), batchHeaderHashBytes, limit, exclusiveStartKey) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") - errorResponse(c, err) - return - } + limit, err := strconv.Atoi(c.DefaultQuery("limit", "10")) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") + errorResponse(c, fmt.Errorf("invalid limit parameter")) + return + } + if limit <= 0 || limit > 1000 { + s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") + errorResponse(c, fmt.Errorf("limit must be between 0 and 1000")) + return + } - var nextPageToken string - if newExclusiveStartKey != nil { - nextPageToken, err = encodeNextToken(newExclusiveStartKey) + var exclusiveStartKey *disperser.BatchIndexExclusiveStartKey + nextToken := c.Query("next_token") + if nextToken != "" { + exclusiveStartKey, err = decodeNextToken(nextToken) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") + errorResponse(c, fmt.Errorf("invalid next_token")) + return + } + } + + metadatas, newExclusiveStartKey, err := s.getBlobsFromBatchHeaderHash(c.Request.Context(), batchHeaderHashBytes, limit, exclusiveStartKey) if err != nil { s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") - errorResponse(c, fmt.Errorf("failed to generate next page token")) + errorResponse(c, err) return } - } - s.metrics.IncrementSuccessfulRequestNum("FetchBlobsFromBatchHeaderHash") - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxFeedBlobAge)) - c.JSON(http.StatusOK, BlobsResponse{ - Meta: Meta{ - Size: len(metadatas), - NextToken: nextPageToken, - }, - Data: metadatas, - }) -} + var nextPageToken string + if newExclusiveStartKey != nil { + nextPageToken, err = encodeNextToken(newExclusiveStartKey) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") + errorResponse(c, fmt.Errorf("failed to generate next page token")) + return + } + } -func decodeNextToken(token string) (*disperser.BatchIndexExclusiveStartKey, error) { - // Decode the base64 string - decodedBytes, err := base64.URLEncoding.DecodeString(token) - if err != nil { - return nil, fmt.Errorf("failed to decode token: %w", err) + s.metrics.IncrementSuccessfulRequestNum("FetchBlobsFromBatchHeaderHash") + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxFeedBlobAge)) + c.JSON(http.StatusOK, BlobsResponse{ + Meta: Meta{ + Size: len(metadatas), + NextToken: nextPageToken, + }, + Data: metadatas, + }) } - // Unmarshal the JSON into a BatchIndexExclusiveStartKey - var key disperser.BatchIndexExclusiveStartKey - err = json.Unmarshal(decodedBytes, &key) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal token: %w", err) - } + func decodeNextToken(token string) (*disperser.BatchIndexExclusiveStartKey, error) { + // Decode the base64 string + decodedBytes, err := base64.URLEncoding.DecodeString(token) + if err != nil { + return nil, fmt.Errorf("failed to decode token: %w", err) + } - return &key, nil -} + // Unmarshal the JSON into a BatchIndexExclusiveStartKey + var key disperser.BatchIndexExclusiveStartKey + err = json.Unmarshal(decodedBytes, &key) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal token: %w", err) + } -func encodeNextToken(key *disperser.BatchIndexExclusiveStartKey) (string, error) { - // Marshal the key to JSON - jsonBytes, err := json.Marshal(key) - if err != nil { - return "", fmt.Errorf("failed to marshal key: %w", err) + return &key, nil } - // Encode the JSON as a base64 string - token := base64.URLEncoding.EncodeToString(jsonBytes) + func encodeNextToken(key *disperser.BatchIndexExclusiveStartKey) (string, error) { + // Marshal the key to JSON + jsonBytes, err := json.Marshal(key) + if err != nil { + return "", fmt.Errorf("failed to marshal key: %w", err) + } - return token, nil -} + // Encode the JSON as a base64 string + token := base64.URLEncoding.EncodeToString(jsonBytes) + + return token, nil + } // FetchBlobsHandler godoc // @@ -503,40 +501,41 @@ func encodeNextToken(key *disperser.BatchIndexExclusiveStartKey) (string, error) // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /feed/blobs [get] -func (s *server) FetchBlobsHandler(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchBlobs", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - limit, err := strconv.Atoi(c.DefaultQuery("limit", "10")) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") - errorResponse(c, fmt.Errorf("invalid limit parameter")) - return - } - if limit <= 0 { - s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") - errorResponse(c, fmt.Errorf("limit must be greater than 0")) - return - } - metadatas, err := s.getBlobs(c.Request.Context(), limit) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchBlobs") - errorResponse(c, err) - return - } + func (s *server) FetchBlobsHandler(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchBlobs", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() - s.metrics.IncrementSuccessfulRequestNum("FetchBlobs") - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxFeedBlobsAge)) - c.JSON(http.StatusOK, BlobsResponse{ - Meta: Meta{ - Size: len(metadatas), - }, - Data: metadatas, - }) -} + limit, err := strconv.Atoi(c.DefaultQuery("limit", "10")) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") + errorResponse(c, fmt.Errorf("invalid limit parameter")) + return + } + if limit <= 0 { + s.metrics.IncrementFailedRequestNum("FetchBlobsFromBatchHeaderHash") + errorResponse(c, fmt.Errorf("limit must be greater than 0")) + return + } + + metadatas, err := s.getBlobs(c.Request.Context(), limit) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchBlobs") + errorResponse(c, err) + return + } + + s.metrics.IncrementSuccessfulRequestNum("FetchBlobs") + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxFeedBlobsAge)) + c.JSON(http.StatusOK, BlobsResponse{ + Meta: Meta{ + Size: len(metadatas), + }, + Data: metadatas, + }) + } // FetchMetricsHandler godoc // @@ -551,34 +550,35 @@ func (s *server) FetchBlobsHandler(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /metrics [get] -func (s *server) FetchMetricsHandler(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchMetrics", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - now := time.Now() - start, err := strconv.ParseInt(c.DefaultQuery("start", "0"), 10, 64) - if err != nil || start == 0 { - start = now.Add(-time.Hour * 1).Unix() - } - end, err := strconv.ParseInt(c.DefaultQuery("end", "0"), 10, 64) - if err != nil || end == 0 { - end = now.Unix() - } + func (s *server) FetchMetricsHandler(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchMetrics", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() - metric, err := s.getMetric(c.Request.Context(), start, end) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchMetrics") - errorResponse(c, err) - return - } + now := time.Now() + start, err := strconv.ParseInt(c.DefaultQuery("start", "0"), 10, 64) + if err != nil || start == 0 { + start = now.Add(-time.Hour * 1).Unix() + } - s.metrics.IncrementSuccessfulRequestNum("FetchMetrics") - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxMetricAage)) - c.JSON(http.StatusOK, metric) -} + end, err := strconv.ParseInt(c.DefaultQuery("end", "0"), 10, 64) + if err != nil || end == 0 { + end = now.Unix() + } + + metric, err := s.getMetric(c.Request.Context(), start, end) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchMetrics") + errorResponse(c, err) + return + } + + s.metrics.IncrementSuccessfulRequestNum("FetchMetrics") + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxMetricAage)) + c.JSON(http.StatusOK, metric) + } // FetchMetricsThroughputHandler godoc // @@ -592,34 +592,35 @@ func (s *server) FetchMetricsHandler(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /metrics/throughput [get] -func (s *server) FetchMetricsThroughputHandler(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchMetricsTroughput", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - now := time.Now() - start, err := strconv.ParseInt(c.DefaultQuery("start", "0"), 10, 64) - if err != nil || start == 0 { - start = now.Add(-time.Hour * 1).Unix() - } - end, err := strconv.ParseInt(c.DefaultQuery("end", "0"), 10, 64) - if err != nil || end == 0 { - end = now.Unix() - } + func (s *server) FetchMetricsThroughputHandler(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchMetricsTroughput", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() - ths, err := s.metricsHandler.getThroughputTimeseries(c.Request.Context(), start, end) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchMetricsTroughput") - errorResponse(c, err) - return - } + now := time.Now() + start, err := strconv.ParseInt(c.DefaultQuery("start", "0"), 10, 64) + if err != nil || start == 0 { + start = now.Add(-time.Hour * 1).Unix() + } - s.metrics.IncrementSuccessfulRequestNum("FetchMetricsTroughput") - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxThroughputAge)) - c.JSON(http.StatusOK, ths) -} + end, err := strconv.ParseInt(c.DefaultQuery("end", "0"), 10, 64) + if err != nil || end == 0 { + end = now.Unix() + } + + ths, err := s.metricsHandler.getThroughputTimeseries(c.Request.Context(), start, end) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchMetricsTroughput") + errorResponse(c, err) + return + } + + s.metrics.IncrementSuccessfulRequestNum("FetchMetricsTroughput") + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxThroughputAge)) + c.JSON(http.StatusOK, ths) + } // FetchNonSigners godoc // @@ -632,27 +633,28 @@ func (s *server) FetchMetricsThroughputHandler(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /metrics/non-signers [get] -func (s *server) FetchNonSigners(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchNonSigners", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - interval, err := strconv.ParseInt(c.DefaultQuery("interval", "3600"), 10, 64) - if err != nil || interval == 0 { - interval = 3600 - } - metric, err := s.getNonSigners(c.Request.Context(), interval) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchNonSigners") - errorResponse(c, err) - return - } - s.metrics.IncrementSuccessfulRequestNum("FetchNonSigners") - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxNonSignerAge)) - c.JSON(http.StatusOK, metric) -} + func (s *server) FetchNonSigners(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchNonSigners", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() + + interval, err := strconv.ParseInt(c.DefaultQuery("interval", "3600"), 10, 64) + if err != nil || interval == 0 { + interval = 3600 + } + metric, err := s.getNonSigners(c.Request.Context(), interval) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchNonSigners") + errorResponse(c, err) + return + } + + s.metrics.IncrementSuccessfulRequestNum("FetchNonSigners") + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxNonSignerAge)) + c.JSON(http.StatusOK, metric) + } // FetchOperatorsNonsigningPercentageHandler godoc // @@ -667,51 +669,52 @@ func (s *server) FetchNonSigners(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /metrics/operator-nonsigning-percentage [get] -func (s *server) FetchOperatorsNonsigningPercentageHandler(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchOperatorsNonsigningPercentageHandler", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - endTime := time.Now() - if c.Query("end") != "" { + func (s *server) FetchOperatorsNonsigningPercentageHandler(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchOperatorsNonsigningPercentageHandler", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() + + endTime := time.Now() + if c.Query("end") != "" { + + var err error + endTime, err = time.Parse("2006-01-02T15:04:05Z", c.Query("end")) + if err != nil { + errorResponse(c, err) + return + } + } - var err error - endTime, err = time.Parse("2006-01-02T15:04:05Z", c.Query("end")) - if err != nil { - errorResponse(c, err) - return + interval, err := strconv.ParseInt(c.DefaultQuery("interval", "3600"), 10, 64) + if err != nil || interval == 0 { + interval = 3600 } - } - interval, err := strconv.ParseInt(c.DefaultQuery("interval", "3600"), 10, 64) - if err != nil || interval == 0 { - interval = 3600 - } + liveOnly := "true" + if c.Query("live_only") != "" { + liveOnly = c.Query("live_only") + if liveOnly != "true" && liveOnly != "false" { + errorResponse(c, errors.New("the live_only param must be \"true\" or \"false\"")) + return + } + } + + startTime := endTime.Add(-time.Duration(interval) * time.Second) - liveOnly := "true" - if c.Query("live_only") != "" { - liveOnly = c.Query("live_only") - if liveOnly != "true" && liveOnly != "false" { - errorResponse(c, errors.New("the live_only param must be \"true\" or \"false\"")) + metric, err := s.getOperatorNonsigningRate(c.Request.Context(), startTime.Unix(), endTime.Unix(), liveOnly == "true") + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchOperatorsNonsigningPercentageHandler") + errorResponse(c, err) return } - } - - startTime := endTime.Add(-time.Duration(interval) * time.Second) - metric, err := s.getOperatorNonsigningRate(c.Request.Context(), startTime.Unix(), endTime.Unix(), liveOnly == "true") - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchOperatorsNonsigningPercentageHandler") - errorResponse(c, err) - return + s.metrics.IncrementSuccessfulRequestNum("FetchOperatorsNonsigningPercentageHandler") + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxOperatorsNonsigningPercentageAge)) + c.JSON(http.StatusOK, metric) } - s.metrics.IncrementSuccessfulRequestNum("FetchOperatorsNonsigningPercentageHandler") - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxOperatorsNonsigningPercentageAge)) - c.JSON(http.StatusOK, metric) -} - // OperatorsStake godoc // // @Summary Operator stake distribution query @@ -723,26 +726,27 @@ func (s *server) FetchOperatorsNonsigningPercentageHandler(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /operators-info/operators-stake [get] -func (s *server) OperatorsStake(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("OperatorsStake", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - operatorId := c.DefaultQuery("operator_id", "") - s.logger.Info("getting operators stake distribution", "operatorId", operatorId) - - operatorsStakeResponse, err := s.operatorHandler.getOperatorsStake(c.Request.Context(), operatorId) - if err != nil { - s.metrics.IncrementFailedRequestNum("OperatorsStake") - errorResponse(c, fmt.Errorf("failed to get operator stake: %w", err)) - return - } - s.metrics.IncrementSuccessfulRequestNum("OperatorsStake") - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxOperatorsStakeAge)) - c.JSON(http.StatusOK, operatorsStakeResponse) -} + func (s *server) OperatorsStake(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("OperatorsStake", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() + + operatorId := c.DefaultQuery("operator_id", "") + s.logger.Info("getting operators stake distribution", "operatorId", operatorId) + + operatorsStakeResponse, err := s.operatorHandler.getOperatorsStake(c.Request.Context(), operatorId) + if err != nil { + s.metrics.IncrementFailedRequestNum("OperatorsStake") + errorResponse(c, fmt.Errorf("failed to get operator stake: %w", err)) + return + } + + s.metrics.IncrementSuccessfulRequestNum("OperatorsStake") + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxOperatorsStakeAge)) + c.JSON(http.StatusOK, operatorsStakeResponse) + } // FetchDeregisteredOperators godoc // @@ -754,45 +758,46 @@ func (s *server) OperatorsStake(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /operators-info/deregistered-operators [get] -func (s *server) FetchDeregisteredOperators(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchDeregisteredOperators", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - // Get query parameters - // Default Value 14 days - days := c.DefaultQuery("days", "14") // If not specified, defaults to 14 - - // Convert days to integer - daysInt, err := strconv.Atoi(days) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'days' parameter"}) - return - } - if daysInt > 30 { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'days' parameter. Max value is 30"}) - return - } + func (s *server) FetchDeregisteredOperators(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchDeregisteredOperators", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() - operatorMetadatas, err := s.getDeregisteredOperatorForDays(c.Request.Context(), int32(daysInt)) - if err != nil { - s.logger.Error("Failed to fetch deregistered operators", "error", err) - s.metrics.IncrementFailedRequestNum("FetchDeregisteredOperators") - errorResponse(c, err) - return - } + // Get query parameters + // Default Value 14 days + days := c.DefaultQuery("days", "14") // If not specified, defaults to 14 - s.metrics.IncrementSuccessfulRequestNum("FetchDeregisteredOperators") - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxDeregisteredOperatorAge)) - c.JSON(http.StatusOK, QueriedStateOperatorsResponse{ - Meta: Meta{ - Size: len(operatorMetadatas), - }, - Data: operatorMetadatas, - }) -} + // Convert days to integer + daysInt, err := strconv.Atoi(days) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'days' parameter"}) + return + } + + if daysInt > 30 { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'days' parameter. Max value is 30"}) + return + } + + operatorMetadatas, err := s.getDeregisteredOperatorForDays(c.Request.Context(), int32(daysInt)) + if err != nil { + s.logger.Error("Failed to fetch deregistered operators", "error", err) + s.metrics.IncrementFailedRequestNum("FetchDeregisteredOperators") + errorResponse(c, err) + return + } + + s.metrics.IncrementSuccessfulRequestNum("FetchDeregisteredOperators") + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxDeregisteredOperatorAge)) + c.JSON(http.StatusOK, QueriedStateOperatorsResponse{ + Meta: Meta{ + Size: len(operatorMetadatas), + }, + Data: operatorMetadatas, + }) + } // FetchRegisteredOperators godoc // @@ -804,44 +809,45 @@ func (s *server) FetchDeregisteredOperators(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /operators-info/registered-operators [get] -func (s *server) FetchRegisteredOperators(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchRegisteredOperators", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - // Get query parameters - // Default Value 14 days - days := c.DefaultQuery("days", "14") // If not specified, defaults to 14 - - // Convert days to integer - daysInt, err := strconv.Atoi(days) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'days' parameter"}) - return - } - if daysInt > 30 { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'days' parameter. Max value is 30"}) - return - } + func (s *server) FetchRegisteredOperators(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchRegisteredOperators", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() - operatorMetadatas, err := s.getRegisteredOperatorForDays(c.Request.Context(), int32(daysInt)) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchRegisteredOperators") - errorResponse(c, err) - return - } + // Get query parameters + // Default Value 14 days + days := c.DefaultQuery("days", "14") // If not specified, defaults to 14 - s.metrics.IncrementSuccessfulRequestNum("FetchRegisteredOperators") - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxDeregisteredOperatorAge)) - c.JSON(http.StatusOK, QueriedStateOperatorsResponse{ - Meta: Meta{ - Size: len(operatorMetadatas), - }, - Data: operatorMetadatas, - }) -} + // Convert days to integer + daysInt, err := strconv.Atoi(days) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'days' parameter"}) + return + } + + if daysInt > 30 { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'days' parameter. Max value is 30"}) + return + } + + operatorMetadatas, err := s.getRegisteredOperatorForDays(c.Request.Context(), int32(daysInt)) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchRegisteredOperators") + errorResponse(c, err) + return + } + + s.metrics.IncrementSuccessfulRequestNum("FetchRegisteredOperators") + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxDeregisteredOperatorAge)) + c.JSON(http.StatusOK, QueriedStateOperatorsResponse{ + Meta: Meta{ + Size: len(operatorMetadatas), + }, + Data: operatorMetadatas, + }) + } // FetchOperatorEjections godoc // @@ -857,52 +863,53 @@ func (s *server) FetchRegisteredOperators(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /operators-info/operator-ejections [get] -func (s *server) FetchOperatorEjections(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchOperatorEjections", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - operatorId := c.DefaultQuery("operator_id", "") // If not specified, defaults to all operators - - days := c.DefaultQuery("days", "1") // If not specified, defaults to 1 - parsedDays, err := strconv.ParseInt(days, 10, 32) - if err != nil || parsedDays < math.MinInt32 || parsedDays > math.MaxInt32 { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'days' parameter"}) - return - } - daysInt := int32(parsedDays) - first := c.DefaultQuery("first", "1000") // If not specified, defaults to 1000 - parsedFirst, err := strconv.ParseInt(first, 10, 32) - if err != nil || parsedFirst < 1 || parsedFirst > 10000 { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'first' parameter. Value must be between 1..10000"}) - return - } - firstInt := int32(parsedFirst) + func (s *server) FetchOperatorEjections(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchOperatorEjections", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() - skip := c.DefaultQuery("skip", "0") // If not specified, defaults to 0 - parsedSkip, err := strconv.ParseInt(skip, 10, 32) - if err != nil || parsedSkip < 0 || parsedSkip > 1000000000 { - c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'skip' parameter. Value must be between 0..1000000000"}) - return - } - skipInt := int32(parsedSkip) - - operatorEjections, err := s.getOperatorEjections(c.Request.Context(), int32(daysInt), operatorId, uint(firstInt), uint(skipInt)) - if err != nil { - s.logger.Error("Failed to fetch ejected operators", "error", err) - s.metrics.IncrementFailedRequestNum("FetchOperatorEjections") - errorResponse(c, err) - return - } + operatorId := c.DefaultQuery("operator_id", "") // If not specified, defaults to all operators - s.metrics.IncrementSuccessfulRequestNum("FetchOperatorEjections") - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxEjectedOperatorAge)) - c.JSON(http.StatusOK, QueriedOperatorEjectionsResponse{ - Ejections: operatorEjections, - }) -} + days := c.DefaultQuery("days", "1") // If not specified, defaults to 1 + parsedDays, err := strconv.ParseInt(days, 10, 32) + if err != nil || parsedDays < math.MinInt32 || parsedDays > math.MaxInt32 { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'days' parameter"}) + return + } + daysInt := int32(parsedDays) + + first := c.DefaultQuery("first", "1000") // If not specified, defaults to 1000 + parsedFirst, err := strconv.ParseInt(first, 10, 32) + if err != nil || parsedFirst < 1 || parsedFirst > 10000 { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'first' parameter. Value must be between 1..10000"}) + return + } + firstInt := int32(parsedFirst) + + skip := c.DefaultQuery("skip", "0") // If not specified, defaults to 0 + parsedSkip, err := strconv.ParseInt(skip, 10, 32) + if err != nil || parsedSkip < 0 || parsedSkip > 1000000000 { + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid 'skip' parameter. Value must be between 0..1000000000"}) + return + } + skipInt := int32(parsedSkip) + + operatorEjections, err := s.getOperatorEjections(c.Request.Context(), int32(daysInt), operatorId, uint(firstInt), uint(skipInt)) + if err != nil { + s.logger.Error("Failed to fetch ejected operators", "error", err) + s.metrics.IncrementFailedRequestNum("FetchOperatorEjections") + errorResponse(c, err) + return + } + + s.metrics.IncrementSuccessfulRequestNum("FetchOperatorEjections") + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxEjectedOperatorAge)) + c.JSON(http.StatusOK, QueriedOperatorEjectionsResponse{ + Ejections: operatorEjections, + }) + } // OperatorPortCheck godoc // @@ -915,31 +922,32 @@ func (s *server) FetchOperatorEjections(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /operators-info/port-check [get] -func (s *server) OperatorPortCheck(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("OperatorPortCheck", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - operatorId := c.DefaultQuery("operator_id", "") - s.logger.Info("checking operator ports", "operatorId", operatorId) - portCheckResponse, err := s.operatorHandler.probeOperatorHosts(c.Request.Context(), operatorId) - if err != nil { - if strings.Contains(err.Error(), "not found") { - err = errNotFound - s.logger.Warn("operator not found", "operatorId", operatorId) - s.metrics.IncrementNotFoundRequestNum("OperatorPortCheck") - } else { - s.logger.Error("operator port check failed", "error", err) - s.metrics.IncrementFailedRequestNum("OperatorPortCheck") + + func (s *server) OperatorPortCheck(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("OperatorPortCheck", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() + + operatorId := c.DefaultQuery("operator_id", "") + s.logger.Info("checking operator ports", "operatorId", operatorId) + portCheckResponse, err := s.operatorHandler.probeOperatorHosts(c.Request.Context(), operatorId) + if err != nil { + if strings.Contains(err.Error(), "not found") { + err = errNotFound + s.logger.Warn("operator not found", "operatorId", operatorId) + s.metrics.IncrementNotFoundRequestNum("OperatorPortCheck") + } else { + s.logger.Error("operator port check failed", "error", err) + s.metrics.IncrementFailedRequestNum("OperatorPortCheck") + } + errorResponse(c, err) + return } - errorResponse(c, err) - return - } - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxOperatorPortCheckAge)) - c.JSON(http.StatusOK, portCheckResponse) -} + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxOperatorPortCheckAge)) + c.JSON(http.StatusOK, portCheckResponse) + } // Semver scan godoc // @@ -949,21 +957,22 @@ func (s *server) OperatorPortCheck(c *gin.Context) { // @Success 200 {object} SemverReportResponse // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /operators-info/semver-scan [get] -func (s *server) SemverScan(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("SemverScan", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - report, err := s.operatorHandler.scanOperatorsHostInfo(c.Request.Context()) - if err != nil { - s.logger.Error("failed to scan operators host info", "error", err) - s.metrics.IncrementFailedRequestNum("SemverScan") - errorResponse(c, err) + + func (s *server) SemverScan(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("SemverScan", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() + + report, err := s.operatorHandler.scanOperatorsHostInfo(c.Request.Context()) + if err != nil { + s.logger.Error("failed to scan operators host info", "error", err) + s.metrics.IncrementFailedRequestNum("SemverScan") + errorResponse(c, err) + } + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxOperatorPortCheckAge)) + c.JSON(http.StatusOK, report) } - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxOperatorPortCheckAge)) - c.JSON(http.StatusOK, report) -} // FetchDisperserServiceAvailability godoc // @@ -975,50 +984,51 @@ func (s *server) SemverScan(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /metrics/disperser-service-availability [get] -func (s *server) FetchDisperserServiceAvailability(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchDisperserServiceAvailability", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - // Check Disperser - services := []string{"Disperser"} - - s.logger.Info("Getting service availability for", "services", strings.Join(services, ", ")) - - availabilityStatuses, err := s.getServiceAvailability(c.Request.Context(), services) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchDisperserServiceAvailability") - errorResponse(c, err) - return - } - s.metrics.IncrementSuccessfulRequestNum("FetchDisperserServiceAvailability") + func (s *server) FetchDisperserServiceAvailability(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchDisperserServiceAvailability", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() + + // Check Disperser + services := []string{"Disperser"} - // Set the status code to 503 if any of the services are not serving - availabilityStatus := http.StatusOK - for _, status := range availabilityStatuses { - if status.ServiceStatus == "NOT_SERVING" { - availabilityStatus = http.StatusServiceUnavailable - break + s.logger.Info("Getting service availability for", "services", strings.Join(services, ", ")) + + availabilityStatuses, err := s.getServiceAvailability(c.Request.Context(), services) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchDisperserServiceAvailability") + errorResponse(c, err) + return } - if status.ServiceStatus == "UNKNOWN" { - availabilityStatus = http.StatusInternalServerError - break + s.metrics.IncrementSuccessfulRequestNum("FetchDisperserServiceAvailability") + + // Set the status code to 503 if any of the services are not serving + availabilityStatus := http.StatusOK + for _, status := range availabilityStatuses { + if status.ServiceStatus == "NOT_SERVING" { + availabilityStatus = http.StatusServiceUnavailable + break + } + + if status.ServiceStatus == "UNKNOWN" { + availabilityStatus = http.StatusInternalServerError + break + } + } + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxDisperserAvailabilityAge)) + c.JSON(availabilityStatus, ServiceAvailabilityResponse{ + Meta: Meta{ + Size: len(availabilityStatuses), + }, + Data: availabilityStatuses, + }) } - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxDisperserAvailabilityAge)) - c.JSON(availabilityStatus, ServiceAvailabilityResponse{ - Meta: Meta{ - Size: len(availabilityStatuses), - }, - Data: availabilityStatuses, - }) -} - // FetchChurnerServiceAvailability godoc // // @Summary Get status of EigenDA churner service. @@ -1029,50 +1039,51 @@ func (s *server) FetchDisperserServiceAvailability(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /metrics/churner-service-availability [get] -func (s *server) FetchChurnerServiceAvailability(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchChurnerServiceAvailability", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - // Check Disperser - services := []string{"Churner"} - - s.logger.Info("Getting service availability for", "services", strings.Join(services, ", ")) - - availabilityStatuses, err := s.getServiceAvailability(c.Request.Context(), services) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchChurnerServiceAvailability") - errorResponse(c, err) - return - } - s.metrics.IncrementSuccessfulRequestNum("FetchChurnerServiceAvailability") + func (s *server) FetchChurnerServiceAvailability(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchChurnerServiceAvailability", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() + + // Check Disperser + services := []string{"Churner"} + + s.logger.Info("Getting service availability for", "services", strings.Join(services, ", ")) - // Set the status code to 503 if any of the services are not serving - availabilityStatus := http.StatusOK - for _, status := range availabilityStatuses { - if status.ServiceStatus == "NOT_SERVING" { - availabilityStatus = http.StatusServiceUnavailable - break + availabilityStatuses, err := s.getServiceAvailability(c.Request.Context(), services) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchChurnerServiceAvailability") + errorResponse(c, err) + return } - if status.ServiceStatus == "UNKNOWN" { - availabilityStatus = http.StatusInternalServerError - break + s.metrics.IncrementSuccessfulRequestNum("FetchChurnerServiceAvailability") + + // Set the status code to 503 if any of the services are not serving + availabilityStatus := http.StatusOK + for _, status := range availabilityStatuses { + if status.ServiceStatus == "NOT_SERVING" { + availabilityStatus = http.StatusServiceUnavailable + break + } + + if status.ServiceStatus == "UNKNOWN" { + availabilityStatus = http.StatusInternalServerError + break + } + } + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxChurnerAvailabilityAge)) + c.JSON(availabilityStatus, ServiceAvailabilityResponse{ + Meta: Meta{ + Size: len(availabilityStatuses), + }, + Data: availabilityStatuses, + }) } - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxChurnerAvailabilityAge)) - c.JSON(availabilityStatus, ServiceAvailabilityResponse{ - Meta: Meta{ - Size: len(availabilityStatuses), - }, - Data: availabilityStatuses, - }) -} - // FetchBatcherAvailability godoc // // @Summary Get status of EigenDA batcher. @@ -1083,49 +1094,51 @@ func (s *server) FetchChurnerServiceAvailability(c *gin.Context) { // @Failure 404 {object} ErrorResponse "error: Not found" // @Failure 500 {object} ErrorResponse "error: Server error" // @Router /metrics/batcher-service-availability [get] -func (s *server) FetchBatcherAvailability(c *gin.Context) { - timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { - s.metrics.ObserveLatency("FetchBatcherAvailability", f*1000) // make milliseconds - })) - defer timer.ObserveDuration() - - // Check Batcher - services := []HttpServiceAvailabilityCheck{{"Batcher", s.batcherHealthEndpt}} - - s.logger.Info("Getting service availability for", "service", services[0].ServiceName, "endpoint", services[0].HealthEndPt) - - availabilityStatuses, err := s.getServiceHealth(c.Request.Context(), services) - if err != nil { - s.metrics.IncrementFailedRequestNum("FetchBatcherAvailability") - errorResponse(c, err) - return - } - s.metrics.IncrementSuccessfulRequestNum("FetchBatcherAvailability") + func (s *server) FetchBatcherAvailability(c *gin.Context) { + timer := prometheus.NewTimer(prometheus.ObserverFunc(func(f float64) { + s.metrics.ObserveLatency("FetchBatcherAvailability", f*1000) // make milliseconds + })) + defer timer.ObserveDuration() + + // Check Batcher + services := []HttpServiceAvailabilityCheck{{"Batcher", s.batcherHealthEndpt}} - // Set the status code to 503 if any of the services are not serving - availabilityStatus := http.StatusOK - for _, status := range availabilityStatuses { - if status.ServiceStatus == "NOT_SERVING" { - availabilityStatus = http.StatusServiceUnavailable - break + s.logger.Info("Getting service availability for", "service", services[0].ServiceName, "endpoint", services[0].HealthEndPt) + + availabilityStatuses, err := s.getServiceHealth(c.Request.Context(), services) + if err != nil { + s.metrics.IncrementFailedRequestNum("FetchBatcherAvailability") + errorResponse(c, err) + return } - if status.ServiceStatus == "UNKNOWN" { - availabilityStatus = http.StatusInternalServerError - break + s.metrics.IncrementSuccessfulRequestNum("FetchBatcherAvailability") + + // Set the status code to 503 if any of the services are not serving + availabilityStatus := http.StatusOK + for _, status := range availabilityStatuses { + if status.ServiceStatus == "NOT_SERVING" { + availabilityStatus = http.StatusServiceUnavailable + break + } + + if status.ServiceStatus == "UNKNOWN" { + availabilityStatus = http.StatusInternalServerError + break + } + } + c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxBatcherAvailabilityAge)) + c.JSON(availabilityStatus, ServiceAvailabilityResponse{ + Meta: Meta{ + Size: len(availabilityStatuses), + }, + Data: availabilityStatuses, + }) } - - c.Writer.Header().Set(cacheControlParam, fmt.Sprintf("max-age=%d", maxBatcherAvailabilityAge)) - c.JSON(availabilityStatus, ServiceAvailabilityResponse{ - Meta: Meta{ - Size: len(availabilityStatuses), - }, - Data: availabilityStatuses, - }) -} +*/ func errorResponse(c *gin.Context, err error) { _ = c.Error(err)