Merge branch 'develop' into merge/release/2026.10-waterloo

This commit is contained in:
Jędrzej Stuczyński
2026-05-26 09:39:20 +01:00
626 changed files with 63345 additions and 40644 deletions
+7 -4
View File
@@ -5,8 +5,10 @@ use axum::Router;
use axum::extract::ConnectInfo;
use axum::extract::connect_info::IntoMakeServiceWithConnectInfo;
use axum::middleware::AddExtension;
use axum::serve::Serve;
use axum::serve::WithGracefulShutdown;
use std::net::SocketAddr;
use tokio::net::TcpListener;
use tokio_util::sync::WaitForCancellationFutureOwned;
pub use router::{HttpServerConfig, NymNodeRouter, api};
@@ -15,6 +17,7 @@ pub mod helpers;
pub mod router;
pub mod state;
type InnerService = IntoMakeServiceWithConnectInfo<Router, SocketAddr>;
type ConnectInfoExt = AddExtension<Router, ConnectInfo<SocketAddr>>;
pub type NymNodeHttpServer = Serve<InnerService, ConnectInfoExt>;
type MakeService = IntoMakeServiceWithConnectInfo<Router, SocketAddr>;
type InnerService = AddExtension<Router, ConnectInfo<SocketAddr>>;
pub type NymNodeHttpServer =
WithGracefulShutdown<TcpListener, MakeService, InnerService, WaitForCancellationFutureOwned>;
@@ -14,7 +14,7 @@ pub struct Config {
pub(super) fn routes<S: Send + Sync + 'static + Clone>(config: Config) -> Router<S> {
if let Some(assets) = config.assets_path {
Router::new().nest_service("/", ServeDir::new(assets))
Router::new().fallback_service(ServeDir::new(assets))
} else {
Router::new().route("/", get(default))
}
+26 -2
View File
@@ -22,6 +22,7 @@ use nym_node_requests::routes;
use std::net::SocketAddr;
use std::path::Path;
use std::sync::Arc;
use tokio_util::sync::WaitForCancellationFutureOwned;
use zeroize::Zeroizing;
pub mod api;
@@ -176,7 +177,7 @@ impl NymNodeRouter {
Redirect::to(&routes::api::v1::metrics::prometheus_absolute())
}),
)
.nest(routes::LANDING_PAGE, landing_page::routes(config.landing))
.merge(landing_page::routes(config.landing))
.nest(routes::API, api::routes(config.api))
.layer(axum::middleware::from_fn(logging::log_request_info))
.with_state(state),
@@ -186,6 +187,7 @@ impl NymNodeRouter {
pub async fn build_server(
self,
bind_address: &SocketAddr,
shutdown: WaitForCancellationFutureOwned,
) -> Result<NymNodeHttpServer, NymNodeHttpError> {
let listener = tokio::net::TcpListener::bind(bind_address)
.await
@@ -198,6 +200,28 @@ impl NymNodeRouter {
listener,
self.inner
.into_make_service_with_connect_info::<SocketAddr>(),
))
)
.with_graceful_shutdown(shutdown))
}
}
#[cfg(test)]
mod tests {
use super::*;
use nym_crypto::asymmetric::{ed25519, x25519};
use nym_node_requests::api::SignedData;
use nym_node_requests::api::v1::lewes_protocol::models::LewesProtocol;
use nym_test_utils::helpers::deterministic_rng;
use std::collections::BTreeMap;
#[test]
fn router_constructs_without_panic() {
let mut rng = deterministic_rng();
let signing = ed25519::KeyPair::new(&mut rng);
let x25519_pub: x25519::DHPublicKey = x25519::PrivateKey::new(&mut rng).public_key().into();
let lp = LewesProtocol::new(false, 0, 0, x25519_pub, BTreeMap::new());
let signed = SignedData::new(lp, signing.private_key()).unwrap();
let config = HttpServerConfig::new(signed);
let _ = NymNodeRouter::new(config, AppState::dummy());
}
}
+26
View File
@@ -73,4 +73,30 @@ impl AppState {
},
}
}
#[cfg(test)]
pub(crate) fn dummy() -> Self {
use crate::node::key_rotation::key::SphinxPrivateKey;
use rand::rngs::OsRng;
let ed25519_keys = ed25519::KeyPair::new(&mut OsRng);
let attester_pk = *ed25519_keys.public_key();
let static_information = StaticNodeInformation {
ed25519_identity_keys: Arc::new(ed25519_keys),
x25519_versioned_noise_key: None,
ip_addresses: vec![],
hostname: None,
};
let active_sphinx = ActiveSphinxKeys::new_fresh(SphinxPrivateKey::new(&mut OsRng, 0));
AppState::new(
static_information,
active_sphinx,
NymNodeMetrics::new(),
SharedVerlocStats::default(),
Url::parse("https://attestation.test").unwrap(),
UpgradeModeState::new(attester_pk),
Duration::from_secs(60),
)
}
}
@@ -9,8 +9,8 @@ mod tests {
use crate::node::lp::directory::LpNodeDetails;
use crate::node::lp::state::SharedLpNodeControlState;
use anyhow::Context;
use nym_lp::packet::version;
use nym_lp::peer::{LpLocalPeer, LpRemotePeer, mock_peers};
use nym_lp_data::packet::version;
use nym_test_utils::helpers::seeded_rng;
use nym_test_utils::mocks::async_read_write::MockIOStream;
use nym_test_utils::traits::TimeboxedSpawnable;
@@ -6,13 +6,15 @@ use crate::node::lp::control::{LP_DURATION_BUCKETS, LpConnectionStats};
use crate::node::lp::error::LpHandlerError;
use crate::node::lp::state::SharedLpClientControlState;
use dashmap::mapref::one::RefMut;
use nym_lp::packet::frame::LpFrameKind;
use nym_lp::packet::{EncryptedLpPacket, ForwardPacketData, LpFrame};
use nym_lp::peer_config::LpReceiverIndex;
use nym_lp::LpTransportSession;
use nym_lp::session::{LpAction, LpInput};
use nym_lp::transport::LpHandshakeChannel;
use nym_lp::transport::traits::LpTransportChannel;
use nym_lp::{LpTransportSession, packet::frame::ExpectedResponseSize};
use nym_lp_data::packet::frame::LpFrameKind;
use nym_lp_data::packet::header::LpReceiverIndex;
use nym_lp_data::packet::{
EncryptedLpPacket, ForwardPacketData, LpFrame, frame::ExpectedResponseSize,
};
use nym_metrics::{add_histogram_obs, inc};
use nym_node_metrics::NymNodeMetrics;
use nym_registration_common::{LpRegistrationRequest, RegistrationStatus};
+1 -1
View File
@@ -17,7 +17,7 @@
use crate::node::lp::error::LpHandlerError;
use crate::node::lp::state::SharedLpDataState;
use nym_lp::packet::OuterHeader;
use nym_lp_data::packet::OuterHeader;
use nym_metrics::inc;
use std::net::SocketAddr;
use tracing::*;
+2 -3
View File
@@ -1,11 +1,10 @@
// Copyright 2026 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use nym_lp::packet::frame::LpFrameKind;
use nym_lp::peer_config::LpReceiverIndex;
use nym_lp::LpError;
use nym_lp::session::LpAction;
use nym_lp::transport::LpTransportError;
use nym_lp::{LpError, packet::MalformedLpPacketError};
use nym_lp_data::packet::{MalformedLpPacketError, frame::LpFrameKind, header::LpReceiverIndex};
use nym_topology::NodeId;
use std::net::{IpAddr, SocketAddr};
use thiserror::Error;
+1 -1
View File
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::node::lp::state::SharedLpClientControlState;
use nym_lp::peer_config::LpReceiverIndex;
use nym_lp_data::packet::header::LpReceiverIndex;
use nym_metrics::{add_histogram_obs, inc};
use nym_registration_common::dvpn::{
LpDvpnRegistrationFinalisation, LpDvpnRegistrationInitialRequest,
+1 -1
View File
@@ -10,7 +10,7 @@ use dashmap::mapref::one::RefMut;
use nym_gateway::node::wireguard::PeerRegistrator;
use nym_lp::LpTransportSession;
use nym_lp::peer::LpLocalPeer;
use nym_lp::peer_config::LpReceiverIndex;
use nym_lp_data::packet::header::LpReceiverIndex;
use nym_mixnet_client::forwarder::MixForwardingSender;
use nym_node_metrics::NymNodeMetrics;
use std::sync::Arc;
+12 -7
View File
@@ -90,6 +90,7 @@ use std::ops::Deref;
use std::path::Path;
use std::sync::Arc;
use tokio::sync::mpsc;
use tokio_util::sync::WaitForCancellationFutureOwned;
use tracing::{debug, error, info, trace};
use zeroize::Zeroizing;
@@ -890,7 +891,10 @@ impl NymNode {
.collect()
}
pub(crate) async fn build_http_server(&self) -> Result<NymNodeHttpServer, NymNodeError> {
pub(crate) async fn build_http_server(
&self,
shutdown: WaitForCancellationFutureOwned,
) -> Result<NymNodeHttpServer, NymNodeError> {
let auxiliary_details = api_requests::v1::node::models::AuxiliaryDetails {
location: self.config.host.location,
announce_ports: AnnouncePorts {
@@ -1041,7 +1045,7 @@ impl NymNode {
);
Ok(NymNodeRouter::new(config, app_state)
.build_server(&self.config.http.bind_address)
.build_server(&self.config.http.bind_address, shutdown)
.await?)
}
@@ -1414,16 +1418,17 @@ impl NymNode {
debug!("config: {:#?}", self.config);
// ##### START HTTP SERVER #####
let http_server = self.build_http_server().await?;
let bind_address = self.config.http.bind_address;
let server_shutdown = self.shutdown_manager.clone_shutdown_token();
let shutdown = self
.shutdown_manager
.clone_shutdown_token()
.cancelled_owned();
let http_server = self.build_http_server(shutdown).await?;
self.shutdown_manager.try_spawn_named(
async move {
info!("starting NymNodeHTTPServer on {bind_address}");
http_server
.with_graceful_shutdown(async move { server_shutdown.cancelled().await })
.await
http_server.await
},
"HttpApi",
);