Merge pull request #3750 from nymtech/release/v1.1.26

Release/v1.1.26
This commit is contained in:
Tommy Verrall
2023-08-08 16:04:32 +02:00
committed by GitHub
56 changed files with 923 additions and 153 deletions
+22
View File
@@ -4,6 +4,28 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
## [Unreleased]
## [v1.1.24] (2023-08-08)
- Latency based gateway selection is serial and slow ([#3710])
- Network-requester: strip comments from allow lists ([#3625])
- Remove (or start maintaining) `upgrade` commands from all binaries ([#3600])
- Set sphinx as default packet type ([#3748])
- Apply fix from feature/ephemera to develop too (#3698) ([#3742])
- Feature/coco demos ([#3732])
- Add updates to community list projects ([#3722])
- Add geo-aware mixnet topology provider ([#3713])
- Add updates to community list projects ([#3711])
[#3710]: https://github.com/nymtech/nym/issues/3710
[#3625]: https://github.com/nymtech/nym/issues/3625
[#3600]: https://github.com/nymtech/nym/issues/3600
[#3748]: https://github.com/nymtech/nym/pull/3748
[#3742]: https://github.com/nymtech/nym/pull/3742
[#3732]: https://github.com/nymtech/nym/pull/3732
[#3722]: https://github.com/nymtech/nym/pull/3722
[#3713]: https://github.com/nymtech/nym/pull/3713
[#3711]: https://github.com/nymtech/nym/pull/3711
## [v1.1.23] (2023-07-04)
- nym-cli: add client identity key signing support ([#3576])
Generated
+29 -9
View File
@@ -1896,7 +1896,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "explorer-api"
version = "1.1.23"
version = "1.1.24"
dependencies = [
"chrono",
"clap 4.2.7",
@@ -1909,6 +1909,7 @@ dependencies = [
"maxminddb",
"nym-bin-common",
"nym-contracts-common",
"nym-explorer-api-requests",
"nym-mixnet-contract-common",
"nym-network-defaults",
"nym-task",
@@ -3529,7 +3530,7 @@ dependencies = [
[[package]]
name = "nym-api"
version = "1.1.24"
version = "1.1.25"
dependencies = [
"anyhow",
"async-trait",
@@ -3666,7 +3667,7 @@ dependencies = [
[[package]]
name = "nym-cli"
version = "1.1.23"
version = "1.1.24"
dependencies = [
"anyhow",
"base64 0.13.1",
@@ -3732,7 +3733,7 @@ dependencies = [
[[package]]
name = "nym-client"
version = "1.1.23"
version = "1.1.24"
dependencies = [
"clap 4.2.7",
"dirs 4.0.0",
@@ -3782,6 +3783,7 @@ dependencies = [
"nym-config",
"nym-credential-storage",
"nym-crypto",
"nym-explorer-api-requests",
"nym-gateway-client",
"nym-gateway-requests",
"nym-network-defaults",
@@ -3792,6 +3794,7 @@ dependencies = [
"nym-topology",
"nym-validator-client",
"rand 0.7.3",
"reqwest",
"serde",
"serde_json",
"sha2 0.10.6",
@@ -4004,9 +4007,21 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "nym-explorer-api-requests"
version = "0.1.0"
dependencies = [
"nym-contracts-common",
"nym-mixnet-contract-common",
"nym-validator-client",
"schemars",
"serde",
"ts-rs",
]
[[package]]
name = "nym-gateway"
version = "1.1.23"
version = "1.1.24"
dependencies = [
"anyhow",
"async-trait",
@@ -4161,7 +4176,7 @@ dependencies = [
[[package]]
name = "nym-mixnode"
version = "1.1.24"
version = "1.1.25"
dependencies = [
"anyhow",
"bs58 0.4.0",
@@ -4278,7 +4293,7 @@ dependencies = [
[[package]]
name = "nym-network-requester"
version = "1.1.23"
version = "1.1.24"
dependencies = [
"anyhow",
"async-file-watcher",
@@ -4325,7 +4340,7 @@ dependencies = [
[[package]]
name = "nym-network-statistics"
version = "1.1.23"
version = "1.1.24"
dependencies = [
"dirs 4.0.0",
"log",
@@ -4482,7 +4497,7 @@ dependencies = [
[[package]]
name = "nym-socks5-client"
version = "1.1.23"
version = "1.1.24"
dependencies = [
"clap 4.2.7",
"lazy_static",
@@ -4520,7 +4535,9 @@ dependencies = [
"nym-bandwidth-controller",
"nym-client-core",
"nym-config",
"nym-contracts-common",
"nym-credential-storage",
"nym-mixnet-contract-common",
"nym-network-defaults",
"nym-service-providers-common",
"nym-socks5-proxy-helpers",
@@ -4530,10 +4547,13 @@ dependencies = [
"nym-validator-client",
"pin-project",
"rand 0.7.3",
"reqwest",
"schemars",
"serde",
"tap",
"thiserror",
"tokio",
"url",
]
[[package]]
+5 -3
View File
@@ -74,6 +74,7 @@ members = [
"common/types",
"common/wasm-utils",
"explorer-api",
"explorer-api/explorer-api-requests",
"gateway",
"gateway/gateway-requests",
"integrations/bity",
@@ -126,7 +127,6 @@ serde-json-wasm = "=0.5.0"
cosmwasm-storage = "=1.3.0"
cosmrs = "=0.14.0"
# same version as used by cosmrs
tendermint-rpc = "=0.32"
cw-utils = "=1.0.1"
cw-storage-plus = "=1.1.0"
cw2 = { version = "=1.1.0" }
@@ -135,19 +135,21 @@ cw4 = { version = "=1.1.0" }
cw-controllers = { version = "=1.1.0" }
dotenvy = "0.15.6"
generic-array = "0.14.7"
k256 = "0.13"
getrandom = "0.2.10"
k256 = "0.13"
lazy_static = "1.4.0"
log = "0.4"
once_cell = "1.7.2"
rand = "0.8.5"
reqwest = "0.11.18"
serde = "1.0.152"
serde_json = "1.0.91"
tap = "1.0.1"
tendermint-rpc = "0.32" # same version as used by cosmrs
thiserror = "1.0.38"
tokio = "1.24.1"
url = "2.2"
zeroize = "1.6.0"
# wasm-related dependencies
wasmtimer = "0.2.0"
wasmtimer = "0.2.0"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.1.23"
version = "1.1.24"
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.23"
version = "1.1.24"
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"
+1
View File
@@ -94,6 +94,7 @@ impl From<Init> for OverrideConfig {
use_anonymous_replies: init_config.use_reply_surbs,
fastmode: init_config.fastmode,
no_cover: init_config.no_cover,
geo_routing: None,
medium_toggle: false,
nyxd_urls: init_config.nyxd_urls,
enabled_credentials_mode: init_config.enabled_credentials_mode,
+14 -1
View File
@@ -16,7 +16,8 @@ use nym_client_core::client::base_client::storage::gateway_details::{
OnDiskGatewayDetails, PersistedGatewayDetails,
};
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
use nym_client_core::config::GatewayEndpointConfig;
use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup;
use nym_client_core::config::{GatewayEndpointConfig, TopologyStructure};
use nym_client_core::error::ClientCoreError;
use nym_config::OptionalSet;
use nym_sphinx::params::{PacketSize, PacketType};
@@ -75,6 +76,7 @@ pub(crate) struct OverrideConfig {
use_anonymous_replies: Option<bool>,
fastmode: bool,
no_cover: bool,
geo_routing: Option<CountryGroup>,
medium_toggle: bool,
nyxd_urls: Option<Vec<url::Url>>,
enabled_credentials_mode: Option<bool>,
@@ -99,6 +101,13 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
let secondary_packet_size = args.medium_toggle.then_some(PacketSize::ExtendedPacket16);
let no_per_hop_delays = args.medium_toggle;
let topology_structure = if args.medium_toggle || args.geo_routing.is_some() {
// TODO: rethink the default group. I just picked one for now.
TopologyStructure::GeoAware(args.geo_routing.unwrap_or(CountryGroup::Europe))
} else {
TopologyStructure::default()
};
let packet_type = if args.outfox {
PacketType::Outfox
} else {
@@ -122,6 +131,10 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
// NOTE: see comment above about the order of the other disble cover traffic config
.with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover)
.with_base(BaseClientConfig::with_packet_type, packet_type)
.with_base(
BaseClientConfig::with_topology_structure,
topology_structure,
)
.with_optional(Config::with_anonymous_replies, args.use_anonymous_replies)
.with_optional(Config::with_port, args.port)
.with_optional_base_custom_env(
+13
View File
@@ -11,6 +11,7 @@ use clap::Args;
use log::*;
use nym_bin_common::version_checker::is_minor_version_compatible;
use nym_client_core::client::base_client::storage::OnDiskPersistent;
use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup;
use nym_crypto::asymmetric::identity;
use nym_socks5_client_core::NymClient;
use nym_sphinx::addressing::clients::Recipient;
@@ -60,6 +61,10 @@ pub(crate) struct Run {
#[clap(long, hide = true)]
no_cover: bool,
/// Set geo-aware mixnode selection when sending mixnet traffic, for experiments only.
#[clap(long, hide = true, value_parser = validate_country_group)]
geo_routing: Option<CountryGroup>,
/// Enable medium mixnet traffic, for experiments only.
/// This includes things like disabling cover traffic, no per hop delays, etc.
#[clap(long, hide = true)]
@@ -82,6 +87,7 @@ impl From<Run> for OverrideConfig {
use_anonymous_replies: run_config.use_anonymous_replies,
fastmode: run_config.fastmode,
no_cover: run_config.no_cover,
geo_routing: run_config.geo_routing,
medium_toggle: run_config.medium_toggle,
nyxd_urls: run_config.nyxd_urls,
enabled_credentials_mode: run_config.enabled_credentials_mode,
@@ -90,6 +96,13 @@ impl From<Run> for OverrideConfig {
}
}
fn validate_country_group(s: &str) -> Result<CountryGroup, String> {
match s.parse() {
Ok(cg) => Ok(cg),
Err(_) => Err(format!("failed to parse country group: {}", s)),
}
}
// this only checks compatibility between config the binary. It does not take into consideration
// network version. It might do so in the future.
fn version_check(cfg: &Config) -> bool {
+13
View File
@@ -2475,6 +2475,7 @@ dependencies = [
"nym-config",
"nym-credential-storage",
"nym-crypto",
"nym-explorer-api-requests",
"nym-gateway-client",
"nym-gateway-requests",
"nym-network-defaults",
@@ -2485,6 +2486,7 @@ dependencies = [
"nym-topology",
"nym-validator-client",
"rand 0.7.3",
"reqwest",
"serde",
"serde_json",
"sha2 0.10.6",
@@ -2689,6 +2691,17 @@ dependencies = [
"zeroize",
]
[[package]]
name = "nym-explorer-api-requests"
version = "0.1.0"
dependencies = [
"nym-contracts-common",
"nym-mixnet-contract-common",
"nym-validator-client",
"schemars",
"serde",
]
[[package]]
name = "nym-gateway-client"
version = "0.1.0"
+1
View File
@@ -246,6 +246,7 @@ impl From<TopologyWasm> for ConfigTopology {
topology.topology_resolution_timeout_ms,
),
disable_refreshing: topology.disable_refreshing,
topology_structure: Default::default(),
}
}
}
+6 -4
View File
@@ -10,27 +10,29 @@ rust-version = "1.66"
[dependencies]
async-trait = { workspace = true }
base64 = "0.21.2"
dirs = "4.0"
dashmap = "5.4.0"
dirs = "4.0"
futures = "0.3"
humantime-serde = "1.0"
log = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
reqwest = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = "0.10.6"
tap = "1.0.1"
thiserror = "1.0.34"
url = { version ="2.2", features = ["serde"] }
tungstenite = { version = "0.13.0", default-features = false }
tokio = { version = "1.24.1", features = ["macros"]}
time = "0.3.17"
tokio = { version = "1.24.1", features = ["macros"]}
tungstenite = { version = "0.13.0", default-features = false }
url = { version ="2.2", features = ["serde"] }
zeroize = { workspace = true }
# internal
nym-bandwidth-controller = { path = "../bandwidth-controller" }
nym-config = { path = "../config" }
nym-crypto = { path = "../crypto" }
nym-explorer-api-requests = { path = "../../explorer-api/explorer-api-requests" }
nym-gateway-client = { path = "../client-libs/gateway-client" }
#gateway-client = { path = "../../common/client-libs/gateway-client", default-features = false, features = ["wasm", "coconut"] }
nym-gateway-requests = { path = "../../gateway/gateway-requests" }
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use super::received_buffer::ReceivedBufferMessage;
use super::topology_control::geo_aware_provider::GeoAwareTopologyProvider;
use crate::client::base_client::storage::MixnetClientStorage;
use crate::client::cover_traffic_stream::LoopCoverTrafficStream;
use crate::client::inbound_messages::{InputMessage, InputMessageReceiver, InputMessageSender};
@@ -339,14 +340,20 @@ where
fn setup_topology_provider(
custom_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
provider_from_config: config::TopologyStructure,
nym_api_urls: Vec<Url>,
) -> Box<dyn TopologyProvider + Send + Sync> {
// if no custom provider was ... provided ..., create one using nym-api
custom_provider.unwrap_or_else(|| {
Box::new(NymApiTopologyProvider::new(
custom_provider.unwrap_or_else(|| match provider_from_config {
config::TopologyStructure::NymApi => Box::new(NymApiTopologyProvider::new(
nym_api_urls,
env!("CARGO_PKG_VERSION").to_string(),
))
)),
config::TopologyStructure::GeoAware(group) => Box::new(GeoAwareTopologyProvider::new(
nym_api_urls,
env!("CARGO_PKG_VERSION").to_string(),
group,
)),
})
}
@@ -521,8 +528,10 @@ where
let topology_provider = Self::setup_topology_provider(
self.custom_topology_provider.take(),
self.config.debug.topology.topology_structure,
self.config.get_nym_api_endpoints(),
);
Self::start_topology_refresher(
topology_provider,
self.config.debug.topology,
@@ -0,0 +1,319 @@
use std::{collections::HashMap, fmt};
use log::{debug, error, info};
use nym_explorer_api_requests::PrettyDetailedMixNodeBond;
use nym_topology::{
nym_topology_from_detailed,
provider_trait::{async_trait, TopologyProvider},
NymTopology,
};
use nym_validator_client::client::MixId;
use rand::{prelude::SliceRandom, thread_rng};
use serde::{Deserialize, Serialize};
use url::Url;
const MIN_NODES_PER_LAYER: usize = 1;
const EXPLORER_API_MIXNODES_URL: &str = "https://explorer.nymtech.net/api/v1/mix-nodes";
// TODO: create a explorer-api-client
async fn fetch_mixnodes_from_explorer_api() -> Option<Vec<PrettyDetailedMixNodeBond>> {
reqwest::get(EXPLORER_API_MIXNODES_URL)
.await
.ok()?
.json::<Vec<PrettyDetailedMixNodeBond>>()
.await
.ok()
}
#[derive(Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub enum CountryGroup {
Europe,
NorthAmerica,
SouthAmerica,
Oceania,
Asia,
Africa,
Unknown,
}
impl CountryGroup {
// We map contry codes into group, which initially are continent codes to a first approximation,
// but we do it manually to reserve the right to tweak this distribution for our purposes.
fn new(country_code: &str) -> Self {
let country_code = country_code.to_uppercase();
use CountryGroup::*;
match country_code.as_ref() {
// Europe
"AT" => Europe,
"BG" => Europe,
"CH" => Europe,
"CY" => Europe,
"CZ" => Europe,
"DE" => Europe,
"DK" => Europe,
"ES" => Europe,
"FI" => Europe,
"FR" => Europe,
"GB" => Europe,
"GR" => Europe,
"IE" => Europe,
"IT" => Europe,
"LT" => Europe,
"LU" => Europe,
"LV" => Europe,
"MD" => Europe,
"MT" => Europe,
"NL" => Europe,
"NO" => Europe,
"PL" => Europe,
"RO" => Europe,
"SE" => Europe,
"SK" => Europe,
"TR" => Europe,
"UA" => Europe,
// North America
"CA" => NorthAmerica,
"MX" => NorthAmerica,
"US" => NorthAmerica,
// South America
"AR" => SouthAmerica,
"BR" => SouthAmerica,
"CL" => SouthAmerica,
"CO" => SouthAmerica,
"CR" => SouthAmerica,
"GT" => SouthAmerica,
// Oceania
"AU" => Oceania,
// Asia
"AM" => Asia,
"BH" => Asia,
"CN" => Asia,
"GE" => Asia,
"HK" => Asia,
"ID" => Asia,
"IL" => Asia,
"IN" => Asia,
"JP" => Asia,
"KH" => Asia,
"KR" => Asia,
"KZ" => Asia,
"MY" => Asia,
"RU" => Asia,
"SG" => Asia,
"TH" => Asia,
"VN" => Asia,
// Africa
"SC" => Africa,
"UG" => Africa,
"ZA" => Africa,
// And group level codes work too
"EU" => Europe,
"NA" => NorthAmerica,
"SA" => SouthAmerica,
"OC" => Oceania,
"AS" => Asia,
"AF" => Africa,
// And some aliases
"EUROPE" => Europe,
"NORTHAMERICA" => NorthAmerica,
"SOUTHAMERICA" => SouthAmerica,
"OCEANIA" => Oceania,
"ASIA" => Asia,
"AFRICA" => Africa,
_ => {
info!("Unknown country code: {}", country_code);
Unknown
}
}
}
}
impl fmt::Display for CountryGroup {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use CountryGroup::*;
match self {
Europe => write!(f, "EU"),
NorthAmerica => write!(f, "NA"),
SouthAmerica => write!(f, "SA"),
Oceania => write!(f, "OC"),
Asia => write!(f, "AS"),
Africa => write!(f, "AF"),
Unknown => write!(f, "Unknown"),
}
}
}
impl std::str::FromStr for CountryGroup {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
let group = CountryGroup::new(s);
if group == CountryGroup::Unknown {
Err(())
} else {
Ok(group)
}
}
}
impl CountryGroup {
#[allow(unused)]
fn known(self) -> Option<CountryGroup> {
use CountryGroup::*;
match self {
Europe | NorthAmerica | SouthAmerica | Oceania | Asia | Africa => Some(self),
Unknown => None,
}
}
}
fn group_mixnodes_by_country_code(
mixnodes: Vec<PrettyDetailedMixNodeBond>,
) -> HashMap<CountryGroup, Vec<MixId>> {
mixnodes
.into_iter()
.fold(HashMap::<CountryGroup, Vec<MixId>>::new(), |mut acc, m| {
if let Some(ref location) = m.location {
let country_code = location.two_letter_iso_country_code.clone();
let group_code = CountryGroup::new(country_code.as_str());
let mixnodes = acc.entry(group_code).or_insert_with(Vec::new);
mixnodes.push(m.mix_id);
}
acc
})
}
fn log_mixnode_distribution(mixnodes: &HashMap<CountryGroup, Vec<MixId>>) {
let mixnode_distribution = mixnodes
.iter()
.map(|(k, v)| format!("{}: {}", k, v.len()))
.collect::<Vec<_>>()
.join(", ");
debug!("Mixnode distribution - {}", mixnode_distribution);
}
fn check_layer_integrity(topology: NymTopology) -> Result<(), ()> {
let mixes = topology.mixes();
if mixes.keys().len() < 3 {
error!("Layer is missing in topology!");
return Err(());
}
for (layer, mixnodes) in mixes {
debug!("Layer {:?} has {} mixnodes", layer, mixnodes.len());
if mixnodes.len() < MIN_NODES_PER_LAYER {
error!(
"There are only {} mixnodes in layer {:?}",
mixnodes.len(),
layer
);
return Err(());
}
}
Ok(())
}
pub struct GeoAwareTopologyProvider {
validator_client: nym_validator_client::client::NymApiClient,
filter_on: CountryGroup,
client_version: String,
}
impl GeoAwareTopologyProvider {
pub fn new(
mut nym_api_urls: Vec<Url>,
client_version: String,
filter_on: CountryGroup,
) -> GeoAwareTopologyProvider {
log::info!(
"Creating geo-aware topology provider with filter on {:?}",
filter_on
);
nym_api_urls.shuffle(&mut thread_rng());
GeoAwareTopologyProvider {
validator_client: nym_validator_client::client::NymApiClient::new(
nym_api_urls[0].clone(),
),
filter_on,
client_version,
}
}
async fn get_topology(&self) -> Option<NymTopology> {
let mixnodes = match self.validator_client.get_cached_active_mixnodes().await {
Err(err) => {
error!("failed to get network mixnodes - {err}");
return None;
}
Ok(mixes) => mixes,
};
let gateways = match self.validator_client.get_cached_gateways().await {
Err(err) => {
error!("failed to get network gateways - {err}");
return None;
}
Ok(gateways) => gateways,
};
// Also fetch mixnodes cached by explorer-api, with the purpose of getting their
// geolocation.
debug!("Fetching mixnodes from explorer-api...");
let Some(mixnodes_from_explorer_api) = fetch_mixnodes_from_explorer_api().await else {
error!("failed to get mixnodes from explorer-api");
return None;
};
// Partition mixnodes_from_explorer_api according to the value of
// two_letter_iso_country_code.
// NOTE: we construct the full distribution here, but only use the one we're interested in.
// The reason we this instead of a straight filter is that this opens up the possibility to
// complement a small grouping with mixnodes from adjecent countries.
let mixnode_distribution = group_mixnodes_by_country_code(mixnodes_from_explorer_api);
log_mixnode_distribution(&mixnode_distribution);
let Some(filtered_mixnode_ids) = mixnode_distribution.get(&self.filter_on) else {
error!("no mixnodes found for: {}", self.filter_on);
return None;
};
let mixnodes = mixnodes
.into_iter()
.filter(|m| filtered_mixnode_ids.contains(&m.mix_id()))
.collect::<Vec<_>>();
let topology = nym_topology_from_detailed(mixnodes, gateways)
.filter_system_version(&self.client_version);
// TODO: return real error type
check_layer_integrity(topology.clone()).ok()?;
Some(topology)
}
}
#[cfg(not(target_arch = "wasm32"))]
#[async_trait]
impl TopologyProvider for GeoAwareTopologyProvider {
// this will be manually refreshed on a timer specified inside mixnet client config
async fn get_new_topology(&mut self) -> Option<NymTopology> {
self.get_topology().await
}
}
#[cfg(target_arch = "wasm32")]
#[async_trait(?Send)]
impl TopologyProvider for GeoAwareTopologyProvider {
// this will be manually refreshed on a timer specified inside mixnet client config
async fn get_new_topology(&mut self) -> Option<NymTopology> {
self.get_topology().await
}
}
@@ -10,6 +10,7 @@ use nym_topology::NymTopologyError;
use std::time::Duration;
mod accessor;
pub mod geo_aware_provider;
pub(crate) mod nym_api_provider;
// TODO: move it to config later
+21 -1
View File
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use std::time::Duration;
use url::Url;
use crate::error::ClientCoreError;
use crate::{client::topology_control::geo_aware_provider::CountryGroup, error::ClientCoreError};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
@@ -158,6 +158,15 @@ impl Config {
self
}
pub fn with_topology_structure(mut self, topology_structure: TopologyStructure) -> Self {
self.set_topology_structure(topology_structure);
self
}
pub fn set_topology_structure(&mut self, topology_structure: TopologyStructure) {
self.debug.topology.topology_structure = topology_structure;
}
pub fn with_no_per_hop_delays(mut self, no_per_hop_delays: bool) -> Self {
if no_per_hop_delays {
self.set_no_per_hop_delays()
@@ -466,6 +475,16 @@ pub struct Topology {
/// the first valid instance.
/// Supersedes `topology_refresh_rate_ms`.
pub disable_refreshing: bool,
/// Specifies the mixnode topology to be used for sending packets.
pub topology_structure: TopologyStructure,
}
#[derive(Default, Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum TopologyStructure {
#[default]
NymApi,
GeoAware(CountryGroup),
}
impl Default for Topology {
@@ -474,6 +493,7 @@ impl Default for Topology {
topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE,
topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT,
disable_refreshing: false,
topology_structure: TopologyStructure::default(),
}
}
}
@@ -267,6 +267,7 @@ impl From<TopologyV1_1_20_2> for Topology {
topology_refresh_rate: value.topology_refresh_rate,
topology_resolution_timeout: value.topology_resolution_timeout,
disable_refreshing: value.disable_refreshing,
topology_structure: Default::default(),
}
}
}
@@ -69,6 +69,10 @@ impl MixNodeDetails {
self.bond_information.mix_id
}
pub fn layer(&self) -> Layer {
self.bond_information.layer
}
pub fn is_unbonding(&self) -> bool {
self.bond_information.is_unbonding
}
+1
View File
@@ -34,6 +34,7 @@ nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
rand_chacha = "0.2"
[features]
default = ["sphinx"]
serde = ["serde_crate", "serde_bytes", "ed25519-dalek/serde", "x25519-dalek/serde"]
asymmetric = ["x25519-dalek", "ed25519-dalek", "zeroize"]
hashing = ["blake3", "digest", "hkdf", "hmac", "generic-array"]
+5
View File
@@ -40,3 +40,8 @@ path = "framing"
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
version = "1.24.1"
features = ["sync"]
[features]
default = ["sphinx"]
sphinx = ["nym-crypto/sphinx", "nym-sphinx-params/sphinx", "nym-sphinx-types/sphinx"]
outfox = ["nym-crypto/outfox", "nym-sphinx-params/outfox", "nym-sphinx-types/outfox"]
+3 -2
View File
@@ -12,5 +12,6 @@ bytes = "1.0"
tokio-util = { version = "0.7.4", features = ["codec"] }
thiserror = "1.0.37"
nym-sphinx-types = { path = "../types" }
nym-sphinx-params = { path = "../params" }
nym-sphinx-types = { path = "../types", features = ["sphinx", "outfox"] }
nym-sphinx-params = { path = "../params", features = ["sphinx", "outfox"] }
+1
View File
@@ -15,5 +15,6 @@ nym-crypto = { path = "../../crypto", features = ["hashing", "symmetric"] }
nym-sphinx-types = { path = "../types" }
[features]
default = ["sphinx"]
sphinx = ["nym-crypto/sphinx", "nym-sphinx-types/outfox"]
outfox = ["nym-crypto/outfox", "nym-sphinx-types/outfox"]
+34 -5
View File
@@ -2,10 +2,10 @@
// SPDX-License-Identifier: Apache-2.0
use crate::PacketType;
use nym_sphinx_types::{
header::HEADER_SIZE, MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD,
PAYLOAD_OVERHEAD_SIZE,
};
#[cfg(feature = "sphinx")]
use nym_sphinx_types::{header::HEADER_SIZE, PAYLOAD_OVERHEAD_SIZE};
#[cfg(feature = "outfox")]
use nym_sphinx_types::{MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD};
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::convert::TryFrom;
@@ -14,6 +14,7 @@ use std::str::FromStr;
use thiserror::Error;
// each sphinx packet contains mandatory header and payload padding + markers
#[cfg(feature = "sphinx")]
const SPHINX_PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE;
// it's up to the smart people to figure those values out : )
@@ -22,16 +23,23 @@ const SPHINX_PACKET_OVERHEAD: usize = HEADER_SIZE + PAYLOAD_OVERHEAD_SIZE;
// TODO: I'm not entirely sure if we can easily extract `<AckEncryptionAlgorithm as NewStreamCipher>::NonceSize`
// into a const usize before relevant stuff is stabilised in rust...
#[cfg(feature = "sphinx")]
const ACK_IV_SIZE: usize = 16;
#[cfg(feature = "sphinx")]
const ACK_PACKET_SIZE: usize = ACK_IV_SIZE + crate::FRAG_ID_LEN + SPHINX_PACKET_OVERHEAD;
#[cfg(feature = "sphinx")]
const REGULAR_PACKET_SIZE: usize = 2 * 1024 + SPHINX_PACKET_OVERHEAD;
#[cfg(feature = "sphinx")]
const EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + SPHINX_PACKET_OVERHEAD;
#[cfg(feature = "sphinx")]
const EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + SPHINX_PACKET_OVERHEAD;
#[cfg(feature = "sphinx")]
const EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + SPHINX_PACKET_OVERHEAD;
#[cfg(feature = "outfox")]
const OUTFOX_ACK_PACKET_SIZE: usize = MIN_PACKET_SIZE + OUTFOX_PACKET_OVERHEAD;
#[cfg(feature = "outfox")]
const OUTFOX_REGULAR_PACKET_SIZE: usize = 2 * 1024 + OUTFOX_PACKET_OVERHEAD;
#[derive(Debug, Error)]
@@ -154,39 +162,55 @@ impl TryFrom<u8> for PacketSize {
impl PacketSize {
pub const fn size(self) -> usize {
#[allow(unreachable_patterns)]
match self {
#[cfg(feature = "sphinx")]
PacketSize::RegularPacket => REGULAR_PACKET_SIZE,
#[cfg(feature = "sphinx")]
PacketSize::AckPacket => ACK_PACKET_SIZE,
#[cfg(feature = "sphinx")]
PacketSize::ExtendedPacket8 => EXTENDED_PACKET_SIZE_8,
#[cfg(feature = "sphinx")]
PacketSize::ExtendedPacket16 => EXTENDED_PACKET_SIZE_16,
#[cfg(feature = "sphinx")]
PacketSize::ExtendedPacket32 => EXTENDED_PACKET_SIZE_32,
#[cfg(feature = "outfox")]
PacketSize::OutfoxRegularPacket => OUTFOX_REGULAR_PACKET_SIZE,
#[cfg(feature = "outfox")]
PacketSize::OutfoxAckPacket => OUTFOX_ACK_PACKET_SIZE,
_ => 0,
}
}
pub const fn header_size(&self) -> usize {
#[allow(unreachable_patterns)]
match self {
#[cfg(feature = "sphinx")]
PacketSize::RegularPacket
| PacketSize::AckPacket
| PacketSize::ExtendedPacket8
| PacketSize::ExtendedPacket16
| PacketSize::ExtendedPacket32 => HEADER_SIZE,
#[cfg(feature = "outfox")]
PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => MIX_PARAMS_LEN,
_ => 0,
}
}
pub const fn payload_overhead(&self) -> usize {
#[allow(unreachable_patterns)]
match self {
#[cfg(feature = "sphinx")]
PacketSize::RegularPacket
| PacketSize::AckPacket
| PacketSize::ExtendedPacket8
| PacketSize::ExtendedPacket16
| PacketSize::ExtendedPacket32 => PAYLOAD_OVERHEAD_SIZE,
#[cfg(feature = "outfox")]
PacketSize::OutfoxRegularPacket | PacketSize::OutfoxAckPacket => {
OUTFOX_PACKET_OVERHEAD - MIX_PARAMS_LEN // Mix params are calculated into the total overhead so we take them out here
}
_ => 0,
}
}
@@ -244,11 +268,16 @@ impl PacketSize {
plaintext_size: usize,
packet_type: PacketType,
) -> Result<Self, InvalidPacketSize> {
#[allow(unreachable_patterns)]
let overhead = match packet_type {
#[cfg(feature = "sphinx")]
PacketType::Mix => SPHINX_PACKET_OVERHEAD,
#[allow(deprecated)]
#[cfg(feature = "sphinx")]
PacketType::Vpn => SPHINX_PACKET_OVERHEAD,
#[cfg(feature = "outfox")]
PacketType::Outfox => OUTFOX_PACKET_OVERHEAD,
_ => 0,
};
let packet_size = plaintext_size + overhead;
Self::get_type(packet_size)
+1
View File
@@ -13,5 +13,6 @@ nym-outfox = { path = "../../../nym-outfox", optional = true }
thiserror = "1"
[features]
default = ["sphinx"]
sphinx = ["sphinx-packet"]
outfox = ["nym-outfox"]
+9 -4
View File
@@ -7,22 +7,27 @@ edition = "2021"
[dependencies]
dirs = "4.0"
futures = "0.3"
log = { workspace = true }
pin-project = "1.0"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
reqwest = "0.11.4"
schemars = { version = "0.8", features = ["preserve_order"] }
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
thiserror = "1.0.34"
tap = "1.0.1"
thiserror = "1.0.34"
tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] }
futures = "0.3"
url = "2.2"
nym-client-core = { path = "../client-core", features = ["fs-surb-storage"] }
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
nym-client-core = { path = "../client-core", features = ["fs-surb-storage"] }
nym-config = { path = "../config" }
nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common" }
nym-credential-storage = { path = "../credential-storage" }
nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
nym-network-defaults = { path = "../network-defaults" }
nym-socks5-proxy-helpers = { path = "../socks5/proxy-helpers" }
nym-service-providers-common = { path = "../../service-providers/common" }
nym-socks5-proxy-helpers = { path = "../socks5/proxy-helpers" }
nym-socks5-requests = { path = "../socks5/requests" }
nym-sphinx = { path = "../nymsphinx" }
nym-task = { path = "../task" }
+1
View File
@@ -24,6 +24,7 @@ use nym_credential_storage::storage::Storage as CredentialStorage;
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::params::PacketType;
use nym_task::{TaskClient, TaskManager};
use std::error::Error;
pub mod config;
+226 -16
View File
@@ -2,6 +2,19 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "aes"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
"ctr",
"opaque-debug 0.3.0",
]
[[package]]
name = "ahash"
version = "0.7.6"
@@ -19,6 +32,12 @@ version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4"
[[package]]
name = "arrayref"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
[[package]]
name = "autocfg"
version = "1.1.0"
@@ -55,13 +74,25 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "blake2"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330"
dependencies = [
"byte-tools",
"crypto-mac 0.7.0",
"digest 0.8.1",
"opaque-debug 0.2.3",
]
[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"generic-array",
"generic-array 0.14.6",
]
[[package]]
@@ -70,7 +101,7 @@ version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
"generic-array 0.14.6",
]
[[package]]
@@ -91,6 +122,12 @@ version = "3.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8"
[[package]]
name = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "byteorder"
version = "1.4.3"
@@ -118,6 +155,25 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chacha"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862"
dependencies = [
"byteorder",
"keystream",
]
[[package]]
name = "cipher"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
dependencies = [
"generic-array 0.14.6",
]
[[package]]
name = "coconut-test"
version = "0.1.0"
@@ -234,15 +290,21 @@ dependencies = [
"libc",
]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "crypto-bigint"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef"
dependencies = [
"generic-array",
"generic-array 0.14.6",
"rand_core 0.6.4",
"subtle",
"subtle 2.4.1",
"zeroize",
]
@@ -252,10 +314,39 @@ version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"generic-array 0.14.6",
"typenum",
]
[[package]]
name = "crypto-mac"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5"
dependencies = [
"generic-array 0.12.4",
"subtle 1.0.0",
]
[[package]]
name = "crypto-mac"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714"
dependencies = [
"generic-array 0.14.6",
"subtle 2.4.1",
]
[[package]]
name = "ctr"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea"
dependencies = [
"cipher",
]
[[package]]
name = "curve25519-dalek"
version = "3.2.0"
@@ -265,7 +356,7 @@ dependencies = [
"byteorder",
"digest 0.9.0",
"rand_core 0.5.1",
"subtle",
"subtle 2.4.1",
"zeroize",
]
@@ -477,13 +568,22 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "digest"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
dependencies = [
"generic-array 0.12.4",
]
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array",
"generic-array 0.14.6",
]
[[package]]
@@ -494,7 +594,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer 0.10.4",
"crypto-common",
"subtle",
"subtle 2.4.1",
]
[[package]]
@@ -570,12 +670,12 @@ dependencies = [
"der",
"digest 0.10.7",
"ff",
"generic-array",
"generic-array 0.14.6",
"group",
"pkcs8",
"rand_core 0.6.4",
"sec1",
"subtle",
"subtle 2.4.1",
"zeroize",
]
@@ -636,7 +736,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160"
dependencies = [
"rand_core 0.6.4",
"subtle",
"subtle 2.4.1",
]
[[package]]
@@ -755,6 +855,15 @@ dependencies = [
"slab",
]
[[package]]
name = "generic-array"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
dependencies = [
"typenum",
]
[[package]]
name = "generic-array"
version = "0.14.6"
@@ -822,7 +931,7 @@ checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7"
dependencies = [
"ff",
"rand_core 0.6.4",
"subtle",
"subtle 2.4.1",
]
[[package]]
@@ -846,6 +955,26 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hkdf"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b"
dependencies = [
"digest 0.9.0",
"hmac 0.11.0",
]
[[package]]
name = "hmac"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
dependencies = [
"crypto-mac 0.11.1",
"digest 0.9.0",
]
[[package]]
name = "hmac"
version = "0.12.1"
@@ -946,6 +1075,12 @@ dependencies = [
"sha2 0.10.6",
]
[[package]]
name = "keystream"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28"
[[package]]
name = "lazy_static"
version = "1.4.0"
@@ -970,6 +1105,12 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "libm"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4"
[[package]]
name = "libz-sys"
version = "1.1.8"
@@ -988,6 +1129,18 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
[[package]]
name = "lioness"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9"
dependencies = [
"arrayref",
"blake2",
"chacha",
"keystream",
]
[[package]]
name = "log"
version = "0.4.17"
@@ -1019,6 +1172,16 @@ dependencies = [
"rand_chacha 0.2.2",
]
[[package]]
name = "num-traits"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "nym-coconut-bandwidth"
version = "0.1.0"
@@ -1257,6 +1420,7 @@ dependencies = [
name = "nym-sphinx-types"
version = "0.2.0"
dependencies = [
"sphinx-packet",
"thiserror",
]
@@ -1302,6 +1466,12 @@ version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "opaque-debug"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "opaque-debug"
version = "0.3.0"
@@ -1492,6 +1662,16 @@ dependencies = [
"getrandom 0.2.10",
]
[[package]]
name = "rand_distr"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56"
dependencies = [
"num-traits",
"rand 0.7.3",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
@@ -1532,7 +1712,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb"
dependencies = [
"crypto-bigint",
"hmac",
"hmac 0.12.1",
"zeroize",
]
@@ -1641,9 +1821,9 @@ checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928"
dependencies = [
"base16ct",
"der",
"generic-array",
"generic-array 0.14.6",
"pkcs8",
"subtle",
"subtle 2.4.1",
"zeroize",
]
@@ -1725,7 +1905,7 @@ dependencies = [
"cfg-if",
"cpufeatures",
"digest 0.9.0",
"opaque-debug",
"opaque-debug 0.3.0",
]
[[package]]
@@ -1758,6 +1938,30 @@ dependencies = [
"autocfg",
]
[[package]]
name = "sphinx-packet"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc43eda802856ee82a7555c7b75ceb9e07451741c7a2f5f23d036020e01189d4"
dependencies = [
"aes",
"arrayref",
"blake2",
"bs58",
"byteorder",
"chacha",
"curve25519-dalek",
"digest 0.9.0",
"hkdf",
"hmac 0.11.0",
"lioness",
"log",
"rand 0.7.3",
"rand_distr",
"sha2 0.9.9",
"subtle 2.4.1",
]
[[package]]
name = "spki"
version = "0.6.0"
@@ -1768,6 +1972,12 @@ dependencies = [
"der",
]
[[package]]
name = "subtle"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee"
[[package]]
name = "subtle"
version = "2.4.1"
+2
View File
@@ -11,6 +11,8 @@
# Quickstart
- [Overview](quickstart/overview.md)
- [Chat demo (webapp)](quickstart/chat-demo.md)
- [Coconut Credential Playground (webapp)](quickstart/cred-playground.md)
- [SOCKS Proxy (CLI)](quickstart/socks-proxy.md)
- [NymConnect Beta (GUI)](quickstart/nymconnect-gui.md)
+2 -2
View File
@@ -1,5 +1,5 @@
# Introduction
Welcome to the Nym Developer Portal, containing the resources and tools needed to build privacy enhanced apps (PEApps) with Nym's technology. Whether you're a seasoned developer or just getting started, our portal is designed to help you create decentralized applications and services utilising the Nym mixnet.
Welcome to the Nym Developer Portal, containing quickstart resources, user manuals, integration information, and tutorials outlining to start building privacy enhanced apps.
Join our community of developers and start building the decentralized future today!
For more in-depth information about nodes, network traffic flows, etc check out the [docs](https://nymtech.net/docs).
@@ -0,0 +1,5 @@
# Chat demo (webapp)
You can find a browser-based 'hello world' chat app [here](https://chat-demo.nymtech.net).
Either open in two browser windows and send messages to yourself, or share with a friend and send messages to each other through the mixnet.
@@ -0,0 +1,5 @@
# Coconut Credential Playground (webapp)
There is a coconut-scheme based Credential Library playground [here](https://coco-demo.nymtech.net/). This is a WASM implementation of our Coconut libraries which generate raw Coconut credentials. Test it to create and re-randomize your own credentials.
For more information on what is happening here check out the [Coconut docs](https://nymtech.net/docs/coconut.html).
@@ -1,13 +1,7 @@
# Overview
There are multiple options to quickly connect to Nym and see the network in action without the need for any code changes to your application. At most, these involve running Nym as a second process alongside an existing application in order to send traffic through the mixnet.
There are multiple options to quickly connect to Nym and play with both the mixnet and credentials on the Sandbox testnet.
Demo applications:
* a browser-based 'hello world' [chat application](https://chat-demo.nymtech.net). Either open in two browser windows and send messages to yourself, or share with a friend and send messages to each other through the mixnet!
* a Coconut-scheme based [Credential Library](https://coco-demo.nymtech.net/). This is a WASM implementation of our Coconut libraries which generate raw Coconut credentials. Test it to create and re-randomize your own credentials!
<br>
Proxy traffic with the Nym Socks5 client:
* set up a plug-and-play connection with the [NymConnect](./nymconnect-gui.md) GUI for proxying Telegram, Electrum, Keybase or Blockstream Green traffic through the mixnet (~2 minutes).
* [Download and run](./socks-proxy.md) the Nym Socks5 client via the CLI, for other desktop applications with SOCKS5 connection options (~30 minutes).
At most, these involve running Nym as a second process alongside an existing application in order to send traffic through the mixnet, most are either interact webpages or a standalone app.
If you've already covered the information in this section, or want to jump straight into integrating/ a Nym connection into an existing application, head to the [Integrations](../integrations/integration-options.md) section.
If you've already covered the information in this section, or want to jump straight into integrating/ a Nym connection into an existing application, head to the [Integrations](../integrations/integration-options.md) section.
+10 -9
View File
@@ -1,6 +1,6 @@
[package]
name = "explorer-api"
version = "1.1.23"
version = "1.1.24"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -8,13 +8,18 @@ edition = "2021"
[dependencies]
chrono = { version = "0.4.19", features = ["serde"] }
clap = { version = "4.0", features = ["cargo", "derive"] }
dotenvy = "0.15.6"
humantime-serde = "1.0"
isocountry = "0.3.2"
itertools = "0.10.3"
lazy_static = "1.4.0"
log = { workspace = true }
maxminddb = "0.23.0"
okapi = { version = "0.7.0-rc.1", features = ["impl_json_schema"] }
pretty_env_logger = "0.4.0"
rand = "0.8.5"
rand_pcg = "0.3.1"
rand_seeder = "0.2.3"
reqwest = "0.11.4"
rocket = { version = "0.5.0-rc.2", features = ["json"] }
rocket_cors = { git="https://github.com/lawliet89/rocket_cors", rev="dfd3662c49e2f6fc37df35091cb94d82f7fb5915" }
@@ -24,15 +29,11 @@ serde = "1.0.126"
serde_json = "1.0.66"
thiserror = "1.0.29"
tokio = {version = "1.21.2", features = ["full"] }
maxminddb = "0.23.0"
dotenvy = "0.15.6"
rand = "0.8.5"
rand_seeder = "0.2.3"
rand_pcg = "0.3.1"
nym-mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet-contract" }
nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" }
nym-network-defaults = { path = "../common/network-defaults" }
nym-bin-common = { path = "../common/bin-common"}
nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" }
nym-explorer-api-requests = { path = "explorer-api-requests" }
nym-mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet-contract" }
nym-network-defaults = { path = "../common/network-defaults" }
nym-task = { path = "../common/task" }
nym-validator-client = { path = "../common/client-libs/validator-client", features=["http-client"] }
@@ -0,0 +1,12 @@
[package]
name = "nym-explorer-api-requests"
version = "0.1.0"
edition = "2021"
[dependencies]
nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts-common" }
nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" }
nym-validator-client = { path = "../../common/client-libs/validator-client" }
schemars = { version = "0.8", features = ["preserve_order"] }
serde = { version = "1.0", features = ["derive"] }
ts-rs = { version = "6.1.2", optional = true }
@@ -0,0 +1,44 @@
use nym_contracts_common::Percent;
use nym_mixnet_contract_common::{Addr, Coin, Layer, MixId, MixNode};
use nym_validator_client::models::NodePerformance;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum MixnodeStatus {
Active, // in both the active set and the rewarded set
Standby, // only in the rewarded set
Inactive, // in neither the rewarded set nor the active set
}
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct PrettyDetailedMixNodeBond {
pub mix_id: MixId,
pub location: Option<Location>,
pub status: MixnodeStatus,
pub pledge_amount: Coin,
pub total_delegation: Coin,
pub owner: Addr,
pub layer: Layer,
pub mix_node: MixNode,
pub stake_saturation: f32,
pub uncapped_saturation: f32,
pub avg_uptime: u8,
pub node_performance: NodePerformance,
pub estimated_operator_apy: f64,
pub estimated_delegators_apy: f64,
pub operating_cost: Coin,
pub profit_margin_percent: Percent,
pub family_id: Option<u16>,
pub blacklisted: bool,
}
#[derive(Clone, Debug, JsonSchema, Serialize, Deserialize)]
pub struct Location {
pub two_letter_iso_country_code: String,
pub three_letter_iso_country_code: String,
pub country_name: String,
pub latitude: Option<f64>,
pub longitude: Option<f64>,
}
@@ -1,9 +1,9 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::mix_nodes::location::Location;
use crate::state::ExplorerApiStateContext;
use log::{info, warn};
use nym_explorer_api_requests::Location;
use nym_task::TaskClient;
pub(crate) struct GeoLocateTask {
@@ -64,7 +64,7 @@ impl GeoLocateTask {
) {
Ok(opt) => match opt {
Some(location) => {
let location = Location::new(location);
let location: Location = location.into();
trace!(
"{} mix nodes already located. Ip {} is located in {:#?}",
+12
View File
@@ -42,6 +42,18 @@ pub(crate) struct Location {
pub(crate) longitude: Option<f64>,
}
impl From<Location> for nym_explorer_api_requests::Location {
fn from(location: Location) -> Self {
nym_explorer_api_requests::Location {
country_name: location.name,
two_letter_iso_country_code: location.iso_alpha2,
three_letter_iso_country_code: location.iso_alpha3,
latitude: location.latitude,
longitude: location.longitude,
}
}
}
impl GeoIp {
pub fn new() -> Self {
let db_path = std::env::var("GEOIP_DB_PATH").unwrap_or_else(|e| {
+2 -1
View File
@@ -6,9 +6,10 @@ use crate::mix_node::delegations::{
};
use crate::mix_node::econ_stats::retrieve_mixnode_econ_stats;
use crate::mix_node::models::{
EconomicDynamicsStats, NodeDescription, NodeStats, PrettyDetailedMixNodeBond, SummedDelegations,
EconomicDynamicsStats, NodeDescription, NodeStats, SummedDelegations,
};
use crate::state::ExplorerApiStateContext;
use nym_explorer_api_requests::PrettyDetailedMixNodeBond;
use nym_mixnet_contract_common::{Delegation, MixId};
use reqwest::Error as ReqwestError;
use rocket::response::status::NotFound;
+1 -1
View File
@@ -1,4 +1,4 @@
pub(crate) mod delegations;
pub(crate) mod econ_stats;
pub(crate) mod http;
pub(crate) mod models;
pub mod models;
+2 -36
View File
@@ -2,49 +2,15 @@
// SPDX-License-Identifier: Apache-2.0
use crate::cache::Cache;
use crate::mix_nodes::location::Location;
use nym_contracts_common::Percent;
use nym_mixnet_contract_common::Delegation;
use nym_mixnet_contract_common::{Addr, Coin, Layer, MixId, MixNode};
use nym_validator_client::models::{NodePerformance, SelectionChance};
use nym_mixnet_contract_common::{Addr, Coin, MixId};
use nym_validator_client::models::SelectionChance;
use serde::Deserialize;
use serde::Serialize;
use std::sync::Arc;
use std::time::SystemTime;
use tokio::sync::RwLock;
#[derive(Clone, Debug, Serialize, JsonSchema, PartialEq)]
#[serde(rename_all = "snake_case")]
pub(crate) enum MixnodeStatus {
Active, // in both the active set and the rewarded set
Standby, // only in the rewarded set
Inactive, // in neither the rewarded set nor the active set
}
#[derive(Clone, Debug, Serialize, JsonSchema)]
pub(crate) struct PrettyDetailedMixNodeBond {
// I leave this to @MS to refactor this type as a lot of things here are redundant thanks to
// the existence of `MixNodeDetails`
pub mix_id: MixId,
pub location: Option<Location>,
pub status: MixnodeStatus,
pub pledge_amount: Coin,
pub total_delegation: Coin,
pub owner: Addr,
pub layer: Layer,
pub mix_node: MixNode,
pub stake_saturation: f32,
pub uncapped_saturation: f32,
pub avg_uptime: u8,
pub node_performance: NodePerformance,
pub estimated_operator_apy: f64,
pub estimated_delegators_apy: f64,
pub operating_cost: Coin,
pub profit_margin_percent: Percent,
pub family_id: Option<u16>,
pub blacklisted: bool,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)]
pub struct SummedDelegations {
pub owner: Addr,
+1 -1
View File
@@ -1,6 +1,6 @@
use crate::mix_node::models::{MixnodeStatus, PrettyDetailedMixNodeBond};
use crate::mix_nodes::models::{MixNodeActiveSetSummary, MixNodeSummary};
use crate::state::ExplorerApiStateContext;
use nym_explorer_api_requests::{MixnodeStatus, PrettyDetailedMixNodeBond};
use rocket::serde::json::Json;
use rocket::{Route, State};
use rocket_okapi::okapi::openapi3::OpenApi;
+1 -22
View File
@@ -1,7 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::geo_ip::location;
use nym_explorer_api_requests::Location;
use nym_mixnet_contract_common::MixId;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
@@ -31,27 +31,6 @@ pub(crate) struct LocationCacheItem {
pub(crate) valid_until: SystemTime,
}
#[derive(Clone, Debug, JsonSchema, Serialize, Deserialize)]
pub(crate) struct Location {
pub(crate) two_letter_iso_country_code: String,
pub(crate) three_letter_iso_country_code: String,
pub(crate) country_name: String,
pub(crate) latitude: Option<f64>,
pub(crate) longitude: Option<f64>,
}
impl Location {
pub(crate) fn new(location: location::Location) -> Self {
Location {
country_name: location.name,
two_letter_iso_country_code: location.iso_alpha2,
three_letter_iso_country_code: location.iso_alpha3,
latitude: location.latitude,
longitude: location.longitude,
}
}
}
impl LocationCacheItem {
pub(crate) fn new_from_location(location: Option<Location>) -> Self {
LocationCacheItem {
+2 -2
View File
@@ -5,6 +5,7 @@ use std::collections::{HashMap, HashSet};
use std::sync::Arc;
use std::time::{Duration, SystemTime};
use nym_explorer_api_requests::{Location, MixnodeStatus, PrettyDetailedMixNodeBond};
use nym_mixnet_contract_common::rewarding::helpers::truncate_reward;
use nym_mixnet_contract_common::MixId;
use serde::Serialize;
@@ -14,8 +15,7 @@ use crate::helpers::best_effort_small_dec_to_f64;
use nym_validator_client::models::MixNodeBondAnnotated;
use super::utils::family_numerical_id;
use crate::mix_node::models::{MixnodeStatus, PrettyDetailedMixNodeBond};
use crate::mix_nodes::location::{Location, LocationCache, LocationCacheItem};
use crate::mix_nodes::location::{LocationCache, LocationCacheItem};
use crate::mix_nodes::CACHE_ENTRY_TTL;
#[derive(Clone, Debug, Serialize, JsonSchema)]
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-gateway"
version = "1.1.23"
version = "1.1.24"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-mixnode"
version = "1.1.24"
version = "1.1.25"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-api"
version = "1.1.24"
version = "1.1.25"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
+6
View File
@@ -2,6 +2,12 @@
## [Unreleased]
## [v1.1.16] (2023-08-08)
- Uncouple network-requester <-> gateway in nym-connect and harbourmaster ([#3472])
[#3472]: https://github.com/nymtech/nym/issues/3472
## [v1.1.15] (2023-07-25)
- NC Desktop - remove sentry DSN from code ([#3694])
+20 -2
View File
@@ -3559,6 +3559,7 @@ dependencies = [
"nym-config",
"nym-credential-storage",
"nym-crypto",
"nym-explorer-api-requests",
"nym-gateway-client",
"nym-gateway-requests",
"nym-network-defaults",
@@ -3569,6 +3570,7 @@ dependencies = [
"nym-topology",
"nym-validator-client",
"rand 0.7.3",
"reqwest",
"serde",
"serde_json",
"sha2 0.10.6",
@@ -3780,6 +3782,17 @@ dependencies = [
"zeroize",
]
[[package]]
name = "nym-explorer-api-requests"
version = "0.1.0"
dependencies = [
"nym-contracts-common",
"nym-mixnet-contract-common",
"nym-validator-client",
"schemars",
"serde",
]
[[package]]
name = "nym-gateway-client"
version = "0.1.0"
@@ -3979,7 +3992,9 @@ dependencies = [
"nym-bandwidth-controller",
"nym-client-core",
"nym-config",
"nym-contracts-common",
"nym-credential-storage",
"nym-mixnet-contract-common",
"nym-network-defaults",
"nym-service-providers-common",
"nym-socks5-proxy-helpers",
@@ -3989,10 +4004,13 @@ dependencies = [
"nym-validator-client",
"pin-project",
"rand 0.7.3",
"reqwest",
"schemars",
"serde",
"tap",
"thiserror",
"tokio",
"url",
]
[[package]]
@@ -5121,9 +5139,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "reqwest"
version = "0.11.15"
version = "0.11.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ba30cc2c0cd02af1222ed216ba659cdb2f879dfe3181852fe7c50b1d0005949"
checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55"
dependencies = [
"base64 0.21.2",
"bytes",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@nym/nym-connect",
"version": "1.1.15",
"version": "1.1.16",
"main": "index.js",
"license": "MIT",
"scripts": {
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-connect"
version = "1.1.15"
version = "1.1.16"
description = "nym-connect"
authors = ["Nym Technologies SA"]
license = ""
+20 -6
View File
@@ -1,17 +1,23 @@
use futures::{channel::mpsc, StreamExt};
use nym_client_core::client::base_client::storage::gateway_details::GatewayDetailsStore;
use nym_client_core::client::base_client::storage::{MixnetClientStorage, OnDiskPersistent};
use nym_client_core::{config::GatewayEndpointConfig, error::ClientCoreStatusMessage};
use nym_socks5_client_core::NymClient as Socks5NymClient;
use nym_socks5_client_core::Socks5ControlMessageSender;
use nym_client_core::{
client::{
base_client::storage::{
gateway_details::GatewayDetailsStore, MixnetClientStorage, OnDiskPersistent,
},
topology_control::geo_aware_provider::CountryGroup,
},
config::{GatewayEndpointConfig, TopologyStructure},
error::ClientCoreStatusMessage,
};
use nym_socks5_client_core::{NymClient as Socks5NymClient, Socks5ControlMessageSender};
use nym_sphinx::params::PacketSize;
use nym_task::manager::TaskStatus;
use std::sync::Arc;
use tap::TapFallible;
use tokio::sync::RwLock;
use crate::config::{Config, PrivacyLevel};
use crate::{
config::{Config, PrivacyLevel},
error::Result,
events::{self, emit_event, emit_status_event},
models::{ConnectionStatusKind, ConnectivityTestResult},
@@ -46,6 +52,14 @@ fn override_config_from_env(config: &mut Config, privacy_level: &PrivacyLevel) {
log::warn!("Disabling per-hop delay");
config.core.base.set_no_per_hop_delays();
// TODO: selectable in the UI
let default_country_group = CountryGroup::Europe;
log::warn!("Using geo-aware mixnode selection: {default_country_group}");
config
.core
.base
.set_topology_structure(TopologyStructure::GeoAware(default_country_group));
}
}
@@ -1,7 +1,7 @@
{
"package": {
"productName": "nym-connect",
"version": "1.1.15"
"version": "1.1.16"
},
"build": {
"distDir": "../dist",
+17
View File
@@ -101,6 +101,12 @@ dependencies = [
"password-hash",
]
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "async-trait"
version = "0.1.64"
@@ -464,6 +470,16 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chacha"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862"
dependencies = [
"byteorder",
"keystream",
]
[[package]]
name = "cipher"
version = "0.4.4"
@@ -3120,6 +3136,7 @@ dependencies = [
name = "nym-sphinx-types"
version = "0.2.0"
dependencies = [
"sphinx-packet",
"thiserror",
]
@@ -3,7 +3,7 @@
[package]
name = "nym-network-requester"
version = "1.1.23"
version = "1.1.24"
authors.workspace = true
edition.workspace = true
rust-version = "1.65"
@@ -136,7 +136,6 @@ impl HostsStore {
})
.map(Host::from)
.collect();
dbg!(&hosts);
Ok(hosts)
}
}
@@ -1,6 +1,6 @@
[package]
name = "nym-network-statistics"
version = "1.1.23"
version = "1.1.24"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-cli"
version = "1.1.23"
version = "1.1.24"
authors.workspace = true
edition = "2021"