feat: introduce /v3/unstable/nym-nodes/semi-skimmed to aggregate LP information (#6499)

* feat: introduce /v3/unstable/nym-nodes/semi-skimmed to aggregate LP information

nym-nodes will require this information to establish shared PSQ

* reorganised imports
This commit is contained in:
Jędrzej Stuczyński
2026-03-03 14:05:02 +00:00
committed by GitHub
parent 611844b248
commit 6569479083
28 changed files with 311 additions and 114 deletions
@@ -23,7 +23,7 @@ use nym_api_requests::models::{
MixnodeCoreStatusResponse, NymNodeDescriptionV1, NymNodeDescriptionV2,
};
use nym_api_requests::nym_nodes::{
NodesByAddressesResponse, SemiSkimmedNodesWithMetadata, SkimmedNode, SkimmedNodesWithMetadata,
NodesByAddressesResponse, SemiSkimmedNodesWithMetadata, SkimmedNodeV1, SkimmedNodesWithMetadata,
};
use nym_coconut_dkg_common::types::EpochId;
use nym_http_api_client::UserAgent;
@@ -354,12 +354,12 @@ impl NymApiClient {
}
#[deprecated(note = "use get_all_basic_active_mixing_assigned_nodes instead")]
pub async fn get_basic_mixnodes(&self) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
pub async fn get_basic_mixnodes(&self) -> Result<Vec<SkimmedNodeV1>, ValidatorClientError> {
Ok(self.nym_api.get_basic_mixnodes().await?.nodes)
}
#[deprecated(note = "use get_all_basic_entry_assigned_nodes instead")]
pub async fn get_basic_gateways(&self) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
pub async fn get_basic_gateways(&self) -> Result<Vec<SkimmedNodeV1>, ValidatorClientError> {
Ok(self.nym_api.get_basic_gateways().await?.nodes)
}
@@ -372,7 +372,7 @@ impl NymApiClient {
#[deprecated(note = "use get_all_basic_entry_assigned_nodes_with_metadata instead")]
pub async fn get_all_basic_entry_assigned_nodes(
&self,
) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
) -> Result<Vec<SkimmedNodeV1>, ValidatorClientError> {
self.get_all_basic_entry_assigned_nodes_with_metadata()
.await
.map(|res| res.nodes)
@@ -389,7 +389,7 @@ impl NymApiClient {
#[deprecated(note = "use get_all_basic_active_mixing_assigned_nodes_with_metadata instead")]
pub async fn get_all_basic_active_mixing_assigned_nodes(
&self,
) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
) -> Result<Vec<SkimmedNodeV1>, ValidatorClientError> {
self.get_all_basic_active_mixing_assigned_nodes_with_metadata()
.await
.map(|res| res.nodes)
@@ -406,7 +406,7 @@ impl NymApiClient {
#[deprecated(note = "use get_all_basic_mixing_capable_nodes_with_metadata instead")]
pub async fn get_all_basic_mixing_capable_nodes(
&self,
) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
) -> Result<Vec<SkimmedNodeV1>, ValidatorClientError> {
self.get_all_basic_mixing_capable_nodes_with_metadata()
.await
.map(|res| res.nodes)
@@ -420,7 +420,7 @@ impl NymApiClient {
/// retrieve basic information for all bonded nodes on the network
#[deprecated(note = "use get_all_basic_nodes_with_metadata instead")]
pub async fn get_all_basic_nodes(&self) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
pub async fn get_all_basic_nodes(&self) -> Result<Vec<SkimmedNodeV1>, ValidatorClientError> {
self.get_all_basic_nodes_with_metadata()
.await
.map(|res| res.nodes)
@@ -4,6 +4,7 @@
use crate::nym_api::error::NymAPIError;
use crate::nym_api::routes::{ecash, CORE_STATUS_COUNT, SINCE_ARG};
use crate::nym_nodes::SkimmedNodesWithMetadata;
use crate::ValidatorClientError;
use async_trait::async_trait;
use nym_api_requests::ecash::models::{
AggregatedCoinIndicesSignatureResponse, AggregatedExpirationDateSignatureResponse,
@@ -20,11 +21,14 @@ use nym_api_requests::models::{
NymNodeDescriptionV1, NymNodeDescriptionV2, PerformanceHistoryResponse, RewardedSetResponse,
SignerInformationResponse,
};
use nym_api_requests::nym_nodes::{
NodesByAddressesRequestBody, NodesByAddressesResponse, PaginatedCachedNodesResponseV1,
PaginatedCachedNodesResponseV2,
};
use nym_api_requests::pagination::PaginatedResponse;
use nym_http_api_client::{ApiClient, NO_PARAMS};
use nym_mixnet_contract_common::{IdentityKeyRef, NodeId, NymNodeDetails};
use std::net::IpAddr;
use time::format_description::BorrowedFormatItem;
use time::Date;
use tracing::instrument;
pub use nym_api_requests::{
ecash::{
models::SpentCredentialsResponse, BlindSignRequestBody, BlindedSignatureResponse,
@@ -36,17 +40,14 @@ pub use nym_api_requests::{
MixnodeCoreStatusResponse, MixnodeStatusReportResponse, MixnodeStatusResponse,
MixnodeUptimeHistoryResponse, StakeSaturationResponse, UptimeResponse,
},
nym_nodes::{CachedNodesResponse, SemiSkimmedNode, SemiSkimmedNodesWithMetadata, SkimmedNode},
nym_nodes::{
CachedNodesResponse, NodesByAddressesRequestBody, NodesByAddressesResponse,
PaginatedCachedNodesResponseV1, PaginatedCachedNodesResponseV2, SemiSkimmedNodeV1,
SemiSkimmedNodeV3, SemiSkimmedNodesWithMetadata, SkimmedNodeV1,
},
NymNetworkDetailsResponse,
};
use nym_http_api_client::{ApiClient, NO_PARAMS};
use nym_mixnet_contract_common::{IdentityKeyRef, NodeId, NymNodeDetails};
use std::net::IpAddr;
use time::format_description::BorrowedFormatItem;
use time::Date;
use tracing::instrument;
use crate::ValidatorClientError;
pub use nym_coconut_dkg_common::types::EpochId;
pub mod error;
@@ -390,7 +391,7 @@ pub trait NymApiClientExt: ApiClient {
#[deprecated]
#[tracing::instrument(level = "debug", skip_all)]
async fn get_basic_mixnodes(&self) -> Result<CachedNodesResponse<SkimmedNode>, NymAPIError> {
async fn get_basic_mixnodes(&self) -> Result<CachedNodesResponse<SkimmedNodeV1>, NymAPIError> {
self.get_json(
&[
routes::V1_API_VERSION,
@@ -406,7 +407,7 @@ pub trait NymApiClientExt: ApiClient {
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_basic_gateways(&self) -> Result<CachedNodesResponse<SkimmedNode>, NymAPIError> {
async fn get_basic_gateways(&self) -> Result<CachedNodesResponse<SkimmedNodeV1>, NymAPIError> {
self.get_json(
&[
routes::V1_API_VERSION,
@@ -443,7 +444,7 @@ pub trait NymApiClientExt: ApiClient {
page: Option<u32>,
per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponseV1<SkimmedNode>, NymAPIError> {
) -> Result<PaginatedCachedNodesResponseV1<SkimmedNodeV1>, NymAPIError> {
let mut params = Vec::new();
if no_legacy {
@@ -485,7 +486,7 @@ pub trait NymApiClientExt: ApiClient {
page: Option<u32>,
per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponseV2<SkimmedNode>, NymAPIError> {
) -> Result<PaginatedCachedNodesResponseV2<SkimmedNodeV1>, NymAPIError> {
let mut params = Vec::new();
if no_legacy {
@@ -527,7 +528,7 @@ pub trait NymApiClientExt: ApiClient {
page: Option<u32>,
per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponseV1<SkimmedNode>, NymAPIError> {
) -> Result<PaginatedCachedNodesResponseV1<SkimmedNodeV1>, NymAPIError> {
let mut params = Vec::new();
if no_legacy {
@@ -569,7 +570,7 @@ pub trait NymApiClientExt: ApiClient {
page: Option<u32>,
per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponseV2<SkimmedNode>, NymAPIError> {
) -> Result<PaginatedCachedNodesResponseV2<SkimmedNodeV1>, NymAPIError> {
let mut params = Vec::new();
if no_legacy {
@@ -612,7 +613,7 @@ pub trait NymApiClientExt: ApiClient {
page: Option<u32>,
per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponseV1<SkimmedNode>, NymAPIError> {
) -> Result<PaginatedCachedNodesResponseV1<SkimmedNodeV1>, NymAPIError> {
let mut params = Vec::new();
if no_legacy {
@@ -654,7 +655,7 @@ pub trait NymApiClientExt: ApiClient {
page: Option<u32>,
per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponseV2<SkimmedNode>, NymAPIError> {
) -> Result<PaginatedCachedNodesResponseV2<SkimmedNodeV1>, NymAPIError> {
let mut params = Vec::new();
if no_legacy {
@@ -695,7 +696,7 @@ pub trait NymApiClientExt: ApiClient {
page: Option<u32>,
per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponseV1<SkimmedNode>, NymAPIError> {
) -> Result<PaginatedCachedNodesResponseV1<SkimmedNodeV1>, NymAPIError> {
let mut params = Vec::new();
if no_legacy {
@@ -733,7 +734,7 @@ pub trait NymApiClientExt: ApiClient {
page: Option<u32>,
per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponseV2<SkimmedNode>, NymAPIError> {
) -> Result<PaginatedCachedNodesResponseV2<SkimmedNodeV1>, NymAPIError> {
let mut params = Vec::new();
if no_legacy {
@@ -770,7 +771,7 @@ pub trait NymApiClientExt: ApiClient {
no_legacy: bool,
page: Option<u32>,
per_page: Option<u32>,
) -> Result<PaginatedCachedNodesResponseV2<SemiSkimmedNode>, NymAPIError> {
) -> Result<PaginatedCachedNodesResponseV2<SemiSkimmedNodeV1>, NymAPIError> {
let mut params = Vec::new();
if no_legacy {
@@ -797,6 +798,21 @@ pub trait NymApiClientExt: ApiClient {
.await
}
#[instrument(level = "debug", skip(self))]
async fn get_expanded_nodes_v3(
&self,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponseV2<SemiSkimmedNodeV3>, NymAPIError> {
let mut params = Vec::new();
if use_bincode {
params.push(("output", "bincode".to_string()))
}
self.get_response("/v3/unstable/nym-nodes/semi-skimmed", &params)
.await
}
#[deprecated]
#[instrument(level = "debug", skip(self))]
async fn get_mixnode_report(
@@ -3,6 +3,7 @@
pub const V1_API_VERSION: &str = "v1";
pub const V2_API_VERSION: &str = "v2";
pub const V3_API_VERSION: &str = "v3";
pub const MIXNODES: &str = "mixnodes";
pub const GATEWAYS: &str = "gateways";
pub const DESCRIBED: &str = "described";
+1
View File
@@ -1401,6 +1401,7 @@ pub trait ApiClient: ApiClientCore {
/// 'get' data from the segment-defined path, e.g. `["api", "v1", "mixnodes"]`, with tuple
/// defined key-value parameters, e.g. `[("since", "12345")]`. Attempt to parse the response
/// into the provided type `T` based on the content type header
#[instrument(level = "debug", skip_all, fields(path=?path))]
async fn get_response<P, T, K, V>(
&self,
path: P,
+3 -3
View File
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use ::serde::{Deserialize, Serialize};
use nym_api_requests::nym_nodes::SkimmedNode;
use nym_api_requests::nym_nodes::SkimmedNodeV1;
use nym_crypto::asymmetric::ed25519;
use nym_mixnet_contract_common::EpochId;
use nym_sphinx_addressing::nodes::NodeIdentity;
@@ -283,11 +283,11 @@ impl NymTopology {
serde_json::from_reader(file).map_err(Into::into)
}
pub fn add_skimmed_nodes(&mut self, nodes: &[SkimmedNode]) {
pub fn add_skimmed_nodes(&mut self, nodes: &[SkimmedNodeV1]) {
self.add_additional_nodes(nodes.iter())
}
pub fn with_skimmed_nodes(mut self, nodes: &[SkimmedNode]) -> Self {
pub fn with_skimmed_nodes(mut self, nodes: &[SkimmedNodeV1]) -> Self {
self.add_skimmed_nodes(nodes);
self
}
+3 -3
View File
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use nym_api_requests::models::DeclaredRolesV1;
use nym_api_requests::nym_nodes::SkimmedNode;
use nym_api_requests::nym_nodes::SkimmedNodeV1;
use nym_crypto::asymmetric::{ed25519, x25519};
use nym_mixnet_contract_common::NodeId;
use nym_sphinx_addressing::nodes::NymNodeRoutingAddress;
@@ -146,10 +146,10 @@ impl<'a> From<&'a RoutingNode> for SphinxNode {
}
}
impl<'a> TryFrom<&'a SkimmedNode> for RoutingNode {
impl<'a> TryFrom<&'a SkimmedNodeV1> for RoutingNode {
type Error = RoutingNodeError;
fn try_from(value: &'a SkimmedNode) -> Result<Self, Self::Error> {
fn try_from(value: &'a SkimmedNodeV1) -> Result<Self, Self::Error> {
// IF YOU EVER ADD "performance" TO RoutingNode,
// MAKE SURE TO UPDATE THE LAZY IMPLEMENTATION OF
// `impl NodeDescriptionTopologyExt for NymNodeDescription`!!!
@@ -6,7 +6,7 @@ use crate::models::{
HostInformationV1, IpPacketRouterDetailsV1, NetworkRequesterDetailsV1,
OffsetDateTimeJsonSchemaWrapper, WebSocketsV1, WireguardDetailsV1,
};
use crate::nym_nodes::{BasicEntryInformation, NodeRole, SemiSkimmedNode, SkimmedNode};
use crate::nym_nodes::{BasicEntryInformation, NodeRole, SemiSkimmedNodeV1, SkimmedNodeV1};
use nym_crypto::asymmetric::{ed25519, x25519};
use nym_mixnet_contract_common::reward_params::Performance;
use nym_mixnet_contract_common::NodeId;
@@ -76,7 +76,7 @@ impl NymNodeDescriptionV1 {
current_rotation_id: u32,
role: NodeRole,
performance: Performance,
) -> SkimmedNode {
) -> SkimmedNodeV1 {
let keys = &self.description.host_information.keys;
let entry = if self.description.declared_role.entry {
Some(self.entry_information())
@@ -84,7 +84,7 @@ impl NymNodeDescriptionV1 {
None
};
SkimmedNode {
SkimmedNodeV1 {
node_id: self.node_id,
ed25519_identity_pubkey: keys.ed25519,
ip_addresses: self.description.host_information.ip_address.clone(),
@@ -105,10 +105,10 @@ impl NymNodeDescriptionV1 {
current_rotation_id: u32,
role: NodeRole,
performance: Performance,
) -> SemiSkimmedNode {
) -> SemiSkimmedNodeV1 {
let skimmed_node = self.to_skimmed_node(current_rotation_id, role, performance);
SemiSkimmedNode {
SemiSkimmedNodeV1 {
basic: skimmed_node,
x25519_noise_versioned_key: self
.description
@@ -7,7 +7,9 @@ use crate::models::{
LewesProtocolDetailsV1, NetworkRequesterDetailsV1, NymNodeDataV1, NymNodeDescriptionV1,
OffsetDateTimeJsonSchemaWrapper, SphinxKeyV1, WebSocketsV1, WireguardDetailsV1,
};
use crate::nym_nodes::{BasicEntryInformation, NodeRole, SemiSkimmedNode, SkimmedNode};
use crate::nym_nodes::{
BasicEntryInformation, NodeRole, SemiSkimmedNodeV1, SemiSkimmedNodeV3, SkimmedNodeV1,
};
use nym_crypto::asymmetric::{ed25519, x25519};
use nym_mixnet_contract_common::reward_params::Performance;
use nym_mixnet_contract_common::NodeId;
@@ -92,7 +94,7 @@ impl NymNodeDescriptionV2 {
current_rotation_id: u32,
role: NodeRole,
performance: Performance,
) -> SkimmedNode {
) -> SkimmedNodeV1 {
let keys = &self.description.host_information.keys;
let entry = if self.description.declared_role.entry {
Some(self.entry_information())
@@ -100,7 +102,7 @@ impl NymNodeDescriptionV2 {
None
};
SkimmedNode {
SkimmedNodeV1 {
node_id: self.node_id,
ed25519_identity_pubkey: keys.ed25519,
ip_addresses: self.description.host_information.ip_address.clone(),
@@ -121,10 +123,10 @@ impl NymNodeDescriptionV2 {
current_rotation_id: u32,
role: NodeRole,
performance: Performance,
) -> SemiSkimmedNode {
) -> SemiSkimmedNodeV1 {
let skimmed_node = self.to_skimmed_node(current_rotation_id, role, performance);
SemiSkimmedNode {
SemiSkimmedNodeV1 {
basic: skimmed_node,
x25519_noise_versioned_key: self
.description
@@ -133,6 +135,26 @@ impl NymNodeDescriptionV2 {
.x25519_versioned_noise,
}
}
pub fn to_semi_skimmed_node_v3(
&self,
current_rotation_id: u32,
role: NodeRole,
performance: Performance,
) -> SemiSkimmedNodeV3 {
let skimmed_node = self.to_skimmed_node(current_rotation_id, role, performance);
SemiSkimmedNodeV3 {
basic: skimmed_node,
noise_key: self
.description
.host_information
.keys
.x25519_versioned_noise,
build_version: self.description.build_information.build_version.clone(),
lp: self.description.lewes_protocol.clone(),
}
}
}
// to whoever is thinking of modifying this struct.
+28 -12
View File
@@ -1,7 +1,9 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::models::{DeclaredRolesV1, NymNodeDataV1, OffsetDateTimeJsonSchemaWrapper};
use crate::models::{
DeclaredRolesV1, LewesProtocolDetailsV1, NymNodeDataV1, OffsetDateTimeJsonSchemaWrapper,
};
use crate::pagination::{PaginatedResponse, Pagination};
use nym_crypto::asymmetric::ed25519::serde_helpers::bs58_ed25519_pubkey;
use nym_crypto::asymmetric::x25519::serde_helpers::bs58_x25519_pubkey;
@@ -18,24 +20,24 @@ use utoipa::ToSchema;
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, utoipa::ToSchema)]
pub struct SkimmedNodesWithMetadata {
pub nodes: Vec<SkimmedNode>,
pub nodes: Vec<SkimmedNodeV1>,
pub metadata: NodesResponseMetadata,
}
impl SkimmedNodesWithMetadata {
pub fn new(nodes: Vec<SkimmedNode>, metadata: NodesResponseMetadata) -> Self {
pub fn new(nodes: Vec<SkimmedNodeV1>, metadata: NodesResponseMetadata) -> Self {
SkimmedNodesWithMetadata { nodes, metadata }
}
}
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, utoipa::ToSchema)]
pub struct SemiSkimmedNodesWithMetadata {
pub nodes: Vec<SemiSkimmedNode>,
pub nodes: Vec<SemiSkimmedNodeV1>,
pub metadata: NodesResponseMetadata,
}
impl SemiSkimmedNodesWithMetadata {
pub fn new(nodes: Vec<SemiSkimmedNode>, metadata: NodesResponseMetadata) -> Self {
pub fn new(nodes: Vec<SemiSkimmedNodeV1>, metadata: NodesResponseMetadata) -> Self {
SemiSkimmedNodesWithMetadata { nodes, metadata }
}
}
@@ -228,9 +230,7 @@ pub struct BasicEntryInformation {
// the bare minimum information needed to construct sphinx packets
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)]
pub struct SkimmedNode {
// in directory v3 all nodes (mixnodes AND gateways) will have a unique id
// but to keep structure consistent, introduce this field now
pub struct SkimmedNodeV1 {
#[schema(value_type = u32)]
pub node_id: NodeId,
@@ -263,7 +263,7 @@ pub struct SkimmedNode {
pub performance: Performance,
}
impl SkimmedNode {
impl SkimmedNodeV1 {
pub fn get_mix_layer(&self) -> Option<u8> {
match self.role {
NodeRole::Mixnode { layer } => Some(layer),
@@ -275,8 +275,8 @@ impl SkimmedNode {
// an intermediate variant that exposes additional data such as noise keys but without
// the full fat of the self-described data
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)]
pub struct SemiSkimmedNode {
pub basic: SkimmedNode,
pub struct SemiSkimmedNodeV1 {
pub basic: SkimmedNodeV1,
pub x25519_noise_versioned_key: Option<VersionedNoiseKeyV1>,
// pub location:
@@ -284,7 +284,7 @@ pub struct SemiSkimmedNode {
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)]
pub struct FullFatNode {
pub expanded: SemiSkimmedNode,
pub expanded: SemiSkimmedNodeV1,
// kinda temporary for now to make as few changes as possible for now
pub self_described: Option<NymNodeDataV1>,
@@ -301,3 +301,19 @@ pub struct NodesByAddressesResponse {
#[schema(value_type = HashMap<String, Option<u32>>)]
pub existence: HashMap<IpAddr, Option<NodeId>>,
}
/// All the information required for sending packets between nodes (sphinx, noise, LP)
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, ToSchema)]
pub struct SemiSkimmedNodeV3 {
/// Basic node information required for mixnet routing
pub basic: SkimmedNodeV1,
/// Noise key of the node
pub noise_key: Option<VersionedNoiseKeyV1>,
/// Build version of this node used as a hint in inferring the Ciphersuite compatibility
pub build_version: String,
/// Information required for establishing an LP connection
pub lp: Option<LewesProtocolDetailsV1>,
}
+3 -1
View File
@@ -10,6 +10,7 @@ use crate::support::http::openapi::ApiDoc;
use crate::support::http::state::AppState;
use crate::unstable_routes::v1::unstable_routes_v1;
use crate::unstable_routes::v2::unstable_routes_v2;
use crate::unstable_routes::v3::unstable_routes_v3;
use crate::{nym_nodes, status};
use anyhow::anyhow;
use axum::response::Redirect;
@@ -70,7 +71,8 @@ impl RouterBuilder {
Router::new()
.nest("/unstable", unstable_routes_v2())
.nest("/nym-nodes", nym_nodes::handlers::v2::routes()),
);
)
.nest("/v3", Router::new().nest("/unstable", unstable_routes_v3()));
Self {
unfinished_router: default_routes,
+1
View File
@@ -4,3 +4,4 @@
pub(crate) mod helpers;
pub(crate) mod v1;
pub(crate) mod v2;
pub(crate) mod v3;
@@ -5,7 +5,7 @@ use crate::node_status_api::models::{AxumErrorResponse, AxumResult};
use crate::support::http::state::AppState;
use crate::unstable_routes::v1::nym_nodes::helpers::NodesParamsWithRole;
use axum::extract::{Query, State};
use nym_api_requests::nym_nodes::{CachedNodesResponse, SemiSkimmedNode};
use nym_api_requests::nym_nodes::{CachedNodesResponse, SemiSkimmedNodeV1};
use nym_http_api_common::FormattedResponse;
#[utoipa::path(
@@ -22,6 +22,6 @@ use nym_http_api_common::FormattedResponse;
pub(crate) async fn nodes_expanded(
_state: State<AppState>,
_query_params: Query<NodesParamsWithRole>,
) -> AxumResult<FormattedResponse<CachedNodesResponse<SemiSkimmedNode>>> {
) -> AxumResult<FormattedResponse<CachedNodesResponse<SemiSkimmedNodeV1>>> {
Err(AxumErrorResponse::not_implemented())
}
@@ -11,7 +11,7 @@ use crate::unstable_routes::v1::nym_nodes::skimmed::{
PaginatedCachedNodesResponseSchema, PaginatedSkimmedNodes,
};
use axum::extract::{Query, State};
use nym_api_requests::nym_nodes::{CachedNodesResponse, NodeRoleQueryParam, SkimmedNode};
use nym_api_requests::nym_nodes::{CachedNodesResponse, NodeRoleQueryParam, SkimmedNodeV1};
use nym_http_api_common::FormattedResponse;
/// Deprecated query that gets ALL gateways
@@ -23,9 +23,9 @@ use nym_http_api_common::FormattedResponse;
context_path = "/v1/unstable/nym-nodes",
responses(
(status = 200, content(
(CachedNodesResponse<SkimmedNode> = "application/json"),
(CachedNodesResponse<SkimmedNode> = "application/yaml"),
(CachedNodesResponse<SkimmedNode> = "application/bincode")
(CachedNodesResponse<SkimmedNodeV1> = "application/json"),
(CachedNodesResponse<SkimmedNodeV1> = "application/yaml"),
(CachedNodesResponse<SkimmedNodeV1> = "application/bincode")
))
),
)]
@@ -34,7 +34,7 @@ use nym_http_api_common::FormattedResponse;
pub(crate) async fn deprecated_gateways_basic(
state: State<AppState>,
query_params: Query<NodesParams>,
) -> AxumResult<FormattedResponse<CachedNodesResponse<SkimmedNode>>> {
) -> AxumResult<FormattedResponse<CachedNodesResponse<SkimmedNodeV1>>> {
let output = query_params.output.unwrap_or_default();
// 1. call '/v1/unstable/skimmed/entry-gateways/all'
@@ -59,9 +59,9 @@ pub(crate) async fn deprecated_gateways_basic(
context_path = "/v1/unstable/nym-nodes",
responses(
(status = 200, content(
(CachedNodesResponse<SkimmedNode> = "application/json"),
(CachedNodesResponse<SkimmedNode> = "application/yaml"),
(CachedNodesResponse<SkimmedNode> = "application/bincode")
(CachedNodesResponse<SkimmedNodeV1> = "application/json"),
(CachedNodesResponse<SkimmedNodeV1> = "application/yaml"),
(CachedNodesResponse<SkimmedNodeV1> = "application/bincode")
))
),
)]
@@ -70,7 +70,7 @@ pub(crate) async fn deprecated_gateways_basic(
pub(crate) async fn deprecated_mixnodes_basic(
state: State<AppState>,
query_params: Query<NodesParams>,
) -> AxumResult<FormattedResponse<CachedNodesResponse<SkimmedNode>>> {
) -> AxumResult<FormattedResponse<CachedNodesResponse<SkimmedNodeV1>>> {
let output = query_params.output.unwrap_or_default();
// 1. call '/v1/unstable/nym-nodes/skimmed/mixnodes/active'
@@ -3,7 +3,7 @@
use crate::node_status_api::models::AxumResult;
use nym_api_requests::models::OffsetDateTimeJsonSchemaWrapper;
use nym_api_requests::nym_nodes::{PaginatedCachedNodesResponseV1, SkimmedNode};
use nym_api_requests::nym_nodes::{PaginatedCachedNodesResponseV1, SkimmedNodeV1};
use nym_api_requests::pagination::PaginatedResponse;
use nym_http_api_common::FormattedResponse;
use utoipa::ToSchema;
@@ -12,7 +12,7 @@ pub(crate) mod handlers;
pub(crate) mod helpers;
pub type PaginatedSkimmedNodes =
AxumResult<FormattedResponse<PaginatedCachedNodesResponseV1<SkimmedNode>>>;
AxumResult<FormattedResponse<PaginatedCachedNodesResponseV1<SkimmedNodeV1>>>;
pub(crate) use handlers::*;
@@ -21,6 +21,6 @@ pub(crate) use handlers::*;
#[schema(title = "PaginatedCachedNodesResponse")]
pub struct PaginatedCachedNodesResponseSchema {
pub refreshed_at: OffsetDateTimeJsonSchemaWrapper,
#[schema(value_type = SkimmedNode)]
pub nodes: PaginatedResponse<SkimmedNode>,
#[schema(value_type = SkimmedNodeV1)]
pub nodes: PaginatedResponse<SkimmedNodeV1>,
}
@@ -9,7 +9,7 @@ use axum::extract::{Query, State};
use nym_api_requests::models::{
NodeAnnotation, NymNodeDescriptionV2, OffsetDateTimeJsonSchemaWrapper,
};
use nym_api_requests::nym_nodes::{NodeRole, PaginatedCachedNodesResponseV2, SemiSkimmedNode};
use nym_api_requests::nym_nodes::{NodeRole, PaginatedCachedNodesResponseV2, SemiSkimmedNodeV1};
use nym_api_requests::pagination::PaginatedResponse;
use nym_http_api_common::FormattedResponse;
use nym_mixnet_contract_common::NodeId;
@@ -18,7 +18,7 @@ use std::collections::HashMap;
use utoipa::ToSchema;
pub type PaginatedSemiSkimmedNodes =
AxumResult<FormattedResponse<PaginatedCachedNodesResponseV2<SemiSkimmedNode>>>;
AxumResult<FormattedResponse<PaginatedCachedNodesResponseV2<SemiSkimmedNodeV1>>>;
//SW TODO : this is copied from skimmed nodes, surely we can do better than that
fn build_nym_nodes_response<'a, NI>(
@@ -27,7 +27,7 @@ fn build_nym_nodes_response<'a, NI>(
annotations: &HashMap<NodeId, NodeAnnotation>,
current_key_rotation: u32,
active_only: bool,
) -> Vec<SemiSkimmedNode>
) -> Vec<SemiSkimmedNodeV1>
where
NI: Iterator<Item = &'a NymNodeDescriptionV2> + 'a,
{
@@ -57,11 +57,11 @@ where
#[allow(dead_code)] // not dead, used in OpenAPI docs
#[derive(ToSchema)]
#[schema(title = "PaginatedCachedNodesExpandedResponseSchema")]
pub struct PaginatedCachedNodesExpandedResponseSchema {
#[schema(title = "PaginatedCachedNodesExpandedV2ResponseSchema")]
pub struct PaginatedCachedNodesExpandedV2ResponseSchema {
pub refreshed_at: OffsetDateTimeJsonSchemaWrapper,
#[schema(value_type = SemiSkimmedNode)]
pub nodes: PaginatedResponse<SemiSkimmedNode>,
#[schema(value_type = SemiSkimmedNodeV1)]
pub nodes: PaginatedResponse<SemiSkimmedNodeV1>,
}
/// Return all Nym Nodes and optionally legacy mixnodes/gateways (if `no-legacy` flag is not used)
@@ -75,9 +75,9 @@ pub struct PaginatedCachedNodesExpandedResponseSchema {
context_path = "/v2/unstable/nym-nodes/semi-skimmed",
responses(
(status = 200, content(
(PaginatedCachedNodesExpandedResponseSchema = "application/json"),
(PaginatedCachedNodesExpandedResponseSchema = "application/yaml"),
(PaginatedCachedNodesExpandedResponseSchema = "application/bincode")
(PaginatedCachedNodesExpandedV2ResponseSchema = "application/json"),
(PaginatedCachedNodesExpandedV2ResponseSchema = "application/yaml"),
(PaginatedCachedNodesExpandedV2ResponseSchema = "application/bincode")
))
)
)]
@@ -9,7 +9,7 @@ use axum::extract::{Query, State};
use nym_api_requests::models::{
NodeAnnotation, NymNodeDescriptionV2, OffsetDateTimeJsonSchemaWrapper,
};
use nym_api_requests::nym_nodes::{NodeRole, PaginatedCachedNodesResponseV2, SkimmedNode};
use nym_api_requests::nym_nodes::{NodeRole, PaginatedCachedNodesResponseV2, SkimmedNodeV1};
use nym_http_api_common::Output;
use nym_mixnet_contract_common::{Interval, NodeId};
use nym_topology::CachedEpochRewardedSet;
@@ -23,7 +23,7 @@ fn build_nym_nodes_response<'a, NI>(
annotations: &HashMap<NodeId, NodeAnnotation>,
current_key_rotation: u32,
active_only: bool,
) -> Vec<SkimmedNode>
) -> Vec<SkimmedNodeV1>
where
NI: Iterator<Item = &'a NymNodeDescriptionV2> + 'a,
{
@@ -56,7 +56,7 @@ fn maybe_add_expires_header(
interval: Interval,
current_key_rotation: u32,
refreshed_at: OffsetDateTimeJsonSchemaWrapper,
nodes: Vec<SkimmedNode>,
nodes: Vec<SkimmedNodeV1>,
active_only: bool,
) -> PaginatedSkimmedNodes {
let base_response = output.to_response(
@@ -3,7 +3,7 @@
use crate::node_status_api::models::AxumResult;
use nym_api_requests::models::OffsetDateTimeJsonSchemaWrapper;
use nym_api_requests::nym_nodes::{PaginatedCachedNodesResponseV2, SkimmedNode};
use nym_api_requests::nym_nodes::{PaginatedCachedNodesResponseV2, SkimmedNodeV1};
use nym_api_requests::pagination::PaginatedResponse;
use nym_http_api_common::FormattedResponse;
use utoipa::ToSchema;
@@ -12,7 +12,7 @@ pub(crate) mod handlers;
pub(crate) mod helpers;
pub type PaginatedSkimmedNodes =
AxumResult<FormattedResponse<PaginatedCachedNodesResponseV2<SkimmedNode>>>;
AxumResult<FormattedResponse<PaginatedCachedNodesResponseV2<SkimmedNodeV1>>>;
pub(crate) use handlers::*;
@@ -21,6 +21,6 @@ pub(crate) use handlers::*;
#[schema(title = "PaginatedCachedNodesResponse")]
pub struct PaginatedCachedNodesResponseSchema {
pub refreshed_at: OffsetDateTimeJsonSchemaWrapper,
#[schema(value_type = SkimmedNode)]
pub nodes: PaginatedResponse<SkimmedNode>,
#[schema(value_type = SkimmedNodeV1)]
pub nodes: PaginatedResponse<SkimmedNodeV1>,
}
+11
View File
@@ -0,0 +1,11 @@
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::support::http::state::AppState;
use axum::Router;
pub(crate) mod nym_nodes;
pub(crate) fn unstable_routes_v3() -> Router<AppState> {
Router::new().nest("/nym-nodes", nym_nodes::routes())
}
@@ -0,0 +1,19 @@
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::support::http::state::AppState;
use crate::unstable_routes::v3::nym_nodes::semi_skimmed::nodes_expanded;
use axum::routing::get;
use axum::Router;
use tower_http::compression::CompressionLayer;
pub(crate) mod semi_skimmed;
pub(crate) fn routes() -> Router<AppState> {
Router::new()
.nest(
"/semi-skimmed",
Router::new().route("/", get(nodes_expanded)),
)
.layer(CompressionLayer::new())
}
@@ -0,0 +1,108 @@
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::node_status_api::models::AxumResult;
use crate::support::http::state::AppState;
use crate::unstable_routes::helpers::refreshed_at;
use axum::extract::{Query, State};
use nym_api_requests::models::{
NodeAnnotation, NymNodeDescriptionV2, OffsetDateTimeJsonSchemaWrapper,
};
use nym_api_requests::nym_nodes::{NodeRole, PaginatedCachedNodesResponseV2, SemiSkimmedNodeV3};
use nym_api_requests::pagination::PaginatedResponse;
use nym_http_api_common::{FormattedResponse, OutputParams};
use nym_mixnet_contract_common::NodeId;
use nym_topology::CachedEpochRewardedSet;
use std::collections::HashMap;
use utoipa::ToSchema;
pub type PaginatedSemiSkimmedNodes =
AxumResult<FormattedResponse<PaginatedCachedNodesResponseV2<SemiSkimmedNodeV3>>>;
fn build_response<'a>(
rewarded_set: &CachedEpochRewardedSet,
nym_nodes: impl Iterator<Item = &'a NymNodeDescriptionV2>,
annotations: &HashMap<NodeId, NodeAnnotation>,
current_key_rotation: u32,
) -> Vec<SemiSkimmedNodeV3> {
let mut nodes = Vec::new();
for nym_node in nym_nodes {
let node_id = nym_node.node_id;
let role: NodeRole = rewarded_set.role(node_id).into();
// honestly, not sure under what exact circumstances this value could be missing,
// but in that case just use 0 performance
let annotation = annotations.get(&node_id).copied().unwrap_or_default();
nodes.push(nym_node.to_semi_skimmed_node_v3(
current_key_rotation,
role,
annotation.last_24h_performance,
));
}
nodes
}
#[allow(dead_code)] // not dead, used in OpenAPI docs
#[derive(ToSchema)]
#[schema(title = "PaginatedCachedNodesExpandedV3ResponseSchema")]
pub struct PaginatedCachedNodesExpandedV3ResponseSchema {
pub refreshed_at: OffsetDateTimeJsonSchemaWrapper,
#[schema(value_type = SemiSkimmedNodeV3)]
pub nodes: PaginatedResponse<SemiSkimmedNodeV3>,
}
/// Return all Nym Nodes that are currently bonded.
#[utoipa::path(
operation_id = "v3_nodes_expanded",
tag = "Unstable Nym Nodes v3",
get,
params(OutputParams),
path = "/semi-skimmed",
context_path = "/v3/unstable/nym-nodes",
responses(
(status = 200, content(
(PaginatedCachedNodesExpandedV3ResponseSchema = "application/json"),
(PaginatedCachedNodesExpandedV3ResponseSchema = "application/yaml"),
(PaginatedCachedNodesExpandedV3ResponseSchema = "application/bincode")
))
)
)]
pub(super) async fn nodes_expanded(
state: State<AppState>,
Query(output): Query<OutputParams>,
) -> PaginatedSemiSkimmedNodes {
// 1. grab all relevant described nym-nodes
let rewarded_set = state.rewarded_set().await?;
let describe_cache = state.describe_nodes_cache_data().await?;
let all_nym_nodes = describe_cache.all_nym_nodes();
let status_cache = &state.node_status_cache();
let annotations = status_cache.node_annotations().await?;
let contract_cache = state.nym_contract_cache();
let current_key_rotation = contract_cache.current_key_rotation_id().await?;
let interval = contract_cache.current_interval().await?;
let nodes = build_response(
&rewarded_set,
all_nym_nodes,
&annotations,
current_key_rotation,
);
// min of all caches
let refreshed_at = refreshed_at([
rewarded_set.timestamp(),
status_cache.cache_timestamp().await,
describe_cache.timestamp(),
]);
Ok(output.to_response(PaginatedCachedNodesResponseV2::new_full(
interval.current_epoch_absolute_id(),
current_key_rotation,
refreshed_at,
nodes,
)))
}
@@ -10,7 +10,7 @@ use nym_crypto::asymmetric::{ed25519, x25519};
use nym_network_defaults::DEFAULT_NYM_NODE_HTTP_PORT;
use nym_node_requests::api::v1::node::models::NodeDescription;
use nym_validator_client::{
client::NymNodeDetails, models::NymNodeDescriptionV1, nym_api::SkimmedNode,
client::NymNodeDetails, models::NymNodeDescriptionV1, nym_api::SkimmedNodeV1,
};
use serde::{Deserialize, Serialize};
use sqlx::FromRow;
@@ -462,7 +462,7 @@ pub(crate) struct NymNodeInsertRecord {
impl NymNodeInsertRecord {
pub fn new(
skimmed_node: SkimmedNode,
skimmed_node: SkimmedNodeV1,
bond_info: Option<&NymNodeDetails>,
self_described: Option<&NymNodeDescriptionV1>,
) -> anyhow::Result<Self> {
@@ -503,7 +503,7 @@ impl NymNodeInsertRecord {
}
}
impl TryFrom<NymNodeDto> for SkimmedNode {
impl TryFrom<NymNodeDto> for SkimmedNodeV1 {
type Error = anyhow::Error;
fn try_from(other: NymNodeDto) -> Result<Self, Self::Error> {
@@ -517,7 +517,7 @@ impl TryFrom<NymNodeDto> for SkimmedNode {
None => None,
};
let skimmed_node = SkimmedNode {
let skimmed_node = SkimmedNodeV1 {
node_id,
ed25519_identity_pubkey: ed25519::PublicKey::from_base58_string(
other.ed25519_identity_pubkey,
@@ -10,7 +10,7 @@ use crate::{
utils::now_utc,
};
use anyhow::Result;
use nym_validator_client::nym_api::SkimmedNode;
use nym_validator_client::nym_api::SkimmedNodeV1;
pub(crate) async fn get_nodes_for_scraping(pool: &DbPool) -> Result<Vec<ScraperNodeInfo>> {
let mut nodes_to_scrape = Vec::new();
@@ -24,7 +24,7 @@ pub(crate) async fn get_nodes_for_scraping(pool: &DbPool) -> Result<Vec<ScraperN
nodes_dto.into_iter().filter_map(|node_dto| {
let node_id = node_dto.node_id;
let http_api_port = node_dto.http_api_port;
match SkimmedNode::try_from(node_dto) {
match SkimmedNodeV1::try_from(node_dto) {
Ok(node) => Some((node, http_api_port)),
Err(e) => {
tracing::error!("Failed to decode node_id={}: {}", node_id, e);
@@ -141,7 +141,7 @@ mod db_tests {
http_api_port: None,
};
let skimmed_node: nym_validator_client::nym_api::SkimmedNode =
let skimmed_node: nym_validator_client::nym_api::SkimmedNodeV1 =
nym_node_dto.try_into().unwrap();
assert_eq!(skimmed_node.node_id, 1);
@@ -174,7 +174,7 @@ fn test_nym_node_insert_record_new() {
let ed25519_pk = nym_crypto::asymmetric::ed25519::PublicKey::from_bytes(&[1; 32]).unwrap();
let x25519_pk = nym_crypto::asymmetric::x25519::PublicKey::from_bytes(&[2; 32]).unwrap();
let skimmed_node = nym_validator_client::nym_api::SkimmedNode {
let skimmed_node = nym_validator_client::nym_api::SkimmedNodeV1 {
node_id: 1,
ed25519_identity_pubkey: ed25519_pk,
ip_addresses: vec!["1.1.1.1".parse().unwrap()],
@@ -226,7 +226,7 @@ fn test_nym_node_insert_record_with_entry() {
let ed25519_pk = nym_crypto::asymmetric::ed25519::PublicKey::from_bytes(&[1; 32]).unwrap();
let x25519_pk = nym_crypto::asymmetric::x25519::PublicKey::from_bytes(&[2; 32]).unwrap();
let skimmed_node = nym_validator_client::nym_api::SkimmedNode {
let skimmed_node = nym_validator_client::nym_api::SkimmedNodeV1 {
node_id: 1,
ed25519_identity_pubkey: ed25519_pk,
ip_addresses: vec!["1.1.1.1".parse().unwrap()],
@@ -438,7 +438,7 @@ fn test_nym_node_dto_with_invalid_keys() {
http_api_port: None,
};
let result: Result<nym_validator_client::nym_api::SkimmedNode, _> = nym_node_dto.try_into();
let result: Result<nym_validator_client::nym_api::SkimmedNodeV1, _> = nym_node_dto.try_into();
assert!(result.is_err());
assert!(
result
@@ -476,7 +476,7 @@ fn test_nym_node_dto_with_invalid_performance() {
http_api_port: None,
};
let result: Result<nym_validator_client::nym_api::SkimmedNode, _> = nym_node_dto.try_into();
let result: Result<nym_validator_client::nym_api::SkimmedNodeV1, _> = nym_node_dto.try_into();
assert!(result.is_err());
assert!(
result
@@ -12,7 +12,7 @@ use nym_node_requests::api::v1::node::models::NodeDescription;
use nym_validator_client::{
client::NodeId,
models::{AuthenticatorDetailsV1, BinaryBuildInformationOwned, IpPacketRouterDetailsV1},
nym_api::SkimmedNode,
nym_api::SkimmedNodeV1,
nym_nodes::{BasicEntryInformation, NodeRole},
};
use serde::{Deserialize, Serialize};
@@ -139,7 +139,7 @@ impl DVpnGateway {
#[instrument(level = tracing::Level::INFO, name = "dvpn_gw_new", skip_all, fields(gateway_key = gateway.gateway_identity_key, node_id = skimmed_node.node_id))]
pub(crate) fn new(
gateway: Gateway,
skimmed_node: &SkimmedNode,
skimmed_node: &SkimmedNodeV1,
socks5_score: Option<&ScoreValue>,
) -> anyhow::Result<Self> {
let location = gateway
@@ -6,7 +6,7 @@ use nym_contracts_common::NaiveFloat;
use nym_crypto::asymmetric::ed25519::PublicKey;
use nym_mixnet_contract_common::NodeId;
use nym_node_status_client::auth::VerifiableRequest;
use nym_validator_client::nym_api::SkimmedNode;
use nym_validator_client::nym_api::SkimmedNodeV1;
use semver::Version;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, net::IpAddr, sync::Arc, time::Duration};
@@ -304,7 +304,7 @@ impl HttpCache {
Ok(records) => {
let mut nodes = HashMap::new();
for dto in records {
match SkimmedNode::try_from(dto) {
match SkimmedNodeV1::try_from(dto) {
Ok(skimmed_node) => {
let key =
skimmed_node.ed25519_identity_pubkey.to_base58_string();
@@ -671,7 +671,7 @@ async fn aggregate_node_info_from_db(
let skimmed_nodes = queries::get_all_nym_nodes(pool).await.map(|records| {
records
.into_iter()
.filter_map(|dto| SkimmedNode::try_from(dto).ok())
.filter_map(|dto| SkimmedNodeV1::try_from(dto).ok())
.map(|skimmed_node| (skimmed_node.node_id, skimmed_node))
.collect::<HashMap<_, _>>()
})?;
@@ -12,7 +12,7 @@ use moka::future::Cache;
use nym_network_defaults::NymNetworkDetails;
use nym_validator_client::{
QueryHttpRpcNyxdClient,
nym_nodes::{NodeRole, SkimmedNode},
nym_nodes::{NodeRole, SkimmedNodeV1},
};
use nym_validator_client::{
client::{NodeId, NymApiClientExt, NymNodeDetails},
@@ -308,7 +308,7 @@ impl Monitor {
fn prepare_nym_node_data(
&self,
skimmed_nodes: Vec<SkimmedNode>,
skimmed_nodes: Vec<SkimmedNodeV1>,
bonded_node_info: &HashMap<NodeId, NymNodeDetails>,
described_nodes: &HashMap<NodeId, NymNodeDescriptionV1>,
) -> Vec<NymNodeInsertRecord> {
@@ -336,7 +336,7 @@ impl Monitor {
async fn prepare_gateway_data(
&mut self,
described_gateways: &[&NymNodeDescriptionV1],
skimmed_gateways: &[SkimmedNode],
skimmed_gateways: &[SkimmedNodeV1],
bonded_nodes: &HashMap<NodeId, NymNodeDetails>,
) -> anyhow::Result<Vec<GatewayInsertRecord>> {
let mut gateway_records = Vec::new();
+2 -2
View File
@@ -20,7 +20,7 @@ use nym_topology::{
use nym_validator_client::ValidatorClientError;
use nym_validator_client::nym_api::NymApiClientExt;
use nym_validator_client::nym_nodes::{
NodesByAddressesResponse, SemiSkimmedNode, SemiSkimmedNodesWithMetadata,
NodesByAddressesResponse, SemiSkimmedNodeV1, SemiSkimmedNodesWithMetadata,
};
use std::collections::{HashMap, HashSet};
use std::net::{IpAddr, SocketAddr};
@@ -200,7 +200,7 @@ impl CachedNetwork {
struct CachedNetworkInner {
rewarded_set: EpochRewardedSet,
topology_metadata: NymTopologyMetadata,
network_nodes: Vec<SemiSkimmedNode>,
network_nodes: Vec<SemiSkimmedNodeV1>,
}
pub struct NetworkRefresher {
+2 -2
View File
@@ -7,7 +7,7 @@
use anyhow::{anyhow, bail, Context, Result};
use nym_api_requests::models::{LPHashFunction, LPKEM};
use nym_api_requests::nym_nodes::SkimmedNode;
use nym_api_requests::nym_nodes::SkimmedNodeV1;
use nym_crypto::asymmetric::ed25519;
use nym_http_api_client::UserAgent;
use nym_kkt_ciphersuite::{Ciphersuite, KEMKeyDigests, SignatureScheme, KEM};
@@ -189,7 +189,7 @@ impl SpeedtestTopology {
}
/// Extract gateway info for LP connections from a SkimmedNode
fn gateway_info_from_skimmed(node: &SkimmedNode) -> Result<GatewayInfo> {
fn gateway_info_from_skimmed(node: &SkimmedNodeV1) -> Result<GatewayInfo> {
todo!("insufficient information to convert into GatewayInfo")
// let first_ip = node
// .ip_addresses