diff --git a/Cargo.lock b/Cargo.lock index 252451a01d..090c0ae3f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2098,7 +2098,7 @@ dependencies = [ [[package]] name = "sphinx" version = "0.1.0" -source = "git+https://github.com/nymtech/sphinx?rev=1d8cefcb6a0cb8e87d00d89eb1ccf2839e92aa1f#1d8cefcb6a0cb8e87d00d89eb1ccf2839e92aa1f" +source = "git+https://github.com/nymtech/sphinx?rev=47c4fbba8272c4aee03cc8165220f33572a96602#47c4fbba8272c4aee03cc8165220f33572a96602" dependencies = [ "aes-ctr", "arrayref", @@ -2110,6 +2110,7 @@ dependencies = [ "hkdf", "hmac", "lioness", + "log", "rand 0.7.2", "rand_distr", "rand_os", diff --git a/common/clients/directory-client/src/presence.rs b/common/clients/directory-client/src/presence.rs index 8db97f673a..f56305f172 100644 --- a/common/clients/directory-client/src/presence.rs +++ b/common/clients/directory-client/src/presence.rs @@ -6,7 +6,10 @@ use std::collections::HashSet; use std::convert::TryInto; use std::io; use std::net::ToSocketAddrs; -use topology::{CocoNode, MixNode, MixProviderNode, NymTopology}; +use topology::coco; +use topology::mix; +use topology::provider; +use topology::NymTopology; // special version of 'PartialEq' that does not care about last_seen field (where applicable) // or order of elements in vectors @@ -23,9 +26,9 @@ pub struct CocoPresence { pub version: String, } -impl Into for CocoPresence { - fn into(self) -> topology::CocoNode { - topology::CocoNode { +impl Into for CocoPresence { + fn into(self) -> topology::coco::Node { + topology::coco::Node { host: self.host, pub_key: self.pub_key, last_seen: self.last_seen, @@ -34,8 +37,8 @@ impl Into for CocoPresence { } } -impl From for CocoPresence { - fn from(cn: CocoNode) -> Self { +impl From for CocoPresence { + fn from(cn: coco::Node) -> Self { CocoPresence { host: cn.host, pub_key: cn.pub_key, @@ -55,10 +58,10 @@ pub struct MixNodePresence { pub version: String, } -impl TryInto for MixNodePresence { +impl TryInto for MixNodePresence { type Error = io::Error; - fn try_into(self) -> Result { + fn try_into(self) -> Result { let resolved_hostname = self.host.to_socket_addrs()?.next(); if resolved_hostname.is_none() { return Err(io::Error::new( @@ -67,7 +70,7 @@ impl TryInto for MixNodePresence { )); } - Ok(topology::MixNode { + Ok(topology::mix::Node { host: resolved_hostname.unwrap(), pub_key: self.pub_key, layer: self.layer, @@ -77,8 +80,8 @@ impl TryInto for MixNodePresence { } } -impl From for MixNodePresence { - fn from(mn: MixNode) -> Self { +impl From for MixNodePresence { + fn from(mn: mix::Node) -> Self { MixNodePresence { host: mn.host.to_string(), pub_key: mn.pub_key, @@ -126,9 +129,9 @@ impl PresenceEq for MixProviderPresence { } } -impl Into for MixProviderPresence { - fn into(self) -> topology::MixProviderNode { - topology::MixProviderNode { +impl Into for MixProviderPresence { + fn into(self) -> topology::provider::Node { + topology::provider::Node { client_listener: self.client_listener.parse().unwrap(), mixnet_listener: self.mixnet_listener.parse().unwrap(), pub_key: self.pub_key, @@ -143,8 +146,8 @@ impl Into for MixProviderPresence { } } -impl From for MixProviderPresence { - fn from(mpn: MixProviderNode) -> Self { +impl From for MixProviderPresence { + fn from(mpn: provider::Node) -> Self { MixProviderPresence { client_listener: mpn.client_listener.to_string(), mixnet_listener: mpn.mixnet_listener.to_string(), @@ -166,16 +169,16 @@ pub struct MixProviderClient { pub pub_key: String, } -impl Into for MixProviderClient { - fn into(self) -> topology::MixProviderClient { - topology::MixProviderClient { +impl Into for MixProviderClient { + fn into(self) -> topology::provider::Client { + topology::provider::Client { pub_key: self.pub_key, } } } -impl From for MixProviderClient { - fn from(mpc: topology::MixProviderClient) -> Self { +impl From for MixProviderClient { + fn from(mpc: topology::provider::Client) -> Self { MixProviderClient { pub_key: mpc.pub_key, } @@ -318,9 +321,9 @@ impl NymTopology for Topology { } fn new_from_nodes( - mix_nodes: Vec, - mix_provider_nodes: Vec, - coco_nodes: Vec, + mix_nodes: Vec, + mix_provider_nodes: Vec, + coco_nodes: Vec, ) -> Self { Topology { coco_nodes: coco_nodes.into_iter().map(|node| node.into()).collect(), @@ -332,21 +335,21 @@ impl NymTopology for Topology { } } - fn get_mix_nodes(&self) -> Vec { + fn mix_nodes(&self) -> Vec { self.mix_nodes .iter() .filter_map(|x| x.clone().try_into().ok()) .collect() } - fn get_mix_provider_nodes(&self) -> Vec { + fn providers(&self) -> Vec { self.mix_provider_nodes .iter() .map(|x| x.clone().into()) .collect() } - fn get_coco_nodes(&self) -> Vec { + fn coco_nodes(&self) -> Vec { self.coco_nodes.iter().map(|x| x.clone().into()).collect() } } @@ -367,7 +370,7 @@ mod converting_mixnode_presence_into_topology_mixnode { version: "".to_string(), }; - let result: Result = mix_presence.try_into(); + let result: Result = mix_presence.try_into(); assert!(result.is_err()) } @@ -383,7 +386,7 @@ mod converting_mixnode_presence_into_topology_mixnode { version: "".to_string(), }; - let result: Result = mix_presence.try_into(); + let result: Result = mix_presence.try_into(); assert!(result.is_ok()) } } diff --git a/common/clients/mix-client/Cargo.toml b/common/clients/mix-client/Cargo.toml index a7ef6e35c8..ccfba9d9e3 100644 --- a/common/clients/mix-client/Cargo.toml +++ b/common/clients/mix-client/Cargo.toml @@ -18,5 +18,6 @@ addressing = {path = "../../addressing"} topology = {path = "../../topology"} ## will be moved to proper dependencies once released -sphinx = { git = "https://github.com/nymtech/sphinx", rev="1d8cefcb6a0cb8e87d00d89eb1ccf2839e92aa1f" } +sphinx = { git = "https://github.com/nymtech/sphinx", rev="47c4fbba8272c4aee03cc8165220f33572a96602" } +# sphinx = { path = "../../../../sphinx"} diff --git a/common/clients/mix-client/src/packet.rs b/common/clients/mix-client/src/packet.rs index cc1a027cb6..7999d1e620 100644 --- a/common/clients/mix-client/src/packet.rs +++ b/common/clients/mix-client/src/packet.rs @@ -28,7 +28,7 @@ pub fn encapsulate_message( topology: &T, average_delay: f64, ) -> (SocketAddr, SphinxPacket) { - let mut providers = topology.get_mix_provider_nodes(); + let mut providers = topology.providers(); let provider = providers.pop().unwrap().into(); let route = topology.route_to(provider).unwrap(); diff --git a/common/clients/provider-client/Cargo.toml b/common/clients/provider-client/Cargo.toml index 450a76cb2b..07c368f9d6 100644 --- a/common/clients/provider-client/Cargo.toml +++ b/common/clients/provider-client/Cargo.toml @@ -16,4 +16,4 @@ tokio = { version = "0.2", features = ["full"] } sfw-provider-requests = { path = "../../../sfw-provider/sfw-provider-requests" } ## will be moved to proper dependencies once released -sphinx = { git = "https://github.com/nymtech/sphinx", rev="1d8cefcb6a0cb8e87d00d89eb1ccf2839e92aa1f" } +sphinx = { git = "https://github.com/nymtech/sphinx", rev="47c4fbba8272c4aee03cc8165220f33572a96602" } diff --git a/common/healthcheck/Cargo.toml b/common/healthcheck/Cargo.toml index 918efa0df9..834a72c65e 100644 --- a/common/healthcheck/Cargo.toml +++ b/common/healthcheck/Cargo.toml @@ -25,6 +25,7 @@ sfw-provider-requests = { path = "../../sfw-provider/sfw-provider-requests" } topology = {path = "../topology" } ## will be moved to proper dependencies once released -sphinx = { git = "https://github.com/nymtech/sphinx", rev="1d8cefcb6a0cb8e87d00d89eb1ccf2839e92aa1f" } +sphinx = { git = "https://github.com/nymtech/sphinx", rev="47c4fbba8272c4aee03cc8165220f33572a96602" } +# sphinx = { path = "../../../sphinx"} [dev-dependencies] diff --git a/common/healthcheck/src/path_check.rs b/common/healthcheck/src/path_check.rs index 89fe995880..f2d8b4879b 100644 --- a/common/healthcheck/src/path_check.rs +++ b/common/healthcheck/src/path_check.rs @@ -6,7 +6,7 @@ use provider_client::ProviderClient; use sphinx::header::delays::Delay; use sphinx::route::{Destination, Node as SphinxNode}; use std::collections::HashMap; -use topology::MixProviderNode; +use topology::provider; #[derive(Debug, PartialEq, Clone)] pub enum PathStatus { @@ -27,7 +27,7 @@ pub(crate) struct PathChecker { impl PathChecker { pub(crate) async fn new( - providers: Vec, + providers: Vec, ephemeral_keys: DummyMixIdentityKeyPair, ) -> Self { let mut provider_clients = HashMap::new(); diff --git a/common/healthcheck/src/result.rs b/common/healthcheck/src/result.rs index 79ec6a291f..b7aae8d33c 100644 --- a/common/healthcheck/src/result.rs +++ b/common/healthcheck/src/result.rs @@ -28,8 +28,8 @@ impl HealthCheckResult { fn zero_score(topology: T) -> Self { warn!("The network is unhealthy, could not send any packets - returning zero score!"); - let mixes = topology.get_mix_nodes(); - let providers = topology.get_mix_provider_nodes(); + let mixes = topology.mix_nodes(); + let providers = topology.providers(); let health = mixes .into_iter() @@ -58,7 +58,7 @@ impl HealthCheckResult { score_threshold: f64, ) -> T { let filtered_mix_nodes = topology - .get_mix_nodes() + .mix_nodes() .into_iter() .filter(|node| { match self.node_score(NodeAddressBytes::from_b64_string(node.pub_key.clone())) { @@ -72,7 +72,7 @@ impl HealthCheckResult { .collect(); let filtered_provider_nodes = topology - .get_mix_provider_nodes() + .providers() .into_iter() .filter(|node| { match self.node_score(NodeAddressBytes::from_b64_string(node.pub_key.clone())) { @@ -85,7 +85,7 @@ impl HealthCheckResult { }) .collect(); // coco nodes remain unchanged as no healthcheck is being run on them or time being - let filtered_coco_nodes = topology.get_coco_nodes(); + let filtered_coco_nodes = topology.coco_nodes(); T::new_from_nodes( filtered_mix_nodes, @@ -110,19 +110,16 @@ impl HealthCheckResult { // create entries for all nodes let mut score_map = HashMap::new(); - topology.get_mix_nodes().into_iter().for_each(|node| { + topology.mix_nodes().into_iter().for_each(|node| { score_map.insert(node.get_pub_key_bytes(), NodeScore::from_mixnode(node)); }); - topology - .get_mix_provider_nodes() - .into_iter() - .for_each(|node| { - score_map.insert(node.get_pub_key_bytes(), NodeScore::from_provider(node)); - }); + topology.providers().into_iter().for_each(|node| { + score_map.insert(node.get_pub_key_bytes(), NodeScore::from_provider(node)); + }); let ephemeral_keys = DummyMixIdentityKeyPair::new(); - let providers = topology.get_mix_provider_nodes(); + let providers = topology.providers(); let mut path_checker = PathChecker::new(providers, ephemeral_keys).await; for i in 0..iterations { diff --git a/common/healthcheck/src/score.rs b/common/healthcheck/src/score.rs index 8f97cf96a8..4d29e8f5b6 100644 --- a/common/healthcheck/src/score.rs +++ b/common/healthcheck/src/score.rs @@ -4,7 +4,8 @@ use std::cmp::Ordering; use std::fmt::Error; use std::fmt::Formatter; use std::net::SocketAddr; -use topology::{MixNode, MixProviderNode}; +use topology::mix; +use topology::provider; // TODO: should 'nodetype' really be part of healthcheck::score @@ -91,7 +92,7 @@ impl PartialEq for NodeScore { } impl NodeScore { - pub(crate) fn from_mixnode(node: MixNode) -> Self { + pub(crate) fn from_mixnode(node: mix::Node) -> Self { NodeScore { typ: NodeType::Mix, pub_key: NodeAddressBytes::from_b64_string(node.pub_key), @@ -103,7 +104,7 @@ impl NodeScore { } } - pub(crate) fn from_provider(node: MixProviderNode) -> Self { + pub(crate) fn from_provider(node: provider::Node) -> Self { NodeScore { typ: NodeType::MixProvider, pub_key: NodeAddressBytes::from_b64_string(node.pub_key), diff --git a/common/topology/Cargo.toml b/common/topology/Cargo.toml index e9e8022c91..6e0e65bf50 100644 --- a/common/topology/Cargo.toml +++ b/common/topology/Cargo.toml @@ -20,4 +20,5 @@ addressing = {path = "../addressing"} version-checker = {path = "../version-checker" } ## will be moved to proper dependencies once released -sphinx = { git = "https://github.com/nymtech/sphinx", rev="1d8cefcb6a0cb8e87d00d89eb1ccf2839e92aa1f" } +sphinx = { git = "https://github.com/nymtech/sphinx", rev="47c4fbba8272c4aee03cc8165220f33572a96602" } +# sphinx = { path = "../../../sphinx"} diff --git a/common/topology/src/coco.rs b/common/topology/src/coco.rs new file mode 100644 index 0000000000..bfc20a093e --- /dev/null +++ b/common/topology/src/coco.rs @@ -0,0 +1,15 @@ +use crate::filter; + +#[derive(Debug, Clone)] +pub struct Node { + pub host: String, + pub pub_key: String, + pub last_seen: u64, + pub version: String, +} + +impl filter::Versioned for Node { + fn version(&self) -> String { + self.version.clone() + } +} diff --git a/common/topology/src/filter.rs b/common/topology/src/filter.rs new file mode 100644 index 0000000000..68242b8b92 --- /dev/null +++ b/common/topology/src/filter.rs @@ -0,0 +1,18 @@ +pub trait Versioned: Clone { + fn version(&self) -> String; +} + +pub trait VersionFilterable { + fn filter_by_version(&self, expected_version: &str) -> Self; +} + +impl VersionFilterable for Vec { + fn filter_by_version(&self, expected_version: &str) -> Self { + self.iter() + .filter(|node| { + version_checker::is_minor_version_compatible(&node.version(), expected_version) + }) + .cloned() + .collect() + } +} diff --git a/common/topology/src/lib.rs b/common/topology/src/lib.rs index 116920e7f0..94ac5a74b4 100644 --- a/common/topology/src/lib.rs +++ b/common/topology/src/lib.rs @@ -1,103 +1,29 @@ -use addressing; -use curve25519_dalek::montgomery::MontgomeryPoint; +use crate::filter::VersionFilterable; use itertools::Itertools; use rand::seq::IteratorRandom; -use sphinx::route::{Node as SphinxNode, NodeAddressBytes}; +use sphinx::route::Node as SphinxNode; use std::cmp::max; use std::collections::HashMap; -use std::net::SocketAddr; -use version_checker; -#[derive(Debug, Clone)] -pub struct MixNode { - pub host: SocketAddr, - pub pub_key: String, - pub layer: u64, - pub last_seen: u64, - pub version: String, -} - -impl Into for MixNode { - fn into(self) -> SphinxNode { - let address_bytes = addressing::encoded_bytes_from_socket_address(self.host); - let key_bytes = self.get_pub_key_bytes(); - let key = MontgomeryPoint(key_bytes); - - SphinxNode::new(NodeAddressBytes::from_bytes(address_bytes), key) - } -} - -impl MixNode { - pub fn get_pub_key_bytes(&self) -> [u8; 32] { - let decoded_key_bytes = base64::decode_config(&self.pub_key, base64::URL_SAFE).unwrap(); - let mut key_bytes = [0; 32]; - key_bytes.copy_from_slice(&decoded_key_bytes[..]); - key_bytes - } -} - -#[derive(Debug, Clone)] -pub struct MixProviderClient { - pub pub_key: String, -} - -#[derive(Debug, Clone)] -pub struct MixProviderNode { - pub client_listener: SocketAddr, - pub mixnet_listener: SocketAddr, - pub pub_key: String, - pub registered_clients: Vec, - pub last_seen: u64, - pub version: String, -} - -impl Into for MixProviderNode { - fn into(self) -> SphinxNode { - let address_bytes = addressing::encoded_bytes_from_socket_address(self.mixnet_listener); - let key_bytes = self.get_pub_key_bytes(); - let key = MontgomeryPoint(key_bytes); - - SphinxNode::new(NodeAddressBytes::from_bytes(address_bytes), key) - } -} - -impl MixProviderNode { - pub fn get_pub_key_bytes(&self) -> [u8; 32] { - let decoded_key_bytes = base64::decode_config(&self.pub_key, base64::URL_SAFE).unwrap(); - let mut key_bytes = [0; 32]; - key_bytes.copy_from_slice(&decoded_key_bytes[..]); - key_bytes - } -} - -#[derive(Debug, Clone)] -pub struct CocoNode { - pub host: String, - pub pub_key: String, - pub last_seen: u64, - pub version: String, -} - -#[derive(Debug)] -pub enum NymTopologyError { - InvalidMixLayerError, - MissingLayerError(Vec), -} +pub mod coco; +mod filter; +pub mod mix; +pub mod provider; pub trait NymTopology: Sized + PartialEq + std::fmt::Debug + Send + Sync { fn new(directory_server: String) -> Self; fn new_from_nodes( - mix_nodes: Vec, - mix_provider_nodes: Vec, - coco_nodes: Vec, + mix_nodes: Vec, + mix_provider_nodes: Vec, + coco_nodes: Vec, ) -> Self; - fn get_mix_nodes(&self) -> Vec; - fn get_mix_provider_nodes(&self) -> Vec; - fn get_coco_nodes(&self) -> Vec; - fn make_layered_topology(&self) -> Result>, NymTopologyError> { - let mut layered_topology: HashMap> = HashMap::new(); + fn mix_nodes(&self) -> Vec; + fn providers(&self) -> Vec; + fn coco_nodes(&self) -> Vec; + fn make_layered_topology(&self) -> Result>, NymTopologyError> { + let mut layered_topology: HashMap> = HashMap::new(); let mut highest_layer = 0; - for mix in self.get_mix_nodes() { + for mix in self.mix_nodes() { // we need to have extra space for provider if mix.layer > sphinx::constants::MAX_PATH_LENGTH as u64 { return Err(NymTopologyError::InvalidMixLayerError); @@ -125,6 +51,8 @@ pub trait NymTopology: Sized + PartialEq + std::fmt::Debug + Send + Sync { Ok(layered_topology) } + + // Tries to get a route through the mix network fn mix_route(&self) -> Result, NymTopologyError> { let mut layered_topology = self.make_layered_topology()?; let num_layers = layered_topology.len(); @@ -137,7 +65,7 @@ pub trait NymTopology: Sized + PartialEq + std::fmt::Debug + Send + Sync { Ok(route) } - // sets a route to specific provider + // Sets up a route to a specific provider fn route_to(&self, provider_node: SphinxNode) -> Result, NymTopologyError> { Ok(self .mix_route()? @@ -148,7 +76,7 @@ pub trait NymTopology: Sized + PartialEq + std::fmt::Debug + Send + Sync { fn all_paths(&self) -> Result>, NymTopologyError> { let mut layered_topology = self.make_layered_topology()?; - let providers = self.get_mix_provider_nodes(); + let providers = self.providers(); let sorted_layers: Vec> = (1..=layered_topology.len() as u64) .map(|layer| layered_topology.remove(&layer).unwrap()) // get all nodes per layer @@ -172,32 +100,13 @@ pub trait NymTopology: Sized + PartialEq + std::fmt::Debug + Send + Sync { expected_provider_version: &str, expected_coco_version: &str, ) -> Self { - let filtered_mixes = self - .get_mix_nodes() - .iter() - .filter(|mix_node| { - version_checker::is_compatible(&mix_node.version, expected_mix_version) - }) - .cloned() - .collect(); - let filtered_providers = self - .get_mix_provider_nodes() - .iter() - .filter(|provider_node| { - version_checker::is_compatible(&provider_node.version, expected_provider_version) - }) - .cloned() - .collect(); - let filtered_coco_nodes = self - .get_coco_nodes() - .iter() - .filter(|coco_node| { - version_checker::is_compatible(&coco_node.version, expected_coco_version) - }) - .cloned() - .collect(); + let mixes = self.mix_nodes().filter_by_version(expected_mix_version); + let providers = self + .providers() + .filter_by_version(expected_provider_version); + let cocos = self.coco_nodes().filter_by_version(expected_coco_version); - Self::new_from_nodes(filtered_mixes, filtered_providers, filtered_coco_nodes) + Self::new_from_nodes(mixes, providers, cocos) } fn can_construct_path_through(&self) -> bool { @@ -208,4 +117,8 @@ pub trait NymTopology: Sized + PartialEq + std::fmt::Debug + Send + Sync { } } -// TODO: tests... +#[derive(Debug)] +pub enum NymTopologyError { + InvalidMixLayerError, + MissingLayerError(Vec), +} diff --git a/common/topology/src/mix.rs b/common/topology/src/mix.rs new file mode 100644 index 0000000000..5236e191fa --- /dev/null +++ b/common/topology/src/mix.rs @@ -0,0 +1,38 @@ +use crate::filter; +use sphinx::route::Node as SphinxNode; +use sphinx::route::NodeAddressBytes; +use std::net::SocketAddr; + +#[derive(Debug, Clone)] +pub struct Node { + pub host: SocketAddr, + pub pub_key: String, + pub layer: u64, + pub last_seen: u64, + pub version: String, +} + +impl Node { + pub fn get_pub_key_bytes(&self) -> [u8; 32] { + let decoded_key_bytes = base64::decode_config(&self.pub_key, base64::URL_SAFE).unwrap(); + let mut key_bytes = [0; 32]; + key_bytes.copy_from_slice(&decoded_key_bytes[..]); + key_bytes + } +} + +impl filter::Versioned for Node { + fn version(&self) -> String { + self.version.clone() + } +} + +impl Into for Node { + fn into(self) -> SphinxNode { + let address_bytes = addressing::encoded_bytes_from_socket_address(self.host); + let key_bytes = self.get_pub_key_bytes(); + let key = sphinx::key::new(key_bytes); + + SphinxNode::new(NodeAddressBytes::from_bytes(address_bytes), key) + } +} diff --git a/common/topology/src/provider.rs b/common/topology/src/provider.rs new file mode 100644 index 0000000000..e9d4869e0e --- /dev/null +++ b/common/topology/src/provider.rs @@ -0,0 +1,44 @@ +use crate::filter; +use sphinx::route::Node as SphinxNode; +use sphinx::route::NodeAddressBytes; +use std::net::SocketAddr; + +#[derive(Debug, Clone)] +pub struct Client { + pub pub_key: String, +} + +#[derive(Debug, Clone)] +pub struct Node { + pub client_listener: SocketAddr, + pub mixnet_listener: SocketAddr, + pub pub_key: String, + pub registered_clients: Vec, + pub last_seen: u64, + pub version: String, +} + +impl Node { + pub fn get_pub_key_bytes(&self) -> [u8; 32] { + let decoded_key_bytes = base64::decode_config(&self.pub_key, base64::URL_SAFE).unwrap(); + let mut key_bytes = [0; 32]; + key_bytes.copy_from_slice(&decoded_key_bytes[..]); + key_bytes + } +} + +impl filter::Versioned for Node { + fn version(&self) -> String { + self.version.clone() + } +} + +impl Into for Node { + fn into(self) -> SphinxNode { + let address_bytes = addressing::encoded_bytes_from_socket_address(self.mixnet_listener); + let key_bytes = self.get_pub_key_bytes(); + let key = sphinx::key::new(key_bytes); + + SphinxNode::new(NodeAddressBytes::from_bytes(address_bytes), key) + } +} diff --git a/common/version-checker/src/lib.rs b/common/version-checker/src/lib.rs index 48125479af..55232a9885 100644 --- a/common/version-checker/src/lib.rs +++ b/common/version-checker/src/lib.rs @@ -6,11 +6,17 @@ use semver::VersionReq; /// concrete version number, because that's what we'll have in our Cargo.toml files (e.g. 0.3.2). /// The patch number in the requirement gets dropped and replaced with a wildcard (0.3.*) as all /// minor versions should be compatible with each other. -pub fn is_compatible(version: &str, req: &str) -> bool { - let version = Version::parse(version).unwrap(); - let tmp = Version::parse(req).unwrap(); +pub fn is_minor_version_compatible(version: &str, req: &str) -> bool { + let version = match Version::parse(version) { + Ok(v) => v, + Err(_) => return false, + }; + let tmp = match Version::parse(req) { + Ok(v) => v, + Err(_) => return false, + }; let wildcard = format!("{}.{}.*", tmp.major, tmp.minor).to_string(); - let semver_requirement = VersionReq::parse(&wildcard).unwrap(); + let semver_requirement = VersionReq::parse(&wildcard).expect("panicked on semver requirement parsing. This should never happen as inputs should already have been sanitized."); semver_requirement.matches(&version) } @@ -21,31 +27,41 @@ mod tests { #[test] fn version_0_3_0_is_compatible_with_requirement_0_3_x() { - assert!(is_compatible("0.3.0", "0.3.2")); + assert!(is_minor_version_compatible("0.3.0", "0.3.2")); } #[test] fn version_0_3_1_is_compatible_with_minimum_requirement_0_3_x() { - assert!(is_compatible("0.3.1", "0.3.2")); + assert!(is_minor_version_compatible("0.3.1", "0.3.2")); } #[test] fn version_0_3_2_is_compatible_with_minimum_requirement_0_3_x() { - assert!(is_compatible("0.3.2", "0.3.0")); + assert!(is_minor_version_compatible("0.3.2", "0.3.0")); } #[test] fn version_0_2_0_is_not_compatible_with_requirement_0_3_x() { - assert!(!is_compatible("0.2.0", "0.3.2")); + assert!(!is_minor_version_compatible("0.2.0", "0.3.2")); } #[test] fn version_0_4_0_is_not_compatible_with_requirement_0_3_x() { - assert!(!is_compatible("0.4.0", "0.3.2")); + assert!(!is_minor_version_compatible("0.4.0", "0.3.2")); } #[test] fn version_1_3_2_is_not_compatible_with_requirement_0_3_x() { - assert!(!is_compatible("1.3.2", "0.3.2")); + assert!(!is_minor_version_compatible("1.3.2", "0.3.2")); + } + + #[test] + fn returns_false_on_foo_version() { + assert!(!is_minor_version_compatible("foo", "0.3.2")); + } + + #[test] + fn returns_false_on_bar_version() { + assert!(!is_minor_version_compatible("0.3.2", "bar")); } } diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index e538c329d9..d02f8bcc22 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -22,7 +22,7 @@ addressing = {path = "../common/addressing" } directory-client = { path = "../common/clients/directory-client" } ## will be moved to proper dependencies once released -sphinx = { git = "https://github.com/nymtech/sphinx", rev="1d8cefcb6a0cb8e87d00d89eb1ccf2839e92aa1f" } +sphinx = { git = "https://github.com/nymtech/sphinx", rev="47c4fbba8272c4aee03cc8165220f33572a96602" } [build-dependencies] built = "0.3.2" diff --git a/nym-client/Cargo.toml b/nym-client/Cargo.toml index 51730b0dd1..24f30726df 100644 --- a/nym-client/Cargo.toml +++ b/nym-client/Cargo.toml @@ -40,7 +40,8 @@ sfw-provider-requests = { path = "../sfw-provider/sfw-provider-requests" } topology = {path = "../common/topology" } ## will be moved to proper dependencies once released -sphinx = { git = "https://github.com/nymtech/sphinx", rev="1d8cefcb6a0cb8e87d00d89eb1ccf2839e92aa1f" } +sphinx = { git = "https://github.com/nymtech/sphinx", rev="47c4fbba8272c4aee03cc8165220f33572a96602" } +# sphinx = { path = "../../sphinx"} # putting this explicitly below everything and most likely, the next time we look into it, it will already have a proper release tokio-tungstenite = { git = "https://github.com/snapview/tokio-tungstenite", rev="308d9680c0e59dd1e8651659a775c05df937934e" } diff --git a/nym-client/src/client/mod.rs b/nym-client/src/client/mod.rs index cf0b609661..c2435acf0d 100644 --- a/nym-client/src/client/mod.rs +++ b/nym-client/src/client/mod.rs @@ -79,7 +79,7 @@ impl NymClient { ) -> SocketAddr { // this is temporary and assumes there exists only a single provider. topology_ctrl_ref.read().await.topology.as_ref().unwrap() - .get_mix_provider_nodes() + .providers() .first() .expect("Could not get a provider from the initial network topology, are you using the right directory server?") .client_listener diff --git a/nym-client/src/sockets/tcp.rs b/nym-client/src/sockets/tcp.rs index e37c901c9a..8f49707c60 100644 --- a/nym-client/src/sockets/tcp.rs +++ b/nym-client/src/sockets/tcp.rs @@ -138,7 +138,7 @@ impl ClientRequest { match topology_data { Some(topology) => { let clients = topology - .get_mix_provider_nodes() + .providers() .iter() .flat_map(|provider| provider.registered_clients.iter()) .filter_map(|client| { diff --git a/nym-client/src/sockets/ws.rs b/nym-client/src/sockets/ws.rs index fa44b925a7..598a146b7c 100644 --- a/nym-client/src/sockets/ws.rs +++ b/nym-client/src/sockets/ws.rs @@ -265,7 +265,7 @@ impl ClientRequest { match topology_data { Some(topology) => { let clients = topology - .get_mix_provider_nodes() + .providers() .iter() .flat_map(|provider| provider.registered_clients.iter()) .map(|client| client.pub_key.clone()) diff --git a/sfw-provider/Cargo.toml b/sfw-provider/Cargo.toml index 4c0fc7c132..bce8917ad1 100644 --- a/sfw-provider/Cargo.toml +++ b/sfw-provider/Cargo.toml @@ -29,7 +29,7 @@ directory-client = { path = "../common/clients/directory-client" } sfw-provider-requests = { path = "./sfw-provider-requests" } ## will be moved to proper dependencies once released -sphinx = { git = "https://github.com/nymtech/sphinx", rev="1d8cefcb6a0cb8e87d00d89eb1ccf2839e92aa1f" } +sphinx = { git = "https://github.com/nymtech/sphinx", rev="47c4fbba8272c4aee03cc8165220f33572a96602" } [build-dependencies] built = "0.3.2" diff --git a/sfw-provider/sfw-provider-requests/Cargo.toml b/sfw-provider/sfw-provider-requests/Cargo.toml index 97763acb6c..0f31948e50 100644 --- a/sfw-provider/sfw-provider-requests/Cargo.toml +++ b/sfw-provider/sfw-provider-requests/Cargo.toml @@ -7,4 +7,4 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -sphinx = { git = "https://github.com/nymtech/sphinx", rev="1d8cefcb6a0cb8e87d00d89eb1ccf2839e92aa1f" } +sphinx = { git = "https://github.com/nymtech/sphinx", rev="47c4fbba8272c4aee03cc8165220f33572a96602" }