Compare commits

...

7 Commits

Author SHA1 Message Date
benedettadavico 09fbbaed49 add mnemonic to ns agent args 2025-07-02 17:28:19 +02:00
Tommy Verrall d6bb0979d0 fix imports
- it was not compiling due to this
2025-06-24 16:12:06 +02:00
Jędrzej Stuczyński fa1d47e941 Bugfix/backwards compat (#5865)
* lowered log severity

* make nodes use legacy encoding for forwarding packets

* note regarding localnet noise
2025-06-19 09:57:46 +01:00
Jędrzej Stuczyński 44ec6d6bc8 bugfix: allow gateways to permit authentication from v4 clients (#5862) 2025-06-18 09:17:54 +01:00
Jędrzej Stuczyński 6d47046a38 fixed client route for obtaining v2 list of gateways (#5859) 2025-06-16 14:32:46 +01:00
Simon Wicky 5cfd09cd99 fix removal of qa env 2025-06-13 10:03:50 +02:00
benedettadavico 40b4670d80 bump versions 2025-06-12 12:21:02 +02:00
29 changed files with 92 additions and 44 deletions
Generated
+7 -7
View File
@@ -4795,7 +4795,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "nym-api"
version = "1.1.60"
version = "1.1.61"
dependencies = [
"anyhow",
"async-trait",
@@ -5084,7 +5084,7 @@ dependencies = [
[[package]]
name = "nym-cli"
version = "1.1.57"
version = "1.1.58"
dependencies = [
"anyhow",
"base64 0.22.1",
@@ -5166,7 +5166,7 @@ dependencies = [
[[package]]
name = "nym-client"
version = "1.1.57"
version = "1.1.58"
dependencies = [
"bs58",
"clap",
@@ -6438,7 +6438,7 @@ dependencies = [
[[package]]
name = "nym-network-requester"
version = "1.1.58"
version = "1.1.59"
dependencies = [
"addr",
"anyhow",
@@ -6488,7 +6488,7 @@ dependencies = [
[[package]]
name = "nym-node"
version = "1.13.0"
version = "1.14.0"
dependencies = [
"anyhow",
"arc-swap",
@@ -7012,7 +7012,7 @@ dependencies = [
[[package]]
name = "nym-socks5-client"
version = "1.1.57"
version = "1.1.58"
dependencies = [
"bs58",
"clap",
@@ -7968,7 +7968,7 @@ dependencies = [
[[package]]
name = "nymvisor"
version = "0.1.22"
version = "0.1.23"
dependencies = [
"anyhow",
"bytes",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.1.57"
version = "1.1.58"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-socks5-client"
version = "1.1.57"
version = "1.1.58"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021"
@@ -124,7 +124,7 @@ impl NymApiTopologyProvider {
// TODO: we really should be getting ACTIVE gateways only
let gateways_fut = self
.validator_client
.get_all_basic_entry_assigned_nodes_v2();
.get_all_basic_entry_assigned_nodes_with_metadata();
let (rewarded_set, mixnodes_res, gateways_res) =
futures::try_join!(rewarded_set_fut, mixnodes_fut, gateways_fut)
+4 -1
View File
@@ -107,7 +107,10 @@ pub async fn gateways_for_init<R: Rng>(
log::debug!("Fetching list of gateways from: {nym_api}");
let gateways = client.get_all_basic_entry_assigned_nodes_v2().await?.nodes;
let gateways = client
.get_all_basic_entry_assigned_nodes_with_metadata()
.await?
.nodes;
info!("nym api reports {} gateways", gateways.len());
log::trace!("Gateways: {:#?}", gateways);
+10 -1
View File
@@ -28,6 +28,7 @@ pub struct Config {
pub maximum_reconnection_backoff: Duration,
pub initial_connection_timeout: Duration,
pub maximum_connection_buffer_size: usize,
pub use_legacy_packet_encoding: bool,
}
impl Config {
@@ -36,12 +37,14 @@ impl Config {
maximum_reconnection_backoff: Duration,
initial_connection_timeout: Duration,
maximum_connection_buffer_size: usize,
use_legacy_packet_encoding: bool,
) -> Self {
Config {
initial_reconnection_backoff,
maximum_reconnection_backoff,
initial_connection_timeout,
maximum_connection_buffer_size,
use_legacy_packet_encoding,
}
}
}
@@ -267,7 +270,12 @@ impl SendWithoutResponse for Client {
fn send_without_response(&self, packet: MixPacket) -> io::Result<()> {
let address = packet.next_hop_address();
trace!("Sending packet to {address}");
let framed_packet = FramedNymPacket::from(packet);
// TODO: optimisation for the future: rather than constantly using legacy encoding,
// once we're addressing by node_id (and thus have full node info here),
// we could simply infer supported encoding based on their version
let framed_packet =
FramedNymPacket::from_mix_packet(packet, self.config.use_legacy_packet_encoding);
let Some(sender) = self.active_connections.get_mut(&address) else {
// there was never a connection to begin with
@@ -328,6 +336,7 @@ mod tests {
maximum_reconnection_backoff: Duration::from_millis(300_000),
initial_connection_timeout: Duration::from_millis(1_500),
maximum_connection_buffer_size: 128,
use_legacy_packet_encoding: false,
},
NoiseConfig::new(
Arc::new(x25519::KeyPair::new(&mut rng)),
@@ -471,12 +471,12 @@ impl NymApiClient {
pub async fn get_all_basic_entry_assigned_nodes(
&self,
) -> Result<Vec<SkimmedNode>, ValidatorClientError> {
self.get_all_basic_entry_assigned_nodes_v2()
self.get_all_basic_entry_assigned_nodes_with_metadata()
.await
.map(|res| res.nodes)
}
pub async fn get_all_basic_entry_assigned_nodes_v2(
pub async fn get_all_basic_entry_assigned_nodes_with_metadata(
&self,
) -> Result<SkimmedNodesWithMetadata, ValidatorClientError> {
collect_paged_skimmed_v2!(self, get_basic_entry_assigned_nodes_v2)
@@ -389,7 +389,6 @@ pub trait NymApiClientExt: ApiClient {
routes::NYM_NODES_ROUTES,
"skimmed",
"entry-gateways",
"all",
],
&params,
)
+2 -1
View File
@@ -131,7 +131,8 @@ impl NoiseConfig {
}
// Only for phased update
//SW This can lead to some troubles if two nodes shares the same IP and one support Noise but not the other. This in only for the progressive update though and there is no workaround
//SW This can lead to some troubles if two nodes share the same IP and one support Noise but not the other.
// This in only for the progressive update though and there is no workaround
pub(crate) fn get_noise_support(&self, ip_addr: IpAddr) -> Option<NoiseVersion> {
let plain_ip_support = self.network.support.inner.load().get(&ip_addr).copied();
+17 -10
View File
@@ -6,7 +6,9 @@ use bytes::{BufMut, BytesMut};
use nym_sphinx_forwarding::packet::MixPacket;
use nym_sphinx_params::key_rotation::SphinxKeyRotation;
use nym_sphinx_params::packet_sizes::PacketSize;
use nym_sphinx_params::packet_version::{PacketVersion, CURRENT_PACKET_VERSION};
use nym_sphinx_params::packet_version::{
PacketVersion, CURRENT_PACKET_VERSION, LEGACY_PACKET_VERSION,
};
use nym_sphinx_params::PacketType;
use nym_sphinx_types::NymPacket;
@@ -19,26 +21,25 @@ pub struct FramedNymPacket {
pub(crate) packet: NymPacket,
}
impl From<MixPacket> for FramedNymPacket {
fn from(packet: MixPacket) -> Self {
let typ = packet.packet_type();
let rot = packet.key_rotation();
FramedNymPacket::new(packet.into_packet(), typ, rot)
}
}
impl FramedNymPacket {
pub fn new(
packet: NymPacket,
packet_type: PacketType,
key_rotation: SphinxKeyRotation,
use_legacy_packet_encoding: bool,
) -> Self {
// If this fails somebody is using the library in a super incorrect way, because they
// already managed to somehow create a sphinx packet
let packet_size = PacketSize::get_type(packet.len()).unwrap();
let packet_version = if use_legacy_packet_encoding {
LEGACY_PACKET_VERSION
} else {
PacketVersion::new()
};
let header = Header {
packet_version: PacketVersion::new(),
packet_version,
packet_size,
key_rotation,
packet_type,
@@ -47,6 +48,12 @@ impl FramedNymPacket {
FramedNymPacket { header, packet }
}
pub fn from_mix_packet(packet: MixPacket, use_legacy_packet_encoding: bool) -> Self {
let typ = packet.packet_type();
let rot = packet.key_rotation();
FramedNymPacket::new(packet.into_packet(), typ, rot, use_legacy_packet_encoding)
}
pub fn header(&self) -> Header {
self.header
}
@@ -10,7 +10,7 @@ use thiserror::Error;
// - packet_version (starting with v1.1.0)
// - packet_size indicator
// - packet_type
// - sphinx key rotation (starting with v1.12.0/v1.13.0 - either Cheddar or Dolcelatte release)
// - sphinx key rotation (starting with v1.13.0 - the Dolcelatte release)
// it also just so happens that the only valid values for packet_size indicator include values 1-6
// therefore if we receive byte `7` (or larger than that) we'll know we received a versioned packet,
@@ -22,6 +22,9 @@ pub const CURRENT_PACKET_VERSION_NUMBER: u8 = KEY_ROTATION_VERSION_NUMBER;
pub const CURRENT_PACKET_VERSION: PacketVersion =
PacketVersion::unchecked(CURRENT_PACKET_VERSION_NUMBER);
pub const LEGACY_PACKET_VERSION: PacketVersion =
PacketVersion::unchecked(INITIAL_PACKET_VERSION_NUMBER);
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct PacketVersion(u8);
+3 -1
View File
@@ -79,7 +79,9 @@ pub async fn current_network_topology_async(
let metadata = mixnodes_res.metadata;
let mixnodes = mixnodes_res.nodes;
let gateways_res = api_client.get_all_basic_entry_assigned_nodes_v2().await?;
let gateways_res = api_client
.get_all_basic_entry_assigned_nodes_with_metadata()
.await?;
if gateways_res.metadata != metadata {
console_warn!("inconsistent nodes metadata between mixnodes and gateways calls! {metadata:?} and {:?}", gateways_res.metadata);
return Err(WasmCoreError::UnavailableNetworkTopology);
@@ -419,6 +419,13 @@ impl<R, S> FreshHandler<R, S> {
return Ok(INITIAL_PROTOCOL_VERSION);
};
// #####
// On backwards compat:
// Currently it is the case that gateways will understand all previous protocol versions
// and will downgrade accordingly, but this will now always be the case.
// For example, once we remove downgrade on legacy auth, anything below version 4 will be rejected
// #####
// a v2 gateway will understand v1 requests, but v1 client will not understand v2 responses
if client_protocol_version == 1 {
return Ok(1);
@@ -434,6 +441,11 @@ impl<R, S> FreshHandler<R, S> {
return Ok(3);
}
// a v5 gateway will understand v4 requests (key-rotation)
if client_protocol_version == 4 {
return Ok(4);
}
// we can't handle clients with higher protocol than ours
// (perhaps we could try to negotiate downgrade on our end? sounds like a nice future improvement)
if client_protocol_version <= CURRENT_PROTOCOL_VERSION {
+1 -1
View File
@@ -4,7 +4,7 @@
[package]
name = "nym-api"
license = "GPL-3.0"
version = "1.1.60"
version = "1.1.61"
authors.workspace = true
edition = "2021"
rust-version.workspace = true
+2 -2
View File
@@ -90,8 +90,8 @@ impl KeyRotationController {
async fn handle_contract_cache_update(&mut self) {
let updated = self.get_contract_data().await;
info!(
"current rotation: {}",
debug!(
"current key rotation: {}",
updated
.key_rotation_state
.key_rotation_id(updated.interval.current_epoch_absolute_id())
@@ -101,7 +101,7 @@ pub(crate) async fn mixnodes_basic_active(
tag = "Unstable Nym Nodes",
get,
params(NodesParams),
path = "/entry-gateways/all",
path = "/entry-gateways",
context_path = "/v2/unstable/nym-nodes/skimmed",
responses(
(status = 200, content(
@@ -124,7 +124,7 @@ pub(crate) async fn entry_gateways_basic_all(
tag = "Unstable Nym Nodes",
get,
params(NodesParams),
path = "/exit-gateways/all",
path = "/exit-gateways",
context_path = "/v2/unstable/nym-nodes/skimmed",
responses(
(status = 200, content(
@@ -21,7 +21,7 @@ export NODE_STATUS_AGENT_SERVER_ADDRESS="http://127.0.0.1"
export NODE_STATUS_AGENT_SERVER_PORT="8000"
export NODE_STATUS_AGENT_PROBE_PATH="$crate_root/nym-gateway-probe"
export NODE_STATUS_AGENT_AUTH_KEY="BjyC9SsHAZUzPRkQR4sPTvVrp4GgaquTh5YfSJksvvWT"
export NODE_STATUS_AGENT_PROBE_EXTRA_ARGS="netstack-download-timeout-sec=30,netstack-num-ping=2,netstack-send-timeout-sec=1,netstack-recv-timeout-sec=1"
export NODE_STATUS_AGENT_PROBE_EXTRA_ARGS="netstack-download-timeout-sec=30,netstack-num-ping=2,netstack-send-timeout-sec=1,netstack-recv-timeout-sec=1,mnemonic=${{ secrets.CANARY_PROBE_MNEMONIC }}"
workers=${1:-1}
echo "Running $workers workers in parallel"
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-node"
version = "1.13.0"
version = "1.14.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
+9
View File
@@ -580,6 +580,13 @@ pub struct MixnetDebug {
/// Maximum number of packets that can be stored waiting to get sent to a particular connection.
pub maximum_connection_buffer_size: usize,
/// Specify whether any framed packets between nodes should use the legacy format (v7)
/// as opposed to the current (v8) one.
/// The legacy format has to be used until sufficient number of nodes on the network has upgraded and understand the new variant.
/// This will allow for optimisations to indicate which [sphinx] key is meant to be used when
/// processing received packets.
pub use_legacy_packet_encoding: bool,
/// Specifies whether this node should **NOT** use noise protocol in the connections (currently not implemented)
pub unsafe_disable_noise: bool,
}
@@ -765,6 +772,8 @@ impl Default for MixnetDebug {
packet_forwarding_maximum_backoff: Self::DEFAULT_PACKET_FORWARDING_MAXIMUM_BACKOFF,
initial_connection_timeout: Self::DEFAULT_INITIAL_CONNECTION_TIMEOUT,
maximum_connection_buffer_size: Self::DEFAULT_MAXIMUM_CONNECTION_BUFFER_SIZE,
// TODO: update this in few releases...
use_legacy_packet_encoding: true,
unsafe_disable_noise: false,
}
}
@@ -1417,6 +1417,7 @@ pub async fn try_upgrade_config_v9<P: AsRef<Path>>(
initial_connection_timeout: old_cfg.mixnet.debug.initial_connection_timeout,
maximum_connection_buffer_size: old_cfg.mixnet.debug.maximum_connection_buffer_size,
unsafe_disable_noise: old_cfg.mixnet.debug.unsafe_disable_noise,
..Default::default()
},
},
storage_paths: NymNodePaths {
+1
View File
@@ -1057,6 +1057,7 @@ impl NymNode {
self.config.mixnet.debug.packet_forwarding_maximum_backoff,
self.config.mixnet.debug.initial_connection_timeout,
self.config.mixnet.debug.maximum_connection_buffer_size,
self.config.mixnet.debug.use_legacy_packet_encoding,
);
let mixnet_client = nym_mixnet_client::Client::new(
mixnet_client_config,
+1
View File
@@ -270,6 +270,7 @@ impl ThroughputTestingClient {
forward_packet,
Default::default(),
self.key_rotation,
false,
))
}
+1 -1
View File
@@ -459,7 +459,7 @@ impl fmt::Display for OptionalValidators {
.as_ref()
.map(|validators| format!(",\nsandbox: [\n{}\n]", validators.iter().format("\n")))
.unwrap_or_default();
write!(f, "{s1}{s2}{s3}")
write!(f, "{s1}{s2}")
}
}
@@ -8,7 +8,7 @@ import { LoadingModal } from 'src/components/Modals/LoadingModal';
import { Results } from 'src/components/TestNode/Results';
import { ErrorModal } from 'src/components/Modals/ErrorModal';
import { PrintResults } from 'src/components/TestNode/PrintResults';
import { MAINNET_VALIDATOR_URL, QA_VALIDATOR_URL } from 'src/constants';
import { MAINNET_VALIDATOR_URL } from 'src/constants';
import { TestStatus } from 'src/components/TestNode/types';
import { isMixnode } from 'src/types';
@@ -63,7 +63,7 @@ export const NodeTestPage = () => {
const loadNodeTestClient = useCallback(async () => {
try {
const nodeTesterId = new Date().toISOString(); // make a new tester id for each session
const validator = network === 'MAINNET' ? MAINNET_VALIDATOR_URL : QA_VALIDATOR_URL;
const validator = network === 'MAINNET' ? MAINNET_VALIDATOR_URL : 'https://rpc.nymtech.net/api/';
const client = await createNodeTesterClient();
await client.tester.init(validator, nodeTesterId);
setNodeTestClient(client);
@@ -48,7 +48,7 @@ impl MyTopologyProvider {
let gateways = self
.validator_client
.get_all_basic_entry_assigned_nodes_v2()
.get_all_basic_entry_assigned_nodes_with_metadata()
.await
.unwrap()
.nodes;
@@ -4,7 +4,7 @@
[package]
name = "nym-network-requester"
license = "GPL-3.0"
version = "1.1.58"
version = "1.1.59"
authors.workspace = true
edition.workspace = true
rust-version = "1.70"
@@ -443,7 +443,7 @@ impl NetworkManager {
));
let id = ctx.nym_node_id(mixnode);
cmds.push(format!(
"{bin_canon_display} -c {env_canon_display} run --id {id} --local"
"{bin_canon_display} -c {env_canon_display} run --id {id} --local --unsafe-disable-noise"
));
}
@@ -454,7 +454,7 @@ impl NetworkManager {
));
let id = ctx.nym_node_id(gateway);
cmds.push(format!(
"{bin_canon_display} -c {env_canon_display} run --id {id} --local"
"{bin_canon_display} -c {env_canon_display} run --id {id} --local --unsafe-disable-noise"
));
}
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-cli"
version = "1.1.57"
version = "1.1.58"
authors.workspace = true
edition = "2021"
license.workspace = true
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nymvisor"
version = "0.1.22"
version = "0.1.23"
authors.workspace = true
repository.workspace = true
homepage.workspace = true