diff --git a/clients/native/src/client/mod.rs b/clients/native/src/client/mod.rs index ab097f28f2..b997c47fb7 100644 --- a/clients/native/src/client/mod.rs +++ b/clients/native/src/client/mod.rs @@ -47,14 +47,12 @@ impl SocketClient { let mut client_config = validator_client::Config::try_from_nym_network_details(&details) .expect("failed to construct validator client config"); - let nymd_url = self - .config + let nymd_url = config .get_base() .get_validator_endpoints() .pop() .expect("No nymd validator endpoint provided"); - let api_url = self - .config + let api_url = config .get_base() .get_validator_api_endpoints() .pop() diff --git a/clients/socks5/src/client/mod.rs b/clients/socks5/src/client/mod.rs index 191f7aaaca..50fe2d0d49 100644 --- a/clients/socks5/src/client/mod.rs +++ b/clients/socks5/src/client/mod.rs @@ -57,14 +57,12 @@ impl NymClient { let mut client_config = validator_client::Config::try_from_nym_network_details(&details) .expect("failed to construct validator client config"); - let nymd_url = self - .config + let nymd_url = config .get_base() .get_validator_endpoints() .pop() .expect("No nymd validator endpoint provided"); - let api_url = self - .config + let api_url = config .get_base() .get_validator_api_endpoints() .pop() diff --git a/nym-connect/Cargo.lock b/nym-connect/Cargo.lock index 298996b5f3..dc321a807f 100644 --- a/nym-connect/Cargo.lock +++ b/nym-connect/Cargo.lock @@ -630,7 +630,7 @@ dependencies = [ [[package]] name = "client-core" -version = "1.1.1" +version = "1.1.2" dependencies = [ "client-connections", "config", @@ -3319,7 +3319,7 @@ dependencies = [ [[package]] name = "nym-connect" -version = "1.1.0" +version = "1.1.2" dependencies = [ "bip39", "client-core", @@ -3352,7 +3352,7 @@ dependencies = [ [[package]] name = "nym-socks5-client" -version = "1.1.1" +version = "1.1.2" dependencies = [ "clap", "client-connections", diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 999378447f..fee58aa9fe 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -2937,7 +2937,7 @@ dependencies = [ [[package]] name = "nym_wallet" -version = "1.1.1" +version = "1.1.2" dependencies = [ "aes-gcm", "argon2 0.3.4", diff --git a/validator-api/src/contract_cache/mod.rs b/validator-api/src/contract_cache/mod.rs index c0ba37faf9..f635933ae6 100644 --- a/validator-api/src/contract_cache/mod.rs +++ b/validator-api/src/contract_cache/mod.rs @@ -5,8 +5,6 @@ use crate::nymd_client::Client; use ::time::OffsetDateTime; use anyhow::Result; use mixnet_contract_common::families::FamilyHead; -use mixnet_contract_common::mixnode::MixNodeDetails; -use mixnet_contract_common::reward_params::{Performance, RewardingParams}; use mixnet_contract_common::{ mixnode::MixNodeDetails, reward_params::RewardingParams, GatewayBond, IdentityKey, Interval, MixId, MixNodeBond, RewardedSetNodeStatus, @@ -64,6 +62,8 @@ struct ValidatorCacheInner { current_reward_params: Cache>, current_interval: Cache>, + + mix_to_family: Cache>, } fn current_unix_timestamp() -> i64 { @@ -126,57 +126,6 @@ impl ValidatorCacheRefresher { self.update_notifier.subscribe() } - async fn annotate_node_with_details( - &self, - mixnodes: Vec, - interval_reward_params: RewardingParams, - current_interval: Interval, - rewarded_set: &HashMap, - ) -> Vec { - let mut annotated = Vec::new(); - for mixnode in mixnodes { - let stake_saturation = mixnode - .rewarding_details - .bond_saturation(&interval_reward_params); - - let uncapped_stake_saturation = mixnode - .rewarding_details - .uncapped_bond_saturation(&interval_reward_params); - - let performance = self - .get_performance(mixnode.mix_id(), current_interval) - .await - .unwrap_or_default(); - - let rewarded_set_status = rewarded_set.get(&mixnode.mix_id()).cloned(); - - let reward_estimate = reward_estimate::compute_reward_estimate( - &mixnode, - performance, - rewarded_set_status, - interval_reward_params, - current_interval, - ); - - let (estimated_operator_apy, estimated_delegators_apy) = - reward_estimate::compute_apy_from_reward( - &mixnode, - reward_estimate, - current_interval, - ); - - annotated.push(MixNodeBondAnnotated { - mixnode_details: mixnode, - stake_saturation, - uncapped_stake_saturation, - performance, - estimated_operator_apy, - estimated_delegators_apy, - }); - } - annotated - } - async fn get_rewarded_set_map(&self) -> HashMap where C: CosmWasmClient + Sync + Send, @@ -217,11 +166,9 @@ impl ValidatorCacheRefresher { let mixnodes = self.nymd_client.get_mixnodes().await?; let gateways = self.nymd_client.get_gateways().await?; - let rewarded_set = self.get_rewarded_set_map().await; + let mix_to_family = self.nymd_client.get_all_family_members().await?; - let mixnodes = self - .annotate_node_with_details(mixnodes, rewarding_params, current_interval, &rewarded_set) - .await; + let rewarded_set_map = self.get_rewarded_set_map().await; let (rewarded_set, active_set) = Self::collect_rewarded_and_active_set_details(&mixnodes, &rewarded_set_map); @@ -240,6 +187,7 @@ impl ValidatorCacheRefresher { active_set, rewarding_params, current_interval, + mix_to_family, ) .await; @@ -322,6 +270,7 @@ impl ValidatorCache { active_set: Vec, rewarding_params: RewardingParams, current_interval: Interval, + mix_to_family: Vec<(IdentityKey, FamilyHead)>, ) { match time::timeout(Duration::from_millis(100), self.inner.write()).await { Ok(mut cache) => { @@ -331,6 +280,7 @@ impl ValidatorCache { cache.active_set.update(active_set); cache.current_reward_params.update(Some(rewarding_params)); cache.current_interval.update(Some(current_interval)); + cache.mix_to_family.update(mix_to_family) } Err(e) => { error!("{}", e); @@ -504,6 +454,16 @@ impl ValidatorCache { } } + pub async fn mix_to_family(&self) -> Cache> { + match time::timeout(Duration::from_millis(100), self.inner.read()).await { + Ok(cache) => cache.mix_to_family.clone(), + Err(e) => { + error!("{}", e); + Cache::new(Vec::new()) + } + } + } + pub(crate) async fn interval_reward_params(&self) -> Cache> { match time::timeout(Duration::from_millis(100), self.inner.read()).await { Ok(cache) => cache.current_reward_params.clone(), @@ -578,6 +538,7 @@ impl ValidatorCacheInner { gateways_blacklist: Cache::default(), current_interval: Cache::default(), current_reward_params: Cache::default(), + mix_to_family: Cache::default(), } } } diff --git a/validator-api/src/epoch_operations/mod.rs b/validator-api/src/epoch_operations/mod.rs index 87d8a84d6f..8615393779 100644 --- a/validator-api/src/epoch_operations/mod.rs +++ b/validator-api/src/epoch_operations/mod.rs @@ -16,17 +16,17 @@ use crate::contract_cache::ValidatorCache; use crate::nymd_client::Client; use crate::storage::models::RewardingReport; use crate::storage::ValidatorApiStorage; +use mixnet_contract_common::families::FamilyHead; use mixnet_contract_common::{ reward_params::Performance, CurrentIntervalResponse, ExecuteMsg, Interval, MixId, }; -use mixnet_contract_common::{Layer, LayerAssignment}; +use mixnet_contract_common::{IdentityKey, Layer, LayerAssignment, MixNodeDetails}; use rand::prelude::SliceRandom; use rand::rngs::OsRng; use std::collections::HashMap; use std::collections::HashSet; use std::time::Duration; use tokio::time::sleep; -use validator_api_requests::models::MixNodeBondAnnotated; use validator_client::nymd::SigningNymdClient; pub(crate) mod error; @@ -90,7 +90,7 @@ impl RewardedSetUpdater { async fn determine_layers( &self, - rewarded_set: &[MixNodeBondAnnotated], + rewarded_set: &[MixNodeDetails], ) -> Result<(Vec, HashMap), RewardingError> { let mut families_in_layer: HashMap = HashMap::new(); let mut assignments = vec![]; @@ -98,12 +98,16 @@ impl RewardedSetUpdater { let mut rng = OsRng; let layers = vec![Layer::One, Layer::Two, Layer::Three]; + let mix_to_family = self.validator_cache.mix_to_family().await.to_vec(); + + let mix_to_family = mix_to_family + .into_iter() + .collect::>(); + for mix in rewarded_set { + let family = mix_to_family.get(&mix.bond_information.identity().to_owned()); // Get layer already assigned to nodes family, if any - let family_layer = mix - .family - .as_ref() - .and_then(|h| families_in_layer.get(h.identity())); + let family_layer = family.and_then(|h| families_in_layer.get(h.identity())); // Same node families are always assigned to the same layer, otherwise layer selected by a random weighted choice let layer = if let Some(layer) = family_layer { @@ -119,7 +123,7 @@ impl RewardedSetUpdater { // layer accounting let layer_entry = layer_assignments.entry(layer).or_insert(0.); *layer_entry += 1.; - if let Some(ref family) = mix.family { + if let Some(family) = family { families_in_layer.insert(family.identity().to_string(), layer); } } @@ -129,9 +133,9 @@ impl RewardedSetUpdater { fn determine_rewarded_set( &self, - mixnodes: &[MixNodeBondAnnotated], + mixnodes: &[MixNodeDetails], nodes_to_select: u32, - ) -> Result, RewardingError> { + ) -> Result, RewardingError> { if mixnodes.is_empty() { return Ok(Vec::new()); } @@ -142,7 +146,7 @@ impl RewardedSetUpdater { let choices = mixnodes .iter() .map(|mix| { - let total_stake = stake_to_f64(mix.mixnode_details.total_stake()); + let total_stake = stake_to_f64(mix.total_stake()); (mix.to_owned(), total_stake) }) .collect::>(); @@ -236,7 +240,7 @@ impl RewardedSetUpdater { async fn update_rewarded_set_and_advance_epoch( &self, - all_mixnodes: &[MixNodeBondAnnotated], + all_mixnodes: &[MixNodeDetails], ) -> Result<(), RewardingError> { // we grab rewarding parameters here as they might have gotten updated when performing epoch actions let rewarding_parameters = self.nymd_client.get_current_rewarding_parameters().await?; @@ -273,7 +277,7 @@ impl RewardedSetUpdater { let epoch_end = interval.current_epoch_end(); - let all_mixnodes = self.validator_cache.mixnodes_detailed().await; + let all_mixnodes = self.validator_cache.mixnodes().await; if all_mixnodes.is_empty() { log::warn!("there don't seem to be any mixnodes on the network!") } diff --git a/validator-api/src/node_status_api/cache.rs b/validator-api/src/node_status_api/cache.rs index dc8dc7447f..289a75a3f5 100644 --- a/validator-api/src/node_status_api/cache.rs +++ b/validator-api/src/node_status_api/cache.rs @@ -3,9 +3,10 @@ use crate::contract_cache::{Cache, CacheNotification, ValidatorCache}; use crate::storage::ValidatorApiStorage; +use mixnet_contract_common::families::FamilyHead; use mixnet_contract_common::reward_params::Performance; use mixnet_contract_common::{ - Interval, MixId, MixNodeDetails, RewardedSetNodeStatus, RewardingParams, + IdentityKey, Interval, MixId, MixNodeDetails, RewardedSetNodeStatus, RewardingParams, }; use rocket::fairing::AdHoc; use std::collections::HashMap; @@ -238,6 +239,7 @@ impl NodeStatusCacheRefresher { let rewarded_set = self.contract_cache.rewarded_set().await; let active_set = self.contract_cache.active_set().await; + let mix_to_family = self.contract_cache.mix_to_family().await; let interval_reward_params = interval_reward_params.ok_or(NodeStatusCacheError::SourceDataMissing)?; @@ -261,6 +263,7 @@ impl NodeStatusCacheRefresher { interval_reward_params, current_interval, &rewarded_set_node_status, + mix_to_family.to_vec(), ) .await; @@ -301,7 +304,12 @@ impl NodeStatusCacheRefresher { interval_reward_params: RewardingParams, current_interval: Interval, rewarded_set: &HashMap, + mix_to_family: Vec<(IdentityKey, FamilyHead)>, ) -> Vec { + let mix_to_family = mix_to_family + .into_iter() + .collect::>(); + let mut annotated = Vec::new(); for mixnode in mixnodes { let stake_saturation = mixnode @@ -332,6 +340,10 @@ impl NodeStatusCacheRefresher { let (estimated_operator_apy, estimated_delegators_apy) = compute_apy_from_reward(&mixnode, reward_estimate, current_interval); + let family = mix_to_family + .get(&mixnode.bond_information.identity().to_string()) + .cloned(); + annotated.push(MixNodeBondAnnotated { mixnode_details: mixnode, stake_saturation, @@ -339,6 +351,7 @@ impl NodeStatusCacheRefresher { performance, estimated_operator_apy, estimated_delegators_apy, + family, }); } annotated