From f47650d6c830d695b9a38f848129485a4c29ba79 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Fri, 16 May 2025 13:03:37 +0200 Subject: [PATCH 1/7] bump binary versions --- Cargo.lock | 14 +++++++------- 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, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1a14cd6b2f..b5f58d1dfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4782,7 +4782,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "nym-api" -version = "1.1.57" +version = "1.1.59" dependencies = [ "anyhow", "async-trait", @@ -5036,7 +5036,7 @@ dependencies = [ [[package]] name = "nym-cli" -version = "1.1.55" +version = "1.1.56" dependencies = [ "anyhow", "base64 0.22.1", @@ -5118,7 +5118,7 @@ dependencies = [ [[package]] name = "nym-client" -version = "1.1.55" +version = "1.1.56" dependencies = [ "bs58", "clap", @@ -6122,7 +6122,7 @@ dependencies = [ [[package]] name = "nym-network-requester" -version = "1.1.56" +version = "1.1.57" dependencies = [ "addr", "anyhow", @@ -6172,7 +6172,7 @@ dependencies = [ [[package]] name = "nym-node" -version = "1.11.0" +version = "1.12.0" dependencies = [ "anyhow", "arc-swap", @@ -6568,7 +6568,7 @@ dependencies = [ [[package]] name = "nym-socks5-client" -version = "1.1.55" +version = "1.1.56" dependencies = [ "bs58", "clap", @@ -7173,7 +7173,7 @@ dependencies = [ [[package]] name = "nymvisor" -version = "0.1.20" +version = "0.1.21" dependencies = [ "anyhow", "bytes", diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index e54e982e81..ba75b7a941 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-client" -version = "1.1.55" +version = "1.1.56" 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 43b88ff3dc..8892199070 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-socks5-client" -version = "1.1.55" +version = "1.1.56" 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 f9aa37314d..ef8d255256 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.57" +version = "1.1.59" authors.workspace = true edition = "2021" rust-version.workspace = true diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index 72eb5924eb..8df4774892 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node" -version = "1.11.0" +version = "1.12.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 8c778f0a0f..11f529d789 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.56" +version = "1.1.57" 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 ea3d84e2ce..1560b61cd6 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-cli" -version = "1.1.55" +version = "1.1.56" authors.workspace = true edition = "2021" license.workspace = true diff --git a/tools/nymvisor/Cargo.toml b/tools/nymvisor/Cargo.toml index c71b4b2ed1..ec5377c1e4 100644 --- a/tools/nymvisor/Cargo.toml +++ b/tools/nymvisor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nymvisor" -version = "0.1.20" +version = "0.1.21" authors.workspace = true repository.workspace = true homepage.workspace = true From e98d60d7ce39a3959b4be258e455d67bf302e681 Mon Sep 17 00:00:00 2001 From: dynco-nym <173912580+dynco-nym@users.noreply.github.com> Date: Mon, 19 May 2025 15:18:41 +0200 Subject: [PATCH 2/7] Add node_bonded field to delegations (#5759) * Add node_bonded field to delegations - clarifies whether the delegation is to a bonded or unbonded node - include delegations to unbonded nodes in the returned list * PR feedback --- nym-api/src/unstable_routes/account/cache.rs | 10 +- .../unstable_routes/account/data_collector.rs | 132 +++++++++++------- nym-api/src/unstable_routes/models.rs | 4 + 3 files changed, 87 insertions(+), 59 deletions(-) diff --git a/nym-api/src/unstable_routes/account/cache.rs b/nym-api/src/unstable_routes/account/cache.rs index 261018962a..a60a13abb0 100644 --- a/nym-api/src/unstable_routes/account/cache.rs +++ b/nym-api/src/unstable_routes/account/cache.rs @@ -108,13 +108,13 @@ impl AddressInfoCache { address: account_id.to_string(), balance: balance.into(), delegations: delegation_data - .delegations() .into_iter() .map(|d| NyxAccountDelegationDetails { - delegated: d.amount, - height: d.height, - node_id: d.node_id, - proxy: d.proxy, + delegated: d.details().amount.clone(), + height: d.details().height, + node_id: d.details().node_id, + proxy: d.details().proxy.clone(), + node_bonded: d.is_node_bonded(), }) .collect(), accumulated_rewards, diff --git a/nym-api/src/unstable_routes/account/data_collector.rs b/nym-api/src/unstable_routes/account/data_collector.rs index f9829b29a8..d2c780d0fb 100644 --- a/nym-api/src/unstable_routes/account/data_collector.rs +++ b/nym-api/src/unstable_routes/account/data_collector.rs @@ -8,10 +8,9 @@ use crate::{ }; use cosmwasm_std::{Coin, Decimal}; use nym_mixnet_contract_common::NodeRewarding; -use nym_topology::NodeId; use nym_validator_client::nyxd::AccountId; use std::collections::{HashMap, HashSet}; -use tracing::warn; +use tracing::error; pub(crate) struct AddressDataCollector { nyxd_client: crate::nyxd::Client, @@ -56,18 +55,18 @@ impl AddressDataCollector { Ok(balance) } - pub(crate) async fn get_delegations(&mut self) -> AxumResult { + pub(crate) async fn get_delegations(&mut self) -> AxumResult> { let og_delegations = self .nyxd_client .get_all_delegator_delegations(&self.account_id) - .await?; + .await? + .into_iter() + .map(|delegation| (delegation.node_id, delegation)) + .collect::>(); - let delegated_to_nodes = og_delegations - .iter() - .map(|d| d.node_id) - .collect::>(); + let mut node_delegation_info = Vec::new(); - let nym_nodes = self + let delegated_to_nodes_bonded = self .nym_contract_cache .all_cached_nym_nodes() .await @@ -85,61 +84,75 @@ impl AddressDataCollector { // add to totals self.total_value += pending_operator_reward; } - if delegated_to_nodes.contains(&node_details.node_id()) { - Some(( - node_details.node_id(), - // avoid cloning node data which we don't need - ( - node_details.rewarding_details.clone(), - node_details.is_unbonding(), - ), - )) + if let Some(delegation) = og_delegations.get(&node_details.node_id()) { + node_delegation_info.push(AddressDelegationInfo { + details: delegation.clone(), + node_reward_info: NodeBondStatus::Bonded { + rewarding_info: node_details.rewarding_details.to_owned(), + unbonding: node_details.is_unbonding(), + }, + }); + + Some(node_details.node_id()) } else { None } }) - .collect::>(); + .collect::>(); - Ok(AddressDelegationInfo { - delegations: og_delegations, - delegated_to_nodes: nym_nodes, - }) + for (node_id, delegation) in og_delegations { + if !delegated_to_nodes_bonded.contains(&node_id) { + node_delegation_info.push(AddressDelegationInfo { + details: delegation.clone(), + node_reward_info: NodeBondStatus::UnBonded, + }); + } + } + + Ok(node_delegation_info) } pub(crate) async fn calculate_rewards( &mut self, - delegation_data: &AddressDelegationInfo, + delegation_data: &Vec, ) -> AxumResult> { let mut accumulated_rewards = Vec::new(); - for delegation in delegation_data.delegations.iter() { - let node_id = &delegation.node_id; + for delegation in delegation_data { + let node_id = delegation.details.node_id; - if let Some((rewarding_details, is_unbonding)) = - delegation_data.delegated_to_nodes.get(node_id) - { - match rewarding_details.determine_delegation_reward(delegation) { - Ok(delegation_reward) => { - let reward = NyxAccountDelegationRewardDetails { - node_id: delegation.node_id, - rewards: decimal_to_coin(delegation_reward, &self.base_denom), - amount_staked: delegation.amount.clone(), - node_still_fully_bonded: !is_unbonding, - }; - // 4. sum the rewards and delegations - self.total_delegations += delegation.amount.amount.u128(); - self.total_value += delegation.amount.amount.u128(); - self.total_value += reward.rewards.amount.u128(); - self.claimable_rewards += reward.rewards.amount.u128(); + match &delegation.node_reward_info { + NodeBondStatus::Bonded { + rewarding_info, + unbonding, + } => { + match rewarding_info.determine_delegation_reward(&delegation.details) { + Ok(delegation_reward) => { + let reward = NyxAccountDelegationRewardDetails { + node_id, + rewards: decimal_to_coin(delegation_reward, &self.base_denom), + amount_staked: delegation.details.amount.clone(), + node_still_fully_bonded: !unbonding, + }; + // 4. sum the rewards and delegations + self.total_delegations += delegation.details.amount.amount.u128(); + self.total_value += delegation.details.amount.amount.u128(); + self.total_value += reward.rewards.amount.u128(); + self.claimable_rewards += reward.rewards.amount.u128(); - accumulated_rewards.push(reward); - } - Err(err) => { - warn!( - "Couldn't determine delegations for {} on node {}: {}", - &self.account_id, node_id, err - ) + accumulated_rewards.push(reward); + } + Err(err) => { + error!( + "Couldn't determine delegations for {} on node {}: {}", + &self.account_id, node_id, err + ) + } } } + NodeBondStatus::UnBonded => { + // directory cache doesn't store node details required to + // calculate rewarding for unbonded nodes + } } } @@ -171,17 +184,27 @@ impl AddressDataCollector { } pub(crate) struct AddressDelegationInfo { - delegations: Vec, - delegated_to_nodes: HashMap, + details: nym_mixnet_contract_common::Delegation, + node_reward_info: NodeBondStatus, } impl AddressDelegationInfo { - pub(crate) fn delegations(self) -> Vec { - self.delegations + pub(crate) fn details(&self) -> &nym_mixnet_contract_common::Delegation { + &self.details + } + + pub(crate) fn is_node_bonded(&self) -> bool { + matches!(self.node_reward_info, NodeBondStatus::Bonded { .. }) } } -type RewardAndBondInfo = (NodeRewarding, bool); +pub(crate) enum NodeBondStatus { + Bonded { + rewarding_info: NodeRewarding, + unbonding: bool, + }, + UnBonded, +} fn decimal_to_coin(decimal: Decimal, denom: impl Into) -> Coin { Coin::new(decimal.to_uint_floor(), denom) @@ -189,6 +212,7 @@ fn decimal_to_coin(decimal: Decimal, denom: impl Into) -> Coin { #[cfg(test)] mod test { + use super::*; #[tokio::test] diff --git a/nym-api/src/unstable_routes/models.rs b/nym-api/src/unstable_routes/models.rs index 9864f19a42..1d802f8aa0 100644 --- a/nym-api/src/unstable_routes/models.rs +++ b/nym-api/src/unstable_routes/models.rs @@ -21,6 +21,7 @@ pub struct NyxAccountDelegationDetails { pub height: u64, #[schema(value_type = Option)] pub proxy: Option, + pub node_bonded: bool, } #[derive(Clone, Debug, Serialize, Deserialize, utoipa::ToSchema, utoipa::ToResponse)] @@ -41,6 +42,9 @@ pub struct NyxAccountDetails { #[schema(value_type = CoinSchema)] pub total_value: Coin, pub delegations: Vec, + /// Shows rewards from delegations to **currently** bonded nodes. + /// Rewards from nodes that user delegated to, but were later unbonded, + /// are claimable, but not shown here. pub accumulated_rewards: Vec, #[schema(value_type = String)] pub total_delegations: Coin, From d7383d74f373922a4bbc1a2620942eecb1f08d5d Mon Sep 17 00:00:00 2001 From: jmwample Date: Fri, 16 May 2025 10:12:38 -0600 Subject: [PATCH 3/7] more relaxed usage of reqwest accept-encoding --- common/http-api-client/Cargo.toml | 2 +- common/http-api-client/src/lib.rs | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/common/http-api-client/Cargo.toml b/common/http-api-client/Cargo.toml index 65332a01a7..8d32367d27 100644 --- a/common/http-api-client/Cargo.toml +++ b/common/http-api-client/Cargo.toml @@ -13,7 +13,7 @@ license.workspace = true [dependencies] async-trait = { workspace = true } bincode = { workspace = true } -reqwest = { workspace = true, features = ["json", "gzip"] } +reqwest = { workspace = true, features = ["json", "gzip", "deflate", "brotli", "zstd"] } http.workspace = true url = { workspace = true } once_cell = { workspace = true } diff --git a/common/http-api-client/src/lib.rs b/common/http-api-client/src/lib.rs index 2e0246bf0b..f1068bb562 100644 --- a/common/http-api-client/src/lib.rs +++ b/common/http-api-client/src/lib.rs @@ -288,14 +288,18 @@ impl ClientBuilder { #[cfg(not(target_arch = "wasm32"))] let reqwest_client_builder = { - let r = reqwest::ClientBuilder::new(); - - // Note this is extra as the `gzip` feature for `reqwest` crate should be enabled which - // `"Enable[s] auto gzip decompression by checking the Content-Encoding response header."` + // Note: I believe the manual enable calls for the compression methods are extra + // as the various compression features for `reqwest` crate should be enabled + // just by including the feature which: + // `"Enable[s] auto decompression by checking the Content-Encoding response header."` // - // I am going to leave it here anyways so that gzip decompression is attempted even if - // that feature is removed. - r.gzip(true) + // I am going to leave these here anyways so that removing a decompression method + // from the features list will throw an error if it is not also removed here. + reqwest::ClientBuilder::new() + .gzip(true) + .deflate(true) + .brotli(true) + .zstd(true) }; ClientBuilder { @@ -559,11 +563,6 @@ impl ApiClientCore for Client { let mut request = self.reqwest_client.request(method.clone(), url); - // Indicate that compressed responses are preferred, but if not supported other encodings are fine. - // TODO: Down the road we can be more selective about adding this, but it's inclusion here guarantees - // that we use compression when available. - request = request.header(reqwest::header::ACCEPT_ENCODING, "gzip;q=1.0, *;q=0.5"); - if let Some(body) = json_body { request = request.json(body); } From 5369e5eab98d09ce0d3469f2c847f3d140488d74 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 27 May 2025 10:03:22 +0200 Subject: [PATCH 4/7] update changelog --- CHANGELOG.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 812ccd617b..d7b686a06f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,58 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ## [Unreleased] +## [2025.10-brie] (2025-05-27) + +- Backport PR 5779 ([#5801]) +- Expanded Accept Encoding for `reqwest` ([#5779]) +- Teach HttpClientError how to report its status code and timeout ([#5770]) +- Skip refreshing the topology on startup as we already have an initial set ([#5768]) +- Fetch the topology from the nym-api concurrently ([#5767]) +- feat: use bincode by default in NymApiClient + remove feature-lock ([#5761]) +- Instrument create_request ([#5760]) +- Add node_bonded field to delegations ([#5759]) +- build(deps): bump mikefarah/yq from 4.45.1 to 4.45.4 ([#5758]) +- Raw route submissions ([#5756]) +- feat: expires header for `/active` nym-api responses ([#5755]) +- Decrease default average packet delay to 15 ms ([#5754]) +- build(deps): bump the patch-updates group across 1 directory with 12 updates ([#5753]) +- Remove pretty_env_logger and switch remaining crates to use tracing ([#5749]) +- Update pretty_env_logger to latest to not depend on unmaintained crate atty ([#5748]) +- Upgrade prometheus crate to fix security warning ([#5747]) +- Downgrade deranged crate to 0.4.0 ([#5746]) +- feat: nym-api bincode + yaml support ([#5745]) +- fix parallel feature in ecash crate with send + sync ([#5744]) +- Remove old test directory - Update validator docker ([#5743]) +- [Feature] `RememberMe` is the new don't `ForgetMe` ([#5742]) +- build(deps): bump ammonia from 4.0.0 to 4.1.0 ([#5739]) +- build(deps): bump base-x from 3.0.9 to 3.0.11 in /testnet-faucet ([#5737]) +- build(deps): bump http-proxy-middleware from 2.0.8 to 2.0.9 ([#5730]) + +[#5801]: https://github.com/nymtech/nym/pull/5801 +[#5779]: https://github.com/nymtech/nym/pull/5779 +[#5770]: https://github.com/nymtech/nym/pull/5770 +[#5768]: https://github.com/nymtech/nym/pull/5768 +[#5767]: https://github.com/nymtech/nym/pull/5767 +[#5761]: https://github.com/nymtech/nym/pull/5761 +[#5760]: https://github.com/nymtech/nym/pull/5760 +[#5759]: https://github.com/nymtech/nym/pull/5759 +[#5758]: https://github.com/nymtech/nym/pull/5758 +[#5756]: https://github.com/nymtech/nym/pull/5756 +[#5755]: https://github.com/nymtech/nym/pull/5755 +[#5754]: https://github.com/nymtech/nym/pull/5754 +[#5753]: https://github.com/nymtech/nym/pull/5753 +[#5749]: https://github.com/nymtech/nym/pull/5749 +[#5748]: https://github.com/nymtech/nym/pull/5748 +[#5747]: https://github.com/nymtech/nym/pull/5747 +[#5746]: https://github.com/nymtech/nym/pull/5746 +[#5745]: https://github.com/nymtech/nym/pull/5745 +[#5744]: https://github.com/nymtech/nym/pull/5744 +[#5743]: https://github.com/nymtech/nym/pull/5743 +[#5742]: https://github.com/nymtech/nym/pull/5742 +[#5739]: https://github.com/nymtech/nym/pull/5739 +[#5737]: https://github.com/nymtech/nym/pull/5737 +[#5730]: https://github.com/nymtech/nym/pull/5730 + ## [2025.9-appenzeller] (2025-05-13) - build(deps): bump clap from 4.5.36 to 4.5.37 in the patch-updates group ([#5722]) From 31772019cd7240f3afe4dc97c87ea8492319a36a Mon Sep 17 00:00:00 2001 From: benedetta davico <46782255+benedettadavico@users.noreply.github.com> Date: Tue, 27 May 2025 11:44:01 +0200 Subject: [PATCH 5/7] Update ci-contracts.yml --- .github/workflows/ci-contracts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-contracts.yml b/.github/workflows/ci-contracts.yml index 2814fd0a26..32ba1e67ad 100644 --- a/.github/workflows/ci-contracts.yml +++ b/.github/workflows/ci-contracts.yml @@ -27,7 +27,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal - toolchain: stable + toolchain: 1.86.0 target: wasm32-unknown-unknown override: true components: rustfmt, clippy From e126c1f7f144b82ef2d10c178526d3588a78de6d Mon Sep 17 00:00:00 2001 From: benedetta davico <46782255+benedettadavico@users.noreply.github.com> Date: Tue, 27 May 2025 11:45:53 +0200 Subject: [PATCH 6/7] Update publish-nym-binaries.yml --- .github/workflows/publish-nym-binaries.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-nym-binaries.yml b/.github/workflows/publish-nym-binaries.yml index 4e8bcb2966..618304e9ae 100644 --- a/.github/workflows/publish-nym-binaries.yml +++ b/.github/workflows/publish-nym-binaries.yml @@ -52,7 +52,7 @@ jobs: - name: Install Rust stable uses: actions-rs/toolchain@v1 with: - toolchain: stable + toolchain: 1.86.0 override: true - name: Build all binaries From ac12455f97b0141fa2ef7d7ceeca725fc13a4fc3 Mon Sep 17 00:00:00 2001 From: benedetta davico <46782255+benedettadavico@users.noreply.github.com> Date: Tue, 27 May 2025 16:35:51 +0200 Subject: [PATCH 7/7] add comment --- .github/workflows/ci-contracts.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci-contracts.yml b/.github/workflows/ci-contracts.yml index 32ba1e67ad..dc8246d851 100644 --- a/.github/workflows/ci-contracts.yml +++ b/.github/workflows/ci-contracts.yml @@ -27,6 +27,7 @@ jobs: uses: actions-rs/toolchain@v1 with: profile: minimal + # pinned due to issues building contracts toolchain: 1.86.0 target: wasm32-unknown-unknown override: true