From f3a449b7cc7456b9606e467d93a83272f348a9f4 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Mon, 6 Oct 2025 14:38:00 +0200 Subject: [PATCH 1/3] bump versions --- Cargo.lock | 16 ++++++++-------- clients/native/Cargo.toml | 2 +- clients/socks5/Cargo.toml | 2 +- nym-api/Cargo.toml | 2 +- nym-node/Cargo.toml | 2 +- service-providers/network-requester/Cargo.toml | 2 +- tools/nym-cli/Cargo.toml | 2 +- tools/nymvisor/Cargo.toml | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc43189a11..2652ebc74e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4787,7 +4787,7 @@ dependencies = [ [[package]] name = "nym-api" -version = "1.1.66" +version = "1.1.67" dependencies = [ "anyhow", "async-trait", @@ -5013,7 +5013,7 @@ dependencies = [ [[package]] name = "nym-cli" -version = "1.1.63" +version = "1.1.64" dependencies = [ "anyhow", "base64 0.22.1", @@ -5096,7 +5096,7 @@ dependencies = [ [[package]] name = "nym-client" -version = "1.1.63" +version = "1.1.64" dependencies = [ "bs58", "clap", @@ -5373,7 +5373,7 @@ dependencies = [ [[package]] name = "nym-credential-proxy" -version = "0.2.0" +version = "0.3.0" dependencies = [ "anyhow", "axum", @@ -6240,7 +6240,7 @@ dependencies = [ [[package]] name = "nym-network-requester" -version = "1.1.64" +version = "1.1.65" dependencies = [ "addr", "anyhow", @@ -6290,7 +6290,7 @@ dependencies = [ [[package]] name = "nym-node" -version = "1.16.0" +version = "1.19.0" dependencies = [ "anyhow", "arc-swap", @@ -6815,7 +6815,7 @@ dependencies = [ [[package]] name = "nym-socks5-client" -version = "1.1.63" +version = "1.1.64" dependencies = [ "bs58", "clap", @@ -7553,7 +7553,7 @@ dependencies = [ [[package]] name = "nymvisor" -version = "0.1.28" +version = "0.1.29" dependencies = [ "anyhow", "bytes", diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 9ac6a9ae3a..c0fb2c0360 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-client" -version = "1.1.63" +version = "1.1.64" authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] description = "Implementation of the Nym Client" edition = "2021" diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index e2ed20d193..07b5a33f66 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-socks5-client" -version = "1.1.63" +version = "1.1.64" authors = ["Dave Hrycyszyn "] description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" edition = "2021" diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 49875a1f6c..43d56f992b 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "nym-api" license = "GPL-3.0" -version = "1.1.66" +version = "1.1.67" authors.workspace = true edition = "2021" rust-version.workspace = true diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index f73e8a2962..1cf019a38c 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node" -version = "1.16.0" +version = "1.19.0" authors.workspace = true repository.workspace = true homepage.workspace = true diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index d13c60bc1f..cc4bdc6221 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "nym-network-requester" license = "GPL-3.0" -version = "1.1.64" +version = "1.1.65" authors.workspace = true edition.workspace = true rust-version = "1.70" diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index 8faf013dad..4757d60b5b 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-cli" -version = "1.1.63" +version = "1.1.64" authors.workspace = true edition = "2021" license.workspace = true diff --git a/tools/nymvisor/Cargo.toml b/tools/nymvisor/Cargo.toml index e1607edab0..330d03cddf 100644 --- a/tools/nymvisor/Cargo.toml +++ b/tools/nymvisor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nymvisor" -version = "0.1.28" +version = "0.1.29" authors.workspace = true repository.workspace = true homepage.workspace = true From df7768dec004fc197511c6102b14dec426634b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 6 Oct 2025 14:02:32 +0100 Subject: [PATCH 2/3] Bugfix/bloomfilters purge (#6089) * remove all old bloomfilters upon starting binary * remove old bloomfilter file upon purging secondary data --- .../node/replay_protection/background_task.rs | 33 ++++++++++------ .../src/node/replay_protection/bloomfilter.rs | 9 +++-- .../src/node/replay_protection/manager.rs | 39 ++++++++++++++++++- 3 files changed, 64 insertions(+), 17 deletions(-) diff --git a/nym-node/src/node/replay_protection/background_task.rs b/nym-node/src/node/replay_protection/background_task.rs index 68092e0208..d47cbd6b82 100644 --- a/nym-node/src/node/replay_protection/background_task.rs +++ b/nym-node/src/node/replay_protection/background_task.rs @@ -1,9 +1,7 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use crate::config::persistence::{ - DEFAULT_RD_BLOOMFILTER_FILE_EXT, DEFAULT_RD_BLOOMFILTER_FLUSH_FILE_EXT, -}; +use crate::config::persistence::DEFAULT_RD_BLOOMFILTER_FLUSH_FILE_EXT; use crate::config::Config; use crate::error::NymNodeError; use crate::node::replay_protection::bloomfilter::RotationFilter; @@ -24,7 +22,6 @@ use tracing::{debug, error, info, trace, warn}; // background task responsible for periodically flushing the bloomfilters to disk pub struct ReplayProtectionDiskFlush { - bloomfilters_directory: PathBuf, disk_flushing_rate: Duration, filters_manager: ReplayProtectionBloomfiltersManager, @@ -124,8 +121,23 @@ impl ReplayProtectionDiskFlush { None }; + // if we have any other stored bloomfilters that are neither primary nor secondary, + // remove them - they are an artifact from an old version that had a bug in purging code + for (rotation_id, path) in filter_files { + if rotation_id == primary_key_rotation_id { + continue; + } + if let Some(secondary_key_rotation_id) = secondary_key_rotation_id { + if secondary_key_rotation_id == rotation_id { + continue; + } + } + info!("stale bloomfilter for rotation {rotation_id} found at: {path:?}. it is going to get removed"); + fs::remove_file(&path) + .map_err(|source| NymNodeError::BloomfilterIoFailure { source, path })?; + } + Ok(ReplayProtectionDiskFlush { - bloomfilters_directory, disk_flushing_rate: config .mixnet .replay_protection @@ -142,15 +154,12 @@ impl ReplayProtectionDiskFlush { } fn bloomfilter_filepath(&self, rotation_id: u32) -> PathBuf { - self.bloomfilters_directory - .join(format!("rot-{rotation_id}")) - .with_extension(DEFAULT_RD_BLOOMFILTER_FILE_EXT) + self.filters_manager.bloomfilter_filepath(rotation_id) } fn current_bloomfilter_being_flushed_filepath(&self, rotation_id: u32) -> PathBuf { - self.bloomfilters_directory - .join(format!("rot-{rotation_id}")) - .with_extension(DEFAULT_RD_BLOOMFILTER_FLUSH_FILE_EXT) + self.filters_manager + .current_bloomfilter_being_flushed_filepath(rotation_id) } pub(crate) fn bloomfilters_manager(&self) -> ReplayProtectionBloomfiltersManager { @@ -213,7 +222,7 @@ impl ReplayProtectionDiskFlush { } async fn flush_filters_to_disk(&self) -> Result<(), NymNodeError> { - if let Some(parent) = self.bloomfilters_directory.parent() { + if let Some(parent) = self.filters_manager.bloomfilters_directory().parent() { fs::create_dir_all(parent).map_err(|source| NymNodeError::BloomfilterIoFailure { source, path: parent.to_path_buf(), diff --git a/nym-node/src/node/replay_protection/bloomfilter.rs b/nym-node/src/node/replay_protection/bloomfilter.rs index 7ae35875cb..96e0dbeab0 100644 --- a/nym-node/src/node/replay_protection/bloomfilter.rs +++ b/nym-node/src/node/replay_protection/bloomfilter.rs @@ -4,6 +4,7 @@ use crate::error::NymNodeError; use bloomfilter::Bloom; use nym_sphinx_types::REPLAY_TAG_SIZE; +use nym_validator_client::models::KeyRotationId; use std::collections::HashMap; use std::fs::File; use std::io::Read; @@ -12,7 +13,6 @@ use std::path::Path; use std::sync::{Arc, Mutex, PoisonError, TryLockError}; use time::OffsetDateTime; use tracing::{error, info, warn}; - // auxiliary data associated with the bloomfilter to get some statistics from the time of its creation // this is needed in order to more accurately resize it upon reset @@ -178,15 +178,16 @@ impl ReplayProtectionBloomfilters { Ok(()) } - pub(crate) fn purge_secondary(&self) -> Result<(), NymNodeError> { + pub(crate) fn purge_secondary(&self) -> Result, NymNodeError> { let mut guard = self .inner .lock() .map_err(|_| NymNodeError::BloomfilterFailure { message: "mutex got poisoned", })?; - guard.overlap = None; - Ok(()) + + let id = guard.overlap.take().map(|f| f.metadata.rotation_id); + Ok(id) } pub(crate) fn primary_metadata( diff --git a/nym-node/src/node/replay_protection/manager.rs b/nym-node/src/node/replay_protection/manager.rs index 56b20d4ea5..920f693951 100644 --- a/nym-node/src/node/replay_protection/manager.rs +++ b/nym-node/src/node/replay_protection/manager.rs @@ -1,6 +1,9 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +use crate::config::persistence::{ + DEFAULT_RD_BLOOMFILTER_FILE_EXT, DEFAULT_RD_BLOOMFILTER_FLUSH_FILE_EXT, +}; use crate::config::Config; use crate::error::NymNodeError; use crate::node::replay_protection::bloomfilter::{ReplayProtectionBloomfilters, RotationFilter}; @@ -8,12 +11,16 @@ use crate::node::replay_protection::items_in_bloomfilter; use human_repr::HumanCount; use nym_node_metrics::NymNodeMetrics; use std::cmp::max; +use std::fs; +use std::path::PathBuf; use std::time::Duration; use time::OffsetDateTime; use tracing::info; #[derive(Clone)] pub(crate) struct ReplayProtectionBloomfiltersManager { + bloomfilters_directory: PathBuf, + target_fp_p: f64, minimum_bloomfilter_packets_per_second: usize, bloomfilter_size_multiplier: f64, @@ -26,6 +33,7 @@ impl ReplayProtectionBloomfiltersManager { pub(crate) fn new_disabled(metrics: NymNodeMetrics) -> Self { // the exact config values are irrelevant as the filters will never be recreated ReplayProtectionBloomfiltersManager { + bloomfilters_directory: Default::default(), target_fp_p: 0.001, minimum_bloomfilter_packets_per_second: 1, bloomfilter_size_multiplier: 1.0, @@ -41,6 +49,12 @@ impl ReplayProtectionBloomfiltersManager { metrics: NymNodeMetrics, ) -> Self { ReplayProtectionBloomfiltersManager { + bloomfilters_directory: config + .mixnet + .replay_protection + .storage_paths + .current_bloomfilters_directory + .clone(), target_fp_p: config.mixnet.replay_protection.debug.false_positive_rate, minimum_bloomfilter_packets_per_second: config .mixnet @@ -57,6 +71,22 @@ impl ReplayProtectionBloomfiltersManager { } } + pub(crate) fn bloomfilters_directory(&self) -> &PathBuf { + &self.bloomfilters_directory + } + + pub(crate) fn bloomfilter_filepath(&self, rotation_id: u32) -> PathBuf { + self.bloomfilters_directory + .join(format!("rot-{rotation_id}")) + .with_extension(DEFAULT_RD_BLOOMFILTER_FILE_EXT) + } + + pub(crate) fn current_bloomfilter_being_flushed_filepath(&self, rotation_id: u32) -> PathBuf { + self.bloomfilters_directory + .join(format!("rot-{rotation_id}")) + .with_extension(DEFAULT_RD_BLOOMFILTER_FLUSH_FILE_EXT) + } + pub(crate) fn bloomfilters(&self) -> ReplayProtectionBloomfilters { self.filters.clone() } @@ -70,7 +100,14 @@ impl ReplayProtectionBloomfiltersManager { } pub(crate) fn purge_secondary(&self) -> Result<(), NymNodeError> { - self.filters.purge_secondary() + // remove data in memory + if let Some(secondary_id) = self.filters.purge_secondary()? { + // remove data on disk (if applicable) + let path = self.bloomfilter_filepath(secondary_id); + fs::remove_file(&path) + .map_err(|source| NymNodeError::BloomfilterIoFailure { source, path })?; + } + Ok(()) } pub(crate) fn promote_pre_announced(&self) -> Result<(), NymNodeError> { From db6defa122ac998ef4026a6d2cb696cc560e1b47 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 14 Oct 2025 12:07:26 +0200 Subject: [PATCH 3/3] update changelog --- CHANGELOG.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f4e602c79..7fe7af3340 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,50 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ## [Unreleased] +## [2025.18-jarlsberg] (2025-10-14) + +- ns-api: add descriptions to dVPN gateway responses ([#6102]) +- NS API: use new probe download filesize and milliseconds field ([#6097]) +- ns-api: use download files size from probes instead of parsing filenames ([#6095]) +- ns-api: add new fields for probe output for query_metadata and download file size and duration in ms ([#6091]) +- Bugfix/bloomfilters purge ([#6089]) +- Hotfix: Update API source in node ping tester script ([#6082]) +- Get wireguard keypair as arg instead of reading it from disk ([#6078]) +- Feature: Ping probe all nodes /described nodes from a server ([#6074]) +- Node Status API: add bridge information to dVPN endpoint ([#6069]) +- frontdoor typo fix ([#6067]) +- Feature: Node rewards tracker ([#6064]) +- [chore] Clippy fix ([#6060]) +- Registration Client ([#6059]) +- Bugfix: Nym node CLI download nym-node exception ([#6058]) +- Feature: Nym node html landing page ([#6053]) +- feat: DKG contract method for updating announce address ([#6050]) +- feat: NS ticket faucet ([#6047]) +- Bridge proto client params in Self-Described ([#6035]) +- Node Status API: remove sqlite support ([#6004]) +- Benny/ci contract fix ([#5962]) + +[#6102]: https://github.com/nymtech/nym/pull/6102 +[#6097]: https://github.com/nymtech/nym/pull/6097 +[#6095]: https://github.com/nymtech/nym/pull/6095 +[#6091]: https://github.com/nymtech/nym/pull/6091 +[#6089]: https://github.com/nymtech/nym/pull/6089 +[#6082]: https://github.com/nymtech/nym/pull/6082 +[#6078]: https://github.com/nymtech/nym/pull/6078 +[#6074]: https://github.com/nymtech/nym/pull/6074 +[#6069]: https://github.com/nymtech/nym/pull/6069 +[#6067]: https://github.com/nymtech/nym/pull/6067 +[#6064]: https://github.com/nymtech/nym/pull/6064 +[#6060]: https://github.com/nymtech/nym/pull/6060 +[#6059]: https://github.com/nymtech/nym/pull/6059 +[#6058]: https://github.com/nymtech/nym/pull/6058 +[#6053]: https://github.com/nymtech/nym/pull/6053 +[#6050]: https://github.com/nymtech/nym/pull/6050 +[#6047]: https://github.com/nymtech/nym/pull/6047 +[#6035]: https://github.com/nymtech/nym/pull/6035 +[#6004]: https://github.com/nymtech/nym/pull/6004 +[#5962]: https://github.com/nymtech/nym/pull/5962 + ## [2025.17-isabirra] (2025-09-29) - Bugfix | Fix the registration handshake ([#6062])