Compare commits

..

5 Commits

Author SHA1 Message Date
Mark Sinclair 70f5d476f2 Tidy up package.json workspace to prefer packages from npm 2023-10-11 14:58:44 +01:00
Mark Sinclair 445f3b0adb Update lock file 2023-10-11 14:58:14 +01:00
Mark Sinclair 42836b3e0e Add packages to version bumper internal tool 2023-10-11 14:57:57 +01:00
Mark Sinclair 7c2318a096 Release Typescript SDK v1.2.0 packages 2023-10-11 11:31:41 +01:00
benedettadavico 1b4bf74107 bump wallet version and update changelog 2023-10-10 09:47:46 +02:00
65 changed files with 267 additions and 2406 deletions
@@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [custom-ubuntu-20.04, macos-latest, windows10]
os: [custom-linux, macos-latest, windows10]
runs-on: ${{ matrix.os }}
env:
CARGO_TERM_COLOR: always
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [custom-ubuntu-20.04]
platform: [custom-runner-linux]
runs-on: ${{ matrix.platform }}
outputs:
@@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [custom-ubuntu-20.04]
platform: [custom-runner-linux]
runs-on: ${{ matrix.platform }}
outputs:
+1 -1
View File
@@ -7,7 +7,7 @@ on:
jobs:
build:
if: ${{ (startsWith(github.ref, 'refs/tags/nym-contracts-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
runs-on: [self-hosted, custom-ubuntu-20.04]
runs-on: [self-hosted, custom-runner-linux]
steps:
- uses: actions/checkout@v2
@@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [custom-ubuntu-20.04]
platform: [custom-runner-linux]
runs-on: ${{ matrix.platform }}
outputs:
@@ -12,7 +12,7 @@ on:
jobs:
build:
name: Build APK
runs-on: custom-ubuntu-20.04
runs-on: custom-runner-linux
env:
ANDROID_HOME: ${{ github.workspace }}/android-sdk
NDK_VERSION: 25.2.9519653
+1 -1
View File
@@ -4,7 +4,7 @@ on:
jobs:
publish:
runs-on: [custom-ubuntu-20.04]
runs-on: [custom-runner-linux]
steps:
- uses: actions/checkout@v2
-3
View File
@@ -3,9 +3,6 @@
Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
- add client registry to Gateway ([#3955])
- add HTTP API to Gateway ([#3955])
- add `/client/<pub-key>`, `clients` and `register` routes to the gateway ([#3955])
## [2023.1-milka] (2023-09-24)
Generated
+33 -71
View File
@@ -766,11 +766,7 @@ dependencies = [
"pin-project-lite 0.2.12",
"rustversion",
"serde",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tower",
"tower-layer",
"tower-service",
@@ -793,18 +789,6 @@ dependencies = [
"tower-service",
]
[[package]]
name = "axum-macros"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62"
dependencies = [
"heck 0.4.1",
"proc-macro2",
"quote",
"syn 2.0.28",
]
[[package]]
name = "backtrace"
version = "0.3.68"
@@ -884,7 +868,7 @@ dependencies = [
"pbkdf2",
"rand_core 0.6.4",
"ripemd",
"sha2 0.10.8",
"sha2 0.10.7",
"subtle 2.4.1",
"zeroize",
]
@@ -1092,7 +1076,7 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896"
dependencies = [
"sha2 0.10.8",
"sha2 0.10.7",
]
[[package]]
@@ -1755,7 +1739,7 @@ dependencies = [
"schemars",
"serde",
"serde-json-wasm",
"sha2 0.10.8",
"sha2 0.10.7",
"thiserror",
]
@@ -2991,7 +2975,7 @@ dependencies = [
[[package]]
name = "extension-storage"
version = "1.2.0-rc.10"
version = "1.2.0"
dependencies = [
"bip39",
"console_error_panic_hook",
@@ -4381,7 +4365,7 @@ dependencies = [
"cfg-if",
"ecdsa 0.14.8",
"elliptic-curve 0.12.3",
"sha2 0.10.8",
"sha2 0.10.7",
]
[[package]]
@@ -4394,7 +4378,7 @@ dependencies = [
"ecdsa 0.16.8",
"elliptic-curve 0.13.5",
"once_cell",
"sha2 0.10.8",
"sha2 0.10.7",
"signature 2.1.0",
]
@@ -4628,7 +4612,7 @@ dependencies = [
"rand 0.8.5",
"rw-stream-sink 0.3.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)",
"sec1 0.3.0",
"sha2 0.10.8",
"sha2 0.10.7",
"smallvec",
"thiserror",
"unsigned-varint",
@@ -4714,7 +4698,7 @@ dependencies = [
"prost-codec",
"rand 0.8.5",
"regex",
"sha2 0.10.8",
"sha2 0.10.7",
"smallvec",
"thiserror",
"unsigned-varint",
@@ -4746,7 +4730,7 @@ dependencies = [
"rand 0.8.5",
"regex",
"serde",
"sha2 0.10.8",
"sha2 0.10.7",
"smallvec",
"thiserror",
"unsigned-varint",
@@ -4789,7 +4773,7 @@ dependencies = [
"quick-protobuf",
"rand 0.8.5",
"serde",
"sha2 0.10.8",
"sha2 0.10.7",
"thiserror",
"zeroize",
]
@@ -4815,7 +4799,7 @@ dependencies = [
"quick-protobuf",
"rand 0.8.5",
"serde",
"sha2 0.10.8",
"sha2 0.10.7",
"smallvec",
"thiserror",
"uint",
@@ -4920,7 +4904,7 @@ dependencies = [
"prost",
"prost-build",
"rand 0.8.5",
"sha2 0.10.8",
"sha2 0.10.7",
"snow",
"static_assertions",
"thiserror",
@@ -4943,7 +4927,7 @@ dependencies = [
"once_cell",
"quick-protobuf",
"rand 0.8.5",
"sha2 0.10.8",
"sha2 0.10.7",
"snow",
"static_assertions",
"thiserror",
@@ -5533,7 +5517,7 @@ dependencies = [
[[package]]
name = "mix-fetch-wasm"
version = "1.2.0-rc.10"
version = "1.2.0"
dependencies = [
"futures",
"js-sys",
@@ -5632,7 +5616,7 @@ dependencies = [
"multihash-derive",
"serde",
"serde-big-array",
"sha2 0.10.8",
"sha2 0.10.7",
"unsigned-varint",
]
@@ -6209,7 +6193,7 @@ dependencies = [
"reqwest",
"serde",
"serde_json",
"sha2 0.10.8",
"sha2 0.10.7",
"sqlx 0.6.3",
"tap",
"tempfile",
@@ -6229,7 +6213,7 @@ dependencies = [
[[package]]
name = "nym-client-wasm"
version = "1.2.0-rc.10"
version = "1.2.0"
dependencies = [
"anyhow",
"futures",
@@ -6479,9 +6463,6 @@ dependencies = [
"anyhow",
"async-trait",
"atty",
"axum",
"axum-macros",
"base64 0.21.4",
"bip39",
"bs58 0.4.0",
"clap 4.3.21",
@@ -6489,11 +6470,8 @@ dependencies = [
"dashmap",
"dirs 4.0.0",
"dotenvy",
"fastrand 2.0.0",
"futures",
"hmac 0.12.1",
"humantime-serde",
"hyper",
"lazy_static",
"log",
"nym-api-requests",
@@ -6517,10 +6495,8 @@ dependencies = [
"once_cell",
"pretty_env_logger",
"rand 0.7.3",
"rand 0.8.5",
"serde",
"serde_json",
"sha2 0.10.8",
"sqlx 0.5.11",
"subtle-encoding",
"thiserror",
@@ -6528,9 +6504,7 @@ dependencies = [
"tokio-stream",
"tokio-tungstenite",
"tokio-util",
"tower",
"url",
"x25519-dalek 2.0.0",
"zeroize",
]
@@ -6858,7 +6832,7 @@ dependencies = [
[[package]]
name = "nym-node-tester-wasm"
version = "1.2.0-rc.10"
version = "1.2.0"
dependencies = [
"futures",
"js-sys",
@@ -7452,7 +7426,7 @@ dependencies = [
[[package]]
name = "nym-wasm-sdk"
version = "1.2.0-rc.10"
version = "1.2.0"
dependencies = [
"mix-fetch-wasm",
"nym-client-wasm",
@@ -7470,8 +7444,6 @@ dependencies = [
"dashmap",
"etherparse",
"futures",
"ip_network",
"ip_network_table",
"log",
"nym-task",
"tap",
@@ -7722,7 +7694,7 @@ checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594"
dependencies = [
"ecdsa 0.14.8",
"elliptic-curve 0.12.3",
"sha2 0.10.8",
"sha2 0.10.7",
]
[[package]]
@@ -7733,7 +7705,7 @@ checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa"
dependencies = [
"ecdsa 0.14.8",
"elliptic-curve 0.12.3",
"sha2 0.10.8",
"sha2 0.10.7",
]
[[package]]
@@ -7967,7 +7939,7 @@ checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48"
dependencies = [
"once_cell",
"pest",
"sha2 0.10.8",
"sha2 0.10.7",
]
[[package]]
@@ -9103,7 +9075,7 @@ version = "7.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512b0ab6853f7e14e3c8754acb43d6f748bb9ced66aa5915a6553ac8213f7731"
dependencies = [
"sha2 0.10.8",
"sha2 0.10.7",
"walkdir",
]
@@ -9597,16 +9569,6 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_path_to_error"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335"
dependencies = [
"itoa",
"serde",
]
[[package]]
name = "serde_repr"
version = "0.1.16"
@@ -9678,9 +9640,9 @@ dependencies = [
[[package]]
name = "sha2"
version = "0.10.8"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8"
dependencies = [
"cfg-if",
"cpufeatures",
@@ -9834,7 +9796,7 @@ dependencies = [
"rand_core 0.6.4",
"ring",
"rustc_version 0.4.0",
"sha2 0.10.8",
"sha2 0.10.7",
"subtle 2.4.1",
]
@@ -10020,7 +9982,7 @@ dependencies = [
"paste",
"percent-encoding",
"rustls 0.19.1",
"sha2 0.10.8",
"sha2 0.10.7",
"smallvec",
"sqlformat 0.1.8",
"sqlx-rt 0.5.13",
@@ -10068,7 +10030,7 @@ dependencies = [
"percent-encoding",
"rustls 0.20.8",
"rustls-pemfile",
"sha2 0.10.8",
"sha2 0.10.7",
"smallvec",
"sqlformat 0.2.1",
"sqlx-rt 0.6.3",
@@ -10091,7 +10053,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"sha2 0.10.8",
"sha2 0.10.7",
"sqlx-core 0.5.13",
"sqlx-rt 0.5.13",
"syn 1.0.109",
@@ -10110,7 +10072,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"sha2 0.10.8",
"sha2 0.10.7",
"sqlx-core 0.6.3",
"sqlx-rt 0.6.3",
"syn 1.0.109",
@@ -10412,7 +10374,7 @@ dependencies = [
"serde_bytes",
"serde_json",
"serde_repr",
"sha2 0.10.8",
"sha2 0.10.7",
"signature 2.1.0",
"subtle 2.4.1",
"subtle-encoding",
@@ -11800,7 +11762,7 @@ dependencies = [
"sdp",
"serde",
"serde_json",
"sha2 0.10.8",
"sha2 0.10.7",
"stun",
"thiserror",
"time",
@@ -11863,7 +11825,7 @@ dependencies = [
"sec1 0.3.0",
"serde",
"sha1",
"sha2 0.10.8",
"sha2 0.10.7",
"signature 1.6.4",
"subtle 2.4.1",
"thiserror",
@@ -86,5 +86,4 @@ required-features = ["http-client"]
default = ["http-client"]
http-client = ["cosmrs/rpc", "openssl"]
generate-ts = []
contract-testing = ["nym-mixnet-contract-common/contract-testing"]
@@ -683,14 +683,13 @@ pub trait MixnetSigningClient {
.await
}
#[cfg(feature = "contract-testing")]
#[cfg(feature = "nym_mixnet_contract_common/contract-testing")]
async fn testing_resolve_all_pending_events(
&self,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
self.execute_mixnet_contract(
fee,
MixnetExecuteMsg::TestingResolveAllPendingEvents { limit: None },
MixnetExecuteMsg::TestingResolveAllPendingEvents {},
vec![],
)
.await
@@ -929,8 +928,8 @@ mod tests {
.withdraw_delegator_reward_on_behalf(owner.parse().unwrap(), mix_id, None)
.ignore(),
#[cfg(feature = "contract-testing")]
MixnetExecuteMsg::TestingResolveAllPendingEvents { .. } => {
#[cfg(feature = "nym_mixnet_contract_common/contract-testing")]
MixnetExecuteMsg::TestingResolveAllPendingEvents {} => {
client.testing_resolve_all_pending_events(None).ignore()
}
};
-2
View File
@@ -22,8 +22,6 @@ bytes = "1.5.0"
dashmap = "5.5.3"
etherparse = "0.13.0"
futures = "0.3.28"
ip_network = "0.4.1"
ip_network_table = "0.2.0"
log.workspace = true
nym-task = { path = "../task" }
tap.workspace = true
+10 -18
View File
@@ -1,48 +1,40 @@
#![cfg_attr(not(target_os = "linux"), allow(dead_code))]
use nym_task::TaskClient;
mod error;
mod event;
mod network_table;
mod platform;
mod setup;
mod tun;
mod udp_listener;
mod wg_tunnel;
// Currently the module related to setting up the virtual network device is platform specific.
#[cfg(target_os = "linux")]
use platform::linux::tun_device;
#[derive(Clone)]
struct TunTaskTx(tokio::sync::mpsc::UnboundedSender<Vec<u8>>);
impl TunTaskTx {
fn send(&self, packet: Vec<u8>) -> Result<(), tokio::sync::mpsc::error::SendError<Vec<u8>>> {
self.0.send(packet)
}
}
type ActivePeers =
dashmap::DashMap<std::net::SocketAddr, tokio::sync::mpsc::UnboundedSender<crate::event::Event>>;
#[cfg(target_os = "linux")]
pub async fn start_wireguard(
task_client: nym_task::TaskClient,
task_client: TaskClient,
) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
use std::sync::Arc;
// The set of active tunnels indexed by the peer's address
let active_peers = Arc::new(udp_listener::ActivePeers::new());
let peers_by_ip = Arc::new(std::sync::Mutex::new(network_table::NetworkTable::new()));
let active_peers = std::sync::Arc::new(ActivePeers::new());
// Start the tun device that is used to relay traffic outbound
let tun_task_tx = tun_device::start_tun_device(peers_by_ip.clone());
let tun_task_tx = tun_device::start_tun_device(active_peers.clone());
// Start the UDP listener that clients connect to
udp_listener::start_udp_listener(tun_task_tx, active_peers, peers_by_ip, task_client).await?;
udp_listener::start_udp_listener(tun_task_tx, active_peers, task_client).await?;
Ok(())
}
#[cfg(not(target_os = "linux"))]
pub async fn start_wireguard(
_task_client: nym_task::TaskClient,
_task_client: TaskClient,
) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
todo!("WireGuard is currently only supported on Linux")
}
-25
View File
@@ -1,25 +0,0 @@
use std::net::IpAddr;
use ip_network::IpNetwork;
use ip_network_table::IpNetworkTable;
#[derive(Default)]
pub(crate) struct NetworkTable<T> {
ips: IpNetworkTable<T>,
}
impl<T> NetworkTable<T> {
pub(crate) fn new() -> Self {
Self {
ips: IpNetworkTable::new(),
}
}
pub fn insert<N: Into<IpNetwork>>(&mut self, network: N, data: T) -> Option<T> {
self.ips.insert(network, data)
}
pub fn longest_match<I: Into<IpAddr>>(&self, ip: I) -> Option<(IpNetwork, &T)> {
self.ips.longest_match(ip)
}
}
@@ -1,17 +1,14 @@
use std::{net::Ipv4Addr, sync::Arc};
use etherparse::{InternetSlice, SlicedPacket};
use tap::TapFallible;
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
sync::mpsc::{self},
sync::mpsc::{self, UnboundedSender},
};
use crate::{
event::Event,
setup::{TUN_BASE_NAME, TUN_DEVICE_ADDRESS, TUN_DEVICE_NETMASK},
udp_listener::PeersByIp,
TunTaskTx,
ActivePeers,
};
fn setup_tokio_tun_device(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> tokio_tun::Tun {
@@ -28,7 +25,7 @@ fn setup_tokio_tun_device(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> t
.expect("Failed to setup tun device, do you have permission?")
}
pub(crate) fn start_tun_device(peers_by_ip: Arc<std::sync::Mutex<PeersByIp>>) -> TunTaskTx {
pub fn start_tun_device(_active_peers: Arc<ActivePeers>) -> UnboundedSender<Vec<u8>> {
let tun = setup_tokio_tun_device(
format!("{}%d", TUN_BASE_NAME).as_str(),
TUN_DEVICE_ADDRESS.parse().unwrap(),
@@ -40,7 +37,6 @@ pub(crate) fn start_tun_device(peers_by_ip: Arc<std::sync::Mutex<PeersByIp>>) ->
// Channels to communicate with the other tasks
let (tun_task_tx, mut tun_task_rx) = mpsc::unbounded_channel::<Vec<u8>>();
let tun_task_tx = TunTaskTx(tun_task_tx);
tokio::spawn(async move {
let mut buf = [0u8; 1024];
@@ -59,16 +55,8 @@ pub(crate) fn start_tun_device(peers_by_ip: Arc<std::sync::Mutex<PeersByIp>>) ->
};
log::info!("iface: read Packet({src_addr} -> {dst_addr}, {len} bytes)");
// Route packet to the correct peer.
if let Some(peer_tx) = peers_by_ip.lock().unwrap().longest_match(dst_addr).map(|(_, tx)| tx) {
log::info!("Forward packet to wg tunnel");
peer_tx
.send(Event::IpPacket(packet.to_vec().into()))
.tap_err(|err| log::error!("{err}"))
.unwrap();
} else {
log::info!("No peer found, packet dropped");
}
// TODO: route packet to the correct peer.
log::info!("...forward packet to the correct peer (NOT YET IMPLEMENTED)");
},
Err(err) => {
log::info!("iface: read error: {err}");
+19 -33
View File
@@ -1,5 +1,3 @@
use std::net::IpAddr;
use base64::{engine::general_purpose, Engine as _};
use boringtun::x25519;
use log::info;
@@ -17,47 +15,35 @@ pub const TUN_DEVICE_NETMASK: &str = "255.255.255.0";
// Corresponding public key: "WM8s8bYegwMa0TJ+xIwhk+dImk2IpDUKslDBCZPizlE="
const PRIVATE_KEY: &str = "AEqXrLFT4qjYq3wmX0456iv94uM6nDj5ugp6Jedcflg=";
// The public keys of the registered peer (clients)
// Corresponding private key: "ILeN6gEh6vJ3Ju8RJ3HVswz+sPgkcKtAYTqzQRhTtlo="
const PEER: &str = "NCIhkgiqxFx1ckKl3Zuh595DzIFl8mxju1Vg995EZhI=";
// The public keys of the registered peers (clients)
const PEERS: &[&str; 1] = &[
// Corresponding private key: "ILeN6gEh6vJ3Ju8RJ3HVswz+sPgkcKtAYTqzQRhTtlo="
"NCIhkgiqxFx1ckKl3Zuh595DzIFl8mxju1Vg995EZhI=",
// Another key
// "mxV/mw7WZTe+0Msa0kvJHMHERDA/cSskiZWQce+TdEs=",
];
// The AllowedIPs for the connected peer, which is one a single IP and the same as the IP that the
// peer has configured on their side.
const ALLOWED_IPS: &str = "10.0.0.2";
fn decode_base64_key(base64_key: &str) -> [u8; 32] {
general_purpose::STANDARD
.decode(base64_key)
pub fn init_static_dev_keys() -> (x25519::StaticSecret, x25519::PublicKey) {
// TODO: this is a temporary solution for development
let static_private_bytes: [u8; 32] = general_purpose::STANDARD
.decode(PRIVATE_KEY)
.unwrap()
.try_into()
.unwrap()
}
pub fn server_static_private_key() -> x25519::StaticSecret {
// TODO: this is a temporary solution for development
let static_private_bytes: [u8; 32] = decode_base64_key(PRIVATE_KEY);
.unwrap();
let static_private = x25519::StaticSecret::try_from(static_private_bytes).unwrap();
let static_public = x25519::PublicKey::from(&static_private);
info!(
"wg public key: {}",
general_purpose::STANDARD.encode(static_public)
);
static_private
}
pub fn peer_static_public_key() -> x25519::PublicKey {
// A single static public key is used during development
let peer_static_public_bytes: [u8; 32] = decode_base64_key(PEER);
// TODO: A single static public key is used for all peers during development
let peer_static_public_bytes: [u8; 32] = general_purpose::STANDARD
.decode(PEERS[0])
.unwrap()
.try_into()
.unwrap();
let peer_static_public = x25519::PublicKey::try_from(peer_static_public_bytes).unwrap();
info!(
"peer public key: {}",
general_purpose::STANDARD.encode(peer_static_public)
);
peer_static_public
}
pub fn peer_allowed_ips() -> ip_network::IpNetwork {
let key: IpAddr = ALLOWED_IPS.parse().unwrap();
let cidr = 0u8;
ip_network::IpNetwork::new_truncate(key, cidr).unwrap()
(static_private, peer_static_public)
}
@@ -6,6 +6,7 @@ use boringtun::{
x25519,
};
use bytes::Bytes;
use etherparse::{InternetSlice, SlicedPacket};
use log::{debug, error, info, warn};
use tap::TapFallible;
use tokio::{
@@ -14,7 +15,7 @@ use tokio::{
time::timeout,
};
use crate::{error::WgError, event::Event, network_table::NetworkTable, TunTaskTx};
use crate::{error::WgError, event::Event};
const MAX_PACKET: usize = 65535;
@@ -26,10 +27,10 @@ pub struct WireGuardTunnel {
udp: Arc<UdpSocket>,
// Peer endpoint
endpoint: Arc<tokio::sync::RwLock<SocketAddr>>,
endpoint: SocketAddr,
// AllowedIPs for this peer
allowed_ips: NetworkTable<()>,
// The source address of the last packet received from the peer
source_addr: Arc<std::sync::RwLock<Option<std::net::Ipv4Addr>>>,
// `boringtun` tunnel, used for crypto & WG protocol
wg_tunnel: Arc<tokio::sync::Mutex<Tunn>>,
@@ -39,7 +40,7 @@ pub struct WireGuardTunnel {
close_rx: broadcast::Receiver<()>,
// Send data to the task that handles sending data through the tun device
tun_task_tx: TunTaskTx,
tun_task_tx: mpsc::UnboundedSender<Vec<u8>>,
}
impl Drop for WireGuardTunnel {
@@ -50,13 +51,12 @@ impl Drop for WireGuardTunnel {
}
impl WireGuardTunnel {
pub(crate) fn new(
pub fn new(
udp: Arc<UdpSocket>,
endpoint: SocketAddr,
static_private: x25519::StaticSecret,
peer_static_public: x25519::PublicKey,
peer_allowed_ips: ip_network::IpNetwork,
tunnel_tx: TunTaskTx,
tunnel_tx: mpsc::UnboundedSender<Vec<u8>>,
) -> (Self, mpsc::UnboundedSender<Event>) {
let local_addr = udp.local_addr().unwrap();
let peer_addr = udp.peer_addr();
@@ -85,14 +85,11 @@ impl WireGuardTunnel {
// Signal close tunnel
let (close_tx, close_rx) = broadcast::channel(1);
let mut allowed_ips = NetworkTable::new();
allowed_ips.insert(peer_allowed_ips, ());
let tunnel = WireGuardTunnel {
peer_rx,
udp,
endpoint: Arc::new(tokio::sync::RwLock::new(endpoint)),
allowed_ips,
endpoint,
source_addr: Default::default(),
wg_tunnel,
close_tx,
close_rx,
@@ -137,7 +134,7 @@ impl WireGuardTunnel {
},
}
}
info!("WireGuard tunnel ({}): closed", self.endpoint.read().await);
info!("WireGuard tunnel ({}): closed", self.endpoint);
}
async fn wg_tunnel_lock(&self) -> Result<tokio::sync::MutexGuard<'_, Tunn>, WgError> {
@@ -146,11 +143,16 @@ impl WireGuardTunnel {
.map_err(|_| WgError::UnableToGetTunnel)
}
#[allow(unused)]
async fn set_endpoint(&self, addr: SocketAddr) {
if *self.endpoint.read().await != addr {
log::info!("wg tunnel update endpoint: {addr}");
*self.endpoint.write().await = addr;
fn set_source_addr(&self, source_addr: std::net::Ipv4Addr) {
let to_update = {
let stored_source_addr = self.source_addr.read().unwrap();
stored_source_addr
.map(|sa| sa != source_addr)
.unwrap_or(true)
};
if to_update {
log::info!("wg tunnel set_source_addr: {source_addr}");
*self.source_addr.write().unwrap() = Some(source_addr);
}
}
@@ -159,9 +161,8 @@ impl WireGuardTunnel {
let mut tunnel = self.wg_tunnel_lock().await?;
match tunnel.decapsulate(None, data, &mut send_buf) {
TunnResult::WriteToNetwork(packet) => {
let endpoint = self.endpoint.read().await;
log::info!("udp: send {} bytes to {}", packet.len(), *endpoint);
if let Err(err) = self.udp.send_to(packet, *endpoint).await {
log::info!("udp: send {} bytes to {}", packet.len(), self.endpoint);
if let Err(err) = self.udp.send_to(packet, self.endpoint).await {
error!("Failed to send decapsulation-instructed packet to WireGuard endpoint: {err:?}");
};
// Flush pending queue
@@ -169,8 +170,8 @@ impl WireGuardTunnel {
let mut send_buf = [0u8; MAX_PACKET];
match tunnel.decapsulate(None, &[], &mut send_buf) {
TunnResult::WriteToNetwork(packet) => {
log::info!("udp: send {} bytes to {}", packet.len(), *endpoint);
if let Err(err) = self.udp.send_to(packet, *endpoint).await {
log::info!("udp: send {} bytes to {}", packet.len(), self.endpoint);
if let Err(err) = self.udp.send_to(packet, self.endpoint).await {
error!("Failed to send decapsulation-instructed packet to WireGuard endpoint: {err:?}");
break;
};
@@ -181,23 +182,14 @@ impl WireGuardTunnel {
}
}
}
TunnResult::WriteToTunnelV4(packet, addr) => {
// TODO: once the flow is redone, we should add updating the endpoint dynamically
// self.set_endpoint(addr);
if self.allowed_ips.longest_match(addr).is_some() {
self.tun_task_tx.send(packet.to_vec()).unwrap();
} else {
warn!("Packet from {addr} not in allowed_ips");
}
}
TunnResult::WriteToTunnelV6(packet, addr) => {
// TODO: once the flow is redone, we should add updating the endpoint dynamically
// self.set_endpoint(addr);
if self.allowed_ips.longest_match(addr).is_some() {
self.tun_task_tx.send(packet.to_vec()).unwrap();
} else {
warn!("Packet (v6) from {addr} not in allowed_ips");
}
TunnResult::WriteToTunnelV4(packet, _) | TunnResult::WriteToTunnelV6(packet, _) => {
let headers = SlicedPacket::from_ip(packet).unwrap();
let (source_addr, _destination_addr) = match headers.ip.unwrap() {
InternetSlice::Ipv4(ip, _) => (ip.source_addr(), ip.destination_addr()),
InternetSlice::Ipv6(_, _) => unimplemented!(),
};
self.set_source_addr(source_addr);
self.tun_task_tx.send(packet.to_vec()).unwrap();
}
TunnResult::Done => {
debug!("WireGuard: decapsulate done");
@@ -217,10 +209,9 @@ impl WireGuardTunnel {
encapsulated_packet.len()
);
let endpoint = self.endpoint.read().await;
info!("consume_eth: send to {}: {}", *endpoint, data.len());
info!("consume_eth: send to {}: {}", self.endpoint, data.len());
self.udp
.send_to(&encapsulated_packet, *endpoint)
.send_to(&encapsulated_packet, self.endpoint)
.await
.unwrap();
}
@@ -253,9 +244,12 @@ impl WireGuardTunnel {
async fn handle_routine_tun_result<'a: 'async_recursion>(&self, result: TunnResult<'a>) {
match result {
TunnResult::WriteToNetwork(packet) => {
let endpoint = self.endpoint.read().await;
log::info!("routine: write to network: {}: {}", endpoint, packet.len());
if let Err(err) = self.udp.send_to(packet, *endpoint).await {
log::info!(
"routine: write to network: {}: {}",
self.endpoint,
packet.len()
);
if let Err(err) = self.udp.send_to(packet, self.endpoint).await {
error!("routine: failed to send packet: {err:?}");
};
}
@@ -282,25 +276,18 @@ impl WireGuardTunnel {
}
}
pub(crate) fn start_wg_tunnel(
pub fn start_wg_tunnel(
endpoint: SocketAddr,
udp: Arc<UdpSocket>,
static_private: x25519::StaticSecret,
peer_static_public: x25519::PublicKey,
peer_allowed_ips: ip_network::IpNetwork,
tunnel_tx: TunTaskTx,
tunnel_tx: mpsc::UnboundedSender<Vec<u8>>,
) -> (
tokio::task::JoinHandle<SocketAddr>,
mpsc::UnboundedSender<Event>,
) {
let (mut tunnel, peer_tx) = WireGuardTunnel::new(
udp,
endpoint,
static_private,
peer_static_public,
peer_allowed_ips,
tunnel_tx,
);
let (mut tunnel, peer_tx) =
WireGuardTunnel::new(udp, endpoint, static_private, peer_static_public, tunnel_tx);
let join_handle = tokio::spawn(async move {
tunnel.spin_off().await;
endpoint
+7 -28
View File
@@ -1,31 +1,22 @@
use std::{net::SocketAddr, sync::Arc};
use dashmap::DashMap;
use futures::StreamExt;
use log::error;
use nym_task::TaskClient;
use tap::TapFallible;
use tokio::{
net::UdpSocket,
sync::mpsc::{self},
};
use tokio::{net::UdpSocket, sync::mpsc::UnboundedSender};
use crate::{
event::Event,
network_table::NetworkTable,
setup::{self, WG_ADDRESS, WG_PORT},
TunTaskTx,
setup::{WG_ADDRESS, WG_PORT},
ActivePeers,
};
const MAX_PACKET: usize = 65535;
pub(crate) type ActivePeers = DashMap<SocketAddr, mpsc::UnboundedSender<Event>>;
pub(crate) type PeersByIp = NetworkTable<mpsc::UnboundedSender<Event>>;
pub(crate) async fn start_udp_listener(
tun_task_tx: TunTaskTx,
pub async fn start_udp_listener(
tun_task_tx: UnboundedSender<Vec<u8>>,
active_peers: Arc<ActivePeers>,
peers_by_ip: Arc<std::sync::Mutex<PeersByIp>>,
mut task_client: TaskClient,
) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
let wg_address = SocketAddr::new(WG_ADDRESS.parse().unwrap(), WG_PORT);
@@ -33,9 +24,7 @@ pub(crate) async fn start_udp_listener(
let udp_socket = Arc::new(UdpSocket::bind(wg_address).await?);
// Setup some static keys for development
let static_private = setup::server_static_private_key();
let peer_static_public = setup::peer_static_public_key();
let peer_allowed_ips = setup::peer_allowed_ips();
let (static_private, peer_static_public) = crate::setup::init_static_dev_keys();
tokio::spawn(async move {
// Each tunnel is run in its own task, and the task handle is stored here so we can remove
@@ -55,7 +44,6 @@ pub(crate) async fn start_udp_listener(
Ok(addr) => {
log::info!("Removing peer: {addr:?}");
active_peers.remove(&addr);
// TODO: remove from peers_by_ip
}
Err(err) => {
error!("WireGuard UDP listener: error receiving shutdown from peer: {err}");
@@ -73,22 +61,13 @@ pub(crate) async fn start_udp_listener(
.unwrap();
} else {
log::info!("udp: received {len} bytes from {addr} from unknown peer, starting tunnel");
// TODO: this is a temporary solution for development since this
// assumes we know the peer_static_public this corresponds to.
// TODO: rework this before production! This is likely not secure!
log::warn!("Assuming peer_static_public is known");
log::warn!("SECURITY: Rework me to do proper handshake before creating the tunnel!");
let (join_handle, peer_tx) = crate::wg_tunnel::start_wg_tunnel(
let (join_handle, peer_tx) = crate::tun::start_wg_tunnel(
addr,
udp_socket.clone(),
static_private.clone(),
peer_static_public,
peer_allowed_ips,
tun_task_tx.clone(),
);
peers_by_ip.lock().unwrap().insert(peer_allowed_ips, peer_tx.clone());
peer_tx.send(Event::WgPacket(buf[..len].to_vec().into()))
.tap_err(|err| log::error!("{err}"))
.unwrap();
@@ -40,7 +40,7 @@ Yes, to run a mix node only is an option. However it will be less rewarded as no
### What are the incentives for the node operator?
In the original setup there were no incentives to run a `network-requester`. After the transition all the users will buy multiple tickets of zkNyms credentials and use those as [anonymous e-cash](https://arxiv.org/abs/2303.08221) to pay for their data traffic ([`Nym API`](https://github.com/nymtech/nym/tree/master/nym-api) will do the do cryptographical checks to prevent double-spending). All collected fees get distributed to all active nodes proportionally to their work by the end of each epoch.
In the original setup there were no incentives to run a `network-requester`. After the transition all the users will buy multiple tickets of zkNyms credentials and use those as [anonymous e-cash](https://arxiv.org/abs/2303.08221) to pay for their data traffic (`[Nym API](https://github.com/nymtech/nym/tree/master/nym-api)` will do the do cryptographical checks to prevent double-spending). All collected fees get distributed to all active nodes proportionally to their work by the end of each epoch.
### How does this change the token economics?
+2 -25
View File
@@ -15,13 +15,6 @@ rust-version = "1.56"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
axum = "0.6.20"
sha2 = "0.10.8"
hmac = "0.12.1"
axum-macros = "0.3.8" # Useful for debugging axum Handler trait errors
fastrand = "2"
x25519-dalek = { version = "2.0.0", features = ["static_secrets"] }
base64 = "0.21.4"
anyhow = { workspace = true }
async-trait = { workspace = true }
atty = "0.2"
@@ -41,21 +34,10 @@ pretty_env_logger = "0.4"
rand = "0.7"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sqlx = { version = "0.5", features = [
"runtime-tokio-rustls",
"sqlite",
"macros",
"migrate",
] }
sqlx = { version = "0.5", features = [ "runtime-tokio-rustls", "sqlite", "macros", "migrate", ] }
subtle-encoding = { version = "0.5", features = ["bech32-preview"] }
thiserror = "1"
tokio = { workspace = true, features = [
"rt-multi-thread",
"net",
"signal",
"fs",
"time",
] }
tokio = { workspace = true, features = [ "rt-multi-thread", "net", "signal", "fs", "time" ] }
tokio-stream = { version = "0.1.11", features = ["fs"] }
tokio-tungstenite = { version = "0.20.1" }
tokio-util = { version = "0.7.4", features = ["codec"] }
@@ -82,11 +64,6 @@ nym-types = { path = "../common/types" }
nym-validator-client = { path = "../common/client-libs/validator-client" }
nym-wireguard = { path = "../common/wireguard", optional = true }
[dev-dependencies]
tower = "0.4.13"
rand = "0.8.5"
hyper = "0.14.27"
[build-dependencies]
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
sqlx = { version = "0.5", features = [
-10
View File
@@ -106,16 +106,6 @@ pub(crate) enum GatewayError {
#[from]
source: NyxdError,
},
#[error("Error verifying hmac digest")]
HmacDigestError {
#[from]
source: hmac::digest::MacError,
},
#[error("Invalid hmac length")]
HmacInvalidLength {
#[from]
source: hmac::digest::InvalidLength,
},
}
impl From<ClientCoreError> for GatewayError {
@@ -1,181 +0,0 @@
use std::{
collections::HashMap,
fmt,
hash::{Hash, Hasher},
net::SocketAddr,
ops::Deref,
str::FromStr,
};
use base64::{engine::general_purpose, Engine};
use hmac::{Hmac, Mac};
use nym_crypto::asymmetric::encryption::PrivateKey;
use serde::{Deserialize, Serialize};
use sha2::Sha256;
use x25519_dalek::StaticSecret;
use crate::error::GatewayError;
#[derive(Debug, Clone, Deserialize, Serialize)]
pub(crate) enum ClientMessage {
Init(InitMessage),
Final(Client),
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub(crate) struct InitMessage {
pub_key: ClientPublicKey,
}
impl InitMessage {
pub fn pub_key(&self) -> &ClientPublicKey {
&self.pub_key
}
#[allow(dead_code)]
pub fn new(pub_key: ClientPublicKey) -> Self {
InitMessage { pub_key }
}
}
// Client that wants to register sends its PublicKey and SocketAddr bytes mac digest encrypted with a DH shared secret.
// Gateway can then verify pub_key payload using the sme process
#[derive(Debug, Clone, Deserialize, Serialize)]
pub(crate) struct Client {
// base64 encoded public key, using x25519-dalek for impl
pub(crate) pub_key: ClientPublicKey,
pub(crate) socket: SocketAddr,
pub(crate) mac: ClientMac,
}
pub type HmacSha256 = Hmac<Sha256>;
impl Client {
// Reusable secret should be gateways Wireguard PK
// Client should perform this step when generating its payload, using its own WG PK
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), GatewayError> {
#[allow(clippy::expect_used)]
let static_secret =
StaticSecret::try_from(gateway_key.to_bytes()).expect("This is infalliable");
let dh = static_secret.diffie_hellman(&self.pub_key);
let mut mac = HmacSha256::new_from_slice(dh.as_bytes())?;
mac.update(self.pub_key.as_bytes());
mac.update(self.socket.ip().to_string().as_bytes());
mac.update(self.socket.port().to_string().as_bytes());
mac.update(&nonce.to_le_bytes());
Ok(mac.verify_slice(&self.mac)?)
}
pub fn pub_key(&self) -> &ClientPublicKey {
&self.pub_key
}
pub fn socket(&self) -> SocketAddr {
self.socket
}
}
// This should go into nym-wireguard crate
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ClientPublicKey(x25519_dalek::PublicKey);
#[derive(Debug, Clone)]
pub(crate) struct ClientMac(Vec<u8>);
impl ClientMac {
#[allow(dead_code)]
pub fn new(mac: Vec<u8>) -> Self {
ClientMac(mac)
}
}
impl Deref for ClientMac {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl fmt::Display for ClientPublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", general_purpose::STANDARD.encode(self.0.as_bytes()))
}
}
impl Hash for ClientPublicKey {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.as_bytes().hash(state)
}
}
impl FromStr for ClientMac {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mac_bytes: Vec<u8> = general_purpose::STANDARD
.decode(s)
.map_err(|_| "Could not base64 decode public key mac representation".to_string())?;
Ok(ClientMac(mac_bytes))
}
}
impl Serialize for ClientMac {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let encoded_key = general_purpose::STANDARD.encode(self.0.clone());
serializer.serialize_str(&encoded_key)
}
}
impl<'de> Deserialize<'de> for ClientMac {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let encoded_key = String::deserialize(deserializer)?;
ClientMac::from_str(&encoded_key).map_err(serde::de::Error::custom)
}
}
impl ClientPublicKey {
#[allow(dead_code)]
pub fn new(key: x25519_dalek::PublicKey) -> Self {
ClientPublicKey(key)
}
pub fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
}
impl Deref for ClientPublicKey {
type Target = x25519_dalek::PublicKey;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl FromStr for ClientPublicKey {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let key_bytes: [u8; 32] = general_purpose::STANDARD
.decode(s)
.map_err(|_| "Could not base64 decode public key representation".to_string())?
.try_into()
.map_err(|_| "Invalid key length".to_string())?;
Ok(ClientPublicKey(x25519_dalek::PublicKey::from(key_bytes)))
}
}
impl Serialize for ClientPublicKey {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let encoded_key = general_purpose::STANDARD.encode(self.0.as_bytes());
serializer.serialize_str(&encoded_key)
}
}
impl<'de> Deserialize<'de> for ClientPublicKey {
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let encoded_key = String::deserialize(deserializer)?;
Ok(ClientPublicKey::from_str(&encoded_key).map_err(serde::de::Error::custom))?
}
}
pub(crate) type ClientRegistry = HashMap<SocketAddr, Client>;
-1
View File
@@ -3,7 +3,6 @@
pub(crate) mod active_clients;
mod bandwidth;
pub(crate) mod client_registration;
pub(crate) mod embedded_network_requester;
pub(crate) mod websocket;
@@ -91,7 +91,7 @@ impl CoconutVerifier {
let req = nym_api_requests::coconut::VerifyCredentialBody::new(
credential.clone(),
proposal_id,
self.nyxd_client.address(),
self.nyxd_client.address().clone(),
);
for client in api_clients {
self.nyxd_client
-1
View File
@@ -1 +0,0 @@
pub(crate) mod v1;
@@ -1,105 +0,0 @@
use axum::extract::Path;
use std::sync::Arc;
use axum::http::StatusCode;
use axum::{extract::State, Json};
use std::str::FromStr;
// use axum_macros::debug_handler;
use crate::node::client_handling::client_registration::{
Client, ClientMessage, ClientPublicKey, InitMessage,
};
use crate::node::http::ApiState;
async fn process_final_message(client: Client, state: Arc<ApiState>) -> StatusCode {
let preshared_nonce = {
let in_progress_ro = state.registration_in_progress.read().await;
if let Some(nonce) = in_progress_ro.get(client.pub_key()) {
*nonce
} else {
return StatusCode::BAD_REQUEST;
}
};
if client
.verify(state.sphinx_key_pair.private_key(), preshared_nonce)
.is_ok()
{
{
let mut in_progress_rw = state.registration_in_progress.write().await;
in_progress_rw.remove(client.pub_key());
}
{
let mut registry_rw = state.client_registry.write().await;
registry_rw.insert(client.socket(), client);
}
return StatusCode::OK;
}
StatusCode::BAD_REQUEST
}
async fn process_init_message(init_message: InitMessage, state: Arc<ApiState>) -> u64 {
let nonce: u64 = fastrand::u64(..);
let mut registry_rw = state.registration_in_progress.write().await;
registry_rw.insert(init_message.pub_key().clone(), nonce);
nonce
}
// #[debug_handler]
pub(crate) async fn register_client(
State(state): State<Arc<ApiState>>,
Json(payload): Json<ClientMessage>,
) -> (StatusCode, Json<Option<u64>>) {
match payload {
ClientMessage::Init(i) => (
StatusCode::OK,
Json(Some(process_init_message(i, Arc::clone(&state)).await)),
),
ClientMessage::Final(client) => (
process_final_message(client, Arc::clone(&state)).await,
Json(None),
),
}
}
pub(crate) async fn get_all_clients(
State(state): State<Arc<ApiState>>,
) -> (StatusCode, Json<Vec<ClientPublicKey>>) {
let registry_ro = state.client_registry.read().await;
(
StatusCode::OK,
Json(
registry_ro
.values()
.map(|c| c.pub_key().clone())
.collect::<Vec<ClientPublicKey>>(),
),
)
}
pub(crate) async fn get_client(
Path(pub_key): Path<String>,
State(state): State<Arc<ApiState>>,
) -> (StatusCode, Json<Vec<Client>>) {
let pub_key = match ClientPublicKey::from_str(&pub_key) {
Ok(pub_key) => pub_key,
Err(_) => return (StatusCode::BAD_REQUEST, Json(vec![])),
};
let registry_ro = state.client_registry.read().await;
let clients = registry_ro
.iter()
.filter_map(|(_, c)| {
if c.pub_key() == &pub_key {
Some(c.clone())
} else {
None
}
})
.collect::<Vec<Client>>();
if clients.is_empty() {
return (StatusCode::NOT_FOUND, Json(clients));
}
(StatusCode::OK, Json(clients))
}
-1
View File
@@ -1 +0,0 @@
pub(crate) mod client_registry;
-206
View File
@@ -1,206 +0,0 @@
use std::{collections::HashMap, sync::Arc};
use axum::{
routing::{get, post},
Router,
};
use log::info;
use nym_crypto::asymmetric::encryption;
use tokio::sync::RwLock;
mod api;
use api::v1::client_registry::*;
use super::client_handling::client_registration::{ClientPublicKey, ClientRegistry};
const ROUTE_PREFIX: &str = "/api/v1/gateway/client-interfaces/wireguard";
pub struct ApiState {
client_registry: Arc<RwLock<ClientRegistry>>,
sphinx_key_pair: Arc<encryption::KeyPair>,
registration_in_progress: Arc<RwLock<HashMap<ClientPublicKey, u64>>>,
}
fn router_with_state(state: Arc<ApiState>) -> Router {
Router::new()
.route(&format!("{}/clients", ROUTE_PREFIX), get(get_all_clients))
.route(&format!("{}/client", ROUTE_PREFIX), post(register_client))
.route(
&format!("{}/client/:pub_key", ROUTE_PREFIX),
get(get_client),
)
.with_state(state)
}
pub(crate) async fn start_http_api(
client_registry: Arc<RwLock<ClientRegistry>>,
sphinx_key_pair: Arc<encryption::KeyPair>,
) {
// Port should be 80 post smoosh
let port = 8000;
info!("Started HTTP API on port {}", port);
let client_registry = Arc::clone(&client_registry);
let state = Arc::new(ApiState {
client_registry,
sphinx_key_pair,
registration_in_progress: Arc::new(RwLock::new(HashMap::new())),
});
let routes = router_with_state(state);
#[allow(clippy::unwrap_used)]
axum::Server::bind(&format!("0.0.0.0:{}", port).parse().unwrap())
.serve(routes.into_make_service())
.await
.unwrap();
}
#[cfg(test)]
mod test {
use std::net::SocketAddr;
use std::str::FromStr;
use std::{collections::HashMap, sync::Arc};
use axum::body::Body;
use axum::http::Request;
use axum::http::StatusCode;
use hmac::Mac;
use tower::Service;
use tower::ServiceExt;
use nym_crypto::asymmetric::encryption;
use tokio::sync::RwLock;
use x25519_dalek::{PublicKey, StaticSecret};
use crate::node::client_handling::client_registration::{
Client, ClientMac, ClientMessage, InitMessage,
};
use crate::node::client_handling::client_registration::{ClientPublicKey, HmacSha256};
use crate::node::http::{router_with_state, ApiState, ROUTE_PREFIX};
#[tokio::test]
async fn registration() {
// 1. Provision random keys for gateway and client
// 2. Generate DH shared secret
// 3. Client submits its public key to the gateway to start the handshake process, gateway responds with nonce
// 4. Client generates mac digest using DH shared secret, its own public key, socket address and port, and nonce
// 5. Client sends its public key, socket address and port, nonce and mac digest to the gateway
// 6. Gateway verifies mac digest and nonce, and stores client's public key and socket address and port
let mut rng = rand::thread_rng();
let gateway_key_pair = encryption::KeyPair::new(&mut rng);
let client_key_pair = encryption::KeyPair::new(&mut rng);
let gateway_static_public =
PublicKey::try_from(gateway_key_pair.public_key().to_bytes()).unwrap();
let client_static_private =
StaticSecret::try_from(client_key_pair.private_key().to_bytes()).unwrap();
let client_static_public =
PublicKey::try_from(client_key_pair.public_key().to_bytes()).unwrap();
let client_dh = client_static_private.diffie_hellman(&gateway_static_public);
let registration_in_progress = Arc::new(RwLock::new(HashMap::new()));
let client_registry = Arc::new(RwLock::new(HashMap::new()));
let state = Arc::new(ApiState {
client_registry: Arc::clone(&client_registry),
sphinx_key_pair: Arc::new(gateway_key_pair),
registration_in_progress: Arc::clone(&registration_in_progress),
});
// `Router` implements `tower::Service<Request<Body>>` so we can
// call it like any tower service, no need to run an HTTP server.
let mut app = router_with_state(state);
let init_message =
ClientMessage::Init(InitMessage::new(ClientPublicKey::new(client_static_public)));
let init_request = Request::builder()
.method("POST")
.uri(format!("{}/client", ROUTE_PREFIX))
.header("Content-type", "application/json")
.body(Body::from(serde_json::to_vec(&init_message).unwrap()))
.unwrap();
let response = ServiceExt::<Request<Body>>::ready(&mut app)
.await
.unwrap()
.call(init_request)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
assert!(!registration_in_progress.read().await.is_empty());
let nonce: Option<u64> =
serde_json::from_slice(&hyper::body::to_bytes(response.into_body()).await.unwrap())
.unwrap();
assert!(nonce.is_some());
let mut mac = HmacSha256::new_from_slice(client_dh.as_bytes()).unwrap();
mac.update(client_static_public.as_bytes());
mac.update("127.0.0.1".as_bytes());
mac.update("8080".as_bytes());
mac.update(&nonce.unwrap().to_le_bytes());
let mac = mac.finalize().into_bytes();
let finalized_message = ClientMessage::Final(Client {
pub_key: ClientPublicKey::new(client_static_public),
socket: SocketAddr::from_str("127.0.0.1:8080").unwrap(),
mac: ClientMac::new(mac.as_slice().to_vec()),
});
let final_request = Request::builder()
.method("POST")
.uri(format!("{}/client", ROUTE_PREFIX))
.header("Content-type", "application/json")
.body(Body::from(serde_json::to_vec(&finalized_message).unwrap()))
.unwrap();
let response = ServiceExt::<Request<Body>>::ready(&mut app)
.await
.unwrap()
.call(final_request)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
assert!(!client_registry.read().await.is_empty());
let clients_request = Request::builder()
.method("GET")
.uri(format!("{}/clients", ROUTE_PREFIX))
.body(Body::empty())
.unwrap();
let response = ServiceExt::<Request<Body>>::ready(&mut app)
.await
.unwrap()
.call(clients_request)
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
let clients: Vec<ClientPublicKey> =
serde_json::from_slice(&hyper::body::to_bytes(response.into_body()).await.unwrap())
.unwrap();
assert!(!clients.is_empty());
let ro_clients = client_registry.read().await.clone();
assert_eq!(
ro_clients
.values()
.map(|c| c.pub_key().clone())
.collect::<Vec<ClientPublicKey>>(),
clients
)
}
}
-15
View File
@@ -1,7 +1,6 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use self::client_handling::client_registration::ClientRegistry;
use self::storage::PersistentStorage;
use crate::commands::helpers::{override_network_requester_config, OverrideNetworkRequesterConfig};
use crate::config::Config;
@@ -13,7 +12,6 @@ use crate::node::client_handling::embedded_network_requester::{
use crate::node::client_handling::websocket;
use crate::node::client_handling::websocket::connection_handler::coconut::CoconutVerifier;
use crate::node::helpers::{initialise_main_storage, load_network_requester_config};
use crate::node::http::start_http_api;
use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler;
use crate::node::statistics::collector::GatewayStatisticsCollector;
use crate::node::storage::Storage;
@@ -29,16 +27,13 @@ use nym_task::{TaskClient, TaskManager};
use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient};
use rand::seq::SliceRandom;
use rand::thread_rng;
use std::collections::HashMap;
use std::error::Error;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::RwLock;
pub(crate) mod client_handling;
pub(crate) mod helpers;
pub(crate) mod http;
pub(crate) mod mixnet_handling;
pub(crate) mod statistics;
pub(crate) mod storage;
@@ -90,8 +85,6 @@ pub(crate) struct Gateway<St = PersistentStorage> {
/// x25519 keypair used for Diffie-Hellman. Currently only used for sphinx key derivation.
sphinx_keypair: Arc<encryption::KeyPair>,
storage: St,
client_registry: Arc<RwLock<ClientRegistry>>,
}
impl<St> Gateway<St> {
@@ -107,7 +100,6 @@ impl<St> Gateway<St> {
sphinx_keypair: Arc::new(helpers::load_sphinx_keys(&config)?),
config,
network_requester_opts,
client_registry: Arc::new(RwLock::new(HashMap::new())),
})
}
@@ -125,7 +117,6 @@ impl<St> Gateway<St> {
identity_keypair: Arc::new(identity_keypair),
sphinx_keypair: Arc::new(sphinx_keypair),
storage,
client_registry: Arc::new(RwLock::new(HashMap::new())),
}
}
@@ -384,12 +375,6 @@ impl<St> Gateway<St> {
bail!("{err}")
}
// This should likely be wireguard feature gated, but its easier to test if it hangs in here
tokio::spawn(start_http_api(
Arc::clone(&self.client_registry),
Arc::clone(&self.sphinx_keypair),
));
info!("Finished nym gateway startup procedure - it should now be able to receive mix and client traffic!");
if let Err(err) = Self::wait_for_interrupt(shutdown).await {
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "extension-storage"
version = "1.2.0-rc.10"
version = "1.2.0"
edition = "2021"
license = "Apache-2.0"
repository = "https://github.com/nymtech/nym"
+6
View File
@@ -2,6 +2,12 @@
## [Unreleased]
## [v1.2.9] (2023-10-10)
- Wallet: Introduce edit account name ([#3895])
[#3895]: https://github.com/nymtech/nym/pull/3895
## [v1.2.8] (2023-08-23)
- [hotfix]: don't assign invalid fields when crossing the JS boundary ([#3805])
+1 -1
View File
@@ -3512,7 +3512,7 @@ dependencies = [
[[package]]
name = "nym_wallet"
version = "1.2.8"
version = "1.2.9"
dependencies = [
"async-trait",
"base64 0.13.1",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@nymproject/nym-wallet-app",
"version": "1.2.8",
"version": "1.2.9",
"main": "index.js",
"license": "MIT",
"scripts": {
@@ -31,7 +31,7 @@
"@nymproject/mui-theme": "^1.0.0",
"@nymproject/react": "^1.0.0",
"@nymproject/types": "^1.0.0",
"@nymproject/node-tester": ">=1.2.0-rc.8",
"@nymproject/node-tester": ">=1.2.0-rc.10 || ^1",
"@storybook/react": "^6.5.15",
"@tauri-apps/api": "^1.2.0",
"@tauri-apps/tauri-forage": "^1.0.0-beta.2",
@@ -123,4 +123,4 @@
"webpack-favicons": "^1.3.8",
"webpack-merge": "^5.8.0"
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym_wallet"
version = "1.2.8"
version = "1.2.9"
description = "Nym Native Wallet"
authors = ["Nym Technologies SA"]
license = ""
+1 -1
View File
@@ -1,7 +1,7 @@
{
"package": {
"productName": "nym-wallet",
"version": "1.2.8"
"version": "1.2.9"
},
"build": {
"distDir": "../dist",
+5 -2
View File
@@ -6,7 +6,10 @@
"workspaces": [
"dist/wasm/**",
"dist/node/**",
"sdk/typescript/packages/**",
"dist/ts/**",
"sdk/typescript/packages/mui-theme",
"sdk/typescript/packages/react-components",
"sdk/typescript/packages/validator-client",
"ts-packages/*",
"nym-wallet",
"nym-connect/**",
@@ -16,6 +19,7 @@
],
"scripts": {
"nuke": "npx rimraf **/node_modules node_modules",
"scrub": "npx rimraf **/dist dist",
"clean": "lerna run clean",
"build:ci:sdk": "run-s build:types build:packages build:wasm build:sdk:ci",
@@ -23,7 +27,6 @@
"build": "run-s build:types build:packages",
"build:wasm": "make sdk-wasm-build",
"build:sdk": "make sdk-typescript-build",
"build:types": "lerna run --scope @nymproject/types build --stream",
"build:packages": "run-s build:packages:theme build:packages:react",
"build:packages:theme": "lerna run --scope @nymproject/mui-theme build",
@@ -45,6 +45,7 @@ use libp2p::ping::Success;
use libp2p::swarm::{keep_alive, NetworkBehaviour, SwarmEvent};
use libp2p::{identity, ping, Multiaddr, PeerId};
use log::{debug, info, LevelFilter};
use nym_sdk::mixnet::MixnetClient;
use std::error::Error;
use std::time::Duration;
@@ -69,7 +70,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
use libp2p::swarm::SwarmBuilder;
use rust_libp2p_nym::transport::NymTransport;
let client = nym_sdk::mixnet::MixnetClient::connect_new().await.unwrap();
let client = MixnetClient::connect_new().await.unwrap();
let transport = NymTransport::new(client, local_key.clone()).await?;
SwarmBuilder::with_tokio_executor(
@@ -80,7 +80,6 @@ pub struct NymTransport {
impl NymTransport {
/// New transport.
#[allow(unused)]
pub async fn new(client: MixnetClient, keypair: Keypair) -> Result<Self, Error> {
Self::new_maybe_with_notify_inbound(client, keypair, None, None).await
}
@@ -1,6 +1,6 @@
{
"name": "@nymproject/contract-clients",
"version": "1.2.0-rc.10",
"version": "1.2.0",
"description": "A client for all Nym smart contracts",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@nymproject/ts-sdk-docs",
"version": "1.2.0-rc.10",
"version": "1.2.0",
"description": "Nym Typescript SDK Docs",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
@@ -28,10 +28,10 @@
"@mui/icons-material": "^5.14.9",
"@mui/lab": "^5.0.0-alpha.145",
"@mui/material": "^5.14.8",
"@nymproject/contract-clients": "^1.2.0-rc.9",
"@nymproject/mix-fetch": "^1.2.0-rc.9",
"@nymproject/mix-fetch-full-fat": "^1.2.0-rc.9",
"@nymproject/sdk-full-fat": "^1.2.0-rc.9",
"@nymproject/contract-clients": ">=1.2.0-rc.10 || ^1",
"@nymproject/mix-fetch": ">=1.2.0-rc.10 || ^1",
"@nymproject/mix-fetch-full-fat": ">=1.2.0-rc.10 || ^1",
"@nymproject/sdk-full-fat": ">=1.2.0-rc.10 || ^1",
"chain-registry": "^1.19.0",
"cosmjs-types": "^0.8.0",
"next": "^13.4.19",
@@ -51,4 +51,4 @@
"typescript": "^4.9.3"
},
"private": false
}
}
@@ -6,7 +6,7 @@
"source": "src/index.html",
"browserslist": "> 0.5%, last 2 versions, not dead",
"dependencies": {
"@nymproject/sdk": "1.2.0-rc.1"
"@nymproject/sdk": ">=1.2.0-rc.10 || ^1"
},
"devDependencies": {
"@types/jest": "^27.0.1",
@@ -4,7 +4,7 @@
"version": "1.0.0",
"license": "Apache-2.0",
"dependencies": {
"@nymproject/sdk": "1.2.0-rc.1"
"@nymproject/sdk": ">=1.2.0-rc.10 || ^1"
},
"devDependencies": {
"@babel/core": "^7.15.0",
@@ -9,7 +9,7 @@
"@mui/material": "^5.0.1",
"@mui/styles": "^5.0.1",
"react-mui-dropzone": "^4.0.6",
"@nymproject/sdk": "1.2.0-rc.1",
"@nymproject/sdk": ">=1.2.0-rc.10 || ^1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-dropzone": "^14.2.3",
@@ -15,6 +15,6 @@
"webpack-cli": "^5.1.4"
},
"dependencies": {
"@nymproject/sdk": "1.2.0-rc.1"
"@nymproject/sdk": ">=1.2.0-rc.10 || ^1"
}
}
@@ -15,6 +15,6 @@
"build": "yarn webpack"
},
"dependencies": {
"@nymproject/sdk": "1.2.0-rc.1"
"@nymproject/sdk": ">=1.2.0-rc.10 || ^1"
}
}
@@ -4,8 +4,8 @@
"license": "Apache-2.0",
"source": "src/index.html",
"dependencies": {
"@nymproject/mix-fetch": ">=1.2.0-rc.10 || ^1",
"parcel": "^2.10.0"
"parcel": "^2.9.3",
"@nymproject/mix-fetch": ">=1.2.0-rc.10 || ^1"
},
"scripts": {
"start": "parcel --no-cache",
@@ -1,35 +1,9 @@
import { SetupMixFetchOps, mixFetch } from '@nymproject/mix-fetch';
import { mixFetch } from '@nymproject/mix-fetch';
import { appendOutput, appendImageOutput } from './utils';
async function main() {
// options for mixFetch (you can also set these with the `createMixFetch` function
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const mixFetchOptionsForSandbox: SetupMixFetchOps = {
preferredGateway: 'HjNEDJuotWV8VD4ufeA1jeheTnfNJ7Jorevp57hgaZua', // with WSS
preferredNetworkRequester:
// 'AzGdJ4MU78Ex22NEWfeycbN7bt3PFZr1MtKstAdhfELG.GSxnKnvKPjjQm3FdtsgG5KyhP6adGbPHRmFWDH4XfUpP@HjNEDJuotWV8VD4ufeA1jeheTnfNJ7Jorevp57hgaZua',
'AzGdJ4MU78Ex22NEWfeycbN7bt3PFZr1MtKstAdhfELG.GSxnKnvKPjjQm3FdtsgG5KyhP6adGbPHRmFWDH4XfUpP@HjNEDJuotWV8VD4ufeA1jeheTnfNJ7Jorevp57hgaZua',
mixFetchOverride: {
requestTimeoutMs: 120_000,
},
extra: {
hiddenGateways: [
{
owner: 'n1ns3v70ul9gnl9l9fkyz8cyxfq75vjcmx8el0t3',
explicitIp: '35.158.238.80',
host: 'sandbox-gateway1.nymtech.net',
sphinxKey: 'BoXeUD7ERGmzRauMjJD3itVNnQiH42ncUb6kcVLrb3dy',
identityKey: 'HjNEDJuotWV8VD4ufeA1jeheTnfNJ7Jorevp57hgaZua',
},
],
},
nymApiUrl: 'https://sandbox-nym-api1.nymtech.net/api',
forceTls: true, // force WSS
};
// options for mixFetch (you can also set these with the `createMixFetch` function
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const mixFetchOptionsMainnet = {
const mixFetchOptions = {
preferredGateway: 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM', // with WSS
preferredNetworkRequester:
'GiRjFWrMxt58pEMuusm4yT3RxoMD1MMPrR9M2N4VWRJP.3CNZBPq4vg7v7qozjGjdPMXcvDmkbWPCgbGCjQVw9n6Z@2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW',
@@ -38,9 +12,6 @@ async function main() {
},
};
const mixFetchOptions = mixFetchOptionsForSandbox;
// disable CORS (in your app, you probably don't want to disable CORS, it is a good thing to leave it enabled)
const args = { mode: 'unsafe-ignore-cors' };
@@ -6,7 +6,7 @@
"source": "src/index.html",
"browserslist": "> 0.5%, last 2 versions, not dead",
"dependencies": {
"@nymproject/sdk": "1.2.0-rc.1"
"@nymproject/sdk": ">=1.2.0-rc.10 || ^1"
},
"devDependencies": {
"@types/jest": "^27.0.1",
@@ -4,7 +4,7 @@
"version": "1.0.0",
"license": "Apache-2.0",
"dependencies": {
"@nymproject/sdk": "1.2.0-rc.1"
"@nymproject/sdk": ">=1.2.0-rc.10 || ^1"
},
"devDependencies": {
"@babel/core": "^7.15.0",
@@ -8,7 +8,7 @@
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.14.0",
"@mui/material": "^5.14.0",
"@nymproject/sdk": "1.2.0-rc.1",
"@nymproject/sdk": ">=1.2.0-rc.10 || ^1",
"parcel": "^2.9.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
@@ -3,7 +3,7 @@
"version": "1.0.0",
"license": "Apache-2.0",
"dependencies": {
"@nymproject/mix-fetch": ">=1.2.0-rc.7 || ^1"
"@nymproject/mix-fetch": ">=1.2.0-rc.10 || ^1"
},
"devDependencies": {
"@babel/core": "^7.22.10",
@@ -4,7 +4,7 @@
"license": "Apache-2.0",
"source": "../src/index.html",
"dependencies": {
"@nymproject/mix-fetch": ">=1.2.0-rc.7 || ^1"
"@nymproject/mix-fetch": ">=1.2.0-rc.10 || ^1"
},
"scripts": {
"start": "npx parcel --no-cache",
@@ -1,6 +1,6 @@
{
"name": "@nymproject/mix-fetch",
"version": "1.2.0-rc.10",
"version": "1.2.0",
"description": "This package is a drop-in replacement for `fetch` to send HTTP requests over the Nym Mixnet.",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
@@ -33,7 +33,7 @@
"tsc": "tsc --noEmit true"
},
"dependencies": {
"@nymproject/mix-fetch-wasm": ">=1.2.0-rc.7 || 1",
"@nymproject/mix-fetch-wasm": ">=1.2.0-rc.10 || ^1",
"comlink": "^4.3.1"
},
"devDependencies": {
@@ -81,4 +81,4 @@
"private": false,
"type": "module",
"types": "./dist/esm/index.d.ts"
}
}
@@ -1,6 +1,6 @@
{
"name": "@nymproject/node-tester",
"version": "1.2.0-rc.10",
"version": "1.2.0",
"description": "This package provides a tester that can send test packets to mixnode that is part of the Nym Mixnet.",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
@@ -25,7 +25,7 @@
"tsc": "tsc --noEmit true"
},
"dependencies": {
"@nymproject/nym-node-tester-wasm": ">=1.2.0-rc.7 || ^1",
"@nymproject/nym-node-tester-wasm": ">=1.2.0-rc.10 || ^1",
"comlink": "^4.3.1"
},
"devDependencies": {
@@ -71,4 +71,4 @@
"private": false,
"type": "module",
"types": "./dist/esm/index.d.ts"
}
}
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk-react",
"version": "1.2.0-rc.10",
"version": "1.2.0",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
"files": [
@@ -20,7 +20,7 @@
"tsc": "tsc --noEmit true"
},
"dependencies": {
"@nymproject/sdk": ">=1.2.0-rc.7 || ^1"
"@nymproject/sdk": ">=1.2.0-rc.10 || ^1"
},
"devDependencies": {
"@babel/core": "^7.17.5",
@@ -67,4 +67,4 @@
"private": false,
"type": "module",
"types": "./dist/index.d.ts"
}
}
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@nymproject/sdk",
"version": "1.2.0-rc.10",
"version": "1.2.0",
"license": "Apache-2.0",
"author": "Nym Technologies SA",
"files": [
@@ -30,7 +30,7 @@
"tsc": "tsc --noEmit true"
},
"dependencies": {
"@nymproject/nym-client-wasm": ">=1.2.0-rc.7 || ^1",
"@nymproject/nym-client-wasm": ">=1.2.0-rc.10 || ^1",
"comlink": "^4.3.1"
},
"devDependencies": {
@@ -80,4 +80,4 @@
"private": false,
"type": "module",
"types": "./dist/esm/index.d.ts"
}
}
@@ -1,6 +1,6 @@
{
"name": "@nymproject/nym-validator-client",
"version": "1.2.0-rc.10",
"version": "1.2.0",
"description": "A TypeScript client for interacting with smart contracts in Nym validators",
"license": "Apache-2.0",
"author": "Nym Technologies SA (https://nymtech.net)",
@@ -34,7 +34,7 @@ use nym_socks5_requests::{
};
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
use nym_sphinx::params::{PacketSize, PacketType};
use nym_sphinx::params::PacketSize;
use nym_sphinx::receiver::ReconstructedMessage;
use nym_statistics_common::collector::StatisticsSender;
use nym_task::connections::LaneQueueLengths;
@@ -186,7 +186,7 @@ impl NRServiceProviderBuilder {
allowed_hosts::HostsStore::new(&config.storage_paths.unknown_list_location);
let outbound_request_filter =
OutboundRequestFilter::new(allowed_hosts, standard_list, unknown_hosts);
OutboundRequestFilter::new(allowed_hosts.clone(), standard_list.clone(), unknown_hosts);
NRServiceProviderBuilder {
config,
@@ -321,7 +321,6 @@ impl NRServiceProviderBuilder {
let stats_collector_clone = stats_collector.clone();
let mixnet_client_sender = mixnet_client.split_sender();
let self_address = *mixnet_client.nym_address();
let packet_type = self.config.base.debug.traffic.packet_type;
// start the listener for mix messages
tokio::spawn(async move {
@@ -329,7 +328,6 @@ impl NRServiceProviderBuilder {
mixnet_client_sender,
mix_input_receiver,
stats_collector_clone,
packet_type,
)
.await;
});
@@ -422,7 +420,6 @@ impl NRServiceProvider {
mixnet_client_sender: nym_sdk::mixnet::MixnetClientSender,
mut mix_input_reader: MixProxyReader<MixnetMessage>,
stats_collector: Option<ServiceStatisticsCollector>,
packet_type: PacketType,
) {
loop {
tokio::select! {
@@ -443,7 +440,7 @@ impl NRServiceProvider {
}
}
let response_message = msg.into_input_message(packet_type);
let response_message = msg.into_input_message();
mixnet_client_sender.send(response_message).await.unwrap();
} else {
log::error!("Exiting: channel closed!");
@@ -11,7 +11,6 @@ use nym_socks5_requests::{
};
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
use nym_sphinx::params::PacketType;
use nym_task::connections::TransmissionLane;
use std::fmt::{Debug, Formatter};
@@ -149,9 +148,8 @@ impl MixnetMessage {
self.data.len()
}
pub(crate) fn into_input_message(self, packet_type: PacketType) -> InputMessage {
self.address
.send_back_to(self.data, self.connection_id, packet_type)
pub(crate) fn into_input_message(self) -> InputMessage {
self.address.send_back_to(self.data, self.connection_id)
}
}
@@ -177,28 +175,17 @@ impl MixnetAddress {
None
}
pub(super) fn send_back_to(
self,
message: Vec<u8>,
connection_id: u64,
packet_type: PacketType,
) -> InputMessage {
pub(super) fn send_back_to(self, message: Vec<u8>, connection_id: u64) -> InputMessage {
match self {
MixnetAddress::Known(recipient) => InputMessage::MessageWrapper {
message: Box::new(InputMessage::Regular {
recipient: *recipient,
data: message,
lane: TransmissionLane::ConnectionId(connection_id),
}),
packet_type,
MixnetAddress::Known(recipient) => InputMessage::Regular {
recipient: *recipient,
data: message,
lane: TransmissionLane::ConnectionId(connection_id),
},
MixnetAddress::Anonymous(sender_tag) => InputMessage::MessageWrapper {
message: Box::new(InputMessage::Reply {
recipient_tag: sender_tag,
data: message,
lane: TransmissionLane::ConnectionId(connection_id),
}),
packet_type,
MixnetAddress::Anonymous(sender_tag) => InputMessage::Reply {
recipient_tag: sender_tag,
data: message,
lane: TransmissionLane::ConnectionId(connection_id),
},
}
}
+14 -5
View File
@@ -174,15 +174,24 @@ fn initialise_internal_packages<P: AsRef<Path>>(root: P) -> InternalPackages {
packages.register_cargo("nym-browser-extension/storage");
// js packages that will have their package.json modified
packages.register_json("nym-wallet");
packages.register_json("sdk/typescript/docs");
packages.register_json("sdk/typescript/examples/chat-app/parcel");
packages.register_json("sdk/typescript/examples/chat-app/plain-html");
packages.register_json("sdk/typescript/examples/chat-app/react-webpack-with-theme-example");
packages.register_json("sdk/typescript/examples/chrome-extension");
packages.register_json("sdk/typescript/examples/firefox-extension");
packages.register_json("sdk/typescript/examples/mix-fetch/browser");
packages.register_json("sdk/typescript/examples/node-tester/parcel");
packages.register_json("sdk/typescript/examples/node-tester/plain-html");
packages.register_json("sdk/typescript/examples/node-tester/react");
packages.register_json("sdk/typescript/packages/mix-fetch");
packages.register_json("sdk/typescript/packages/mui-theme");
packages.register_json("sdk/typescript/packages/mix-fetch/internal-dev");
packages.register_json("sdk/typescript/packages/mix-fetch/internal-dev/parcel");
packages.register_json("sdk/typescript/packages/node-tester");
packages.register_json("sdk/typescript/packages/react-components");
packages.register_json("sdk/typescript/packages/nodejs-client");
packages.register_json("sdk/typescript/packages/sdk");
packages.register_json("sdk/typescript/packages/sdk-react");
packages.register_json("sdk/typescript/packages/validator-client");
packages.register_json("sdk/typescript/codegen/contract-clients");
packages.register_json("sdk/typescript/docs");
// dependencies that will have their versions adjusted in the above packages
packages.register_known_js_dependency("@nymproject/mix-fetch");
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "nym-client-wasm"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jedrzej Stuczynski <andrew@nymtech.net>"]
version = "1.2.0-rc.10"
version = "1.2.0"
edition = "2021"
keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy", "client"]
license = "Apache-2.0"
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "nym-wasm-sdk"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
version = "1.2.0-rc.10"
version = "1.2.0"
edition = "2021"
keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy"]
license = "Apache-2.0"
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "mix-fetch-wasm"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
version = "1.2.0-rc.10"
version = "1.2.0"
edition = "2021"
keywords = ["nym", "fetch", "wasm", "webassembly", "privacy"]
license = "Apache-2.0"
+1 -1
View File
@@ -1,7 +1,7 @@
[package]
name = "nym-node-tester-wasm"
authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"]
version = "1.2.0-rc.10"
version = "1.2.0"
edition = "2021"
keywords = ["nym", "sphinx", "webassembly", "privacy", "tester"]
license = "Apache-2.0"
+47 -1478
View File
File diff suppressed because it is too large Load Diff