diff --git a/atoma-daemon/docs/openapi.yml b/atoma-daemon/docs/openapi.yml index fef6df95..e42f05cb 100644 --- a/atoma-daemon/docs/openapi.yml +++ b/atoma-daemon/docs/openapi.yml @@ -9,89 +9,24 @@ servers: - url: http://localhost:8080 description: Local development server paths: - /almost_filled_stacks/{fraction}: + /attestation_disputes/against/nodes/{node_id}: get: tags: - - Almost filled stacks - summary: List almost filled stacks - description: Retrieves all stacks that are filled above a specified fraction threshold for all registered nodes. - operationId: almost_filled_stacks_fraction_get - parameters: - - name: fraction - in: path - description: The fraction threshold (0.0 to 100.0) to filter stacks - required: true - schema: - type: number - format: double - responses: - '200': - description: Stack objects that are filled above the specified fraction threshold - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Stack' - '500': - description: Internal server error - /almost_filled_stacks/{id}/{fraction}: - get: - tags: - - Almost filled stacks - summary: List almost filled stacks for a specific node - description: |- - Retrieves all stacks that are filled above a specified fraction threshold for a specific node. - - # Arguments - * `daemon_state` - The shared state containing the state manager - * `node_small_id` - The small ID of the node whose stacks should be retrieved - * `fraction` - The fraction threshold (0.0 to 100.0) to filter stacks - - # Returns - * `Result>>` - A JSON response containing a list of stacks - - `Ok(Json>)` - Successfully retrieved stacks - - `Err(StatusCode::INTERNAL_SERVER_ERROR)` - Failed to retrieve stacks from state manager - - # Example Response - Returns a JSON array of Stack objects for the specified node that are filled above the fraction threshold - operationId: almost_filled_stacks_get + - Attestation disputes + summary: List against attestation disputes + description: Lists all attestation disputes against a specific node. + operationId: attestation_disputes_against_nodes_list parameters: - - name: id + - name: node_id in: path - description: The small ID of the node whose stacks should be retrieved + description: The small ID of the node whose disputes should be retrieved required: true schema: type: integer format: int64 - - name: fraction - in: path - description: The fraction threshold (0.0 to 100.0) to filter stacks - required: true - schema: - type: number - format: double - responses: - '200': - description: List of node stacks - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Stack' - '500': - description: Internal server error - /attestation_disputes/against: - get: - tags: - - Attestation disputes - summary: List attestation disputes against currently registered nodes - description: Retrieves all attestation disputes against the currently registered nodes. - operationId: attestation_disputes_against_list responses: '200': - description: List of all against attestation disputes where the registered nodes are the defendants + description: List of against attestation disputes where the specified node is the defendant content: application/json: schema: @@ -100,42 +35,24 @@ paths: $ref: '#/components/schemas/StackAttestationDispute' '500': description: Internal server error - /attestation_disputes/against/{id}: + /attestation_disputes/own/nodes/{node_id}: get: tags: - Attestation disputes - summary: List attestation disputes against a specific node - description: Retrieves all attestation disputes against a specific node. - operationId: attestation_disputes_against_get + summary: List own attestation disputes + description: Lists all attestation disputes initiated by a specific node. + operationId: attestation_disputes_own_nodes_list parameters: - - name: id + - name: node_id in: path - description: The small ID of the node whose disputes should be retrieved + description: The small ID of the node whose initiated disputes should be retrieved required: true schema: type: integer format: int64 responses: '200': - description: List of against attestation disputes where the specified node is the defendant - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/StackAttestationDispute' - '500': - description: Internal server error - /attestation_disputes/own: - get: - tags: - - Attestation disputes - summary: List attestation disputes initiated by currently registered nodes - description: Retrieves all attestation disputes initiated by the currently registered nodes. - operationId: attestation_disputes_own_list - responses: - '200': - description: List of all own attestation disputes where the registered nodes are the plaintiffs + description: List of own attestation disputes where the specified node is the plaintiff content: application/json: schema: @@ -144,30 +61,30 @@ paths: $ref: '#/components/schemas/StackAttestationDispute' '500': description: Internal server error - /attestation_disputes/own/{id}: + /claimed-stacks/claimed_stacks/nodes/{node_id}: get: tags: - - Attestation disputes - summary: List attestation disputes initiated by a specific node - description: Retrieves all attestation disputes initiated by a specific node. - operationId: attestation_disputes_own_get + - Claimed stacks + summary: List claimed stacks + description: Lists all claimed stacks for a specific node identified by its small ID. + operationId: claimed_stacks_nodes_list parameters: - - name: id + - name: node_id in: path - description: The small ID of the node whose initiated disputes should be retrieved + description: Node small ID required: true schema: type: integer format: int64 responses: '200': - description: List of own attestation disputes where the specified node is the plaintiff + description: List of claimed stacks matching the criteria content: application/json: schema: type: array items: - $ref: '#/components/schemas/StackAttestationDispute' + $ref: '#/components/schemas/StackSettlementTicket' '500': description: Internal server error /nodes/claim-funds: @@ -175,7 +92,10 @@ paths: tags: - Nodes summary: Create claim funds transaction - description: Claims funds for completed stacks. + description: |- + Create claim funds transaction + + Claims funds for completed stacks. operationId: nodes_claim_funds requestBody: content: @@ -197,7 +117,10 @@ paths: tags: - Nodes summary: Create model subscription transaction - description: Subscribes a node to a specific model. + description: |- + Create model subscription transaction + + Subscribes a node to a specific model. operationId: nodes_model_subscribe requestBody: content: @@ -219,7 +142,10 @@ paths: tags: - Nodes summary: Create node registration transaction - description: Registers a new node in the system. + description: |- + Create node registration transaction + + Registers a new node in the system. operationId: nodes_register requestBody: content: @@ -241,7 +167,10 @@ paths: tags: - Nodes summary: Create attestation proof transaction - description: Submits attestations for stack settlement. + description: |- + Create attestation proof transaction + + Submits attestations for stack settlement. operationId: nodes_submit_attestations requestBody: content: @@ -263,7 +192,10 @@ paths: tags: - Nodes summary: Create task subscription transaction - description: Subscribes a node to a specific task. + description: |- + Create task subscription transaction + + Subscribes a node to a specific task. operationId: nodes_task_subscribe requestBody: content: @@ -281,10 +213,11 @@ paths: '500': description: Failed to submit task subscription transaction /nodes/task-unsubscribe: - post: + delete: tags: - Nodes - summary: Unsubscribes a node from a specific task. + summary: Delete task subscription + description: Unsubscribes a node from a specific task. operationId: nodes_task_unsubscribe requestBody: content: @@ -306,7 +239,10 @@ paths: tags: - Nodes summary: Modify task subscription - description: Updates an existing task subscription for a node. + description: |- + Modify task subscription + + Updates an existing task subscription for a node. operationId: nodes_task_update_subscription requestBody: content: @@ -328,7 +264,10 @@ paths: tags: - Nodes summary: Create try settle stacks transaction - description: Attempts to settle stacks for a node. + description: |- + Create try settle stacks transaction + + Attempts to settle stacks for a node. operationId: nodes_try_settle_stacks requestBody: content: @@ -345,86 +284,33 @@ paths: $ref: '#/components/schemas/NodeTrySettleStacksResponse' '500': description: Failed to submit try settle stacks - /stacks/claimed_stacks: - get: - tags: - - Stacks - summary: List all claimed stacks for currently registered nodes - description: Retrieves all claimed stacks for the currently registered node badges. - operationId: claimed_stacks_list - responses: - '200': - description: List of all StackSettlementTicket objects for all registered nodes - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/StackSettlementTicket' - '500': - description: Internal server error - /stacks/claimed_stacks/{id}: + /stacks/stacks/nodes/{node_id}: get: tags: - Stacks - summary: List all claimed stacks for a specific node - description: Retrieves all claimed stacks for a specific node identified by its small ID. - operationId: claimed_stacks_get + summary: List stacks + description: Lists all stacks for a specific node identified by its small ID. + operationId: stacks_nodes_list parameters: - - name: id + - name: node_id in: path - description: The small ID of the node whose claimed stacks should be retrieved + description: Node small ID required: true schema: type: integer format: int64 - responses: - '200': - description: List of StackSettlementTicket objects for the specified node - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/StackSettlementTicket' - '500': - description: Internal server error - /stacks/stacks: - get: - tags: - - Stacks - summary: List all stacks for currently registered nodes - description: Retrieves all stacks associated with the currently registered node badges. - operationId: stacks_list - responses: - '200': - description: List of all Stack objects for all registered nodes - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Stack' - '500': - description: Internal server error - /stacks/stacks/{id}: - get: - tags: - - Stacks - summary: List all stacks for a specific node - description: Retrieves all stacks for a specific node identified by its small ID. - operationId: stacks_get - parameters: - - name: id - in: path - description: The small ID of the node whose stacks should be retrieved - required: true + - name: min_fill_fraction + in: query + description: Optional minimum fill fraction (0.0 to 100.0) + required: false schema: - type: integer - format: int64 + type: + - number + - 'null' + format: double responses: '200': - description: List of Stack objects for the specified node + description: List of Stack objects matching the criteria content: application/json: schema: @@ -433,35 +319,15 @@ paths: $ref: '#/components/schemas/Stack' '500': description: Internal server error - /subscriptions/: + /subscriptions/nodes/{node_id}: get: tags: - Subscriptions - summary: List all subscriptions for currently registered nodes - description: Retrieves all node subscriptions for the currently registered node badges. - operationId: subscriptions_list - responses: - '200': - description: List of all node subscriptions - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/NodeSubscription' - '404': - description: No node badges registered - '500': - description: Internal server error - /subscriptions/{id}: - get: - tags: - - Subscriptions - summary: List all subscriptions for a specific node - description: Retrieves all subscriptions for a specific node identified by its small ID. - operationId: subscriptions_get + summary: List subscriptions + description: Lists all subscriptions for a specific node identified by its small ID. + operationId: subscriptions_nodes_list parameters: - - name: id + - name: node_id in: path description: The small ID of the node whose subscriptions should be retrieved required: true @@ -1110,6 +976,14 @@ components: type: integer format: int64 description: Unique small integer identifier for the stack involved in the dispute + StackQuery: + type: object + properties: + min_fill_fraction: + type: + - number + - 'null' + format: double StackSettlementTicket: type: object description: Represents a settlement ticket for a compute stack @@ -1227,6 +1101,8 @@ components: tags: - name: Almost filled stacks description: Almost filled stacks management +- name: Claimed stacks + description: Claimed stacks management - name: Attestation disputes description: Attestation disputes management - name: Nodes diff --git a/atoma-daemon/src/components/openapi.rs b/atoma-daemon/src/components/openapi.rs index de113107..4898be69 100644 --- a/atoma-daemon/src/components/openapi.rs +++ b/atoma-daemon/src/components/openapi.rs @@ -2,17 +2,15 @@ use axum::Router; use utoipa::OpenApi; use utoipa_swagger_ui::SwaggerUi; -use crate::handlers::{ - almost_filled_stacks, attestation_disputes, nodes, stacks, subscriptions, tasks, -}; +use crate::handlers::{attestation_disputes, claimed_stacks, nodes, stacks, subscriptions, tasks}; pub fn openapi_routes() -> Router { /// OpenAPI documentation for the Atoma daemon API. #[derive(OpenApi)] #[openapi( nest( - (path = almost_filled_stacks::ALMOST_FILLED_STACKS_PATH, api = almost_filled_stacks::AlmostFilledStacksOpenApi, tags = ["Almost filled stacks"]), (path = attestation_disputes::ATTESTATION_DISPUTES_PATH, api = attestation_disputes::AttestationDisputesOpenApi, tags = ["Attestation disputes"]), + (path = claimed_stacks::CLAIMED_STACKS_PATH, api = claimed_stacks::ClaimedStacksOpenApi, tags = ["Claimed stacks"]), (path = nodes::NODES_PATH, api = nodes::NodesOpenApi, tags = ["Nodes"]), (path = stacks::STACKS_PATH, api = stacks::StacksOpenApi, tags = ["Stacks"]), (path = subscriptions::SUBSCRIPTIONS_PATH, api = subscriptions::SubscriptionsOpenApi, tags = ["Subscriptions"]), @@ -20,6 +18,7 @@ pub fn openapi_routes() -> Router { ), tags( (name = "Almost filled stacks", description = "Almost filled stacks management"), + (name = "Claimed stacks", description = "Claimed stacks management"), (name = "Attestation disputes", description = "Attestation disputes management"), (name = "Nodes", description = "Nodes management"), (name = "Stacks", description = "Stacks management"), diff --git a/atoma-daemon/src/handlers/almost_filled_stacks.rs b/atoma-daemon/src/handlers/almost_filled_stacks.rs deleted file mode 100644 index a13a043f..00000000 --- a/atoma-daemon/src/handlers/almost_filled_stacks.rs +++ /dev/null @@ -1,123 +0,0 @@ -use atoma_state::types::Stack; -use axum::{ - extract::{Path, State}, - http::StatusCode, - routing::get, - Json, Router, -}; -use tracing::error; -use utoipa::OpenApi; - -use crate::DaemonState; - -pub const ALMOST_FILLED_STACKS_PATH: &str = "/almost_filled_stacks"; - -#[derive(OpenApi)] -#[openapi( - paths(almost_filled_stacks_fraction_get, almost_filled_stacks_get), - components(schemas(Stack)) -)] -pub(crate) struct AlmostFilledStacksOpenApi; - -//TODO: we should implement the following endpoints: -// - GET /stacks - List all stacks. A filter `fraction` can be applied -// - GET /stacks/nodes/:id - List all stacks for a specific node. A filter `fraction` can be applied -// Move into stacks.rs - -/// Router for handling almost filled stacks endpoints -/// -/// Creates routes for: -/// - GET /almost_filled_stacks - Get stacks above threshold for all nodes -/// - GET /almost_filled_stacks/:id - Get stacks above threshold for specific node -pub fn almost_filled_stacks_router() -> Router { - Router::new() - .route( - ALMOST_FILLED_STACKS_PATH, - get(almost_filled_stacks_fraction_get), - ) - .route( - &format!("{ALMOST_FILLED_STACKS_PATH}/:id"), - get(almost_filled_stacks_get), - ) -} - -/// List almost filled stacks -/// -/// Retrieves all stacks that are filled above a specified fraction threshold for all registered nodes. -#[utoipa::path( - get, - path = "/{fraction}", - params( - ("fraction" = f64, Path, description = "The fraction threshold (0.0 to 100.0) to filter stacks") - ), - responses( - (status = OK, description = "Stack objects that are filled above the specified fraction threshold", body = Vec), - (status = INTERNAL_SERVER_ERROR, description = "Internal server error") - ) -)] -pub async fn almost_filled_stacks_fraction_get( - State(daemon_state): State, - Path(fraction): Path, -) -> Result>, StatusCode> { - Ok(Json( - daemon_state - .atoma_state - .get_almost_filled_stacks( - &daemon_state - .node_badges - .iter() - .map(|(_, small_id)| *small_id as i64) - .collect::>(), - fraction, - ) - .await - .map_err(|_| { - error!("Failed to get all almost filled stacks"); - StatusCode::INTERNAL_SERVER_ERROR - })?, - )) -} - -/// List almost filled stacks for a specific node -/// -/// Retrieves all stacks that are filled above a specified fraction threshold for a specific node. -/// -/// # Arguments -/// * `daemon_state` - The shared state containing the state manager -/// * `node_small_id` - The small ID of the node whose stacks should be retrieved -/// * `fraction` - The fraction threshold (0.0 to 100.0) to filter stacks -/// -/// # Returns -/// * `Result>>` - A JSON response containing a list of stacks -/// - `Ok(Json>)` - Successfully retrieved stacks -/// - `Err(StatusCode::INTERNAL_SERVER_ERROR)` - Failed to retrieve stacks from state manager -/// -/// # Example Response -/// Returns a JSON array of Stack objects for the specified node that are filled above the fraction threshold -#[utoipa::path( - get, - path = "/{id}/{fraction}", - params( - ("id" = i64, Path, description = "The small ID of the node whose stacks should be retrieved"), - ("fraction" = f64, Path, description = "The fraction threshold (0.0 to 100.0) to filter stacks") - ), - responses( - (status = OK, description = "List of node stacks", body = Vec), - (status = INTERNAL_SERVER_ERROR, description = "Internal server error") - ) -)] -pub async fn almost_filled_stacks_get( - State(daemon_state): State, - Path((node_small_id, fraction)): Path<(i64, f64)>, -) -> Result>, StatusCode> { - Ok(Json( - daemon_state - .atoma_state - .get_almost_filled_stacks(&[node_small_id], fraction) - .await - .map_err(|_| { - error!("Failed to get node almost filled stacks"); - StatusCode::INTERNAL_SERVER_ERROR - })?, - )) -} diff --git a/atoma-daemon/src/handlers/attestation_disputes.rs b/atoma-daemon/src/handlers/attestation_disputes.rs index a2b09acb..a71e22ed 100644 --- a/atoma-daemon/src/handlers/attestation_disputes.rs +++ b/atoma-daemon/src/handlers/attestation_disputes.rs @@ -15,10 +15,8 @@ pub const ATTESTATION_DISPUTES_PATH: &str = "/attestation_disputes"; #[derive(OpenApi)] #[openapi( paths( - attestation_disputes_against_list, - attestation_disputes_against_get, - attestation_disputes_own_list, - attestation_disputes_own_get + attestation_disputes_against_nodes_list, + attestation_disputes_own_nodes_list ), components(schemas(StackAttestationDispute)) )] @@ -26,80 +24,36 @@ pub(crate) struct AttestationDisputesOpenApi; //TODO: this endpoint can be merged into one (I think) through filters +//TODO: this endpoint can be merged into one (I think) through filters + /// Router for handling attestation disputes endpoints -/// -/// Creates routes for: -/// - GET /attestation_disputes/against - Get all attestation disputes against the registered nodes -/// - GET /attestation_disputes/against/:id - Get attestation disputes against a specific node -/// - GET /attestation_disputes/own - Get all attestation disputes initiated by the registered nodes -/// - GET /attestation_disputes/own/:id - Get attestation disputes initiated by a specific node pub fn attestation_disputes_router() -> Router { Router::new() .route( - &format!("{ATTESTATION_DISPUTES_PATH}/against"), - get(attestation_disputes_against_list), - ) - .route( - &format!("{ATTESTATION_DISPUTES_PATH}/against/:id"), - get(attestation_disputes_against_get), - ) - .route( - &format!("{ATTESTATION_DISPUTES_PATH}/own"), - get(attestation_disputes_own_list), + &format!("{ATTESTATION_DISPUTES_PATH}/against/nodes/:node_id"), + get(attestation_disputes_against_nodes_list), ) .route( - &format!("{ATTESTATION_DISPUTES_PATH}/own/:id"), - get(attestation_disputes_own_get), + &format!("{ATTESTATION_DISPUTES_PATH}/own/nodes/:node_id"), + get(attestation_disputes_own_nodes_list), ) } -/// List attestation disputes against currently registered nodes +/// List against attestation disputes /// -/// Retrieves all attestation disputes against the currently registered nodes. +/// Lists all attestation disputes against a specific node. #[utoipa::path( get, - path = "/against", - responses( - (status = OK, description = "List of all against attestation disputes where the registered nodes are the defendants", body = Vec), - (status = INTERNAL_SERVER_ERROR, description = "Internal server error") - ) -)] -pub async fn attestation_disputes_against_list( - State(daemon_state): State, -) -> Result>, StatusCode> { - Ok(Json( - daemon_state - .atoma_state - .get_against_attestation_disputes( - &daemon_state - .node_badges - .iter() - .map(|(_, small_id)| *small_id as i64) - .collect::>(), - ) - .await - .map_err(|_| { - error!("Failed to get all attestation disputes"); - StatusCode::INTERNAL_SERVER_ERROR - })?, - )) -} - -/// List attestation disputes against a specific node -/// -/// Retrieves all attestation disputes against a specific node. -#[utoipa::path( - get, - path = "/against/{id}", + path = "/against/nodes/{node_id}", params( - ("id" = i64, Path, description = "The small ID of the node whose disputes should be retrieved") + ("node_id" = i64, Path, description = "The small ID of the node whose disputes should be retrieved") ), responses( (status = OK, description = "List of against attestation disputes where the specified node is the defendant", body = Vec), (status = INTERNAL_SERVER_ERROR, description = "Internal server error") ) )] -pub async fn attestation_disputes_against_get( +pub async fn attestation_disputes_against_nodes_list( State(daemon_state): State, Path(node_small_id): Path, ) -> Result>, StatusCode> { @@ -115,53 +69,21 @@ pub async fn attestation_disputes_against_get( )) } -/// List attestation disputes initiated by currently registered nodes -/// -/// Retrieves all attestation disputes initiated by the currently registered nodes. -#[utoipa::path( - get, - path = "/own", - responses( - (status = OK, description = "List of all own attestation disputes where the registered nodes are the plaintiffs", body = Vec), - (status = INTERNAL_SERVER_ERROR, description = "Internal server error") - ) -)] -pub async fn attestation_disputes_own_list( - State(daemon_state): State, -) -> Result>, StatusCode> { - Ok(Json( - daemon_state - .atoma_state - .get_own_attestation_disputes( - &daemon_state - .node_badges - .iter() - .map(|(_, small_id)| *small_id as i64) - .collect::>(), - ) - .await - .map_err(|_| { - error!("Failed to get all own attestation disputes"); - StatusCode::INTERNAL_SERVER_ERROR - })?, - )) -} - -/// List attestation disputes initiated by a specific node +/// List own attestation disputes /// -/// Retrieves all attestation disputes initiated by a specific node. +/// Lists all attestation disputes initiated by a specific node. #[utoipa::path( get, - path = "/own/{id}", + path = "/own/nodes/{node_id}", params( - ("id" = i64, Path, description = "The small ID of the node whose initiated disputes should be retrieved") + ("node_id" = i64, Path, description = "The small ID of the node whose initiated disputes should be retrieved") ), responses( (status = OK, description = "List of own attestation disputes where the specified node is the plaintiff", body = Vec), (status = INTERNAL_SERVER_ERROR, description = "Internal server error") ) )] -pub async fn attestation_disputes_own_get( +pub async fn attestation_disputes_own_nodes_list( State(daemon_state): State, Path(node_small_id): Path, ) -> Result>, StatusCode> { diff --git a/atoma-daemon/src/handlers/claimed_stacks.rs b/atoma-daemon/src/handlers/claimed_stacks.rs new file mode 100644 index 00000000..52a1a55b --- /dev/null +++ b/atoma-daemon/src/handlers/claimed_stacks.rs @@ -0,0 +1,53 @@ +use atoma_state::types::StackSettlementTicket; +use axum::{extract::Path, extract::State, http::StatusCode, routing::get, Json, Router}; +use tracing::error; +use utoipa::OpenApi; + +use crate::DaemonState; + +pub const CLAIMED_STACKS_PATH: &str = "/claimed-stacks"; + +#[derive(OpenApi)] +#[openapi( + paths(claimed_stacks_nodes_list), + components(schemas(StackSettlementTicket)) +)] +pub(crate) struct ClaimedStacksOpenApi; + +pub fn claimed_stacks_router() -> Router { + Router::new().route( + &format!("{CLAIMED_STACKS_PATH}/nodes/:node_id"), + get(claimed_stacks_nodes_list), + ) +} + +/// List claimed stacks +/// +/// Lists all claimed stacks for a specific node identified by its small ID. +#[utoipa::path( + get, + path = "/claimed_stacks/nodes/{node_id}", + params( + ("node_id" = i64, Path, description = "Node small ID") + ), + responses( + (status = OK, description = "List of claimed stacks matching the criteria", body = Vec), + (status = INTERNAL_SERVER_ERROR, description = "Internal server error") + ) +)] +pub async fn claimed_stacks_nodes_list( + State(daemon_state): State, + Path(node_id): Path, +) -> Result>, StatusCode> { + let node_ids = vec![node_id]; + + daemon_state + .atoma_state + .get_claimed_stacks(&node_ids) + .await + .map(Json) + .map_err(|_| { + error!("Failed to get claimed stacks"); + StatusCode::INTERNAL_SERVER_ERROR + }) +} diff --git a/atoma-daemon/src/handlers/mod.rs b/atoma-daemon/src/handlers/mod.rs index 05146822..4867faa0 100644 --- a/atoma-daemon/src/handlers/mod.rs +++ b/atoma-daemon/src/handlers/mod.rs @@ -1,5 +1,5 @@ -pub(crate) mod almost_filled_stacks; pub(crate) mod attestation_disputes; +pub(crate) mod claimed_stacks; pub(crate) mod nodes; pub(crate) mod stacks; pub(crate) mod subscriptions; diff --git a/atoma-daemon/src/handlers/nodes.rs b/atoma-daemon/src/handlers/nodes.rs index a5820c09..695fd9cb 100644 --- a/atoma-daemon/src/handlers/nodes.rs +++ b/atoma-daemon/src/handlers/nodes.rs @@ -1,4 +1,9 @@ -use axum::{extract::State, http::StatusCode, routing::post, Json, Router}; +use axum::{ + extract::State, + http::StatusCode, + routing::{delete, post}, + Json, Router, +}; use tracing::{error, info}; use utoipa::OpenApi; @@ -74,7 +79,7 @@ pub fn nodes_router() -> Router { ) .route( &format!("{NODES_PATH}/task-unsubscribe"), - post(nodes_task_unsubscribe), + delete(nodes_task_unsubscribe), ) .route( &format!("{NODES_PATH}/try-settle-stacks"), @@ -90,6 +95,8 @@ pub fn nodes_router() -> Router { ) } +/// Create node registration transaction +/// /// Create node registration transaction /// /// Registers a new node in the system. @@ -123,6 +130,8 @@ pub async fn nodes_register( Ok(Json(NodeRegistrationResponse { tx_digest })) } +/// Create model subscription transaction +/// /// Create model subscription transaction /// /// Subscribes a node to a specific model. @@ -167,6 +176,8 @@ pub async fn nodes_model_subscribe( Ok(Json(NodeModelSubscriptionResponse { tx_digest })) } +/// Create task subscription transaction +/// /// Create task subscription transaction /// /// Subscribes a node to a specific task. @@ -213,6 +224,8 @@ pub async fn nodes_task_subscribe( Ok(Json(NodeTaskSubscriptionResponse { tx_digest })) } +/// Modify task subscription +/// /// Modify task subscription /// /// Updates an existing task subscription for a node. @@ -259,11 +272,11 @@ pub async fn nodes_task_update_subscription( Ok(Json(NodeTaskUpdateSubscriptionResponse { tx_digest })) } -//TODO: change to delete - +/// Delete task subscription +/// /// Unsubscribes a node from a specific task. #[utoipa::path( - post, + delete, path = "/task-unsubscribe", request_body = NodeTaskUnsubscriptionRequest, responses( @@ -301,6 +314,8 @@ pub async fn nodes_task_unsubscribe( Ok(Json(NodeTaskUnsubscriptionResponse { tx_digest })) } +/// Create try settle stacks transaction +/// /// Create try settle stacks transaction /// /// Attempts to settle stacks for a node. @@ -366,6 +381,8 @@ pub async fn nodes_try_settle_stacks( Ok(Json(NodeTrySettleStacksResponse { tx_digests })) } +/// Create attestation proof transaction +/// /// Create attestation proof transaction /// /// Submits attestations for stack settlement. @@ -479,6 +496,8 @@ pub async fn nodes_submit_attestations( Ok(Json(NodeAttestationProofResponse { tx_digests })) } +/// Create claim funds transaction +/// /// Create claim funds transaction /// /// Claims funds for completed stacks. diff --git a/atoma-daemon/src/handlers/stacks.rs b/atoma-daemon/src/handlers/stacks.rs index 4ed93d9c..49eafe9a 100644 --- a/atoma-daemon/src/handlers/stacks.rs +++ b/atoma-daemon/src/handlers/stacks.rs @@ -1,160 +1,73 @@ use atoma_state::types::{Stack, StackSettlementTicket}; use axum::{ - extract::{Path, State}, + extract::{Path, Query, State}, http::StatusCode, routing::get, Json, Router, }; +use serde::Deserialize; use tracing::error; -use utoipa::OpenApi; +use utoipa::{OpenApi, ToSchema}; use crate::DaemonState; pub const STACKS_PATH: &str = "/stacks"; +#[derive(Deserialize, ToSchema)] +pub struct StackQuery { + min_fill_fraction: Option, +} + #[derive(OpenApi)] #[openapi( - paths(stacks_list, stacks_get, claimed_stacks_list, claimed_stacks_get), - components(schemas(Stack, StackSettlementTicket)) + paths(stacks_nodes_list), + components(schemas(Stack, StackSettlementTicket, StackQuery)) )] pub(crate) struct StacksOpenApi; -//TODO: all of these endpoints should be deleted and replaced with the ones I suggested in the TODO of almost_filled_stacks.rs. If necessary, we can add additional filters to the endpoints to accomplish the functionality present in these endpoints. - -/// Router for handling stack-related endpoints -/// -/// This function sets up the routing for various stack-related operations, -/// including listing all stacks, retrieving specific stacks by ID, listing claimed stacks, -/// and retrieving specific claimed stacks by ID. Each route corresponds to a specific -/// operation that can be performed on stacks within the system. pub fn stacks_router() -> Router { - Router::new() - .route(STACKS_PATH, get(stacks_list)) - .route(&format!("{STACKS_PATH}/:id"), get(stacks_get)) - .route("/claimed_stacks", get(claimed_stacks_list)) - .route("/claimed_stacks/:id", get(claimed_stacks_get)) -} - -/// List all stacks for currently registered nodes -/// -/// Retrieves all stacks associated with the currently registered node badges. -#[utoipa::path( - get, - path = "/stacks", - responses( - (status = OK, description = "List of all Stack objects for all registered nodes", body = Vec), - (status = INTERNAL_SERVER_ERROR, description = "Internal server error") + Router::new().route( + &format!("{STACKS_PATH}/nodes/:node_id"), + get(stacks_nodes_list), ) -)] -pub async fn stacks_list( - State(daemon_state): State, -) -> Result>, StatusCode> { - Ok(Json( - daemon_state - .atoma_state - .get_stacks_by_node_small_ids( - &daemon_state - .node_badges - .iter() - .map(|(_, small_id)| *small_id as i64) - .collect::>(), - ) - .await - .map_err(|_| { - error!("Failed to get all node stacks"); - StatusCode::INTERNAL_SERVER_ERROR - })?, - )) } -/// List all stacks for a specific node +/// List stacks /// -/// Retrieves all stacks for a specific node identified by its small ID. +/// Lists all stacks for a specific node identified by its small ID. #[utoipa::path( get, - path = "/stacks/{id}", + path = "/stacks/nodes/{node_id}", params( - ("id" = i64, Path, description = "The small ID of the node whose stacks should be retrieved") + ("node_id" = i64, Path, description = "Node small ID"), + ("min_fill_fraction" = Option, Query, description = "Optional minimum fill fraction (0.0 to 100.0)") ), responses( - (status = OK, description = "List of Stack objects for the specified node", body = Vec), + (status = OK, description = "List of Stack objects matching the criteria", body = Vec), (status = INTERNAL_SERVER_ERROR, description = "Internal server error") ) )] -pub async fn stacks_get( +pub async fn stacks_nodes_list( State(daemon_state): State, - Path(node_small_id): Path, + Path(node_id): Path, + Query(query): Query, ) -> Result>, StatusCode> { - Ok(Json( - daemon_state - .atoma_state - .get_stack_by_id(node_small_id) - .await - .map_err(|_| { - error!("Failed to get node stack"); - StatusCode::INTERNAL_SERVER_ERROR - })?, - )) -} + let node_ids = vec![node_id]; -/// List all claimed stacks for currently registered nodes -/// -/// Retrieves all claimed stacks for the currently registered node badges. -#[utoipa::path( - get, - path = "/claimed_stacks", - responses( - (status = OK, description = "List of all StackSettlementTicket objects for all registered nodes", body = Vec), - (status = INTERNAL_SERVER_ERROR, description = "Internal server error") - ) -)] -pub async fn claimed_stacks_list( - State(daemon_state): State, -) -> Result>, StatusCode> { - Ok(Json( + let stacks = if let Some(fraction) = query.min_fill_fraction { daemon_state .atoma_state - .get_claimed_stacks( - &daemon_state - .node_badges - .iter() - .map(|(_, small_id)| *small_id as i64) - .collect::>(), - ) + .get_almost_filled_stacks(&node_ids, fraction) .await - .map_err(|_| { - error!("Failed to get all claimed stacks"); - StatusCode::INTERNAL_SERVER_ERROR - })?, - )) -} - -/// List all claimed stacks for a specific node -/// -/// Retrieves all claimed stacks for a specific node identified by its small ID. -#[utoipa::path( - get, - path = "/claimed_stacks/{id}", - params( - ("id" = i64, Path, description = "The small ID of the node whose claimed stacks should be retrieved") - ), - responses( - (status = OK, description = "List of StackSettlementTicket objects for the specified node", body = Vec), - (status = INTERNAL_SERVER_ERROR, description = "Internal server error") - ) -)] -pub async fn claimed_stacks_get( - State(daemon_state): State, - Path(node_small_id): Path, -) -> Result>, StatusCode> { - Ok(Json( + } else { daemon_state .atoma_state - .get_claimed_stacks(&[node_small_id]) + .get_stacks_by_node_small_ids(&node_ids) .await - .map_err(|_| { - error!("Failed to get node claimed stacks"); - StatusCode::INTERNAL_SERVER_ERROR - })?, - )) + }; + + stacks.map(Json).map_err(|_| { + error!("Failed to get stacks"); + StatusCode::INTERNAL_SERVER_ERROR + }) } diff --git a/atoma-daemon/src/handlers/subscriptions.rs b/atoma-daemon/src/handlers/subscriptions.rs index 74981ee0..ae72baad 100644 --- a/atoma-daemon/src/handlers/subscriptions.rs +++ b/atoma-daemon/src/handlers/subscriptions.rs @@ -13,10 +13,7 @@ use crate::DaemonState; pub const SUBSCRIPTIONS_PATH: &str = "/subscriptions"; #[derive(OpenApi)] -#[openapi( - paths(subscriptions_list, subscriptions_get), - components(schemas(NodeSubscription)) -)] +#[openapi(paths(subscriptions_nodes_list), components(schemas(NodeSubscription)))] pub(crate) struct SubscriptionsOpenApi; /// Router for handling subscription-related endpoints @@ -26,62 +23,27 @@ pub(crate) struct SubscriptionsOpenApi; /// Each route corresponds to a specific operation that can be performed on subscriptions /// within the system. pub fn subscriptions_router() -> Router { - Router::new() - .route(SUBSCRIPTIONS_PATH, get(subscriptions_list)) - .route(&format!("{SUBSCRIPTIONS_PATH}/:id"), get(subscriptions_get)) -} - -/// List all subscriptions for currently registered nodes -/// -/// Retrieves all node subscriptions for the currently registered node badges. -#[utoipa::path( - get, - path = "/", - responses( - (status = OK, description = "List of all node subscriptions", body = Vec), - (status = NOT_FOUND, description = "No node badges registered"), - (status = INTERNAL_SERVER_ERROR, description = "Internal server error") + Router::new().route( + &format!("{SUBSCRIPTIONS_PATH}/nodes/:node_id"), + get(subscriptions_nodes_list), ) -)] -pub async fn subscriptions_list( - State(daemon_state): State, -) -> Result>, StatusCode> { - let current_node_badges = daemon_state.node_badges; - if current_node_badges.is_empty() { - return Err(StatusCode::NOT_FOUND); - } - let all_node_subscriptions = daemon_state - .atoma_state - .get_all_node_subscriptions( - ¤t_node_badges - .iter() - .map(|(_, small_id)| *small_id as i64) - .collect::>(), - ) - .await - .map_err(|_| { - error!("Failed to get all node subscriptions"); - StatusCode::INTERNAL_SERVER_ERROR - })?; - Ok(Json(all_node_subscriptions)) } -//TODO: this endpoint should be deleted and add filter on subscriptions_list. -/// List all subscriptions for a specific node +/// List subscriptions /// -/// Retrieves all subscriptions for a specific node identified by its small ID. +/// Lists all subscriptions for a specific node identified by its small ID. #[utoipa::path( get, - path = "/{id}", + path = "/nodes/{node_id}", params( - ("id" = i64, Path, description = "The small ID of the node whose subscriptions should be retrieved") + ("node_id" = i64, Path, description = "The small ID of the node whose subscriptions should be retrieved") ), responses( (status = OK, description = "List of node subscriptions", body = Vec), (status = INTERNAL_SERVER_ERROR, description = "Internal server error") ) )] -pub async fn subscriptions_get( +pub async fn subscriptions_nodes_list( State(daemon_state): State, Path(node_small_id): Path, ) -> Result>, StatusCode> { diff --git a/atoma-daemon/src/server.rs b/atoma-daemon/src/server.rs index 6cdb5e69..3b6bf754 100644 --- a/atoma-daemon/src/server.rs +++ b/atoma-daemon/src/server.rs @@ -12,9 +12,9 @@ use tracing::instrument; use crate::{ components::openapi::openapi_routes, handlers::{ - almost_filled_stacks::almost_filled_stacks_router, - attestation_disputes::attestation_disputes_router, nodes::nodes_router, - stacks::stacks_router, subscriptions::subscriptions_router, tasks::tasks_router, + attestation_disputes::attestation_disputes_router, claimed_stacks::claimed_stacks_router, + nodes::nodes_router, stacks::stacks_router, subscriptions::subscriptions_router, + tasks::tasks_router, }, }; @@ -176,8 +176,8 @@ pub async fn run_server( /// ``` pub fn create_router(daemon_state: DaemonState) -> Router { Router::new() - .merge(almost_filled_stacks_router()) .merge(attestation_disputes_router()) + .merge(claimed_stacks_router()) .merge(nodes_router()) .merge(stacks_router()) .merge(subscriptions_router())