Merge pull request #6536 from nymtech/release/2026.5-raclette
Raclette to develop
This commit is contained in:
@@ -4,6 +4,52 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [2026.5-raclette] (2026-03-10)
|
||||
|
||||
- bugfix: correctly populate gateway probe LP data ([#6533])
|
||||
- chore: introduce additional prometheus metrics for registration times ([#6532])
|
||||
- bugfix: lp information to have proper snake_case on API endpoints ([#6531])
|
||||
- removed redundant LP states ([#6509])
|
||||
- chore: removed all matrix notifications from github actions ([#6495])
|
||||
- feat: Lewes Protocol with PSQv2 ([#6491])
|
||||
- build(deps): bump minimatch from 3.1.2 to 3.1.4 in /documentation/docs ([#6486])
|
||||
- build(deps): bump bn.js from 4.12.2 to 4.12.3 in /documentation/docs ([#6484])
|
||||
- build(deps): bump bn.js from 4.12.2 to 4.12.3 ([#6483])
|
||||
- build(deps): bump ajv from 8.17.1 to 8.18.0 in /clients/native/examples/js-examples/websocket ([#6478])
|
||||
- build(deps): bump ajv from 6.12.6 to 6.14.0 in /documentation/docs ([#6477])
|
||||
- build(deps): bump minimatch and glob in /documentation/scripts/post-process ([#6476])
|
||||
- build(deps): bump hono from 4.11.9 to 4.12.0 ([#6475])
|
||||
- build(deps): bump keccak from 0.1.5 to 0.1.6 ([#6472])
|
||||
- build(deps-dev): bump qs from 6.14.1 to 6.14.2 in /clients/native/examples/js-examples/websocket ([#6466])
|
||||
- build(deps): bump mikefarah/yq from 4.52.2 to 4.52.4 ([#6465])
|
||||
- Otel minimal v2 ([#6464])
|
||||
- build(deps): bump qs and express in /wasm/client/internal-dev ([#6461])
|
||||
- bugfix: restore 'latest_measurement' field for nym-node /verloc endpoint ([#6452])
|
||||
- build(deps-dev): bump webpack from 5.77.0 to 5.104.1 in /wasm/node-tester/internal-dev ([#6451])
|
||||
- Max/mixfetch concurrent test ([#6417])
|
||||
|
||||
[#6533]: https://github.com/nymtech/nym/pull/6533
|
||||
[#6532]: https://github.com/nymtech/nym/pull/6532
|
||||
[#6531]: https://github.com/nymtech/nym/pull/6531
|
||||
[#6509]: https://github.com/nymtech/nym/pull/6509
|
||||
[#6495]: https://github.com/nymtech/nym/pull/6495
|
||||
[#6491]: https://github.com/nymtech/nym/pull/6491
|
||||
[#6486]: https://github.com/nymtech/nym/pull/6486
|
||||
[#6484]: https://github.com/nymtech/nym/pull/6484
|
||||
[#6483]: https://github.com/nymtech/nym/pull/6483
|
||||
[#6478]: https://github.com/nymtech/nym/pull/6478
|
||||
[#6477]: https://github.com/nymtech/nym/pull/6477
|
||||
[#6476]: https://github.com/nymtech/nym/pull/6476
|
||||
[#6475]: https://github.com/nymtech/nym/pull/6475
|
||||
[#6472]: https://github.com/nymtech/nym/pull/6472
|
||||
[#6466]: https://github.com/nymtech/nym/pull/6466
|
||||
[#6465]: https://github.com/nymtech/nym/pull/6465
|
||||
[#6464]: https://github.com/nymtech/nym/pull/6464
|
||||
[#6461]: https://github.com/nymtech/nym/pull/6461
|
||||
[#6452]: https://github.com/nymtech/nym/pull/6452
|
||||
[#6451]: https://github.com/nymtech/nym/pull/6451
|
||||
[#6417]: https://github.com/nymtech/nym/pull/6417
|
||||
|
||||
## [2026.4-quark] (2026-02-24)
|
||||
|
||||
- Enhance CI workflow with feature inputs ([#6462])
|
||||
|
||||
Generated
+1
@@ -6520,6 +6520,7 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"rand 0.9.2",
|
||||
"reqwest 0.13.1",
|
||||
"semver 1.0.26",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"time",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub use crate::ip_pool::IpPair;
|
||||
use crate::ip_pool::allocated_ip_pair;
|
||||
use crate::{
|
||||
IpPool,
|
||||
@@ -23,6 +24,7 @@ use nym_credentials_interface::CredentialSpendingData;
|
||||
use nym_gateway_requests::models::CredentialSpendingRequest;
|
||||
use nym_gateway_storage::traits::BandwidthGatewayStorage;
|
||||
use nym_node_metrics::NymNodeMetrics;
|
||||
use nym_node_metrics::prometheus_wrapper::{PROMETHEUS_METRICS, PrometheusMetric};
|
||||
use nym_wireguard_types::{
|
||||
DEFAULT_IP_CLEANUP_INTERVAL, DEFAULT_IP_STALE_AGE, DEFAULT_PEER_TIMEOUT_CHECK,
|
||||
};
|
||||
@@ -35,8 +37,6 @@ use tokio::sync::{RwLock, mpsc};
|
||||
use tokio_stream::{StreamExt, wrappers::IntervalStream};
|
||||
use tracing::{debug, error, info, trace};
|
||||
|
||||
pub use crate::ip_pool::IpPair;
|
||||
|
||||
#[cfg(feature = "mock")]
|
||||
pub mod mock;
|
||||
|
||||
@@ -261,6 +261,10 @@ impl PeerController {
|
||||
}
|
||||
|
||||
async fn handle_add_request(&mut self, peer: &Peer) -> Result<()> {
|
||||
// observation will get automatically added once dropped
|
||||
let _metric_timer =
|
||||
PROMETHEUS_METRICS.start_timer(PrometheusMetric::WireguardDefguardPeerCreation);
|
||||
|
||||
nym_metrics::inc!("wg_peer_addition_attempts");
|
||||
|
||||
// confirm ip allocation so that it wouldn't be released for as long as the peer exists
|
||||
|
||||
@@ -32,6 +32,7 @@ use nym_crypto::asymmetric::x25519;
|
||||
use nym_gateway_requests::models::CredentialSpendingRequest;
|
||||
use nym_gateway_storage::models::PersistedBandwidth;
|
||||
use nym_lp::peer_config::LpReceiverIndex;
|
||||
use nym_node_metrics::prometheus_wrapper::{PrometheusMetric, PROMETHEUS_METRICS};
|
||||
use nym_registration_common::dvpn::{
|
||||
LpDvpnRegistrationFinalisation, LpDvpnRegistrationInitialRequest,
|
||||
};
|
||||
@@ -126,6 +127,9 @@ impl PeerRegistrator {
|
||||
credential: CredentialSpendingData,
|
||||
client_id: i64,
|
||||
) -> Result<i64, GatewayWireguardError> {
|
||||
let _metric_timer = PROMETHEUS_METRICS
|
||||
.start_timer(PrometheusMetric::PeerRegistrationCredentialVerification);
|
||||
|
||||
let bandwidth = self.credential_storage_preparation(client_id).await?;
|
||||
let client_bandwidth = ClientBandwidth::new(bandwidth.into());
|
||||
let mut verifier = CredentialVerifier::new(
|
||||
@@ -232,6 +236,9 @@ impl PeerRegistrator {
|
||||
request_id: u64,
|
||||
reply_to: Option<Recipient>,
|
||||
) -> Result<SerialisedResponse, GatewayWireguardError> {
|
||||
let _metric_timer = PROMETHEUS_METRICS
|
||||
.start_timer(PrometheusMetric::DvpnAuthenticatorClientRegistrationMsg1);
|
||||
|
||||
let remote_public = init_message.pub_key();
|
||||
|
||||
// 1. check if there's any pending registration already in progress,
|
||||
@@ -269,6 +276,9 @@ impl PeerRegistrator {
|
||||
request_id: u64,
|
||||
reply_to: Option<Recipient>,
|
||||
) -> Result<SerialisedResponse, GatewayWireguardError> {
|
||||
let _metric_timer = PROMETHEUS_METRICS
|
||||
.start_timer(PrometheusMetric::DvpnAuthenticatorClientRegistrationMsg2);
|
||||
|
||||
let peer = final_message.gateway_client_pub_key();
|
||||
// 1. check if there's any pending registration associated with this peer
|
||||
let pending_data = self
|
||||
@@ -312,6 +322,9 @@ impl PeerRegistrator {
|
||||
init_msg: LpDvpnRegistrationInitialRequest,
|
||||
receiver_index: LpReceiverIndex,
|
||||
) -> Result<LpRegistrationResponse, GatewayWireguardError> {
|
||||
let _metric_timer =
|
||||
PROMETHEUS_METRICS.start_timer(PrometheusMetric::DvpnLpClientRegistrationMsg1);
|
||||
|
||||
let remote_public = init_msg.wg_public_key;
|
||||
let psk = Key::new(init_msg.psk);
|
||||
|
||||
@@ -343,6 +356,9 @@ impl PeerRegistrator {
|
||||
final_msg: LpDvpnRegistrationFinalisation,
|
||||
receiver_index: LpReceiverIndex,
|
||||
) -> Result<LpRegistrationResponse, GatewayWireguardError> {
|
||||
let _metric_timer =
|
||||
PROMETHEUS_METRICS.start_timer(PrometheusMetric::DvpnLpClientRegistrationMsg2);
|
||||
|
||||
// 1. check if there's any pending registration associated with this peer
|
||||
let pending_data = self
|
||||
.pending_registrations
|
||||
|
||||
@@ -296,6 +296,7 @@ fn translate_digests(
|
||||
ToSchema,
|
||||
Ord,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
#[non_exhaustive]
|
||||
pub enum LPKEM {
|
||||
@@ -319,6 +320,7 @@ pub enum LPKEM {
|
||||
ToSchema,
|
||||
Ord,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
#[non_exhaustive]
|
||||
pub enum LPHashFunction {
|
||||
@@ -343,6 +345,7 @@ pub enum LPHashFunction {
|
||||
EnumString,
|
||||
ToSchema,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
#[non_exhaustive]
|
||||
pub enum LPSignatureScheme {
|
||||
|
||||
@@ -26,6 +26,7 @@ rand09.workspace = true
|
||||
reqwest = { workspace = true, features = ["socks"] }
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
semver.workspace = true
|
||||
time = { workspace = true }
|
||||
tokio = { workspace = true, features = [
|
||||
"process",
|
||||
|
||||
@@ -12,6 +12,7 @@ use nym_bin_common::build_information::BinaryBuildInformationOwned;
|
||||
use nym_http_api_client::UserAgent;
|
||||
use nym_kkt_ciphersuite::Ciphersuite;
|
||||
use nym_kkt_ciphersuite::{KEM, KEMKeyDigests};
|
||||
use nym_lp::packet::version;
|
||||
use nym_lp::peer::{DHPublicKey, LpRemotePeer};
|
||||
use nym_network_defaults::DEFAULT_NYM_NODE_HTTP_PORT;
|
||||
use nym_node_requests::api::client::NymNodeApiClientExt;
|
||||
@@ -129,16 +130,32 @@ impl DirectoryNode {
|
||||
.copied()
|
||||
.ok_or_else(|| anyhow!("no ip address known"))?;
|
||||
|
||||
// let lp_data = description.lewes_protocol.as_ref().and_then(|lp_data| {
|
||||
// Some(TestedNodeLpDetails {
|
||||
// address: SocketAddr::new(ip_address, lp_data.control_port),
|
||||
// expected_kem_key_hashes: lp_data.kem_keys().ok()?,
|
||||
// expected_signing_key_hashes: lp_data.signing_keys().ok()?,
|
||||
// x25519: lp_data.x25519,
|
||||
// // \/ TODO: proper derivation from build version
|
||||
// lp_version: version::CURRENT,
|
||||
// })
|
||||
// });
|
||||
let identity = self.identity();
|
||||
|
||||
let lp_data = match description.lewes_protocol.as_ref() {
|
||||
Some(lp_data) => {
|
||||
// 1. verify the signature, if it's invalid, completely bail on the node
|
||||
if !lp_data.verify(&identity) {
|
||||
warn!("{identity} provided malformed lp data");
|
||||
bail!("{identity} provided malformed lp data");
|
||||
}
|
||||
|
||||
let version: semver::Version =
|
||||
description.build_information.build_version.parse()?;
|
||||
let Some(ciphersuite) = Ciphersuite::from_node_version(version) else {
|
||||
bail!("failed to identify valid ciphersuite for {identity}");
|
||||
};
|
||||
|
||||
Some(TestedNodeLpDetails {
|
||||
address: SocketAddr::new(ip_address, lp_data.content.control_port),
|
||||
expected_kem_key_hashes: lp_data.content.kem_keys()?,
|
||||
x25519: lp_data.content.x25519,
|
||||
lp_version: version::CURRENT,
|
||||
ciphersuite,
|
||||
})
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
Ok(TestedNodeDetails {
|
||||
identity: self.identity(),
|
||||
@@ -147,7 +164,7 @@ impl DirectoryNode {
|
||||
authenticator_address,
|
||||
authenticator_version,
|
||||
ip_address: Some(ip_address),
|
||||
lp_data: None,
|
||||
lp_data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,18 @@ const CLIENT_SESSION_DURATION_BUCKETS: &[f64] = &[
|
||||
259200., // 72h+ (implicitly)
|
||||
];
|
||||
|
||||
const REG_LATENCY_BUCKETS: &[f64] = &[
|
||||
0.001, // 1ms
|
||||
0.005, // 5ms
|
||||
0.01, // 10ms
|
||||
0.05, // 50ms
|
||||
0.1, // 100ms
|
||||
0.25, // 250ms
|
||||
0.5, // 500ms
|
||||
1.0, // 1s
|
||||
2.0, // 2s
|
||||
];
|
||||
|
||||
#[derive(Clone, Debug, EnumIter, Display, EnumProperty, EnumCount, Eq, Hash, PartialEq)]
|
||||
#[strum(serialize_all = "snake_case", prefix = "nym_node_")]
|
||||
pub enum PrometheusMetric {
|
||||
@@ -139,6 +151,34 @@ pub enum PrometheusMetric {
|
||||
#[strum(props(help = "The current receiving rate of wireguard"))]
|
||||
WireguardBytesRxRate,
|
||||
|
||||
#[strum(props(help = "The distribution of defguard peer creation time"))]
|
||||
WireguardDefguardPeerCreation,
|
||||
|
||||
#[strum(props(
|
||||
help = "The distribution of time it takes to verify a credential during peer registration"
|
||||
))]
|
||||
PeerRegistrationCredentialVerification,
|
||||
|
||||
#[strum(props(
|
||||
help = "The distribution of time for client dvpn registration through the authenticator for msg1"
|
||||
))]
|
||||
DvpnAuthenticatorClientRegistrationMsg1,
|
||||
|
||||
#[strum(props(
|
||||
help = "The distribution of time for client dvpn registration through the authenticator for msg2"
|
||||
))]
|
||||
DvpnAuthenticatorClientRegistrationMsg2,
|
||||
|
||||
#[strum(props(
|
||||
help = "The distribution of time for client dvpn registration through the lp for msg1"
|
||||
))]
|
||||
DvpnLpClientRegistrationMsg1,
|
||||
|
||||
#[strum(props(
|
||||
help = "The distribution of time for client dvpn registration through the lp for msg2"
|
||||
))]
|
||||
DvpnLpClientRegistrationMsg2,
|
||||
|
||||
// # NETWORK
|
||||
#[strum(props(help = "The number of active ingress mixnet connections"))]
|
||||
NetworkActiveIngressMixnetConnections,
|
||||
@@ -271,6 +311,24 @@ impl PrometheusMetric {
|
||||
PrometheusMetric::WireguardActivePeers => Metric::new_int_gauge(&name, help),
|
||||
PrometheusMetric::WireguardBytesTxRate => Metric::new_float_gauge(&name, help),
|
||||
PrometheusMetric::WireguardBytesRxRate => Metric::new_float_gauge(&name, help),
|
||||
PrometheusMetric::WireguardDefguardPeerCreation => {
|
||||
Metric::new_histogram(&name, help, Some(REG_LATENCY_BUCKETS))
|
||||
}
|
||||
PrometheusMetric::DvpnAuthenticatorClientRegistrationMsg1 => {
|
||||
Metric::new_histogram(&name, help, Some(REG_LATENCY_BUCKETS))
|
||||
}
|
||||
PrometheusMetric::DvpnAuthenticatorClientRegistrationMsg2 => {
|
||||
Metric::new_histogram(&name, help, Some(REG_LATENCY_BUCKETS))
|
||||
}
|
||||
PrometheusMetric::DvpnLpClientRegistrationMsg1 => {
|
||||
Metric::new_histogram(&name, help, Some(REG_LATENCY_BUCKETS))
|
||||
}
|
||||
PrometheusMetric::DvpnLpClientRegistrationMsg2 => {
|
||||
Metric::new_histogram(&name, help, Some(REG_LATENCY_BUCKETS))
|
||||
}
|
||||
PrometheusMetric::PeerRegistrationCredentialVerification => {
|
||||
Metric::new_histogram(&name, help, Some(REG_LATENCY_BUCKETS))
|
||||
}
|
||||
PrometheusMetric::NetworkActiveIngressMixnetConnections => {
|
||||
Metric::new_int_gauge(&name, help)
|
||||
}
|
||||
@@ -388,7 +446,7 @@ mod tests {
|
||||
// a sanity check for anyone adding new metrics. if this test fails,
|
||||
// make sure any methods on `PrometheusMetric` enum don't need updating
|
||||
// or require custom Display impl
|
||||
assert_eq!(39, PrometheusMetric::COUNT)
|
||||
assert_eq!(45, PrometheusMetric::COUNT)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -71,6 +71,7 @@ impl LewesProtocol {
|
||||
EnumString,
|
||||
Ord,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
|
||||
pub enum LPKEM {
|
||||
@@ -112,6 +113,7 @@ impl From<nym_kkt_ciphersuite::KEM> for LPKEM {
|
||||
EnumIter,
|
||||
Ord,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
|
||||
pub enum LPHashFunction {
|
||||
@@ -158,6 +160,7 @@ impl From<nym_kkt_ciphersuite::HashFunction> for LPHashFunction {
|
||||
EnumString,
|
||||
EnumIter,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "lowercase")]
|
||||
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
|
||||
pub enum LPSignatureScheme {
|
||||
|
||||
Reference in New Issue
Block a user