diff --git a/Cargo.lock b/Cargo.lock index 1e36ee6a52..9c25c39827 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6066,7 +6066,7 @@ dependencies = [ [[package]] name = "nym-node" -version = "1.3.0" +version = "1.3.1" dependencies = [ "anyhow", "async-trait", diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 8280701644..d3e2f2bf1a 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -19,8 +19,9 @@ use nym_api_requests::ecash::{ PartialExpirationDateSignatureResponse, VerificationKeyResponse, }; use nym_api_requests::models::{ - ApiHealthResponse, GatewayBondAnnotated, GatewayCoreStatusResponse, MixnodeCoreStatusResponse, - MixnodeStatusResponse, NymNodeDescription, RewardEstimationResponse, StakeSaturationResponse, + ApiHealthResponse, GatewayBondAnnotated, GatewayCoreStatusResponse, + HistoricalPerformanceResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse, + NymNodeDescription, RewardEstimationResponse, StakeSaturationResponse, }; use nym_api_requests::models::{LegacyDescribedGateway, MixNodeBondAnnotated}; use nym_api_requests::nym_nodes::SkimmedNode; @@ -264,6 +265,31 @@ impl Client { Ok(self.nym_api.get_gateways_detailed_unfiltered().await?) } + pub async fn get_full_node_performance_history( + &self, + node_id: NodeId, + ) -> Result, ValidatorClientError> { + // TODO: deal with paging in macro or some helper function or something, because it's the same pattern everywhere + let mut page = 0; + let mut history = Vec::new(); + + loop { + let mut res = self + .nym_api + .get_node_performance_history(node_id, Some(page), None) + .await?; + + history.append(&mut res.history.data); + if history.len() < res.history.pagination.total { + page += 1 + } else { + break; + } + } + + Ok(history) + } + // TODO: combine with NymApiClient... pub async fn get_all_cached_described_nodes( &self, 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 730c70c860..d790deda70 100644 --- a/common/client-libs/validator-client/src/nym_api/mod.rs +++ b/common/client-libs/validator-client/src/nym_api/mod.rs @@ -13,7 +13,7 @@ use nym_api_requests::ecash::models::{ use nym_api_requests::ecash::VerificationKeyResponse; use nym_api_requests::models::{ AnnotationResponse, ApiHealthResponse, LegacyDescribedMixNode, NodePerformanceResponse, - NodeRefreshBody, NymNodeDescription, RewardedSetResponse, + NodeRefreshBody, NymNodeDescription, PerformanceHistoryResponse, RewardedSetResponse, }; use nym_api_requests::nym_nodes::PaginatedCachedNodesResponse; use nym_api_requests::pagination::PaginatedResponse; @@ -163,6 +163,35 @@ pub trait NymApiClientExt: ApiClient { .await } + #[tracing::instrument(level = "debug", skip_all)] + async fn get_node_performance_history( + &self, + node_id: NodeId, + page: Option, + per_page: Option, + ) -> Result { + let mut params = Vec::new(); + + if let Some(page) = page { + params.push(("page", page.to_string())) + } + + if let Some(per_page) = per_page { + params.push(("per_page", per_page.to_string())) + } + + self.get_json( + &[ + routes::API_VERSION, + routes::NYM_NODES_ROUTES, + routes::NYM_NODES_PERFORMANCE_HISTORY, + &*node_id.to_string(), + ], + ¶ms, + ) + .await + } + #[tracing::instrument(level = "debug", skip_all)] async fn get_nodes_described( &self, @@ -179,8 +208,15 @@ pub trait NymApiClientExt: ApiClient { params.push(("per_page", per_page.to_string())) } - self.get_json(&[routes::API_VERSION, "nym-nodes", "described"], ¶ms) - .await + self.get_json( + &[ + routes::API_VERSION, + routes::NYM_NODES_ROUTES, + routes::NYM_NODES_DESCRIBED, + ], + ¶ms, + ) + .await } #[tracing::instrument(level = "debug", skip_all)] @@ -199,8 +235,15 @@ pub trait NymApiClientExt: ApiClient { params.push(("per_page", per_page.to_string())) } - self.get_json(&[routes::API_VERSION, "nym-nodes", "bonded"], ¶ms) - .await + self.get_json( + &[ + routes::API_VERSION, + routes::NYM_NODES_ROUTES, + routes::NYM_NODES_BONDED, + ], + ¶ms, + ) + .await } #[deprecated] @@ -210,7 +253,7 @@ pub trait NymApiClientExt: ApiClient { &[ routes::API_VERSION, "unstable", - "nym-nodes", + routes::NYM_NODES_ROUTES, "mixnodes", "skimmed", ], @@ -226,7 +269,7 @@ pub trait NymApiClientExt: ApiClient { &[ routes::API_VERSION, "unstable", - "nym-nodes", + routes::NYM_NODES_ROUTES, "gateways", "skimmed", ], @@ -238,7 +281,11 @@ pub trait NymApiClientExt: ApiClient { #[instrument(level = "debug", skip(self))] async fn get_rewarded_set(&self) -> Result { self.get_json( - &[routes::API_VERSION, "nym-nodes", "rewarded-set"], + &[ + routes::API_VERSION, + routes::NYM_NODES_ROUTES, + routes::NYM_NODES_REWARDED_SET, + ], NO_PARAMS, ) .await @@ -271,7 +318,7 @@ pub trait NymApiClientExt: ApiClient { &[ routes::API_VERSION, "unstable", - "nym-nodes", + routes::NYM_NODES_ROUTES, "skimmed", "entry-gateways", "all", @@ -308,7 +355,7 @@ pub trait NymApiClientExt: ApiClient { &[ routes::API_VERSION, "unstable", - "nym-nodes", + routes::NYM_NODES_ROUTES, "skimmed", "mixnodes", "active", @@ -345,7 +392,7 @@ pub trait NymApiClientExt: ApiClient { &[ routes::API_VERSION, "unstable", - "nym-nodes", + routes::NYM_NODES_ROUTES, "skimmed", "mixnodes", "all", @@ -377,7 +424,12 @@ pub trait NymApiClientExt: ApiClient { } self.get_json( - &[routes::API_VERSION, "unstable", "nym-nodes", "skimmed"], + &[ + routes::API_VERSION, + "unstable", + routes::NYM_NODES_ROUTES, + "skimmed", + ], ¶ms, ) .await @@ -686,8 +738,8 @@ pub trait NymApiClientExt: ApiClient { self.get_json( &[ routes::API_VERSION, - "nym-nodes", - "performance", + routes::NYM_NODES_ROUTES, + routes::NYM_NODES_PERFORMANCE, &node_id.to_string(), ], NO_PARAMS, @@ -702,8 +754,8 @@ pub trait NymApiClientExt: ApiClient { self.get_json( &[ routes::API_VERSION, - "nym-nodes", - "annotation", + routes::NYM_NODES_ROUTES, + routes::NYM_NODES_ANNOTATION, &node_id.to_string(), ], NO_PARAMS, @@ -927,7 +979,11 @@ pub trait NymApiClientExt: ApiClient { request: &NodeRefreshBody, ) -> Result<(), NymAPIError> { self.post_json( - &[routes::API_VERSION, "nym-nodes", "refresh-described"], + &[ + routes::API_VERSION, + routes::NYM_NODES_ROUTES, + routes::NYM_NODES_REFRESH_DESCRIBED, + ], NO_PARAMS, request, ) 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 3553d2ed79..ec14678279 100644 --- a/common/client-libs/validator-client/src/nym_api/routes.rs +++ b/common/client-libs/validator-client/src/nym_api/routes.rs @@ -34,6 +34,19 @@ pub mod ecash { pub const EPOCH_ID_PARAM: &str = "epoch_id"; } +pub const NYM_NODES_ROUTES: &str = "nym-nodes"; + +pub use nym_nodes::*; +pub mod nym_nodes { + pub const NYM_NODES_PERFORMANCE_HISTORY: &str = "performance-history"; + pub const NYM_NODES_PERFORMANCE: &str = "performance"; + pub const NYM_NODES_ANNOTATION: &str = "annotation"; + pub const NYM_NODES_DESCRIBED: &str = "described"; + pub const NYM_NODES_BONDED: &str = "bonded"; + pub const NYM_NODES_REWARDED_SET: &str = "rewarded-set"; + pub const NYM_NODES_REFRESH_DESCRIBED: &str = "refresh-described"; +} + pub const STATUS_ROUTES: &str = "status"; pub const API_STATUS_ROUTES: &str = "api-status"; pub const HEALTH: &str = "health";