LP: announced KEM key hashes (#6349)
* announce KEM key hashes and use generated value within LpStateMachine * added digest of remote KEM key into LpSession * changed constructor to LpSession to take explicit key materials for local and remote this makes it easier to change keys required by each party without having to change all the interfaces everywhere again * extended the changes to LpStateMachine constructor * modify the interface to LpRegistrationHandler and LpListener * gateway probe fixes * temp nym-lp-client fixes * review nits * remove network test * introduced v2/nym-nodes/described endpoint for returning nodes description alongside LP data * missed V1 -> V2 description replacements * removed deprecated call within mix-fetch * use old v1 call in network stats
This commit is contained in:
committed by
GitHub
parent
7462926bcf
commit
c1ddcc75cf
@@ -1,61 +1,61 @@
|
||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use nym_api_requests::models::{DescribedNodeType, NymNodeData, NymNodeDescription};
|
||||
use nym_api_requests::models::{DescribedNodeTypeV2, NymNodeDataV2, NymNodeDescriptionV2};
|
||||
use nym_mixnet_contract_common::NodeId;
|
||||
use std::collections::HashMap;
|
||||
use std::net::IpAddr;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DescribedNodes {
|
||||
pub(crate) nodes: HashMap<NodeId, NymNodeDescription>,
|
||||
pub(crate) nodes: HashMap<NodeId, NymNodeDescriptionV2>,
|
||||
pub(crate) addresses_cache: HashMap<IpAddr, NodeId>,
|
||||
}
|
||||
|
||||
impl DescribedNodes {
|
||||
pub fn force_update(&mut self, node: NymNodeDescription) {
|
||||
pub fn force_update(&mut self, node: NymNodeDescriptionV2) {
|
||||
for ip in &node.description.host_information.ip_address {
|
||||
self.addresses_cache.insert(*ip, node.node_id);
|
||||
}
|
||||
self.nodes.insert(node.node_id, node);
|
||||
}
|
||||
|
||||
pub fn get_description(&self, node_id: &NodeId) -> Option<&NymNodeData> {
|
||||
pub fn get_description(&self, node_id: &NodeId) -> Option<&NymNodeDataV2> {
|
||||
self.nodes.get(node_id).map(|n| &n.description)
|
||||
}
|
||||
|
||||
pub fn get_node(&self, node_id: &NodeId) -> Option<&NymNodeDescription> {
|
||||
pub fn get_node(&self, node_id: &NodeId) -> Option<&NymNodeDescriptionV2> {
|
||||
self.nodes.get(node_id)
|
||||
}
|
||||
|
||||
pub fn all_nodes(&self) -> impl Iterator<Item = &NymNodeDescription> {
|
||||
pub fn all_nodes(&self) -> impl Iterator<Item = &NymNodeDescriptionV2> {
|
||||
self.nodes.values()
|
||||
}
|
||||
|
||||
pub fn all_nym_nodes(&self) -> impl Iterator<Item = &NymNodeDescription> {
|
||||
pub fn all_nym_nodes(&self) -> impl Iterator<Item = &NymNodeDescriptionV2> {
|
||||
self.nodes
|
||||
.values()
|
||||
.filter(|n| n.contract_node_type == DescribedNodeType::NymNode)
|
||||
.filter(|n| n.contract_node_type == DescribedNodeTypeV2::NymNode)
|
||||
}
|
||||
|
||||
pub fn mixing_nym_nodes(&self) -> impl Iterator<Item = &NymNodeDescription> {
|
||||
pub fn mixing_nym_nodes(&self) -> impl Iterator<Item = &NymNodeDescriptionV2> {
|
||||
self.nodes
|
||||
.values()
|
||||
.filter(|n| n.contract_node_type == DescribedNodeType::NymNode)
|
||||
.filter(|n| n.contract_node_type == DescribedNodeTypeV2::NymNode)
|
||||
.filter(|n| n.description.declared_role.mixnode)
|
||||
}
|
||||
|
||||
pub fn entry_capable_nym_nodes(&self) -> impl Iterator<Item = &NymNodeDescription> {
|
||||
pub fn entry_capable_nym_nodes(&self) -> impl Iterator<Item = &NymNodeDescriptionV2> {
|
||||
self.nodes
|
||||
.values()
|
||||
.filter(|n| n.contract_node_type == DescribedNodeType::NymNode)
|
||||
.filter(|n| n.contract_node_type == DescribedNodeTypeV2::NymNode)
|
||||
.filter(|n| n.description.declared_role.entry)
|
||||
}
|
||||
|
||||
pub fn exit_capable_nym_nodes(&self) -> impl Iterator<Item = &NymNodeDescription> {
|
||||
pub fn exit_capable_nym_nodes(&self) -> impl Iterator<Item = &NymNodeDescriptionV2> {
|
||||
self.nodes
|
||||
.values()
|
||||
.filter(|n| n.contract_node_type == DescribedNodeType::NymNode)
|
||||
.filter(|n| n.contract_node_type == DescribedNodeTypeV2::NymNode)
|
||||
.filter(|n| n.description.declared_role.can_operate_exit_gateway())
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::support::caching::cache::UninitialisedCache;
|
||||
use nym_api_requests::models::NymNodeDescription;
|
||||
use nym_api_requests::models::{NymNodeDescriptionV1, NymNodeDescriptionV2};
|
||||
use nym_config::defaults::DEFAULT_NYM_NODE_HTTP_PORT;
|
||||
use nym_mixnet_contract_common::NodeId;
|
||||
use nym_node_requests::api::client::NymNodeApiClientError;
|
||||
@@ -68,7 +68,19 @@ pub(crate) trait NodeDescriptionTopologyExt {
|
||||
) -> Result<RoutingNode, RoutingNodeError>;
|
||||
}
|
||||
|
||||
impl NodeDescriptionTopologyExt for NymNodeDescription {
|
||||
impl NodeDescriptionTopologyExt for NymNodeDescriptionV1 {
|
||||
fn try_to_topology_node(
|
||||
&self,
|
||||
current_rotation_id: u32,
|
||||
) -> Result<RoutingNode, RoutingNodeError> {
|
||||
// for the purposes of routing, performance is completely ignored,
|
||||
// so add dummy value and piggyback on existing conversion
|
||||
(&self.to_skimmed_node(current_rotation_id, Default::default(), Default::default()))
|
||||
.try_into()
|
||||
}
|
||||
}
|
||||
|
||||
impl NodeDescriptionTopologyExt for NymNodeDescriptionV2 {
|
||||
fn try_to_topology_node(
|
||||
&self,
|
||||
current_rotation_id: u32,
|
||||
|
||||
@@ -5,14 +5,14 @@ use crate::node_describe_cache::NodeDescribeCacheError;
|
||||
use futures::future::{maybe_done, MaybeDone};
|
||||
use futures::{FutureExt, TryFutureExt};
|
||||
use nym_api_requests::models::{
|
||||
AuthenticatorDetails, DeclaredRoles, HostInformation, IpPacketRouterDetails,
|
||||
LewesProtocolDetails, NetworkRequesterDetails, NymNodeData, WebSockets, WireguardDetails,
|
||||
AuthenticatorDetailsV2, AuxiliaryDetailsV2, DeclaredRolesV2, HostInformationV2,
|
||||
IpPacketRouterDetailsV2, LewesProtocolDetailsV1, NetworkRequesterDetailsV2, NymNodeDataV2,
|
||||
WebSocketsV2, WireguardDetailsV2,
|
||||
};
|
||||
use nym_bin_common::build_information::BinaryBuildInformationOwned;
|
||||
use nym_config::defaults::mainnet;
|
||||
use nym_mixnet_contract_common::NodeId;
|
||||
use nym_node_requests::api::client::{NymNodeApiClientError, NymNodeApiClientExt};
|
||||
use nym_node_requests::api::v1::node::models::AuxiliaryDetails;
|
||||
use nym_node_requests::api::Client;
|
||||
use pin_project::pin_project;
|
||||
use std::future::Future;
|
||||
@@ -23,14 +23,14 @@ use tracing::debug;
|
||||
|
||||
async fn network_requester_future(
|
||||
client: &Client,
|
||||
) -> Result<Option<NetworkRequesterDetails>, NymNodeApiClientError> {
|
||||
) -> Result<Option<NetworkRequesterDetailsV2>, NymNodeApiClientError> {
|
||||
let Ok(nr) = client.get_network_requester().await else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
client.get_exit_policy().await.map(|exit_policy| {
|
||||
let uses_nym_exit_policy = exit_policy.upstream_source == mainnet::EXIT_POLICY_URL;
|
||||
Some(NetworkRequesterDetails {
|
||||
Some(NetworkRequesterDetailsV2 {
|
||||
address: nr.address,
|
||||
uses_exit_policy: exit_policy.enabled && uses_nym_exit_policy,
|
||||
})
|
||||
@@ -55,7 +55,8 @@ pub(crate) async fn query_for_described_data(
|
||||
// old nym-nodes will not have this field, so use the default instead
|
||||
debug!("could not obtain auxiliary details of node {node_id}: {err} is it running an old version?")
|
||||
})
|
||||
.unwrap_or_else(|_| AuxiliaryDetails::default()),
|
||||
.ok_into()
|
||||
.unwrap_or_else(|_| AuxiliaryDetailsV2::default()),
|
||||
client.get_mixnet_websockets().ok_into().map_err(map_query_err),
|
||||
network_requester_future(client).map_err(map_query_err),
|
||||
// `ok_into` ultimately calls `IpPacketRouter::into` to transform it into `IpPacketRouterDetails`
|
||||
@@ -112,14 +113,14 @@ impl<F1, F2, F3, F4, F5, F6, F7, F8, F9> Future
|
||||
for NodeDescribedInfoMegaFuture<F1, F2, F3, F4, F5, F6, F7, F8, F9>
|
||||
where
|
||||
F1: Future<Output = Result<BinaryBuildInformationOwned, NodeDescribeCacheError>>,
|
||||
F2: Future<Output = Result<DeclaredRoles, NodeDescribeCacheError>>,
|
||||
F3: Future<Output = AuxiliaryDetails>,
|
||||
F4: Future<Output = Result<WebSockets, NodeDescribeCacheError>>,
|
||||
F5: Future<Output = Result<Option<NetworkRequesterDetails>, NodeDescribeCacheError>>,
|
||||
F6: Future<Output = Option<IpPacketRouterDetails>>,
|
||||
F7: Future<Output = Option<AuthenticatorDetails>>,
|
||||
F8: Future<Output = Option<WireguardDetails>>,
|
||||
F9: Future<Output = Option<LewesProtocolDetails>>,
|
||||
F2: Future<Output = Result<DeclaredRolesV2, NodeDescribeCacheError>>,
|
||||
F3: Future<Output = AuxiliaryDetailsV2>,
|
||||
F4: Future<Output = Result<WebSocketsV2, NodeDescribeCacheError>>,
|
||||
F5: Future<Output = Result<Option<NetworkRequesterDetailsV2>, NodeDescribeCacheError>>,
|
||||
F6: Future<Output = Option<IpPacketRouterDetailsV2>>,
|
||||
F7: Future<Output = Option<AuthenticatorDetailsV2>>,
|
||||
F8: Future<Output = Option<WireguardDetailsV2>>,
|
||||
F9: Future<Output = Option<LewesProtocolDetailsV1>>,
|
||||
{
|
||||
type Output = Result<UnwrappedResolvedNodeDescribedInfo, NodeDescribeCacheError>;
|
||||
|
||||
@@ -202,15 +203,15 @@ where
|
||||
|
||||
struct ResolvedNodeDescribedInfo {
|
||||
build_info: Result<BinaryBuildInformationOwned, NodeDescribeCacheError>,
|
||||
roles: Result<DeclaredRoles, NodeDescribeCacheError>,
|
||||
roles: Result<DeclaredRolesV2, NodeDescribeCacheError>,
|
||||
// TODO: in the future make it return a Result as well.
|
||||
auxiliary_details: AuxiliaryDetails,
|
||||
websockets: Result<WebSockets, NodeDescribeCacheError>,
|
||||
network_requester: Result<Option<NetworkRequesterDetails>, NodeDescribeCacheError>,
|
||||
ipr: Option<IpPacketRouterDetails>,
|
||||
authenticator: Option<AuthenticatorDetails>,
|
||||
wireguard: Option<WireguardDetails>,
|
||||
lewes_protocol: Option<LewesProtocolDetails>,
|
||||
auxiliary_details: AuxiliaryDetailsV2,
|
||||
websockets: Result<WebSocketsV2, NodeDescribeCacheError>,
|
||||
network_requester: Result<Option<NetworkRequesterDetailsV2>, NodeDescribeCacheError>,
|
||||
ipr: Option<IpPacketRouterDetailsV2>,
|
||||
authenticator: Option<AuthenticatorDetailsV2>,
|
||||
wireguard: Option<WireguardDetailsV2>,
|
||||
lewes_protocol: Option<LewesProtocolDetailsV1>,
|
||||
}
|
||||
|
||||
impl ResolvedNodeDescribedInfo {
|
||||
@@ -232,22 +233,22 @@ impl ResolvedNodeDescribedInfo {
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct UnwrappedResolvedNodeDescribedInfo {
|
||||
pub(crate) build_info: BinaryBuildInformationOwned,
|
||||
pub(crate) roles: DeclaredRoles,
|
||||
pub(crate) auxiliary_details: AuxiliaryDetails,
|
||||
pub(crate) websockets: WebSockets,
|
||||
pub(crate) network_requester: Option<NetworkRequesterDetails>,
|
||||
pub(crate) ipr: Option<IpPacketRouterDetails>,
|
||||
pub(crate) authenticator: Option<AuthenticatorDetails>,
|
||||
pub(crate) wireguard: Option<WireguardDetails>,
|
||||
pub(crate) lewes_protocol: Option<LewesProtocolDetails>,
|
||||
pub(crate) roles: DeclaredRolesV2,
|
||||
pub(crate) auxiliary_details: AuxiliaryDetailsV2,
|
||||
pub(crate) websockets: WebSocketsV2,
|
||||
pub(crate) network_requester: Option<NetworkRequesterDetailsV2>,
|
||||
pub(crate) ipr: Option<IpPacketRouterDetailsV2>,
|
||||
pub(crate) authenticator: Option<AuthenticatorDetailsV2>,
|
||||
pub(crate) wireguard: Option<WireguardDetailsV2>,
|
||||
pub(crate) lewes_protocol: Option<LewesProtocolDetailsV1>,
|
||||
}
|
||||
|
||||
impl UnwrappedResolvedNodeDescribedInfo {
|
||||
pub(crate) fn into_node_description(
|
||||
self,
|
||||
host_info: impl Into<HostInformation>,
|
||||
) -> NymNodeData {
|
||||
NymNodeData {
|
||||
host_info: impl Into<HostInformationV2>,
|
||||
) -> NymNodeDataV2 {
|
||||
NymNodeDataV2 {
|
||||
host_information: host_info.into(),
|
||||
last_polled: OffsetDateTime::now_utc().into(),
|
||||
build_information: self.build_info,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
use crate::node_describe_cache::query_helpers::query_for_described_data;
|
||||
use crate::node_describe_cache::NodeDescribeCacheError;
|
||||
use nym_api_requests::models::{DescribedNodeType, NymNodeDescription};
|
||||
use nym_api_requests::models::{DescribedNodeTypeV2, NymNodeDescriptionV2};
|
||||
use nym_bin_common::bin_info;
|
||||
use nym_config::defaults::DEFAULT_NYM_NODE_HTTP_PORT;
|
||||
use nym_crypto::asymmetric::ed25519;
|
||||
@@ -18,7 +18,7 @@ pub(crate) struct RefreshData {
|
||||
host: String,
|
||||
node_id: NodeId,
|
||||
expected_identity: ed25519::PublicKey,
|
||||
node_type: DescribedNodeType,
|
||||
node_type: DescribedNodeTypeV2,
|
||||
|
||||
port: Option<u16>,
|
||||
}
|
||||
@@ -30,7 +30,7 @@ impl<'a> TryFrom<&'a NymNodeDetails> for RefreshData {
|
||||
Ok(RefreshData::new(
|
||||
&node.bond_information.node.host,
|
||||
node.bond_information.identity().parse()?,
|
||||
DescribedNodeType::NymNode,
|
||||
DescribedNodeTypeV2::NymNode,
|
||||
node.node_id(),
|
||||
node.bond_information.node.custom_http_port,
|
||||
))
|
||||
@@ -41,7 +41,7 @@ impl RefreshData {
|
||||
pub fn new(
|
||||
host: impl Into<String>,
|
||||
expected_identity: ed25519::PublicKey,
|
||||
node_type: DescribedNodeType,
|
||||
node_type: DescribedNodeTypeV2,
|
||||
node_id: NodeId,
|
||||
port: Option<u16>,
|
||||
) -> Self {
|
||||
@@ -58,7 +58,7 @@ impl RefreshData {
|
||||
self.node_id
|
||||
}
|
||||
|
||||
pub(crate) async fn try_refresh(self, allow_all_ips: bool) -> Option<NymNodeDescription> {
|
||||
pub(crate) async fn try_refresh(self, allow_all_ips: bool) -> Option<NymNodeDescriptionV2> {
|
||||
match try_get_description(self, allow_all_ips).await {
|
||||
Ok(description) => Some(description),
|
||||
Err(err) => {
|
||||
@@ -124,7 +124,7 @@ async fn try_get_client(
|
||||
async fn try_get_description(
|
||||
data: RefreshData,
|
||||
allow_all_ips: bool,
|
||||
) -> Result<NymNodeDescription, NodeDescribeCacheError> {
|
||||
) -> Result<NymNodeDescriptionV2, NodeDescribeCacheError> {
|
||||
let client = try_get_client(&data.host, data.node_id, data.port).await?;
|
||||
|
||||
let map_query_err = |err| NodeDescribeCacheError::ApiFailure {
|
||||
@@ -158,7 +158,7 @@ async fn try_get_description(
|
||||
let node_info = query_for_described_data(&client, data.node_id).await?;
|
||||
let description = node_info.into_node_description(host_info.data);
|
||||
|
||||
Ok(NymNodeDescription {
|
||||
Ok(NymNodeDescriptionV2 {
|
||||
node_id: data.node_id,
|
||||
contract_node_type: data.node_type,
|
||||
description,
|
||||
|
||||
Reference in New Issue
Block a user