Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f9b1d72b4 | |||
| 51db3d0d5d | |||
| 17708cdf92 | |||
| a9c56ef9ac | |||
| 724420f97c | |||
| 5c8749a2e1 |
Generated
+42
-116
@@ -2930,7 +2930,7 @@ dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"rustversion",
|
||||
"windows 0.61.3",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3600,7 +3600,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core 0.61.2",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4951,51 +4951,6 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-authenticator"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"bs58",
|
||||
"bytes",
|
||||
"clap",
|
||||
"defguard_wireguard_rs",
|
||||
"fastrand 2.3.0",
|
||||
"futures",
|
||||
"ipnetwork",
|
||||
"log",
|
||||
"mock_instant",
|
||||
"nym-authenticator-requests",
|
||||
"nym-bin-common",
|
||||
"nym-client-core",
|
||||
"nym-config",
|
||||
"nym-credential-verification",
|
||||
"nym-credentials-interface",
|
||||
"nym-crypto",
|
||||
"nym-gateway-requests",
|
||||
"nym-gateway-storage",
|
||||
"nym-id",
|
||||
"nym-network-defaults",
|
||||
"nym-sdk",
|
||||
"nym-service-provider-requests-common",
|
||||
"nym-service-providers-common",
|
||||
"nym-sphinx",
|
||||
"nym-task",
|
||||
"nym-types",
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.12",
|
||||
"time",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tokio-util",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-authenticator-requests"
|
||||
version = "0.1.0"
|
||||
@@ -5728,14 +5683,18 @@ version = "1.1.36"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"bincode",
|
||||
"bip39",
|
||||
"bs58",
|
||||
"dashmap",
|
||||
"defguard_wireguard_rs",
|
||||
"fastrand 2.3.0",
|
||||
"futures",
|
||||
"ipnetwork",
|
||||
"mock_instant",
|
||||
"nym-api-requests",
|
||||
"nym-authenticator",
|
||||
"nym-authenticator-requests",
|
||||
"nym-client-core",
|
||||
"nym-credential-verification",
|
||||
"nym-credentials",
|
||||
"nym-credentials-interface",
|
||||
@@ -5743,6 +5702,7 @@ dependencies = [
|
||||
"nym-gateway-requests",
|
||||
"nym-gateway-stats-storage",
|
||||
"nym-gateway-storage",
|
||||
"nym-id",
|
||||
"nym-ip-packet-router",
|
||||
"nym-mixnet-client",
|
||||
"nym-mixnode-common",
|
||||
@@ -5750,6 +5710,7 @@ dependencies = [
|
||||
"nym-network-requester",
|
||||
"nym-node-metrics",
|
||||
"nym-sdk",
|
||||
"nym-service-provider-requests-common",
|
||||
"nym-sphinx",
|
||||
"nym-statistics-common",
|
||||
"nym-task",
|
||||
@@ -5759,8 +5720,8 @@ dependencies = [
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"sha2 0.10.9",
|
||||
"sqlx",
|
||||
"thiserror 2.0.12",
|
||||
"time",
|
||||
"tokio",
|
||||
@@ -6276,7 +6237,6 @@ dependencies = [
|
||||
"indicatif 0.17.11",
|
||||
"ipnetwork",
|
||||
"lioness",
|
||||
"nym-authenticator",
|
||||
"nym-bin-common",
|
||||
"nym-client-core-config-types",
|
||||
"nym-config",
|
||||
@@ -7450,6 +7410,25 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-core-foundation"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-io-kit"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
@@ -9713,7 +9692,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"windows 0.61.3",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -9943,16 +9922,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.33.1"
|
||||
version = "0.37.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fc858248ea01b66f19d8e8a6d55f41deaf91e9d495246fd01368d99935c6c01"
|
||||
checksum = "07cec4dc2d2e357ca1e610cfb07de2fa7a10fc3e9fe89f72545f3d244ea87753"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"rayon",
|
||||
"windows 0.57.0",
|
||||
"objc2-core-foundation",
|
||||
"objc2-io-kit",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -11699,16 +11678,6 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143"
|
||||
dependencies = [
|
||||
"windows-core 0.57.0",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows"
|
||||
version = "0.61.3"
|
||||
@@ -11716,7 +11685,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
|
||||
dependencies = [
|
||||
"windows-collections",
|
||||
"windows-core 0.61.2",
|
||||
"windows-core",
|
||||
"windows-future",
|
||||
"windows-link",
|
||||
"windows-numerics",
|
||||
@@ -11728,19 +11697,7 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d"
|
||||
dependencies = [
|
||||
"windows-implement 0.57.0",
|
||||
"windows-interface 0.57.0",
|
||||
"windows-result 0.1.2",
|
||||
"windows-targets 0.52.6",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -11749,10 +11706,10 @@ version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
||||
dependencies = [
|
||||
"windows-implement 0.60.0",
|
||||
"windows-interface 0.59.1",
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link",
|
||||
"windows-result 0.3.4",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
@@ -11762,22 +11719,11 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
"windows-core",
|
||||
"windows-link",
|
||||
"windows-threading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.0"
|
||||
@@ -11789,17 +11735,6 @@ dependencies = [
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.57.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.104",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.1"
|
||||
@@ -11823,19 +11758,10 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1"
|
||||
dependencies = [
|
||||
"windows-core 0.61.2",
|
||||
"windows-core",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.3.4"
|
||||
|
||||
+2
-4
@@ -127,7 +127,6 @@ members = [
|
||||
"sdk/ffi/go",
|
||||
"sdk/ffi/shared",
|
||||
"sdk/rust/nym-sdk",
|
||||
"service-providers/authenticator",
|
||||
"service-providers/common",
|
||||
"service-providers/ip-packet-router",
|
||||
"service-providers/network-requester",
|
||||
@@ -165,13 +164,12 @@ default-members = [
|
||||
"nym-statistics-api",
|
||||
"nym-validator-rewarder",
|
||||
"nyx-chain-watcher",
|
||||
"service-providers/authenticator",
|
||||
"service-providers/ip-packet-router",
|
||||
"service-providers/network-requester",
|
||||
"tools/nymvisor",
|
||||
]
|
||||
|
||||
exclude = ["explorer", "contracts", "nym-wallet", "cpu-cycles"]
|
||||
exclude = ["contracts", "nym-wallet", "cpu-cycles"]
|
||||
|
||||
[workspace.package]
|
||||
authors = ["Nym Technologies SA"]
|
||||
@@ -325,7 +323,7 @@ strum = "0.27.2"
|
||||
strum_macros = "0.27.2"
|
||||
subtle-encoding = "0.5"
|
||||
syn = "1"
|
||||
sysinfo = "0.33.0"
|
||||
sysinfo = "0.37.0"
|
||||
tap = "1.0.1"
|
||||
tar = "0.4.44"
|
||||
tempfile = "3.20"
|
||||
|
||||
@@ -86,6 +86,25 @@ impl IntervalRewardParams {
|
||||
pub fn to_inline_json(&self) -> String {
|
||||
to_json_string(self).unwrap_or_else(|_| "serialisation failure".into())
|
||||
}
|
||||
|
||||
pub fn active_node_work(&self, standby_node_work: Decimal) -> WorkFactor {
|
||||
self.active_set_work_factor * standby_node_work
|
||||
}
|
||||
|
||||
pub fn standby_node_work(
|
||||
&self,
|
||||
rewarded_set_size: Decimal,
|
||||
standby_set_size: Decimal,
|
||||
) -> WorkFactor {
|
||||
let f = self.active_set_work_factor;
|
||||
let k = rewarded_set_size;
|
||||
let one = Decimal::one();
|
||||
|
||||
// nodes in reserve
|
||||
let k_r = standby_set_size;
|
||||
|
||||
one / (f * k - (f - one) * k_r)
|
||||
}
|
||||
}
|
||||
|
||||
/// Parameters used for reward calculation.
|
||||
@@ -109,18 +128,15 @@ pub struct RewardingParams {
|
||||
|
||||
impl RewardingParams {
|
||||
pub fn active_node_work(&self) -> WorkFactor {
|
||||
self.interval.active_set_work_factor * self.standby_node_work()
|
||||
let standby_work = self.standby_node_work();
|
||||
self.interval.active_node_work(standby_work)
|
||||
}
|
||||
|
||||
pub fn standby_node_work(&self) -> WorkFactor {
|
||||
let f = self.interval.active_set_work_factor;
|
||||
let k = self.dec_rewarded_set_size();
|
||||
let one = Decimal::one();
|
||||
|
||||
// nodes in reserve
|
||||
let k_r = self.dec_standby_set_size();
|
||||
|
||||
one / (f * k - (f - one) * k_r)
|
||||
let rewarded_set_size = self.dec_rewarded_set_size();
|
||||
let standby_set_size = self.dec_standby_set_size();
|
||||
self.interval
|
||||
.standby_node_work(rewarded_set_size, standby_set_size)
|
||||
}
|
||||
|
||||
pub fn rewarded_set_size(&self) -> u32 {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
use crate::config_score::{ConfigScoreParams, OutdatedVersionWeights, VersionScoreFormulaParams};
|
||||
use crate::nym_node::Role;
|
||||
use crate::reward_params::RewardedSetParams;
|
||||
use crate::EpochId;
|
||||
use contracts_common::Percent;
|
||||
use cosmwasm_schema::cw_serde;
|
||||
@@ -85,7 +86,11 @@ impl RewardedSet {
|
||||
}
|
||||
|
||||
pub fn rewarded_set_size(&self) -> usize {
|
||||
self.active_set_size() + self.standby.len()
|
||||
self.active_set_size() + self.standby_set_size()
|
||||
}
|
||||
|
||||
pub fn standby_set_size(&self) -> usize {
|
||||
self.standby.len()
|
||||
}
|
||||
|
||||
pub fn get_role(&self, node_id: NodeId) -> Option<Role> {
|
||||
@@ -110,6 +115,13 @@ impl RewardedSet {
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn matches_parameters(&self, params: RewardedSetParams) -> bool {
|
||||
self.entry_gateways.len() <= params.entry_gateways as usize
|
||||
&& self.exit_gateways.len() <= params.exit_gateways as usize
|
||||
&& self.layer1.len() + self.layer2.len() + self.layer3.len() <= params.mixnodes as usize
|
||||
&& self.standby.len() <= params.standby as usize
|
||||
}
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
|
||||
@@ -130,12 +130,7 @@ impl VerlocMeasurement {
|
||||
let variance_micros = data
|
||||
.iter()
|
||||
.map(|&value| {
|
||||
// make sure we don't underflow
|
||||
let diff = if mean > value {
|
||||
mean - value
|
||||
} else {
|
||||
value - mean
|
||||
};
|
||||
let diff = mean.abs_diff(value);
|
||||
// we don't need nanos precision
|
||||
let diff_micros = diff.as_micros();
|
||||
diff_micros * diff_micros
|
||||
|
||||
+16
-10
@@ -11,7 +11,7 @@ authors = [
|
||||
]
|
||||
description = "Implementation of the Nym Mixnet Gateway"
|
||||
edition = "2021"
|
||||
rust-version = "1.76"
|
||||
rust-version = "1.77"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -20,13 +20,16 @@ path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
bincode = { workspace = true }
|
||||
async-trait = { workspace = true }
|
||||
bip39 = { workspace = true }
|
||||
bs58 = { workspace = true }
|
||||
dashmap = { workspace = true }
|
||||
fastrand = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
ipnetwork = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
sha2 = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
time = { workspace = true }
|
||||
@@ -44,8 +47,8 @@ tracing = { workspace = true }
|
||||
url = { workspace = true, features = ["serde"] }
|
||||
zeroize = { workspace = true }
|
||||
|
||||
|
||||
# internal
|
||||
nym-authenticator = { path = "../service-providers/authenticator" }
|
||||
nym-api-requests = { path = "../nym-api/nym-api-requests" }
|
||||
nym-credentials = { path = "../common/credentials" }
|
||||
nym-credentials-interface = { path = "../common/credentials-interface" }
|
||||
@@ -71,13 +74,16 @@ nym-node-metrics = { path = "../nym-node/nym-node-metrics" }
|
||||
nym-wireguard = { path = "../common/wireguard" }
|
||||
nym-wireguard-types = { path = "../common/wireguard-types", default-features = false }
|
||||
|
||||
nym-authenticator-requests = { path = "../common/authenticator-requests" }
|
||||
nym-client-core = { path = "../common/client-core", features = ["cli"] }
|
||||
nym-id = { path = "../common/nym-id" }
|
||||
nym-service-provider-requests-common = { path = "../common/service-provider-requests-common" }
|
||||
|
||||
|
||||
defguard_wireguard_rs = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
|
||||
sqlx = { workspace = true, features = [
|
||||
"runtime-tokio-rustls",
|
||||
"sqlite",
|
||||
"macros",
|
||||
"migrate",
|
||||
] }
|
||||
[dev-dependencies]
|
||||
nym-gateway-storage = { path = "../common/gateway-storage", features = ["mock"] }
|
||||
nym-wireguard = { path = "../common/wireguard", features = ["mock"] }
|
||||
mock_instant = "0.5.3"
|
||||
time = { workspace = true }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use nym_authenticator::error::AuthenticatorError;
|
||||
use crate::node::internal_service_providers::authenticator::error::AuthenticatorError;
|
||||
use nym_gateway_stats_storage::error::StatsStorageError;
|
||||
use nym_gateway_storage::error::GatewayStorageError;
|
||||
use nym_ip_packet_router::error::IpPacketRouterError;
|
||||
|
||||
@@ -10,3 +10,5 @@ pub mod node;
|
||||
|
||||
pub use error::GatewayError;
|
||||
pub use node::GatewayTasksBuilder;
|
||||
|
||||
pub use node::internal_service_providers::authenticator as nym_authenticator;
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use nym_network_defaults::{
|
||||
WG_PORT, WG_TUN_DEVICE_IP_ADDRESS_V4, WG_TUN_DEVICE_IP_ADDRESS_V6, WG_TUN_DEVICE_NETMASK_V4,
|
||||
WG_TUN_DEVICE_NETMASK_V6,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
||||
|
||||
pub use nym_client_core::config::Config as BaseClientConfig;
|
||||
pub use persistence::AuthenticatorPaths;
|
||||
|
||||
pub mod persistence;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
||||
pub struct Config {
|
||||
#[serde(flatten)]
|
||||
pub base: BaseClientConfig,
|
||||
|
||||
#[serde(default)]
|
||||
pub authenticator: Authenticator,
|
||||
|
||||
pub storage_paths: AuthenticatorPaths,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn validate(&self) -> bool {
|
||||
// no other sections have explicit requirements (yet)
|
||||
self.base.validate()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(default, deny_unknown_fields)]
|
||||
pub struct Authenticator {
|
||||
/// Socket address this node will use for binding its wireguard interface.
|
||||
/// default: `0.0.0.0:51822`
|
||||
pub bind_address: SocketAddr,
|
||||
|
||||
/// Private IP address of the wireguard gateway.
|
||||
/// default: `10.1.0.1`
|
||||
pub private_ipv4: Ipv4Addr,
|
||||
|
||||
/// Private IP address of the wireguard gateway.
|
||||
/// default: `fc01::1`
|
||||
pub private_ipv6: Ipv6Addr,
|
||||
|
||||
/// Port announced to external clients wishing to connect to the wireguard interface.
|
||||
/// Useful in the instances where the node is behind a proxy.
|
||||
pub announced_port: u16,
|
||||
|
||||
/// The prefix denoting the maximum number of the clients that can be connected via Wireguard using IPv4.
|
||||
/// The maximum value for IPv4 is 32
|
||||
pub private_network_prefix_v4: u8,
|
||||
|
||||
/// The prefix denoting the maximum number of the clients that can be connected via Wireguard using IPv6.
|
||||
/// The maximum value for IPv6 is 128
|
||||
pub private_network_prefix_v6: u8,
|
||||
}
|
||||
|
||||
impl Default for Authenticator {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), WG_PORT),
|
||||
private_ipv4: WG_TUN_DEVICE_IP_ADDRESS_V4,
|
||||
private_ipv6: WG_TUN_DEVICE_IP_ADDRESS_V6,
|
||||
announced_port: WG_PORT,
|
||||
private_network_prefix_v4: WG_TUN_DEVICE_NETMASK_V4,
|
||||
private_network_prefix_v6: WG_TUN_DEVICE_NETMASK_V6,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Authenticator> for nym_wireguard_types::Config {
|
||||
fn from(value: Authenticator) -> Self {
|
||||
nym_wireguard_types::Config {
|
||||
bind_address: value.bind_address,
|
||||
private_ipv4: value.private_ipv4,
|
||||
private_ipv6: value.private_ipv6,
|
||||
announced_port: value.announced_port,
|
||||
private_network_prefix_v4: value.private_network_prefix_v4,
|
||||
private_network_prefix_v6: value.private_network_prefix_v6,
|
||||
}
|
||||
}
|
||||
}
|
||||
-2
@@ -101,5 +101,3 @@ pub enum AuthenticatorError {
|
||||
#[error("no credential received")]
|
||||
NoCredentialReceived,
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, AuthenticatorError>;
|
||||
+3
-1
@@ -5,7 +5,9 @@ use nym_client_core::{config::disk_persistence::CommonClientPaths, TopologyProvi
|
||||
use nym_sdk::{GatewayTransceiver, NymNetworkDetails};
|
||||
use nym_task::TaskClient;
|
||||
|
||||
use crate::{config::BaseClientConfig, error::AuthenticatorError};
|
||||
use crate::node::internal_service_providers::authenticator::{
|
||||
config::BaseClientConfig, error::AuthenticatorError,
|
||||
};
|
||||
|
||||
// Helper function to create the mixnet client.
|
||||
// This is NOT in the SDK since we don't want to expose any of the client-core config types.
|
||||
+28
-24
@@ -7,8 +7,10 @@ use std::{
|
||||
time::{Duration, SystemTime},
|
||||
};
|
||||
|
||||
use crate::{config::Config, error::*, seen_credential_cache::SeenCredentialCache};
|
||||
use crate::{error::AuthenticatorError, peer_manager::PeerManager};
|
||||
use crate::node::internal_service_providers::authenticator::{
|
||||
config::Config, error::AuthenticatorError, peer_manager::PeerManager,
|
||||
seen_credential_cache::SeenCredentialCache,
|
||||
};
|
||||
use defguard_wireguard_rs::net::IpAddrMask;
|
||||
use defguard_wireguard_rs::{host::Peer, key::Key};
|
||||
use futures::StreamExt;
|
||||
@@ -44,7 +46,7 @@ use rand::{prelude::IteratorRandom, thread_rng};
|
||||
use tokio::sync::RwLock;
|
||||
use tokio_stream::wrappers::IntervalStream;
|
||||
|
||||
type AuthenticatorHandleResult = Result<(Vec<u8>, Option<Recipient>)>;
|
||||
type AuthenticatorHandleResult = Result<(Vec<u8>, Option<Recipient>), AuthenticatorError>;
|
||||
const DEFAULT_REGISTRATION_TIMEOUT_CHECK: Duration = Duration::from_secs(60); // 1 minute
|
||||
|
||||
pub(crate) struct RegistredAndFree {
|
||||
@@ -110,7 +112,7 @@ impl MixnetListener {
|
||||
self.peer_manager.wireguard_gateway_data.keypair()
|
||||
}
|
||||
|
||||
async fn remove_stale_registrations(&self) -> Result<()> {
|
||||
async fn remove_stale_registrations(&self) -> Result<(), AuthenticatorError> {
|
||||
let mut registred_and_free = self.registred_and_free.write().await;
|
||||
let registred_values: Vec<_> = registred_and_free
|
||||
.registration_in_progres
|
||||
@@ -130,7 +132,7 @@ impl MixnetListener {
|
||||
registred_and_free
|
||||
.registration_in_progres
|
||||
.remove(®.gateway_data.pub_key());
|
||||
log::debug!(
|
||||
tracing::debug!(
|
||||
"Removed stale registration of {}",
|
||||
reg.gateway_data.pub_key()
|
||||
);
|
||||
@@ -146,7 +148,7 @@ impl MixnetListener {
|
||||
registred_and_free
|
||||
.registration_in_progres
|
||||
.remove(®.gateway_data.pub_key());
|
||||
log::debug!(
|
||||
tracing::debug!(
|
||||
"Removed stale registration of {}",
|
||||
reg.gateway_data.pub_key()
|
||||
);
|
||||
@@ -748,7 +750,7 @@ impl MixnetListener {
|
||||
&mut self,
|
||||
reconstructed: ReconstructedMessage,
|
||||
) -> AuthenticatorHandleResult {
|
||||
log::debug!(
|
||||
tracing::debug!(
|
||||
"Received message with sender_tag: {:?}",
|
||||
reconstructed.sender_tag
|
||||
);
|
||||
@@ -801,7 +803,7 @@ impl MixnetListener {
|
||||
response: Vec<u8>,
|
||||
recipient: Option<Recipient>,
|
||||
sender_tag: Option<AnonymousSenderTag>,
|
||||
) -> Result<()> {
|
||||
) -> Result<(), AuthenticatorError> {
|
||||
let input_message = create_input_message(recipient, sender_tag, response)?;
|
||||
self.mixnet_client.send(input_message).await.map_err(|err| {
|
||||
AuthenticatorError::FailedToSendPacketToMixnet {
|
||||
@@ -810,18 +812,18 @@ impl MixnetListener {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) async fn run(mut self) -> Result<()> {
|
||||
log::info!("Using authenticator version {CURRENT_VERSION}");
|
||||
pub(crate) async fn run(mut self) -> Result<(), AuthenticatorError> {
|
||||
tracing::info!("Using authenticator version {CURRENT_VERSION}");
|
||||
let mut task_client = self.task_handle.fork("main_loop");
|
||||
|
||||
while !task_client.is_shutdown() {
|
||||
tokio::select! {
|
||||
_ = task_client.recv() => {
|
||||
log::debug!("Authenticator [main loop]: received shutdown");
|
||||
tracing::debug!("Authenticator [main loop]: received shutdown");
|
||||
},
|
||||
_ = self.timeout_check_interval.next() => {
|
||||
if let Err(e) = self.remove_stale_registrations().await {
|
||||
log::error!("Could not clear stale registrations. The registration process might get jammed soon - {e:?}");
|
||||
tracing::error!("Could not clear stale registrations. The registration process might get jammed soon - {e:?}");
|
||||
}
|
||||
self.seen_credential_cache.remove_stale();
|
||||
}
|
||||
@@ -831,23 +833,23 @@ impl MixnetListener {
|
||||
match self.on_reconstructed_message(msg).await {
|
||||
Ok((response, recipient)) => {
|
||||
if let Err(err) = self.handle_response(response, recipient, sender_tag).await {
|
||||
log::error!("Mixnet listener failed to handle response: {err}");
|
||||
tracing::error!("Mixnet listener failed to handle response: {err}");
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("Error handling reconstructed mixnet message: {err}");
|
||||
tracing::error!("Error handling reconstructed mixnet message: {err}");
|
||||
}
|
||||
|
||||
};
|
||||
} else {
|
||||
log::trace!("Authenticator [main loop]: stopping since channel closed");
|
||||
tracing::trace!("Authenticator [main loop]: stopping since channel closed");
|
||||
break;
|
||||
};
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
log::debug!("Authenticator: stopping");
|
||||
tracing::debug!("Authenticator: stopping");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -855,7 +857,7 @@ impl MixnetListener {
|
||||
pub async fn credential_storage_preparation(
|
||||
ecash_verifier: Arc<dyn EcashManager + Send + Sync>,
|
||||
client_id: i64,
|
||||
) -> Result<PersistedBandwidth> {
|
||||
) -> Result<PersistedBandwidth, AuthenticatorError> {
|
||||
ecash_verifier
|
||||
.storage()
|
||||
.create_bandwidth_entry(client_id)
|
||||
@@ -874,7 +876,7 @@ async fn credential_verification(
|
||||
ecash_verifier: Arc<dyn EcashManager + Send + Sync>,
|
||||
credential: CredentialSpendingData,
|
||||
client_id: i64,
|
||||
) -> Result<i64> {
|
||||
) -> Result<i64, AuthenticatorError> {
|
||||
let bandwidth = credential_storage_preparation(ecash_verifier.clone(), client_id).await?;
|
||||
let client_bandwidth = ClientBandwidth::new(bandwidth.into());
|
||||
let mut verifier = CredentialVerifier::new(
|
||||
@@ -891,7 +893,9 @@ async fn credential_verification(
|
||||
Ok(verifier.verify().await?)
|
||||
}
|
||||
|
||||
fn deserialize_request(reconstructed: &ReconstructedMessage) -> Result<AuthenticatorRequest> {
|
||||
fn deserialize_request(
|
||||
reconstructed: &ReconstructedMessage,
|
||||
) -> Result<AuthenticatorRequest, AuthenticatorError> {
|
||||
let request_version = *reconstructed
|
||||
.message
|
||||
.first_chunk::<2>()
|
||||
@@ -948,7 +952,7 @@ fn deserialize_request(reconstructed: &ReconstructedMessage) -> Result<Authentic
|
||||
}
|
||||
}
|
||||
[version, _] => {
|
||||
log::info!("Received packet with invalid version: v{version}");
|
||||
tracing::info!("Received packet with invalid version: v{version}");
|
||||
Err(AuthenticatorError::InvalidPacketVersion(version))
|
||||
}
|
||||
}
|
||||
@@ -958,11 +962,11 @@ fn create_input_message(
|
||||
nym_address: Option<Recipient>,
|
||||
reply_to_tag: Option<AnonymousSenderTag>,
|
||||
response_packet: Vec<u8>,
|
||||
) -> Result<InputMessage> {
|
||||
) -> Result<InputMessage, AuthenticatorError> {
|
||||
let lane = TransmissionLane::General;
|
||||
let packet_type = None;
|
||||
if let Some(reply_to_tag) = reply_to_tag {
|
||||
log::debug!("Creating message using SURB");
|
||||
tracing::debug!("Creating message using SURB");
|
||||
Ok(InputMessage::new_reply(
|
||||
reply_to_tag,
|
||||
response_packet,
|
||||
@@ -970,7 +974,7 @@ fn create_input_message(
|
||||
packet_type,
|
||||
))
|
||||
} else if let Some(nym_address) = nym_address {
|
||||
log::debug!("Creating message using nym_address");
|
||||
tracing::debug!("Creating message using nym_address");
|
||||
Ok(InputMessage::new_regular(
|
||||
nym_address,
|
||||
response_packet,
|
||||
@@ -978,7 +982,7 @@ fn create_input_message(
|
||||
packet_type,
|
||||
))
|
||||
} else {
|
||||
log::error!("No nym-address or sender tag provided");
|
||||
tracing::error!("No nym-address or sender tag provided");
|
||||
Err(AuthenticatorError::MissingReplyToForOldClient)
|
||||
}
|
||||
}
|
||||
+18
-11
@@ -1,8 +1,7 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::{net::IpAddr, path::Path, sync::Arc, time::SystemTime};
|
||||
|
||||
use crate::node::internal_service_providers::authenticator::error::AuthenticatorError;
|
||||
use futures::channel::oneshot;
|
||||
use ipnetwork::IpNetwork;
|
||||
use nym_client_core::{HardcodedTopologyProvider, TopologyProvider};
|
||||
@@ -10,8 +9,16 @@ use nym_credential_verification::ecash::EcashManager;
|
||||
use nym_sdk::{mixnet::Recipient, GatewayTransceiver};
|
||||
use nym_task::{TaskClient, TaskHandle};
|
||||
use nym_wireguard::WireguardGatewayData;
|
||||
use std::{net::IpAddr, path::Path, sync::Arc, time::SystemTime};
|
||||
|
||||
use crate::{config::Config, error::AuthenticatorError};
|
||||
pub mod config;
|
||||
pub mod error;
|
||||
pub mod mixnet_client;
|
||||
pub mod mixnet_listener;
|
||||
mod peer_manager;
|
||||
mod seen_credential_cache;
|
||||
|
||||
pub use config::Config;
|
||||
|
||||
pub struct OnStartData {
|
||||
// to add more fields as required
|
||||
@@ -26,7 +33,7 @@ impl OnStartData {
|
||||
|
||||
pub struct Authenticator {
|
||||
#[allow(unused)]
|
||||
config: Config,
|
||||
config: crate::node::internal_service_providers::authenticator::Config,
|
||||
wait_for_gateway: bool,
|
||||
custom_topology_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
|
||||
custom_gateway_transceiver: Option<Box<dyn GatewayTransceiver + Send + Sync>>,
|
||||
@@ -39,7 +46,7 @@ pub struct Authenticator {
|
||||
|
||||
impl Authenticator {
|
||||
pub fn new(
|
||||
config: Config,
|
||||
config: crate::node::internal_service_providers::authenticator::Config,
|
||||
wireguard_gateway_data: WireguardGatewayData,
|
||||
used_private_network_ips: Vec<IpAddr>,
|
||||
ecash_verifier: Arc<EcashManager>,
|
||||
@@ -119,7 +126,7 @@ impl Authenticator {
|
||||
let task_handle: TaskHandle = self.shutdown.map(Into::into).unwrap_or_default();
|
||||
|
||||
// Connect to the mixnet
|
||||
let mixnet_client = crate::mixnet_client::create_mixnet_client(
|
||||
let mixnet_client = crate::node::internal_service_providers::authenticator::mixnet_client::create_mixnet_client(
|
||||
&self.config.base,
|
||||
task_handle
|
||||
.get_handle()
|
||||
@@ -129,7 +136,7 @@ impl Authenticator {
|
||||
self.wait_for_gateway,
|
||||
&self.config.storage_paths.common_paths,
|
||||
)
|
||||
.await?;
|
||||
.await?;
|
||||
|
||||
let self_address = *mixnet_client.nym_address();
|
||||
|
||||
@@ -150,7 +157,7 @@ impl Authenticator {
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
let mixnet_listener = crate::mixnet_listener::MixnetListener::new(
|
||||
let mixnet_listener = crate::node::internal_service_providers::authenticator::mixnet_listener::MixnetListener::new(
|
||||
self.config,
|
||||
free_private_network_ips,
|
||||
self.wireguard_gateway_data,
|
||||
@@ -159,8 +166,8 @@ impl Authenticator {
|
||||
self.ecash_verifier,
|
||||
);
|
||||
|
||||
log::info!("The address of this client is: {self_address}");
|
||||
log::info!("All systems go. Press CTRL-C to stop the server.");
|
||||
tracing::info!("The address of this client is: {self_address}");
|
||||
tracing::info!("All systems go. Press CTRL-C to stop the server.");
|
||||
|
||||
if let Some(on_start) = self.on_start {
|
||||
if on_start.send(OnStartData::new(self_address)).is_err() {
|
||||
+19
-8
@@ -1,7 +1,7 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::error::*;
|
||||
use crate::node::internal_service_providers::authenticator::error::AuthenticatorError;
|
||||
use defguard_wireguard_rs::{host::Peer, key::Key};
|
||||
use futures::channel::oneshot;
|
||||
use nym_credential_verification::{ClientBandwidth, CredentialVerifier};
|
||||
@@ -19,7 +19,7 @@ impl PeerManager {
|
||||
wireguard_gateway_data,
|
||||
}
|
||||
}
|
||||
pub async fn add_peer(&mut self, peer: Peer) -> Result<()> {
|
||||
pub async fn add_peer(&mut self, peer: Peer) -> Result<(), AuthenticatorError> {
|
||||
let (response_tx, response_rx) = oneshot::channel();
|
||||
let msg = PeerControlRequest::AddPeer { peer, response_tx };
|
||||
self.wireguard_gateway_data
|
||||
@@ -38,7 +38,7 @@ impl PeerManager {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn _remove_peer(&mut self, pub_key: PeerPublicKey) -> Result<()> {
|
||||
pub async fn _remove_peer(&mut self, pub_key: PeerPublicKey) -> Result<(), AuthenticatorError> {
|
||||
let key = Key::new(pub_key.to_bytes());
|
||||
let (response_tx, response_rx) = oneshot::channel();
|
||||
let msg = PeerControlRequest::RemovePeer { key, response_tx };
|
||||
@@ -60,7 +60,10 @@ impl PeerManager {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn query_peer(&mut self, public_key: PeerPublicKey) -> Result<Option<Peer>> {
|
||||
pub async fn query_peer(
|
||||
&mut self,
|
||||
public_key: PeerPublicKey,
|
||||
) -> Result<Option<Peer>, AuthenticatorError> {
|
||||
let key = Key::new(public_key.to_bytes());
|
||||
let (response_tx, response_rx) = oneshot::channel();
|
||||
let msg = PeerControlRequest::QueryPeer { key, response_tx };
|
||||
@@ -82,12 +85,18 @@ impl PeerManager {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn query_bandwidth(&mut self, public_key: PeerPublicKey) -> Result<i64> {
|
||||
pub async fn query_bandwidth(
|
||||
&mut self,
|
||||
public_key: PeerPublicKey,
|
||||
) -> Result<i64, AuthenticatorError> {
|
||||
let client_bandwidth = self.query_client_bandwidth(public_key).await?;
|
||||
Ok(client_bandwidth.available().await)
|
||||
}
|
||||
|
||||
pub async fn query_client_bandwidth(&mut self, key: PeerPublicKey) -> Result<ClientBandwidth> {
|
||||
pub async fn query_client_bandwidth(
|
||||
&mut self,
|
||||
key: PeerPublicKey,
|
||||
) -> Result<ClientBandwidth, AuthenticatorError> {
|
||||
let key = Key::new(key.to_bytes());
|
||||
let (response_tx, response_rx) = oneshot::channel();
|
||||
let msg = PeerControlRequest::GetClientBandwidth { key, response_tx };
|
||||
@@ -115,7 +124,7 @@ impl PeerManager {
|
||||
&mut self,
|
||||
key: PeerPublicKey,
|
||||
credential: CredentialSpendingData,
|
||||
) -> Result<CredentialVerifier> {
|
||||
) -> Result<CredentialVerifier, AuthenticatorError> {
|
||||
let key = Key::new(key.to_bytes());
|
||||
let (response_tx, response_rx) = oneshot::channel();
|
||||
let msg = PeerControlRequest::GetVerifier {
|
||||
@@ -157,7 +166,9 @@ mod tests {
|
||||
use time::{Duration, OffsetDateTime};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use crate::{config::Authenticator, mixnet_listener::credential_storage_preparation};
|
||||
use crate::nym_authenticator::{
|
||||
config::Authenticator, mixnet_listener::credential_storage_preparation,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ impl SeenCredentialCache {
|
||||
let now = SystemTime::now();
|
||||
self.cached_credentials.retain(|_, value| {
|
||||
let Ok(cache_time) = now.duration_since(value.timestamp) else {
|
||||
log::warn!("Got decreasing consecutive system timestamps");
|
||||
tracing::warn!("Got decreasing consecutive system timestamps");
|
||||
return false;
|
||||
};
|
||||
cache_time < SEEN_CREDENTIAL_CACHE_TIME
|
||||
+6
-4
@@ -5,10 +5,10 @@ use crate::node::client_handling::embedded_clients::{LocalEmbeddedClientHandle,
|
||||
use crate::node::client_handling::websocket::message_receiver::{
|
||||
MixMessageReceiver, MixMessageSender,
|
||||
};
|
||||
use crate::node::internal_service_providers::authenticator::Authenticator;
|
||||
use crate::GatewayError;
|
||||
use async_trait::async_trait;
|
||||
use futures::channel::{mpsc, oneshot};
|
||||
use nym_authenticator::Authenticator;
|
||||
use nym_crypto::asymmetric::ed25519;
|
||||
use nym_ip_packet_router::error::IpPacketRouterError;
|
||||
use nym_ip_packet_router::IpPacketRouter;
|
||||
@@ -22,6 +22,8 @@ use std::fmt::Display;
|
||||
use tokio::task::JoinHandle;
|
||||
use tracing::error;
|
||||
|
||||
pub mod authenticator;
|
||||
|
||||
pub trait LocalRecipient {
|
||||
fn address(&self) -> Recipient;
|
||||
}
|
||||
@@ -38,7 +40,7 @@ impl LocalRecipient for nym_ip_packet_router::OnStartData {
|
||||
}
|
||||
}
|
||||
|
||||
impl LocalRecipient for nym_authenticator::OnStartData {
|
||||
impl LocalRecipient for authenticator::OnStartData {
|
||||
fn address(&self) -> Recipient {
|
||||
self.address
|
||||
}
|
||||
@@ -78,8 +80,8 @@ impl RunnableServiceProvider for IpPacketRouter {
|
||||
#[async_trait]
|
||||
impl RunnableServiceProvider for Authenticator {
|
||||
const NAME: &'static str = "authenticator";
|
||||
type OnStartData = nym_authenticator::OnStartData;
|
||||
type Error = nym_authenticator::error::AuthenticatorError;
|
||||
type OnStartData = authenticator::OnStartData;
|
||||
type Error = authenticator::error::AuthenticatorError;
|
||||
|
||||
async fn run_service_provider(self) -> Result<(), Self::Error> {
|
||||
self.run_service_provider().await
|
||||
@@ -5,10 +5,10 @@ use crate::config::Config;
|
||||
use crate::error::GatewayError;
|
||||
use crate::node::client_handling::websocket;
|
||||
use crate::node::internal_service_providers::{
|
||||
ExitServiceProviders, ServiceProviderBeingBuilt, SpMessageRouterBuilder,
|
||||
authenticator, ExitServiceProviders, ServiceProviderBeingBuilt, SpMessageRouterBuilder,
|
||||
};
|
||||
use crate::node::stale_data_cleaner::StaleMessagesCleaner;
|
||||
use futures::channel::oneshot;
|
||||
use nym_authenticator::Authenticator;
|
||||
use nym_credential_verification::ecash::{
|
||||
credential_sender::CredentialHandlerConfig, EcashManager,
|
||||
};
|
||||
@@ -18,6 +18,7 @@ use nym_mixnet_client::forwarder::MixForwardingSender;
|
||||
use nym_network_defaults::NymNetworkDetails;
|
||||
use nym_network_requester::NRServiceProviderBuilder;
|
||||
use nym_node_metrics::events::MetricEventsSender;
|
||||
use nym_node_metrics::NymNodeMetrics;
|
||||
use nym_task::TaskClient;
|
||||
use nym_topology::TopologyProvider;
|
||||
use nym_validator_client::nyxd::{Coin, CosmWasmClient};
|
||||
@@ -31,10 +32,10 @@ use tracing::*;
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
pub(crate) mod client_handling;
|
||||
mod internal_service_providers;
|
||||
pub(crate) mod internal_service_providers;
|
||||
mod stale_data_cleaner;
|
||||
|
||||
use crate::node::stale_data_cleaner::StaleMessagesCleaner;
|
||||
use crate::node::internal_service_providers::authenticator::Authenticator;
|
||||
pub use client_handling::active_clients::ActiveClientsStore;
|
||||
pub use nym_gateway_stats_storage::PersistentStatsStorage;
|
||||
pub use nym_gateway_storage::{
|
||||
@@ -42,7 +43,6 @@ pub use nym_gateway_storage::{
|
||||
traits::{BandwidthGatewayStorage, InboxGatewayStorage},
|
||||
GatewayStorage,
|
||||
};
|
||||
use nym_node_metrics::NymNodeMetrics;
|
||||
pub use nym_sdk::{NymApiTopologyProvider, NymApiTopologyProviderConfig, UserAgent};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -61,7 +61,7 @@ pub struct LocalIpPacketRouterOpts {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LocalAuthenticatorOpts {
|
||||
pub config: nym_authenticator::Config,
|
||||
pub config: authenticator::Config,
|
||||
|
||||
pub custom_mixnet_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
@@ -5,12 +5,16 @@ use crate::epoch_operations::EpochAdvancer;
|
||||
use crate::support::caching::Cache;
|
||||
use cosmwasm_std::{Decimal, Fraction};
|
||||
use nym_api_requests::models::NodeAnnotation;
|
||||
use nym_mixnet_contract_common::helpers::IntoBaseDecimal;
|
||||
use nym_mixnet_contract_common::reward_params::{NodeRewardingParameters, Performance, WorkFactor};
|
||||
use nym_mixnet_contract_common::{EpochRewardedSet, ExecuteMsg, NodeId, RewardingParams};
|
||||
use nym_mixnet_contract_common::{
|
||||
EpochRewardedSet, ExecuteMsg, NodeId, RewardedSet, RewardingParams,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::max;
|
||||
use std::collections::HashMap;
|
||||
use tokio::sync::RwLockReadGuard;
|
||||
use tracing::error;
|
||||
use tracing::{debug, error};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub(crate) struct NodeWithPerformance {
|
||||
@@ -73,6 +77,137 @@ pub(super) fn stake_to_f64(stake: Decimal) -> f64 {
|
||||
}
|
||||
}
|
||||
|
||||
struct PerNodeWork {
|
||||
active: WorkFactor,
|
||||
standby: WorkFactor,
|
||||
}
|
||||
|
||||
struct NodeWorkCalculationComponents {
|
||||
active_set_size: Decimal,
|
||||
standby_set_size: Decimal,
|
||||
per_node_work: PerNodeWork,
|
||||
}
|
||||
|
||||
impl NodeWorkCalculationComponents {
|
||||
fn standby_set_work_share(&self) -> Decimal {
|
||||
self.standby_set_size * self.per_node_work.standby
|
||||
}
|
||||
|
||||
fn active_set_work_share(&self) -> Decimal {
|
||||
self.active_set_size * self.per_node_work.active
|
||||
}
|
||||
}
|
||||
|
||||
fn default_node_work_calculation(
|
||||
nodes: &RewardedSet,
|
||||
global_rewarding_params: RewardingParams,
|
||||
) -> NodeWorkCalculationComponents {
|
||||
let per_node_work = PerNodeWork {
|
||||
active: global_rewarding_params.active_node_work(),
|
||||
standby: global_rewarding_params.standby_node_work(),
|
||||
};
|
||||
// SANITY CHECK:
|
||||
// SAFETY: 0 decimal places is within the range of `Decimal`
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let standby_set_size = Decimal::from_atomics(nodes.standby.len() as u128, 0).unwrap();
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let active_set_size = Decimal::from_atomics(nodes.active_set_size() as u128, 0).unwrap();
|
||||
|
||||
NodeWorkCalculationComponents {
|
||||
active_set_size,
|
||||
standby_set_size,
|
||||
per_node_work,
|
||||
}
|
||||
}
|
||||
|
||||
fn manual_node_work_calculation(
|
||||
nodes: &RewardedSet,
|
||||
global_rewarding_params: RewardingParams,
|
||||
) -> NodeWorkCalculationComponents {
|
||||
// calculate everything manually based on the actual rewarded set on hand
|
||||
// but always attempt to minimise the node work, so take the maximum values
|
||||
// of the set sizes between new and old parameters
|
||||
// (more nodes = smaller per-node work as it has to be spread through more entries)
|
||||
let rewarded_set_size = max(
|
||||
global_rewarding_params.rewarded_set.rewarded_set_size(),
|
||||
nodes.rewarded_set_size() as u32,
|
||||
);
|
||||
let standby_set_size = max(
|
||||
global_rewarding_params.rewarded_set.standby,
|
||||
nodes.standby_set_size() as u32,
|
||||
);
|
||||
// the unwraps here are fine as we're guaranteed an `u32` is going to fit in a Decimal with 0 decimal places
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let rewarded_set_size_dec = rewarded_set_size.into_base_decimal().unwrap();
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let standby_set_size_dec = standby_set_size.into_base_decimal().unwrap();
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let active_set_size = rewarded_set_size
|
||||
.saturating_sub(standby_set_size)
|
||||
.into_base_decimal()
|
||||
.unwrap();
|
||||
|
||||
let standby_node_work = global_rewarding_params
|
||||
.interval
|
||||
.standby_node_work(rewarded_set_size_dec, standby_set_size_dec);
|
||||
let active_node_work = global_rewarding_params
|
||||
.interval
|
||||
.active_node_work(standby_node_work);
|
||||
let per_node_work = PerNodeWork {
|
||||
active: active_node_work,
|
||||
standby: standby_node_work,
|
||||
};
|
||||
|
||||
NodeWorkCalculationComponents {
|
||||
active_set_size,
|
||||
standby_set_size: standby_set_size_dec,
|
||||
per_node_work,
|
||||
}
|
||||
}
|
||||
|
||||
fn determine_per_node_work(
|
||||
nodes: &RewardedSet,
|
||||
// we only need reward parameters for active set work factor and rewarded/active set sizes;
|
||||
// we do not need exact values of reward pool, staking supply, etc., so it's fine if it's slightly out of sync
|
||||
global_rewarding_params: RewardingParams,
|
||||
) -> PerNodeWork {
|
||||
// currently we are using constant omega for nodes, but that will change with tickets
|
||||
// or different reward split between entry, exit, etc. at that point this will have to be calculated elsewhere
|
||||
let res = if nodes.matches_parameters(global_rewarding_params.rewarded_set) {
|
||||
default_node_work_calculation(nodes, global_rewarding_params)
|
||||
} else {
|
||||
error!("the current rewarded set does not much current rewarding parameters. this could only be expected if rewarded set distribution has been changed mid-epoch");
|
||||
manual_node_work_calculation(nodes, global_rewarding_params)
|
||||
};
|
||||
|
||||
let active_node_work_factor = res.per_node_work.active;
|
||||
let standby_node_work_factor = res.per_node_work.standby;
|
||||
|
||||
debug!("using {active_node_work_factor} as active node work factor and {standby_node_work_factor} as standby node work factor");
|
||||
|
||||
let standby_share = res.standby_set_work_share();
|
||||
let active_share = res.active_set_work_share();
|
||||
let total_work = standby_share + active_share;
|
||||
|
||||
// this HAS TO blow up. there's no recovery
|
||||
#[allow(clippy::panic)]
|
||||
if total_work > Decimal::one() {
|
||||
panic!("work calculation logic is flawed! somehow the total work in the system is greater than 1! \
|
||||
total work={total_work}, \
|
||||
active set share={active_share}, \
|
||||
standby share={standby_share}, \
|
||||
active node work factor={active_node_work_factor}, \
|
||||
standby node work factor={standby_node_work_factor}, \
|
||||
active set size={} \
|
||||
standby set size={}", res.active_set_size, res.standby_set_size);
|
||||
}
|
||||
|
||||
PerNodeWork {
|
||||
active: active_node_work_factor,
|
||||
standby: standby_node_work_factor,
|
||||
}
|
||||
}
|
||||
|
||||
impl EpochAdvancer {
|
||||
fn load_performance(
|
||||
status_cache: &Option<RwLockReadGuard<'_, Cache<HashMap<NodeId, NodeAnnotation>>>>,
|
||||
@@ -99,23 +234,9 @@ impl EpochAdvancer {
|
||||
global_rewarding_params: RewardingParams,
|
||||
) -> Vec<RewardedNodeWithParams> {
|
||||
let nodes = &nodes.assignment;
|
||||
// currently we are using constant omega for nodes, but that will change with tickets
|
||||
// or different reward split between entry, exit, etc. at that point this will have to be calculated elsewhere
|
||||
let active_node_work_factor = global_rewarding_params.active_node_work();
|
||||
let standby_node_work_factor = global_rewarding_params.standby_node_work();
|
||||
|
||||
// SANITY CHECK:
|
||||
// SAFETY: 0 decimal places is within the range of `Decimal`
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let standby_share = Decimal::from_atomics(nodes.standby.len() as u128, 0).unwrap()
|
||||
* standby_node_work_factor;
|
||||
#[allow(clippy::unwrap_used)]
|
||||
let active_share = Decimal::from_atomics(nodes.active_set_size() as u128, 0).unwrap()
|
||||
* active_node_work_factor;
|
||||
let total_work = standby_share + active_share;
|
||||
|
||||
// this HAS TO blow up. there's no recovery
|
||||
assert!(total_work <= Decimal::one(), "work calculation logic is flawed! somehow the total work in the system is greater than 1!");
|
||||
let nodes_work = determine_per_node_work(nodes, global_rewarding_params);
|
||||
let active_node_work_factor = nodes_work.active;
|
||||
let standby_node_work_factor = nodes_work.standby;
|
||||
|
||||
let status_cache = self.status_cache.node_annotations().await;
|
||||
if status_cache.is_none() {
|
||||
@@ -161,6 +282,9 @@ impl EpochAdvancer {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use nym_contracts_common::Percent;
|
||||
use nym_mixnet_contract_common::reward_params::RewardedSetParams;
|
||||
use nym_mixnet_contract_common::IntervalRewardParams;
|
||||
|
||||
fn compare_large_floats(a: f64, b: f64) {
|
||||
// for very large floats, allow for smaller larger epsilon
|
||||
@@ -206,4 +330,72 @@ mod tests {
|
||||
compare_large_floats(expected_f64, stake_to_f64(decimal))
|
||||
}
|
||||
}
|
||||
|
||||
fn dummy_rewarding_params() -> RewardingParams {
|
||||
RewardingParams {
|
||||
interval: IntervalRewardParams {
|
||||
reward_pool: Decimal::from_atomics(100_000_000_000_000u128, 0).unwrap(),
|
||||
staking_supply: Decimal::from_atomics(123_456_000_000_000u128, 0).unwrap(),
|
||||
staking_supply_scale_factor: Percent::hundred(),
|
||||
epoch_reward_budget: Decimal::from_ratio(100_000_000_000_000u128, 1234u32)
|
||||
* Decimal::percent(1),
|
||||
stake_saturation_point: Decimal::from_ratio(123_456_000_000_000u128, 313u32),
|
||||
sybil_resistance: Percent::from_percentage_value(23).unwrap(),
|
||||
active_set_work_factor: Decimal::from_atomics(10u32, 0).unwrap(),
|
||||
interval_pool_emission: Percent::from_percentage_value(1).unwrap(),
|
||||
},
|
||||
rewarded_set: RewardedSetParams {
|
||||
entry_gateways: 50,
|
||||
exit_gateways: 70,
|
||||
mixnodes: 120,
|
||||
standby: 20,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn determining_nodes_work() {
|
||||
let params = dummy_rewarding_params();
|
||||
// matched parameters
|
||||
let rewarded_set = RewardedSet {
|
||||
entry_gateways: (1..)
|
||||
.take(params.rewarded_set.entry_gateways as usize)
|
||||
.collect(),
|
||||
exit_gateways: (1000..)
|
||||
.take(params.rewarded_set.exit_gateways as usize)
|
||||
.collect(),
|
||||
layer1: (2000..)
|
||||
.take(params.rewarded_set.mixnodes as usize / 3)
|
||||
.collect(),
|
||||
layer2: (3000..)
|
||||
.take(params.rewarded_set.mixnodes as usize / 3)
|
||||
.collect(),
|
||||
layer3: (4000..)
|
||||
.take(params.rewarded_set.mixnodes as usize / 3)
|
||||
.collect(),
|
||||
standby: (5000..)
|
||||
.take(params.rewarded_set.standby as usize)
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let work = determine_per_node_work(&rewarded_set, params);
|
||||
assert_eq!(work.active, params.active_node_work());
|
||||
assert_eq!(work.standby, params.standby_node_work());
|
||||
|
||||
// updated
|
||||
// here we're interested in the fact that the calculation does not panic, i.e. total work <= 1
|
||||
let params = dummy_rewarding_params();
|
||||
let rewarded_set = RewardedSet {
|
||||
entry_gateways: (1..).take(250).collect(),
|
||||
exit_gateways: (1000..).take(100).collect(),
|
||||
layer1: (2000..).take(10).collect(),
|
||||
layer2: (3000..).take(10).collect(),
|
||||
layer3: (4000..).take(10).collect(),
|
||||
standby: (5000..).take(5).collect(),
|
||||
};
|
||||
|
||||
let work = determine_per_node_work(&rewarded_set, params);
|
||||
assert_ne!(work.active, params.active_node_work());
|
||||
assert_ne!(work.standby, params.standby_node_work());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,6 @@ nym-node-metrics = { path = "nym-node-metrics" }
|
||||
|
||||
# nodes:
|
||||
nym-gateway = { path = "../gateway" }
|
||||
nym-authenticator = { path = "../service-providers/authenticator" }
|
||||
nym-network-requester = { path = "../service-providers/network-requester" }
|
||||
nym-ip-packet-router = { path = "../service-providers/ip-packet-router" }
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use clap::crate_version;
|
||||
use nym_gateway::node::{
|
||||
LocalAuthenticatorOpts, LocalIpPacketRouterOpts, LocalNetworkRequesterOpts,
|
||||
};
|
||||
use nym_gateway::nym_authenticator;
|
||||
|
||||
// a temporary solution until further refactoring is made
|
||||
fn ephemeral_gateway_config(config: &Config) -> nym_gateway::config::Config {
|
||||
@@ -182,7 +183,6 @@ pub fn gateway_tasks_config(config: &Config) -> GatewayTasksConfig {
|
||||
.authenticator
|
||||
.to_common_client_paths(),
|
||||
},
|
||||
logging: config.logging,
|
||||
},
|
||||
custom_mixnet_path: None,
|
||||
};
|
||||
|
||||
@@ -21,6 +21,7 @@ use nym_config::{
|
||||
must_get_home, parse_urls, read_config_from_toml_file, save_formatted_config_to_file,
|
||||
NymConfigTemplate, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR,
|
||||
};
|
||||
use nym_gateway::nym_authenticator;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::env;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
[package]
|
||||
name = "nym-authenticator"
|
||||
version = "0.1.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
documentation.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
bincode = { workspace = true }
|
||||
bs58 = { workspace = true }
|
||||
bytes = { workspace = true }
|
||||
clap = { workspace = true, features = ["cargo", "derive"] }
|
||||
defguard_wireguard_rs = { workspace = true }
|
||||
fastrand = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
ipnetwork = { workspace = true }
|
||||
log = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "net"] }
|
||||
tokio-stream = { workspace = true }
|
||||
tokio-util = { workspace = true, features = ["codec"] }
|
||||
url = { workspace = true }
|
||||
|
||||
nym-authenticator-requests = { path = "../../common/authenticator-requests" }
|
||||
nym-bin-common = { path = "../../common/bin-common", features = [
|
||||
"clap",
|
||||
"output_format",
|
||||
"basic_tracing",
|
||||
] }
|
||||
nym-client-core = { path = "../../common/client-core", features = ["cli"] }
|
||||
nym-config = { path = "../../common/config" }
|
||||
nym-credentials-interface = { path = "../../common/credentials-interface" }
|
||||
nym-credential-verification = { path = "../../common/credential-verification" }
|
||||
nym-crypto = { path = "../../common/crypto" }
|
||||
nym-gateway-requests = { path = "../../common/gateway-requests" }
|
||||
nym-gateway-storage = { path = "../../common/gateway-storage" }
|
||||
nym-id = { path = "../../common/nym-id" }
|
||||
nym-network-defaults = { path = "../../common/network-defaults" }
|
||||
nym-sdk = { path = "../../sdk/rust/nym-sdk" }
|
||||
nym-service-providers-common = { path = "../common" }
|
||||
nym-service-provider-requests-common = { path = "../../common/service-provider-requests-common" }
|
||||
nym-sphinx = { path = "../../common/nymsphinx" }
|
||||
nym-task = { path = "../../common/task" }
|
||||
nym-types = { path = "../../common/types" }
|
||||
nym-wireguard = { path = "../../common/wireguard" }
|
||||
nym-wireguard-types = { path = "../../common/wireguard-types" }
|
||||
|
||||
[dev-dependencies]
|
||||
mock_instant = "0.5.3"
|
||||
time = { workspace = true }
|
||||
|
||||
nym-wireguard = { path = "../../common/wireguard", features = ["mock"] }
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use log::{info, trace};
|
||||
use std::path::Path;
|
||||
|
||||
use crate::{config::old_config_v1_1_54::ConfigV1_1_54, error::AuthenticatorError};
|
||||
|
||||
async fn try_upgrade_v1_1_54_config<P: AsRef<Path>>(id: P) -> Result<bool, AuthenticatorError> {
|
||||
// explicitly load it as v1.1.54 (which is incompatible with the current one, i.e. +1.1.55)
|
||||
let Ok(old_config) = ConfigV1_1_54::read_from_default_path(id) else {
|
||||
// if we failed to load it, there might have been nothing to upgrade
|
||||
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
||||
return Ok(false);
|
||||
};
|
||||
info!("It seems the client is using <= v1.1.54 config template.");
|
||||
info!("It is going to get updated to the current specification.");
|
||||
|
||||
let updated = old_config.try_upgrade()?;
|
||||
|
||||
updated.save_to_default_location()?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub async fn try_upgrade_config<P: AsRef<Path>>(id: P) -> Result<(), AuthenticatorError> {
|
||||
trace!("Attempting to upgrade config");
|
||||
if try_upgrade_v1_1_54_config(id).await? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use nym_bin_common::logging::LoggingSettings;
|
||||
pub use nym_client_core::config::Config as BaseClientConfig;
|
||||
use nym_client_core::{cli_helpers::CliClientConfig, config::disk_persistence::CommonClientPaths};
|
||||
use nym_config::{
|
||||
must_get_home, save_formatted_config_to_file, NymConfigTemplate, OptionalSet,
|
||||
DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR,
|
||||
};
|
||||
use nym_network_defaults::{
|
||||
WG_PORT, WG_TUN_DEVICE_IP_ADDRESS_V4, WG_TUN_DEVICE_IP_ADDRESS_V6, WG_TUN_DEVICE_NETMASK_V4,
|
||||
WG_TUN_DEVICE_NETMASK_V6,
|
||||
};
|
||||
use nym_service_providers_common::DEFAULT_SERVICE_PROVIDERS_DIR;
|
||||
pub use persistence::AuthenticatorPaths;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
io,
|
||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||
path::{Path, PathBuf},
|
||||
str::FromStr,
|
||||
};
|
||||
use template::CONFIG_TEMPLATE;
|
||||
|
||||
pub mod helpers;
|
||||
pub mod old_config_v1_1_54;
|
||||
pub mod persistence;
|
||||
pub mod template;
|
||||
|
||||
const DEFAULT_AUTHENTICATOR_DIR: &str = "authenticator";
|
||||
|
||||
/// Derive default path to authenticator's config directory.
|
||||
/// It should get resolved to `$HOME/.nym/service-providers/authenticator/<id>/config`
|
||||
pub fn default_config_directory<P: AsRef<Path>>(id: P) -> PathBuf {
|
||||
must_get_home()
|
||||
.join(NYM_DIR)
|
||||
.join(DEFAULT_SERVICE_PROVIDERS_DIR)
|
||||
.join(DEFAULT_AUTHENTICATOR_DIR)
|
||||
.join(id)
|
||||
.join(DEFAULT_CONFIG_DIR)
|
||||
}
|
||||
|
||||
/// Derive default path to authenticator's config file.
|
||||
/// It should get resolved to `$HOME/.nym/service-providers/authenticator/<id>/config/config.toml`
|
||||
pub fn default_config_filepath<P: AsRef<Path>>(id: P) -> PathBuf {
|
||||
default_config_directory(id).join(DEFAULT_CONFIG_FILENAME)
|
||||
}
|
||||
|
||||
/// Derive default path to authenticator's data directory where files, such as keys, are stored.
|
||||
/// It should get resolved to `$HOME/.nym/service-providers/authenticator/<id>/data`
|
||||
pub fn default_data_directory<P: AsRef<Path>>(id: P) -> PathBuf {
|
||||
must_get_home()
|
||||
.join(NYM_DIR)
|
||||
.join(DEFAULT_SERVICE_PROVIDERS_DIR)
|
||||
.join(DEFAULT_AUTHENTICATOR_DIR)
|
||||
.join(id)
|
||||
.join(DEFAULT_DATA_DIR)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Config {
|
||||
#[serde(flatten)]
|
||||
pub base: BaseClientConfig,
|
||||
|
||||
#[serde(default)]
|
||||
pub authenticator: Authenticator,
|
||||
|
||||
pub storage_paths: AuthenticatorPaths,
|
||||
|
||||
pub logging: LoggingSettings,
|
||||
}
|
||||
|
||||
impl NymConfigTemplate for Config {
|
||||
fn template(&self) -> &'static str {
|
||||
CONFIG_TEMPLATE
|
||||
}
|
||||
}
|
||||
|
||||
impl CliClientConfig for Config {
|
||||
fn common_paths(&self) -> &CommonClientPaths {
|
||||
&self.storage_paths.common_paths
|
||||
}
|
||||
|
||||
fn core_config(&self) -> &BaseClientConfig {
|
||||
&self.base
|
||||
}
|
||||
|
||||
fn default_store_location(&self) -> PathBuf {
|
||||
self.default_location()
|
||||
}
|
||||
|
||||
fn save_to<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
||||
save_formatted_config_to_file(self, path)
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new<S: AsRef<str>>(id: S) -> Self {
|
||||
Config {
|
||||
base: BaseClientConfig::new(id.as_ref(), env!("CARGO_PKG_VERSION")),
|
||||
authenticator: Default::default(),
|
||||
storage_paths: AuthenticatorPaths::new_base(default_data_directory(id.as_ref())),
|
||||
logging: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn with_data_directory<P: AsRef<Path>>(mut self, data_directory: P) -> Self {
|
||||
self.storage_paths = AuthenticatorPaths::new_base(data_directory);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
|
||||
nym_config::read_config_from_toml_file(path)
|
||||
}
|
||||
|
||||
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
|
||||
Self::read_from_toml_file(default_config_filepath(id))
|
||||
}
|
||||
|
||||
pub fn default_location(&self) -> PathBuf {
|
||||
default_config_filepath(&self.base.client.id)
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn save_to_default_location(&self) -> io::Result<()> {
|
||||
let config_save_location: PathBuf = self.default_location();
|
||||
save_formatted_config_to_file(self, config_save_location)
|
||||
}
|
||||
|
||||
pub fn validate(&self) -> bool {
|
||||
// no other sections have explicit requirements (yet)
|
||||
self.base.validate()
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn set_no_poisson_process(&mut self) {
|
||||
self.base.set_no_poisson_process()
|
||||
}
|
||||
|
||||
// poor man's 'builder' method
|
||||
#[allow(unused)]
|
||||
pub fn with_base<F, T>(mut self, f: F, val: T) -> Self
|
||||
where
|
||||
F: Fn(BaseClientConfig, T) -> BaseClientConfig,
|
||||
{
|
||||
self.base = f(self.base, val);
|
||||
self
|
||||
}
|
||||
|
||||
// helper methods to use `OptionalSet` trait. Those are defined due to very... ehm. 'specific' structure of this config
|
||||
// (plz, lets refactor it)
|
||||
pub fn with_optional_base<F, T>(mut self, f: F, val: Option<T>) -> Self
|
||||
where
|
||||
F: Fn(BaseClientConfig, T) -> BaseClientConfig,
|
||||
{
|
||||
self.base = self.base.with_optional(f, val);
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn with_optional_base_env<F, T>(mut self, f: F, val: Option<T>, env_var: &str) -> Self
|
||||
where
|
||||
F: Fn(BaseClientConfig, T) -> BaseClientConfig,
|
||||
T: FromStr,
|
||||
<T as FromStr>::Err: std::fmt::Debug,
|
||||
{
|
||||
self.base = self.base.with_optional_env(f, val, env_var);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_optional_base_custom_env<F, T, G>(
|
||||
mut self,
|
||||
f: F,
|
||||
val: Option<T>,
|
||||
env_var: &str,
|
||||
parser: G,
|
||||
) -> Self
|
||||
where
|
||||
F: Fn(BaseClientConfig, T) -> BaseClientConfig,
|
||||
G: Fn(&str) -> T,
|
||||
{
|
||||
self.base = self.base.with_optional_custom_env(f, val, env_var, parser);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(default, deny_unknown_fields)]
|
||||
pub struct Authenticator {
|
||||
/// Socket address this node will use for binding its wireguard interface.
|
||||
/// default: `0.0.0.0:51822`
|
||||
pub bind_address: SocketAddr,
|
||||
|
||||
/// Private IP address of the wireguard gateway.
|
||||
/// default: `10.1.0.1`
|
||||
pub private_ipv4: Ipv4Addr,
|
||||
|
||||
/// Private IP address of the wireguard gateway.
|
||||
/// default: `fc01::1`
|
||||
pub private_ipv6: Ipv6Addr,
|
||||
|
||||
/// Port announced to external clients wishing to connect to the wireguard interface.
|
||||
/// Useful in the instances where the node is behind a proxy.
|
||||
pub announced_port: u16,
|
||||
|
||||
/// The prefix denoting the maximum number of the clients that can be connected via Wireguard using IPv4.
|
||||
/// The maximum value for IPv4 is 32
|
||||
pub private_network_prefix_v4: u8,
|
||||
|
||||
/// The prefix denoting the maximum number of the clients that can be connected via Wireguard using IPv6.
|
||||
/// The maximum value for IPv6 is 128
|
||||
pub private_network_prefix_v6: u8,
|
||||
}
|
||||
|
||||
impl Default for Authenticator {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), WG_PORT),
|
||||
private_ipv4: WG_TUN_DEVICE_IP_ADDRESS_V4,
|
||||
private_ipv6: WG_TUN_DEVICE_IP_ADDRESS_V6,
|
||||
announced_port: WG_PORT,
|
||||
private_network_prefix_v4: WG_TUN_DEVICE_NETMASK_V4,
|
||||
private_network_prefix_v6: WG_TUN_DEVICE_NETMASK_V6,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Authenticator> for nym_wireguard_types::Config {
|
||||
fn from(value: Authenticator) -> Self {
|
||||
nym_wireguard_types::Config {
|
||||
bind_address: value.bind_address,
|
||||
private_ipv4: value.private_ipv4,
|
||||
private_ipv6: value.private_ipv6,
|
||||
announced_port: value.announced_port,
|
||||
private_network_prefix_v4: value.private_network_prefix_v4,
|
||||
private_network_prefix_v6: value.private_network_prefix_v6,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
use std::{io, path::Path};
|
||||
|
||||
use nym_bin_common::logging::LoggingSettings;
|
||||
pub use nym_client_core::config::old_config_v1_1_54::ConfigV1_1_54 as BaseConfigV1_1_54;
|
||||
use nym_config::read_config_from_toml_file;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{config::Config, error::AuthenticatorError};
|
||||
|
||||
use super::{default_config_filepath, Authenticator, AuthenticatorPaths};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct ConfigV1_1_54 {
|
||||
#[serde(flatten)]
|
||||
pub base: BaseConfigV1_1_54,
|
||||
|
||||
#[serde(default)]
|
||||
pub authenticator: Authenticator,
|
||||
|
||||
pub storage_paths: AuthenticatorPaths,
|
||||
|
||||
pub logging: LoggingSettings,
|
||||
}
|
||||
|
||||
impl ConfigV1_1_54 {
|
||||
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
|
||||
read_config_from_toml_file(path)
|
||||
}
|
||||
|
||||
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
|
||||
Self::read_from_toml_file(default_config_filepath(id))
|
||||
}
|
||||
|
||||
pub fn try_upgrade(self) -> Result<Config, AuthenticatorError> {
|
||||
Ok(Config {
|
||||
base: self.base.into(),
|
||||
authenticator: self.authenticator,
|
||||
storage_paths: self.storage_paths,
|
||||
logging: self.logging,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub(crate) const CONFIG_TEMPLATE: &str =
|
||||
// While using normal toml marshalling would have been way simpler with less overhead,
|
||||
// I think it's useful to have comments attached to the saved config file to explain behaviour of
|
||||
// particular fields.
|
||||
// Note: any changes to the template must be reflected in the appropriate structs.
|
||||
r#"
|
||||
# This is a TOML config file.
|
||||
# For more information, see https://github.com/toml-lang/toml
|
||||
|
||||
##### main base client config options #####
|
||||
|
||||
[client]
|
||||
# Version of the client for which this configuration was created.
|
||||
version = '{{ client.version }}'
|
||||
|
||||
# Human readable ID of this particular client.
|
||||
id = '{{ client.id }}'
|
||||
|
||||
# Indicates whether this client is running in a disabled credentials mode, thus attempting
|
||||
# to claim bandwidth without presenting bandwidth credentials.
|
||||
disabled_credentials_mode = {{ client.disabled_credentials_mode }}
|
||||
|
||||
# Addresses to nyxd validators via which the client can communicate with the chain.
|
||||
nyxd_urls = [
|
||||
{{#each client.nyxd_urls }}
|
||||
'{{this}}',
|
||||
{{/each}}
|
||||
]
|
||||
|
||||
# Addresses to APIs running on validator from which the client gets the view of the network.
|
||||
nym_api_urls = [
|
||||
{{#each client.nym_api_urls }}
|
||||
'{{this}}',
|
||||
{{/each}}
|
||||
]
|
||||
|
||||
[storage_paths]
|
||||
|
||||
# Path to file containing private identity key.
|
||||
keys.private_identity_key_file = '{{ storage_paths.keys.private_identity_key_file }}'
|
||||
|
||||
# Path to file containing public identity key.
|
||||
keys.public_identity_key_file = '{{ storage_paths.keys.public_identity_key_file }}'
|
||||
|
||||
# Path to file containing private encryption key.
|
||||
keys.private_encryption_key_file = '{{ storage_paths.keys.private_encryption_key_file }}'
|
||||
|
||||
# Path to file containing public encryption key.
|
||||
keys.public_encryption_key_file = '{{ storage_paths.keys.public_encryption_key_file }}'
|
||||
|
||||
# Path to file containing key used for encrypting and decrypting the content of an
|
||||
# acknowledgement so that nobody besides the client knows which packet it refers to.
|
||||
keys.ack_key_file = '{{ storage_paths.keys.ack_key_file }}'
|
||||
|
||||
# Path to the database containing bandwidth credentials
|
||||
credentials_database = '{{ storage_paths.credentials_database }}'
|
||||
|
||||
# Path to the persistent store for received reply surbs, unused encryption keys and used sender tags.
|
||||
reply_surb_database = '{{ storage_paths.reply_surb_database }}'
|
||||
|
||||
# Path to the file containing information about gateways used by this client,
|
||||
# i.e. details such as their public keys, owner addresses or the network information.
|
||||
gateway_registrations = '{{ storage_paths.gateway_registrations }}'
|
||||
|
||||
# Location of the file containing our allow.list
|
||||
allowed_list_location = '{{ storage_paths.allowed_list_location }}'
|
||||
|
||||
# Location of the file containing our unknown.list
|
||||
unknown_list_location = '{{ storage_paths.unknown_list_location }}'
|
||||
|
||||
|
||||
##### logging configuration options #####
|
||||
|
||||
[logging]
|
||||
|
||||
# TODO
|
||||
|
||||
|
||||
##### debug configuration options #####
|
||||
# The following options should not be modified unless you know EXACTLY what you are doing
|
||||
# as if set incorrectly, they may impact your anonymity.
|
||||
|
||||
[debug]
|
||||
|
||||
[debug.acknowledgements]
|
||||
average_ack_delay = '{{ debug.acknowledgements.average_ack_delay }}'
|
||||
|
||||
[debug.cover_traffic]
|
||||
loop_cover_traffic_average_delay = '{{ debug.cover_traffic.loop_cover_traffic_average_delay }}'
|
||||
|
||||
"#;
|
||||
@@ -1,13 +0,0 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub use authenticator::{Authenticator, OnStartData};
|
||||
pub use config::Config;
|
||||
|
||||
pub mod authenticator;
|
||||
pub mod config;
|
||||
pub mod error;
|
||||
pub mod mixnet_client;
|
||||
pub mod mixnet_listener;
|
||||
mod peer_manager;
|
||||
mod seen_credential_cache;
|
||||
Reference in New Issue
Block a user