From 12ed9150698f804cde17acfa28bd2eff7367c910 Mon Sep 17 00:00:00 2001 From: jmwample Date: Mon, 3 Mar 2025 16:45:38 -0700 Subject: [PATCH] skeleton of changes for nym api batch requests --- .../validator-client/src/client.rs | 5 ++ .../validator-client/src/nym_api/mod.rs | 49 ++++++++++++++----- .../validator-client/src/nym_api/routes.rs | 4 ++ .../nym_nodes/handlers/unstable/skimmed.rs | 36 ++++++++++++-- 4 files changed, 77 insertions(+), 17 deletions(-) diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index c41ba519d4..0aa91df2dc 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -498,6 +498,11 @@ impl NymApiClient { Ok(nodes) } + /// retrieve basic information for all bonded nodes on the network + pub async fn retrieve_basic_nodes_batch(&self, node_ids: Vec) -> Result, ValidatorClientError> { + Ok(self.nym_api.retrieve_basic_nodes_batch(&node_ids).await?.nodes) + } + pub async fn health(&self) -> Result { Ok(self.nym_api.health().await?) } diff --git a/common/client-libs/validator-client/src/nym_api/mod.rs b/common/client-libs/validator-client/src/nym_api/mod.rs index a9b1bc54d5..de15c43a65 100644 --- a/common/client-libs/validator-client/src/nym_api/mod.rs +++ b/common/client-libs/validator-client/src/nym_api/mod.rs @@ -270,10 +270,10 @@ pub trait NymApiClientExt: ApiClient { self.get_json( &[ routes::API_VERSION, - "unstable", + routes::UNSTABLE, routes::NYM_NODES_ROUTES, "mixnodes", - "skimmed", + routes::SKIMMED, ], NO_PARAMS, ) @@ -286,10 +286,10 @@ pub trait NymApiClientExt: ApiClient { self.get_json( &[ routes::API_VERSION, - "unstable", + routes::UNSTABLE, routes::NYM_NODES_ROUTES, "gateways", - "skimmed", + routes::SKIMMED, ], NO_PARAMS, ) @@ -335,9 +335,9 @@ pub trait NymApiClientExt: ApiClient { self.get_json( &[ routes::API_VERSION, - "unstable", + routes::UNSTABLE, routes::NYM_NODES_ROUTES, - "skimmed", + routes::SKIMMED, "entry-gateways", "all", ], @@ -372,9 +372,9 @@ pub trait NymApiClientExt: ApiClient { self.get_json( &[ routes::API_VERSION, - "unstable", + routes::UNSTABLE, routes::NYM_NODES_ROUTES, - "skimmed", + routes::SKIMMED, "mixnodes", "active", ], @@ -409,9 +409,9 @@ pub trait NymApiClientExt: ApiClient { self.get_json( &[ routes::API_VERSION, - "unstable", + routes::UNSTABLE, routes::NYM_NODES_ROUTES, - "skimmed", + routes::SKIMMED, "mixnodes", "all", ], @@ -420,6 +420,31 @@ pub trait NymApiClientExt: ApiClient { .await } + /// Send a Post request with a set of node ids. A successful response will contain descriptors + /// for all nodes associated with those node IDs available in the current full topology. + /// + /// If a provided node ID is not present there will be no descriptor for that node in the response. + /// + /// If no node IDs are provided the response will contain no descriptors. + #[instrument(level = "debug", skip(self))] + async fn retrieve_basic_nodes_batch( + &self, + node_ids: &[NodeId], + ) -> Result, NymAPIError> { + self.post_json( + &[ + routes::API_VERSION, + routes::UNSTABLE, + routes::NYM_NODES_ROUTES, + routes::SKIMMED, + routes::BATCH, + ], + NO_PARAMS, + node_ids, + ) + .await + } + #[instrument(level = "debug", skip(self))] async fn get_basic_nodes( &self, @@ -444,9 +469,9 @@ pub trait NymApiClientExt: ApiClient { self.get_json( &[ routes::API_VERSION, - "unstable", + routes::UNSTABLE, routes::NYM_NODES_ROUTES, - "skimmed", + routes::SKIMMED, ], ¶ms, ) diff --git a/common/client-libs/validator-client/src/nym_api/routes.rs b/common/client-libs/validator-client/src/nym_api/routes.rs index 8787264c4a..084755550a 100644 --- a/common/client-libs/validator-client/src/nym_api/routes.rs +++ b/common/client-libs/validator-client/src/nym_api/routes.rs @@ -74,3 +74,7 @@ pub const SERVICE_PROVIDERS: &str = "services"; pub const DETAILS: &str = "details"; pub const CHAIN_STATUS: &str = "chain-status"; pub const NETWORK: &str = "network"; + +pub const UNSTABLE: &str = "unstable"; +pub const SKIMMED: &str = "skimmed"; +pub const BATCH: &str = "batch"; diff --git a/nym-api/src/nym_nodes/handlers/unstable/skimmed.rs b/nym-api/src/nym_nodes/handlers/unstable/skimmed.rs index 8eb5388dea..2b17245397 100644 --- a/nym-api/src/nym_nodes/handlers/unstable/skimmed.rs +++ b/nym-api/src/nym_nodes/handlers/unstable/skimmed.rs @@ -25,6 +25,7 @@ use tracing::trace; use utoipa::ToSchema; pub type PaginatedSkimmedNodes = AxumResult>>; +type SkimmedNodes = AxumResult>>; /// Given all relevant caches, build part of response for JUST Nym Nodes fn build_nym_nodes_response<'a, NI>( @@ -196,7 +197,7 @@ where pub(super) async fn deprecated_gateways_basic( state: State, query_params: Query, -) -> AxumResult>> { +) -> SkimmedNodes { // 1. call '/v1/unstable/skimmed/entry-gateways/all' let all_gateways = entry_gateways_basic_all(state, query_params).await?; @@ -223,7 +224,7 @@ pub(super) async fn deprecated_gateways_basic( pub(super) async fn deprecated_mixnodes_basic( state: State, query_params: Query, -) -> AxumResult>> { +) -> SkimmedNodes { // 1. call '/v1/unstable/nym-nodes/skimmed/mixnodes/active' let active_mixnodes = mixnodes_basic_active(state, query_params).await?; @@ -239,7 +240,7 @@ async fn nodes_basic( state: State, Query(_query_params): Query, active_only: bool, -) -> PaginatedSkimmedNodes { +) -> SkimmedNodes { // unfortunately we have to build the response semi-manually here as we need to add two sources of legacy nodes // 1. grab all relevant described nym-nodes @@ -281,10 +282,10 @@ async fn nodes_basic( legacy_gateways.timestamp(), ]); - Ok(Json(PaginatedCachedNodesResponse::new_full( + Ok(Json(CachedNodesResponse { refreshed_at, nodes, - ))) + })) } #[allow(dead_code)] // not dead, used in OpenAPI docs @@ -329,6 +330,31 @@ pub(super) async fn nodes_basic_all( nodes_basic(state, Query(query_params.into()), false).await } +/// Post request handler taking a json array of NodeId (u32) values and returning descriptors for +/// the provided NodeId values. A successful response will contain descriptors for all nodes +/// associated with those node IDs available in the current full topology. +/// +/// If a provided node ID is not present in the current topology there will be no descriptor for +/// that node in the response. +/// +/// If no node IDs are provided the response will contain no descriptors. +#[utoipa::path( + tag = "Unstable Nym Nodes batch by Node ID", + get, + params(NodesParamsWithRole), + path = "batch", + context_path = "/v1/unstable/nym-nodes/skimmed", + responses( + (status = 200, body = PaginatedCachedNodesResponseSchema) + ) +)] +pub(super) async fn nodes_basic_batch( + state: State, + Query(query_params): Query, +) -> SkimmedNodes { + nodes_basic(state, Query(query_params.into()), false).await +} + /// Return Nym Nodes and optionally legacy mixnodes/gateways (if `no-legacy` flag is not used) /// that are currently bonded and are in the **active set** #[utoipa::path(