Compare commits

...

12 Commits

Author SHA1 Message Date
Tommy Verrall b45eb16783 Update ci-build-upload-binaries.yml 2024-08-05 11:48:07 +02:00
Tommy Verrall f8523dc7d1 Update publish-nym-binaries.yml 2024-08-05 11:47:00 +02:00
Bogdan-Ștefan Neacşu 3d5ac0b883 Fix version 1 not having template correspondent initially (#4733) 2024-07-29 12:38:27 +02:00
benedettadavico de0fb7459d update changelog 2024-07-26 15:28:06 +02:00
benedettadavico e2ead6dbe1 bumping binaries versions 2024-07-26 15:25:47 +02:00
Jędrzej Stuczyński 7b10d92ca4 Merge pull request #4731 from nymtech/chore/1.80-lints
chore: fix 1.80 lint issues
2024-07-26 11:51:23 +01:00
Jędrzej Stuczyński 2c6e5eb673 cherry-pick: fix build issues 2024-07-26 11:11:52 +01:00
Jon Häggblad 02fde4e530 Handle clients with different versions in IPR (#4723)
* Add signable_request function

* Export key type in function signature

* Cargo.lock

* Track client version and respond using it

* Internally use v7 and then down convert if needed

* Local response type

* Streamline

* Strong type for client version

* Remove commented out code

* rustfmt

* Ignore sign verification fail for v6
2024-07-24 15:35:59 +02:00
import this cc25fc1f32 [DOCs/operators]: Changelog for v2024.8 wispa & guide syntax edits (#4728)
* changelog for release v2024.8-wispa

* clarify syntax

* typo fix
2024-07-24 12:38:25 +00:00
benedetta davico c971e486b5 Merge pull request #4726 from nymtech/release/2024.8-wispa
Release/2024.8 wispa into develop
2024-07-24 12:48:57 +02:00
import this 96a9eb6f6a [DOCs/docs]: Commnet out extra stubs (#4727)
* commnet out stubs

* fix broken links - ready to merge
2024-07-24 11:58:14 +02:00
John Smith 08042c61ad [DOCs/operators]: Update troubleshooting/vps-isp.md with manual IPv6 configuration (#4651)
* Update vps-isp.md

Added an extra diagnostic step, which helped me to debug lack of routability.

* Update vps-isp.md

Implementing serinko's comments

* Update vps-isp.md

Changed possibly to possible and added how to find IPv6 Gateway.

* Update vps-isp.md

Fixed ifup/ifdown link
2024-07-24 08:53:49 +00:00
42 changed files with 718 additions and 158 deletions
@@ -8,11 +8,6 @@ on:
required: true
default: false
type: boolean
enable_wireguard:
description: "Add --features wireguard"
required: true
default: false
type: boolean
enable_deb:
description: "True to enable cargo-deb installation and .deb package building"
required: false
@@ -42,7 +37,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-20.04]
platform: [ ubuntu-20.04 ]
runs-on: ${{ matrix.platform }}
env:
@@ -70,9 +65,6 @@ jobs:
- name: Set CARGO_FEATURES
run: |
echo 'CARGO_FEATURES=--features wireguard' >> $GITHUB_ENV
if: >
github.event_name == 'schedule' ||
(github.event_name == 'workflow_dispatch' && inputs.enable_wireguard == true)
- name: Install Rust stable
uses: actions-rs/toolchain@v1
+6 -2
View File
@@ -51,6 +51,10 @@ jobs:
echo 'RUSTFLAGS="--cfg tokio_unstable"' >> $GITHUB_ENV
if: github.event_name == 'workflow_dispatch' && inputs.add_tokio_unstable == true
- name: Set CARGO_FEATURES
run: |
echo 'CARGO_FEATURES=--features wireguard' >> $GITHUB_ENV
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
@@ -60,8 +64,8 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --release
args: --workspace --release ${{ env.CARGO_FEATURES }}
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
+14
View File
@@ -4,6 +4,20 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
## [Unreleased]
## [2024.9-topdeck] (2024-07-26)
- chore: fix 1.80 lint issues ([#4731])
- Handle clients with different versions in IPR ([#4723])
- Add 1GB/day/user bandwidth cap ([#4717])
- Feature/merge back ([#4710])
- removed mixnode/gateway config migration code and disabled cli without explicit flag ([#4706])
[#4731]: https://github.com/nymtech/nym/pull/4731
[#4723]: https://github.com/nymtech/nym/pull/4723
[#4717]: https://github.com/nymtech/nym/pull/4717
[#4710]: https://github.com/nymtech/nym/pull/4710
[#4706]: https://github.com/nymtech/nym/pull/4706
## [2024.8-wispa] (2024-07-10)
- add event parsing to support cosmos_sdk > 0.50 ([#4697])
Generated
+9 -8
View File
@@ -2093,7 +2093,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "explorer-api"
version = "1.1.37"
version = "1.1.38"
dependencies = [
"chrono",
"clap 4.5.4",
@@ -3849,7 +3849,7 @@ dependencies = [
[[package]]
name = "nym-api"
version = "1.1.41"
version = "1.1.42"
dependencies = [
"anyhow",
"async-trait",
@@ -4057,7 +4057,7 @@ dependencies = [
[[package]]
name = "nym-cli"
version = "1.1.39"
version = "1.1.40"
dependencies = [
"anyhow",
"base64 0.13.1",
@@ -4136,7 +4136,7 @@ dependencies = [
[[package]]
name = "nym-client"
version = "1.1.38"
version = "1.1.39"
dependencies = [
"bs58 0.5.1",
"clap 4.5.4",
@@ -4950,7 +4950,7 @@ dependencies = [
[[package]]
name = "nym-network-requester"
version = "1.1.39"
version = "1.1.40"
dependencies = [
"addr",
"anyhow",
@@ -5001,7 +5001,7 @@ dependencies = [
[[package]]
name = "nym-node"
version = "1.1.5"
version = "1.1.6"
dependencies = [
"anyhow",
"bip39",
@@ -5264,7 +5264,7 @@ dependencies = [
[[package]]
name = "nym-socks5-client"
version = "1.1.38"
version = "1.1.39"
dependencies = [
"bs58 0.5.1",
"clap 4.5.4",
@@ -5779,7 +5779,7 @@ dependencies = [
[[package]]
name = "nymvisor"
version = "0.1.4"
version = "0.1.5"
dependencies = [
"anyhow",
"bytes",
@@ -9439,6 +9439,7 @@ dependencies = [
name = "wasm-utils"
version = "0.1.0"
dependencies = [
"console_error_panic_hook",
"futures",
"getrandom 0.2.15",
"gloo-net",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.1.38"
version = "1.1.39"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-socks5-client"
version = "1.1.38"
version = "1.1.39"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021"
@@ -1,6 +1,11 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// TEMPORARY WORKAROUND:
// those features are expected as the below should only get activated whenever
// the corresponding features in tendermint-rpc are enabled transitively
#![allow(unexpected_cfgs)]
use crate::nyxd::cosmwasm_client::client_traits::SigningCosmWasmClient;
use crate::nyxd::error::NyxdError;
use crate::nyxd::{Config, GasPrice, Hash, Height};
@@ -1,6 +1,11 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// TEMPORARY WORKAROUND:
// those features are expected as the below should only get activated whenever
// the corresponding features in tendermint-rpc are enabled transitively
#![allow(unexpected_cfgs)]
use crate::nyxd::contract_traits::{NymContractsProvider, TypedNymContracts};
use crate::nyxd::cosmwasm_client::types::{
ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, InstantiateResult,
@@ -1,6 +1,11 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// TEMPORARY WORKAROUND:
// those features are expected as the below should only get activated whenever
// the corresponding features in tendermint-rpc are enabled transitively
#![allow(unexpected_cfgs)]
use async_trait::async_trait;
use cosmrs::tendermint::{self, abci, block::Height, evidence::Evidence, Genesis, Hash};
use serde::{de::DeserializeOwned, Serialize};
@@ -0,0 +1,69 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{v6, v7};
impl From<v7::response::StaticConnectFailureReason> for v6::response::StaticConnectFailureReason {
fn from(failure: v7::response::StaticConnectFailureReason) -> Self {
match failure {
v7::response::StaticConnectFailureReason::RequestedIpAlreadyInUse => {
v6::response::StaticConnectFailureReason::RequestedIpAlreadyInUse
}
v7::response::StaticConnectFailureReason::RequestedNymAddressAlreadyInUse => {
v6::response::StaticConnectFailureReason::RequestedNymAddressAlreadyInUse
}
v7::response::StaticConnectFailureReason::OutOfDateTimestamp => {
v6::response::StaticConnectFailureReason::Other("out of date timestamp".to_string())
}
v7::response::StaticConnectFailureReason::Other(reason) => {
v6::response::StaticConnectFailureReason::Other(reason)
}
}
}
}
impl From<v7::response::DynamicConnectFailureReason> for v6::response::DynamicConnectFailureReason {
fn from(failure: v7::response::DynamicConnectFailureReason) -> Self {
match failure {
v7::response::DynamicConnectFailureReason::RequestedNymAddressAlreadyInUse => {
v6::response::DynamicConnectFailureReason::RequestedNymAddressAlreadyInUse
}
v7::response::DynamicConnectFailureReason::NoAvailableIp => {
v6::response::DynamicConnectFailureReason::NoAvailableIp
}
v7::response::DynamicConnectFailureReason::Other(err) => {
v6::response::DynamicConnectFailureReason::Other(err)
}
}
}
}
impl From<v7::response::InfoResponseReply> for v6::response::InfoResponseReply {
fn from(reply: v7::response::InfoResponseReply) -> Self {
match reply {
v7::response::InfoResponseReply::Generic { msg } => {
v6::response::InfoResponseReply::Generic { msg }
}
v7::response::InfoResponseReply::VersionMismatch {
request_version,
response_version,
} => v6::response::InfoResponseReply::VersionMismatch {
request_version,
response_version,
},
v7::response::InfoResponseReply::ExitPolicyFilterCheckFailed { dst } => {
v6::response::InfoResponseReply::ExitPolicyFilterCheckFailed { dst }
}
}
}
}
impl From<v7::response::InfoLevel> for v6::response::InfoLevel {
fn from(level: v7::response::InfoLevel) -> Self {
match level {
v7::response::InfoLevel::Info => v6::response::InfoLevel::Info,
v7::response::InfoLevel::Warn => v6::response::InfoLevel::Warn,
v7::response::InfoLevel::Error => v6::response::InfoLevel::Error,
}
}
}
+1
View File
@@ -1,3 +1,4 @@
pub mod conversion;
pub mod request;
pub mod response;
@@ -198,6 +198,17 @@ impl IpPacketRequestData {
| IpPacketRequestData::Health(_) => None,
}
}
pub fn signable_request(&self) -> Option<Result<Vec<u8>, SignatureError>> {
match self {
IpPacketRequestData::StaticConnect(request) => Some(request.request()),
IpPacketRequestData::DynamicConnect(request) => Some(request.request()),
IpPacketRequestData::Disconnect(request) => Some(request.request()),
IpPacketRequestData::Data(_) => None,
IpPacketRequestData::Ping(_) => None,
IpPacketRequestData::Health(_) => None,
}
}
}
// A static connect request is when the client provides the internal IP address it will use on the
-1
View File
@@ -44,7 +44,6 @@ pub enum NymTopologyError {
PayloadBuilder,
#[error("Outfox: {0}")]
#[cfg(feature = "outfox")]
Outfox(#[from] nym_sphinx_types::OutfoxError),
#[error("{0}")]
@@ -7,6 +7,7 @@ use nym_sphinx_routing::SphinxRouteMaker;
use nym_sphinx_types::Node;
use rand::{CryptoRng, Rng};
#[allow(dead_code)]
pub struct NymTopologyRouteProvider<R> {
rng: R,
inner: NymTopology,
+3 -1
View File
@@ -17,6 +17,8 @@ gloo-utils = { workspace = true }
gloo-net = { workspace = true, features = ["websocket"], optional = true }
#gloo-net = { path = "../../../../gloo/crates/net", features = ["websocket"], optional = true }
console_error_panic_hook = { workspace = true, optional = true }
# we don't want entire tokio-tungstenite, tungstenite itself is just fine - we just want message and error enums
[dependencies.tungstenite]
workspace = true
@@ -28,7 +30,7 @@ workspace = true
optional = true
[features]
default = ["sleep"]
default = ["sleep", "console_error_panic_hook"]
sleep = ["web-sys", "web-sys/Window"]
websocket = [
"getrandom",
-4
View File
@@ -15,10 +15,6 @@
# Nodes
- [Node Types (Previously Setup Guides)](nodes/overview.md)
- [Mix Node](nodes/mixnode.md)
- [Gateway](nodes/gateway.md)
- [Network Requester](nodes/network-requester.md)
- [Validator](nodes/validator.md)
# Wallet
- [Desktop Wallet](wallet/desktop-wallet.md)
@@ -9,31 +9,31 @@ At a high level, our technologies include:
* a **mixnet**, which encrypts and mixes Sphinx packet traffic so that it cannot be determined who is communicating with whom. Our mixnet is based on a modified version of the **Loopix** design.
* a privacy enhancing signature scheme called **Coconut**. Coconut allows a shift in thinking about resource access control, from an identity-based paradigm based on _who you are_ to a privacy-preserving paradigm based on _right to use_.
* **Sphinx**, a way of transmitting armoured, layer-encrypted information packets which are indistinguishable from each other at a binary level.
* the **Nyx** blockchain, a general-purpose CosmWasm-enabled smart contract platform, and the home of the smart contracts which keep track of the mixnet.
* the **Nyx** blockchain, a general-purpose CosmWasm-enabled smart contract platform, and the home of the smart contracts which keep track of the mixnet.
The most important thing to note is that these technologies ensure privacy at two different levels of the stack: **network data transmission**, and **transactions**.
Here's an overview diagram of the different types of nodes making up the network:
Here's an overview diagram of the different types of nodes making up the network:
![Nym Platform](../images/nym-platform-dark.png)
Developers can think of the network as being comprised of **infrastructure nodes** and **clients** for interacting with this infrastructure via **P**rivacy-**e**nhanced **app**lications (PEApps).
Developers can think of the network as being comprised of **infrastructure nodes** and **clients** for interacting with this infrastructure via **P**rivacy-**e**nhanced **app**lications (PEApps).
## Mixnet Infrastructure
## Mixnet Infrastructure
The mixnet - the different pieces of software that your traffic will pass through when using an privacy-enhanced app (PEApp) - is made up of several different types of nodes:
* **Mix Nodes** provide network security for network content _and_ metadata, making it impossible to see who is communicating with who, by performing packet-mixing on traffic travelling through the network.
* **Mix Nodes** provide network security for network content _and_ metadata, making it impossible to see who is communicating with who, by performing packet-mixing on traffic travelling through the network.
* **Gateways** act as message storage for clients which may go offline and come back online again, and defend against denial of service attacks. The default gateway implementation included in the Nym platform code holds packets for later retrieval. For many applications (such as simple chat), this is usable out of the box, as it provides a place that potentially offline clients can retrieve packets from. The access token allows clients to pull messages from the gateway node.
* **Services** are applications that communicate with nym clients, listening and sending traffic to the mixnet. This is an umbrella term for a variety of different pieces of code, such as the [network requester](../nodes/network-requester.md) binary.
* **Services** are applications that communicate with nym clients, listening and sending traffic to the mixnet. This is an umbrella term for a variety of different pieces of code, such as the network requester binary.
* **Nyx Blockchain Validators** secure the network with proof-of-stake Sybil defenses, determine which nodes are included within the network, and work together to create Coconut threshold credentials which provide anonymous access to data and resources. They also produce blocks and secure the Nyx Blockchain. Initially, this chain was used only to house the CosmWasm smart contracts keeping track of Nym's network topology, token vesting contracts, and the `NYM` token itself. In recent months, we've decided to expand the role of Nyx and instead expand its role by making it an open smart contract platform for anyone to upload CosmWasm smart contracts to. Validators also provide privacy-enhanced credentials based on the testimony of a set of decentralized, blockchain-based issuing authorities. Nym validators use the [Coconut](https://arxiv.org/abs/1802.07344) [signature scheme](https://en.wikipedia.org/wiki/Digital_signature) to issue credentials. This allows privacy apps to generate anonymous resource claims through decentralised authorities, then use them with Service Providers.
## Privacy-enhanced applications (PEApps)
## Privacy-enhanced applications (PEApps)
PEApps use a Nym client to connect to the network in order to get the available Network Topology for traffic routing, and send/receive packets to other users and services. Clients, in order to send traffic through the mixnet, connect to gateways. Since applications may go online and offline, a client's gateway provides a sort of mailbox where apps can receive their messages.
Nym clients connect to gateways. Messages are automatically piped to connected clients and deleted from the gateway's disk storage. If a client is offline when a message arrives, it will be stored for later retrieval. When the client connects, all messages will be delivered, and deleted from the gateway's disk.
Nym clients connect to gateways. Messages are automatically piped to connected clients and deleted from the gateway's disk storage. If a client is offline when a message arrives, it will be stored for later retrieval. When the client connects, all messages will be delivered, and deleted from the gateway's disk.
When it starts up, a client registers itself with a gateway, and the gateway returns an access token. The access token plus the gateway's IP can then be used as a form of addressing for delivering packets.
@@ -46,4 +46,4 @@ Service Providers (SPs) may interact with external systems on behalf of a user.
There is also a special category of Service Provider, namely SPs that do not visibly interact with any external systems. You might think of these as crypto-utopiapps: they're doing something, but it's not possible from outside to say with any certainty what their function is, or who is interacting with them.
All apps talk with gateways using Sphinx packets and a small set of simple control messages. These messages are sent to gateways over websockets. Each app client has a long-lived relationship with its gateway; Nym defines messages for clients registering and authenticating with gateways, as well as sending encrypted Sphinx packets.
All apps talk with gateways using Sphinx packets and a small set of simple control messages. These messages are sent to gateways over websockets. Each app client has a long-lived relationship with its gateway; Nym defines messages for clients registering and authenticating with gateways, as well as sending encrypted Sphinx packets.
+10 -11
View File
@@ -8,7 +8,7 @@ Nym has two main codebases:
- the [Nym platform](https://github.com/nymtech/nym), written in Rust. This contains all of our code _except_ for the validators.
- the [Nym validators](https://github.com/nymtech/nyxd), written in Go.
> This page details how to build the main Nym platform code. **If you want to build and run a validator, [go here](../nodes/validator.md) instead.**
> This page details how to build the main Nym platform code. **If you want to build and run a validator, [go here](https://nymtech.net/operators/nodes/validator-setup.html) instead.**
## Prerequisites
- Debian/Ubuntu: `pkg-config`, `build-essential`, `libssl-dev`, `curl`, `jq`, `git`
@@ -54,18 +54,17 @@ cargo build --release # build your binaries with **mainnet** configuration
Quite a bit of stuff gets built. The key working parts are:
* [mix node](../nodes/mixnode.md): `nym-mixnode`
* [gateway node](../nodes/gateway.md): `nym-gateway`
* [websocket client](https://nymtech.net/developers/clients/websocket-client.md): `nym-client`
* [socks5 client](https://nymtech.net/developers/clients/socks5-client.md): `nym-socks5-client`
* [network requester](../nodes/network-requester.md): `nym-network-requester`
* [nym-cli tool](../tools/nym-cli.md): `nym-cli`
* [Nym Node](https://nymtech.net/operators/nodes/nym-node.html): `nym-node`
* [Validator](https://nymtech.net/operators/nodes/validator-setup.html)
* [websocket client](https://nymtech.net/docs/clients/websocket-client.html): `nym-client`
* [socks5 client](https://nymtech.net/docs/clients/socks5-client.html): `nym-socks5-client`
* [webassembly client](https://nymtech.net/docs/clients/webassembly-client.html): `webassembly-client`
* [nym-cli tool](https://nymtech.net/docs/tools/nym-cli.html): `nym-cli`
* [nym-api](https://nymtech.net/operators/nodes/nym-api.html): `nym-api`
[//]: # (* [nymvisor]&#40;https://nymtech.net/operators/nodes/nymvisor-upgrade.html&#41;: `nymvisor`)
* [nymvisor](https://nymtech.net/operators/nodes/nymvisor-upgrade.html): `nymvisor`
The repository also contains Typescript applications which aren't built in this process. These can be built by following the instructions on their respective docs pages.
* [Nym Wallet](../wallet/desktop-wallet.md)
* [Network Explorer UI](../explorers/mixnet-explorer.md)
* [Nym Wallet](https://nymtech.net/docs/wallet/desktop-wallet.html)
* [Network Explorer UI](https://nymtech.net/docs/explorers/mixnet-explorer.html)
> You cannot build from GitHub's .zip or .tar.gz archive files on the releases page - the Nym build scripts automatically include the current git commit hash in the built binary during compilation, so the build will fail if you use the archive code (which isn't a Git repository). Check the code out from github using `git clone` instead.
+4 -6
View File
@@ -1,9 +1,7 @@
# Node Types
> This section was previously the node setup guides. These have been migrated to their own [**Operator Guides**](https://nymtech.net/operators) book.
>
> For setup and maintenance guides, go to the Operators book linked above.
>
> This section is a little spartan for the moment, but we will be adding detailed information about how exactly each node functions, as well as references to any literature and technical specs in the near future.
```admonish info
We are working on a detailed description of how each component of Nym Mixnet and Nyx blockchain functions, as well as references to any literature and technical specs.
This section contains information on the different node types of the mixnet and blockchain.
Meanwhile please refer to our [**Operators Guide**](https://nymtech.net/operators) book.
```
+211 -1
View File
@@ -2,6 +2,216 @@
This page displays a full list of all the changes during our release cycle from [`v2024.3-eclipse`](https://github.com/nymtech/nym/blob/nym-binaries-v2024.3-eclipse/CHANGELOG.md) onwards. Operators can find here the newest updates together with links to relevant documentation. The list is sorted so that the newest changes appear first.
## `v2024.8-wispa`
- [Release binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2024.8-wispa)
- [Release CHANGELOG.md](https://github.com/nymtech/nym/blob/nym-binaries-v2024.8-wispa/CHANGELOG.md)
- [`nym-node`](nodes/nym-node.md) version `1.1.5`
~~~admonish example collapsible=true title='CHANGELOG.md'
- add event parsing to support cosmos_sdk > 0.50 ([#4697])
- Fix NR config compatibility ([#4690])
- Remove UserAgent constructor since it's weakly typed ([#4689])
- [bugfix]: Node_api_check CLI looked over roles on blacklisted nodes ([#4687])
- Add mixnodes to self describing api cache ([#4684])
- Move and whole bump of crates to workspace and upgrade some ([#4680])
- Remove code that refers to removed nym-network-statistics ([#4679])
- Remove nym-network-statistics ([#4678])
- Create UserAgent that can be passed from the binary to the nym api client ([#4677])
- Add authenticator ([#4667])
[#4697]: https://github.com/nymtech/nym/pull/4697
[#4690]: https://github.com/nymtech/nym/pull/4690
[#4689]: https://github.com/nymtech/nym/pull/4689
[#4687]: https://github.com/nymtech/nym/pull/4687
[#4684]: https://github.com/nymtech/nym/pull/4684
[#4680]: https://github.com/nymtech/nym/pull/4680
[#4679]: https://github.com/nymtech/nym/pull/4679
[#4678]: https://github.com/nymtech/nym/pull/4678
[#4677]: https://github.com/nymtech/nym/pull/4677
[#4667]: https://github.com/nymtech/nym/pull/4667
~~~
### Features
* [Default construct NodeRole](https://github.com/nymtech/nym/pull/4721): To preserve compatibility with newer clients interacting with older `nym-api`
~~~admonish example collapsible=true title='Testing steps performed'
1. Reviewed the changes in the `nym-api-requests/src/models.rs` file.
2. Verified that the `NymNodeDescription` struct includes the new `role` field with a default value set by `default_node_role`.
3. Checked the implementation of the `default_node_role` function to ensure it returns `NodeRole::Inactive`.
4. Ran the updated code in the sandbox environment.
5. Monitored the sandbox environment for any issues or errors related to the changes.
**Notes (if any):**
The test was successful. No issues were flagged during the testing in the sandbox environment. The new default value for `NodeRole` ensures backward compatibility without causing disruptions.
~~~
* [Default construct NodeRole for backwards compatibility (apply [\#4721](https://github.com/nymtech/nym/pull/4721) on develop)](https://github.com/nymtech/nym/pull/4722)
* [Add upgrades to `nym-node` for `authenticator` changes](https://github.com/nymtech/nym/pull/4703)
~~~admonish example collapsible=true title='Testing steps performed'
1. Reviewed the changes in the `gateway/src/error.rs` and `gateway/src/node/mod.rs` files.
2. Verified the new error enum `AuthenticatorStartupFailure` was added to `GatewayError`.
3. Confirmed the implementation of the `StartedAuthenticator` struct and its usage in the `start_authenticator` function.
4. Ran the updated code in the canary environment.
5. Monitored the canary environment for any issues or errors related to the changes.
~~~
* [Add event parsing to support `cosmos_sdk` > `0.50`](https://github.com/nymtech/nym/pull/4697)
~~~admonish example collapsible=true title='Testing steps performed'
1. Reviewed the changes in `common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs`, `logs.rs`, `types.rs`, and `nym-api/src/coconut/tests/mod.rs` files.
2. Verified the addition of event parsing in the relevant functions and structs.
3. Ensured that the `find_attribute` function correctly parses event attributes.
4. Ran the updated code in the sandbox environment.
5. Broadcasted transactions on the sandbox network to test the changes.
6. Monitored the sandbox network for any malformed responses or errors after the test chain upgrade.
~~~
* [Send bandwidth status messages when connecting](https://github.com/nymtech/nym/pull/4691): When connecting to the gateway we get received the available bandwidth left. Emit a status messages for this, for consumption by the application layer.
~~~admonish example collapsible=true title='Testing steps performed'
1. Reviewed the changes in `common/bandwidth-controller/src/event.rs`, `common/bandwidth-controller/src/lib.rs`, and `common/client-libs/gateway-client/src/client.rs` files.
2. Verified the implementation of `BandwidthStatusMessage` enum for emitting status messages.
3. Ensured `GatewayClient` is updated to send bandwidth status messages when connecting.
4. Deployed the updated code on the canary environment.
5. Connected to the gateway and checked for the emission of bandwidth status messages.
6. Verified that the messages were correctly parsed and consumed by the application layer.
7. Ran the VPN client to observe the parsed events.
~~~
* [Fix NR config compatibility](https://github.com/nymtech/nym/pull/4690): Recently we deleted the old statistics service provider. This fixes some issues where old configs didn't work with the latest changes.
- Make NR able to read config with old keys in
- Remove deleted config keys from NR template
~~~admonish example collapsible=true title='Testing steps performed'
1. Reviewed the changes in the `service-providers/network-requester/src/config/mod.rs` and `service-providers/network-requester/src/config/template.rs` files.
2. Ensured `NetworkRequester` config is able to read old keys for compatibility.
3. Removed old and deleted config keys from the `NetworkRequester` template.
4. Compiled the project to verify no issues or warnings appeared.
5. Ran all tests to ensure that the changes did not affect the functionality.
6. Validated that no leftover code from the old statistics service provider caused any issues.
~~~
* [Remove `UserAgent` constructor since it's weakly typed](https://github.com/nymtech/nym/pull/4689):
~~~admonish example collapsible=true title='Testing steps performed'
1. Reviewed the changes in `common/http-api-client/src/user_agent.rs` file.
2. Verified the removal of the `UserAgent` constructor and ensured that all instances of `UserAgent::new` are updated accordingly.
3. Checked the implementation of `UserAgent` struct using `BinaryBuildInformation` and `BinaryBuildInformationOwned`.
4. Deployed the updated code across different environments (QA, sandbox, and canary).
5. Ran tests to ensure that the `UserAgent` struct functions correctly without the constructor.
~~~
* [Add mixnodes to self describing api cache](https://github.com/nymtech/nym/pull/4684):
- Abstracts getting the self describing info a bit
- Adds mixnodes to the cache refresher as well
- Adds `role` field to the `NodeDescription` struct, to be able to distinguish between mixnodes and gateways
- Switched to using `NodeStatusCache` instead of `ContractCache`
~~~admonish example collapsible=true title='Testing steps performed'
Called the new `/mixnodes/described` endpoint as well as the existing `/gateways/described` endpoint and verified that the data returned for each was correct based on the settings that different nodes have when they are setup.
For gateway endpoint, the “role” for now does not differentiate between entry and exit gateways, this will be implemented in the future.
~~~
* [Move and whole bump of crates to workspace and upgrade some](https://github.com/nymtech/nym/pull/4680):
- Fix cargo warning for `default_features`
- Move dirs 4.0 to workspace
- Use workspace `base64` dep
- Move `rand_chacha` and `x25519-dalek` to workspace
- Use workspace `ed25519-dalek` dep
- Move `itertools` to workspace deps and upgrade
- Move a few partial deps to workspace while preserving versions
~~~admonish example collapsible=true title='Testing steps performed'
1. Reviewed the changes to move and upgrade crates to the workspace.
2. Verified the updated dependencies:
- Moved `dirs` to version 4.0 in the workspace.
- Updated the `base64` dependency to use the workspace version.
- Moved `rand_chacha` and `x25519-dalek` to the workspace.
- Updated `ed25519-dalek` to use the workspace version.
- Moved and upgraded `itertools` in the workspace.
- Moved other partial dependencies to the workspace while preserving their versions.
3. Ensured the `Cargo.toml` files across the project reflect these changes correctly.
4. Compiled the entire project to check for any issues or warnings.
5. Verified that all tests pass successfully after the changes.
~~~
* [Remove `nym-network-statistics`](https://github.com/nymtech/nym/pull/4678): Remove `nym-network-statistics` service provider that is no longer used.
~~~admonish example collapsible=true title='Testing steps performed'
1. Reviewed the project to identify all references to `nym-network-statistics`.
2. Removed all code and dependencies associated with `nym-network-statistics`.
3. Ensured that no references to `nym-network-statistics` remain in the codebase, including comments, imports, and configuration files.
4. Compiled the project to check for any issues or warnings.
5. Ran all tests to ensure the removal did not affect the functionality of the project.
~~~
* [Remove code that refers to removed `nym-network-statistics`](https://github.com/nymtech/nym/pull/4679): Follow up to [\#4678](https://github.com/nymtech/nym/pull/4678) where all code interacting with it is removed.
~~~admonish example collapsible=true title='Testing steps performed'
1. Reviewed the project to identify all references to `nym-network-statistics`.
2. Removed all code and dependencies associated with `nym-network-statistics`.
3. Ensured that no references to `nym-network-statistics` remain in the codebase, including comments, imports, and configuration files.
4. Compiled the project to check for any issues or warnings.
5. Ran all tests to ensure the removal did not affect the functionality of the project.
~~~
* [Create `UserAgent` that can be passed from the binary to the `nym-api` client](https://github.com/nymtech/nym/pull/4677):
- Support setting `UserAgent` for the validator client
- Support setting `UserAgent` in the SDK `MixnetClient`
- Set `UserAgent` when getting the list of gateways and topology in
- `nym-client`
- `nym-socks5-client`
- Standalone `ip-packet-router`
~~~admonish example collapsible=true title='Testing steps performed'
Used the nym-vpn-cli to test this, and we can visibly see the `UserAgent`, no issues with the comments mentioned above.
Example of the user agent sent:
`nym-client/1.1.36/x86_64-unknown-linux-gnu/e18bb70`
<img width="1435" alt="image" src="https://github.com/nymtech/nym/assets/60836166/5d4cc76f-84e6-45cb-9102-adc2b58a25d9">
Connected with no problems
~~~
* [Add `authenticator`](https://github.com/nymtech/nym/pull/4667)
### Bugfix
* [`Node_api_check.py` CLI looked over roles on blacklisted nodes](https://github.com/nymtech/nym/pull/4687): Removing/correcting this redundant function which results in unwanted error print, will resolve in the program not looking up the `roles` endpoint for blacklisted GWs, instead just ignores the role description and still return all other endpoints.
### Operators Guide updates
* [Create a guide to backup and restore `nym-node`](https://nymtech.net/operators/nodes/maintenance.html#backup-a-node), PR [\#4720](https://github.com/nymtech/nym/pull/4720)
* [Add manual IPv6 ifup/down network configuration](https://nymtech.net/operators/troubleshooting/vps-isp.html#network-configuration), PR [\#4651](https://github.com/nymtech/nym/pull/4651)
* [Extend ISP list](https://nymtech.net/operators/legal/isp-list.html)
* [Add SSL cert bot block to WSS setup](https://nymtech.net/operators/nodes/proxy-configuration.html#web-secure-socket-setup), [PR here](https://github.com/nymtech/nym/commits/develop/): WSS setup fully works!
* [Correct `HTTP API port` in bonding page](https://nymtech.net/operators/nodes/bonding.html#bond-via-the-desktop-wallet-recommended) , [PR \#4707](https://github.com/nymtech/nym/pull/4707): Change `HTTP API port` to `8080` on every `nym-node` by opening `config.toml` and making sure that your binding addresses and ports are as in the block below. Then go to desktop wallet and open the box called `Show advanced options` and make sure all your ports are set correctly (usually this means to change `HTTP api port` to `8080` for `mixnode` mode).
~~~admonish example collapsible=true title='snap of binding addresses and ports in `config.toml`'
```toml
[host]
public_ips = [
'<YOUR_PUBLIC_IPv4>'
]
[mixnet]
bind_address = '0.0.0.0:1789'
[http]
bind_address = '0.0.0.0:8080'
[mixnode]
[mixnode.verloc]
bind_address = '0.0.0.0:1790'
[entry_gateway]
bind_address = '0.0.0.0:9000'
```
~~~
* [Comment our deprecated node pages in `/docs`](https://github.com/nymtech/nym/pull/4727)
- Fixes [issue \#4632](https://github.com/nymtech/nym/issues/4632)
* [Remove redundant syntax from the setup guide](https://github.com/nymtech/nym/pull/4682)
---
## `v2024.7-doubledecker`
- [Release binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2024.7-doubledecker)
@@ -42,7 +252,7 @@ This page displays a full list of all the changes during our release cycle from
### Features
- [Remove the `nym-mixnode` and `nym-gateway` binaries from the CI upload builds action](https://github.com/nymtech/nym/pull/4693):
- [Remove the `nym-mixnode` and `nym-gateway` binaries from the CI upload builds action](https://github.com/nymtech/nym/pull/4693)
- [Add an early return in `parse_raw_str_logs` for empty raw log strings.](https://github.com/nymtech/nym/pull/4686): This accommodates for the v50 + chain upgrade.
- [Bump braces from `3.0.2` to `3.0.3` in `/wasm/mix-fetch/internal-dev`](https://github.com/nymtech/nym/pull/4672): Version update of [braces](https://github.com/micromatch/braces)
- [Bump braces from `3.0.2` to `3.0.3` in `/clients/native/examples/js-examples/websocket`](https://github.com/nymtech/nym/pull/4663): Version update of [braces](https://github.com/micromatch/braces).
@@ -122,6 +122,10 @@ RestartSec=30
WantedBy=multi-user.target
```
```admonish warning title=""
[Accepting T&Cs](setup.md#terms--conditions) is done via a flag `--accept-operator-terms-and-conditions` added explicitly to `nym-node run` command every time. If you use systemd automation, add the flag to your service file's `ExecStart` line.
```
3. Save the file
```admonish note
@@ -114,6 +114,8 @@ tmux attach-session
#### systemd
> Configuration of `systemd` service files for `nym-node` is under [Nym Node - Configuration](configuration.md#systemd) page.
##### For Nymvisor
> Since you're running your node via a Nymvisor instance, as well as creating a Nymvisor `.service` file, you will also want to **stop any previous node automation process you already have running**.
@@ -277,11 +279,13 @@ scp -r -3 <SOURCE_USER_NAME>@<SOURCE_HOST_ADDRESS>:~/.nym/nym-nodes <TARGET_USER
* Edit `~/.nym/nym-nodes/<ID>/config/config.toml` config with the new listening address IP - it's the one under the header `[host]`, called `public_ips = ['<YOUR_PUBLIC_IP>',]` and add your new location (field `location = <LOCATION>`, formats like: 'Jamaica', or two-letter alpha2 (e.g. 'JM'), three-letter alpha3 (e.g. 'JAM') or three-digit numeric-3 (e.g. '388') can be provided). You can see your IP by running a command `echo "$(curl -4 https://ifconfig.me)"`.
* Try to run the node and see if everything works.
* Setup the [systemd](#systemd) automation (don't forget to add the [terms and conditions flag](setup.md#terms--conditions)) to `ExecStart` command, reload the daemon and run the service. If you want to use the exact same service config file, you can also copy it from one VPS to another following the same logic:
* Setup the [systemd](#systemd) automation. If you want to use the exact same service config file, you can also copy it from one VPS to another following the same logic by opening your **local terminal** (as that one's ssh key is authorized in both of the VPS) and running:
```sh
scp -r -3 <SOURCE_USER_NAME>@<SOURCE_HOST_ADDRESS>:/etc/systemd/system/nym-node.service <TARGET_USER_NAME>@<TARGET_HOST_ADDRESS>:/etc/systemd/system/nym-node.service
```
Note: [Accepting T&Cs](setup.md#terms--conditions) is done via a flag `--accept-operator-terms-and-conditions` added explicitly to `nym-node run` command every time. If you use [systemd](configuration.md#systemd) automation, add the flag to your service file's `ExecStart` line.
**In your desktop wallet**
* Change the node smart contract info via the wallet interface. Open Nym Wallet, go to *Bonding*, open *Gateway Settings* or *Mixnode Settings* and change *Host* value to the new `nym-node` IP address. Otherwise the keys will point to the old IP address in the smart contract, and the node will not be able to be connected, and it will fail up-time checks, returning zero performance.
+1 -1
View File
@@ -114,7 +114,7 @@ From `nym-node` version `1.1.3` onward is required to accept [**Operators Terms
There has been a long ongoing discussion whether and how to apply Terms and Conditions for Nym network operators, with an aim to stay aligned with the philosophy of Free Software and provide legal defense for both node operators and Nym developers. To understand better the reasoning behind this decision, you can listen to the first [Nym Operator Town Hall](https://www.youtube.com/live/7hwb8bAZIuc?si=3mQ2ed7AyUA1SsCp&t=915) introducing the T&Cs or to [Operator AMA with CEO Harry Halpin](https://www.youtube.com/watch?v=yIN-zYQw0I0) from June 4th, 2024, explaining pros and cons of T&Cs implementation.
Accepting T&Cs is done via an explicit flag `--accept-operator-terms-and-conditions` added to `nym-node run` command.
Accepting T&Cs is done via a flag `--accept-operator-terms-and-conditions` added explicitly to `nym-node run` command every time. If you use [systemd](configuration.md#systemd) automation, add the flag to your service file's `ExecStart` line.
To check whether any node has T&Cs accepted or not can be done by querying Swagger API endpoint `/auxiliary_details` via one of these ports (depending on node setup):
```sh
@@ -23,8 +23,48 @@ Begin with the steps listed in [*Connectivity Test and Configuration*](../nodes/
4. Search or ask your ISP for additional documentation related to IPv6 routing and ask them to provide you with `IPv6 IP address` and `IPv6 IP gateway address`
- For example Digital Ocean setup isn't the most straight forward, but it's [well documented](https://docs.digitalocean.com/products/networking/ipv6/how-to/enable/#on-existing-droplets) and it works.
5. Search for guides regarding your particular system and distribution. For Debian based distributions using systemd, some generic guides such as [this one](https://cloudzy.com/blog/configure-ipv6-on-ubuntu/) work as well.
5. Search for guides regarding your particular system and distribution. For Debian based distributions using systemd, some generic guides such as [this one](https://cloudzy.com/blog/configure-ipv6-on-ubuntu/) or [this one](https://help.ovhcloud.com/csm/en-ie-vps-configuring-ipv6?id=kb_article_view&sysparm_article=KB0047567) work as well.
### Network configuration
On modern Debian based Linux distributions, the network is configured by either [Netplan](https://netplan.io/) or [ifup/ifdown](https://manpages.debian.org/testing/ifupdown/ifup.8.en.html) utilities . It is very easy to check which one you have.
1. If you have the following folder `/etc/netplan` which has got a YAML file - you are likely to have Netplan.
2. If you have the following folder `/etc/network` and it is not empty - you are likely to have ifup/down.
Most contemporary Ubuntu/Debian distributions come with Netplan, however it is possible that your hosting provider is using a custom version of ISO. For example, Debian 12 (latest version as of June 2024) may come with ifup/down.
Nym operator community members have tested a VPS with Netplan and where in some cases `nym-node --mode exit-gateway` was not routing IP packets properly even after running `network_tunnel_manager.sh` script. We are working on a guide to setup Netplan configuration manually for such cases.
Configuration of ifup/ifdown is a bit simpler. If the `network_tunnel_manager.sh` script doesn't do the job, open `/etc/network/interfaces` file (research if your system uses a different naming for it) and configure it similarly to this:
```sh
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address <YOUR_IPV4_ADDRESS>
netmask NETMASK
gateway <YOUR_IPV4_GATEWAY>
iface eth0 inet6 static
accept_ra 0
address <YOUR_IPV6_ADDRESS>
netmask 64
gateway <YOUR_IPV6_GATEWAY>
post-up /sbin/ip -r route add <YOUR_IPV6_GATEWAY> dev eth0
post-up /sbin/ip -r route add default via <YOUR_IPV6_GATEWAY>
```
Last two lines are particularly important as they enable IPv6 routing. You can find YOUR_IPV6_GATEWAY using your server's control panel. There is no single way to find the gateway, so please access your control panel to find yours or open a support ticket. Here is an example of how it looks on [OVH](https://help.ovhcloud.com/csm/en-ie-vps-configuring-ipv6?id=kb_article_view&sysparm_article=KB0047567).
```admonish warning title="WARNING"
Be extra careful editing this file since you may lock yourself out of the server. If it happens, you can always access the server via the hoster's VNC panel.
```
Once finished, save the file and reboot the server. Now, running `ip a` command should return correct IPv4 and IPv6 addresses.
Finally re-run `network_tunnel_manager.sh` script, following the steps in node [IPv6 configuration chapter](https://github.com/nymtech/nym/nodes/configuration.md#ipv6-configuration).
## Other VPS troubleshooting
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "explorer-api"
version = "1.1.37"
version = "1.1.38"
edition = "2021"
license.workspace = true
+1 -1
View File
@@ -4,7 +4,7 @@
[package]
name = "nym-api"
license = "GPL-3.0"
version = "1.1.41"
version = "1.1.42"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
+1
View File
@@ -20,6 +20,7 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
/// - BTE public key (alongside the proof of discrete log)
/// - ed25519 public key
/// - announce address to be used by clients for obtaining credentials
///
/// Upon successful registration, the node will receive a unique "NodeIndex"
/// which is the x-coordinate of the to be derived keys.
///
+1 -8
View File
@@ -4,7 +4,6 @@
use crate::coconut::storage::models::{EpochCredentials, IssuedCredential};
use crate::support::storage::manager::StorageManager;
use nym_coconut_dkg_common::types::EpochId;
use thiserror::Error;
#[async_trait]
pub trait CoconutStorageManagerExt {
@@ -23,6 +22,7 @@ pub trait CoconutStorageManagerExt {
/// # Arguments
///
/// * `epoch_id`: Id of the (coconut) epoch in question.
#[allow(dead_code)]
async fn create_epoch_credentials_entry(&self, epoch_id: EpochId) -> Result<(), sqlx::Error>;
/// Update the EpochCredentials by incrementing the total number of issued credentials,
@@ -361,10 +361,3 @@ impl CoconutStorageManagerExt for StorageManager {
Ok(())
}
}
#[derive(Debug, Error)]
#[error("tried to store an invalid nonce. the received value is {got} while current is {current}. expected {current} + 1")]
pub struct UnexpectedNonce {
current: u32,
got: u32,
}
+3 -3
View File
@@ -33,12 +33,12 @@ pub fn pseudorandom_account(rng: &mut ChaCha20Rng) -> AccountId {
AccountId::new("n", &dummy_account_key_hash).unwrap()
}
pub fn dealer_fixture(mut rng: &mut ChaCha20Rng, id: NodeIndex) -> DealerDetails {
pub fn dealer_fixture(rng: &mut ChaCha20Rng, id: NodeIndex) -> DealerDetails {
// we might possibly need that private key later on
let keypair = DkgKeyPair::new(dkg::params(), &mut rng);
let keypair = DkgKeyPair::new(dkg::params(), rng.clone());
let addr = pseudorandom_account(rng);
let identity_keypair = identity::KeyPair::new(&mut rng);
let identity_keypair = identity::KeyPair::new(rng);
let bte_public_key_with_proof = bs58::encode(&keypair.public_key().to_bytes()).into_string();
let port = 8080 + id;
+7 -7
View File
@@ -63,15 +63,15 @@ impl RewardedSetUpdater {
/// 2. it queries the mixnet contract to check the current `EpochState` in order to figure out whether
/// a different nym-api has already started epoch transition (not yet applicable)
/// 3. it sends a `BeginEpochTransition` message to the mixnet contract causing the following to happen:
/// - if successful, the address of the this validator is going to be saved as being responsible for progressing this epoch.
/// What it means in practice is that once we have multiple instances of nym-api running,
/// only this one will try to perform the rest of the actions. It will also allow it to
/// more easily recover in case of crashes.
/// - if successful, the address of this validator is going to be saved as being responsible for progressing this epoch.
/// What it means in practice is that once we have multiple instances of nym-api running,
/// only this one will try to perform the rest of the actions. It will also allow it to
/// more easily recover in case of crashes.
/// - the `EpochState` changes to `Rewarding`, meaning the nym-api will now be allowed to send
/// `RewardMixnode` transactions. However, it's not going to be able anything else like `ReconcileEpochEvents`
/// until that is done.
/// `RewardMixnode` transactions. However, it's not going to be able anything else like `ReconcileEpochEvents`
/// until that is done.
/// - ability to send transactions (by other users) that get resolved once given epoch/interval rolls over,
/// such as `BondMixnode` or `DelegateToMixnode` will temporarily be frozen until the entire procedure is finished.
/// such as `BondMixnode` or `DelegateToMixnode` will temporarily be frozen until the entire procedure is finished.
/// 4. it obtains the current rewarded set and for each node in there (**SORTED BY MIX_ID!!**),
/// it sends (in a single batch) `RewardMixnode` message with the measured performance.
/// Once the final message gets executed, the mixnet contract automatically transitions
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-node"
version = "1.1.5"
version = "1.1.6"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
@@ -15,7 +15,9 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct WireguardPathsV1 {
#[serde(skip)]
pub private_diffie_hellman_key_file: PathBuf,
#[serde(skip)]
pub public_diffie_hellman_key_file: PathBuf,
}
+1
View File
@@ -272,6 +272,7 @@ impl WalletStateInner {
/// 1. from the configuration file
/// 2. provided remotely
/// 3. hardcoded fallback
///
/// The format is the config backend format, which is flat due to serialization preference.
pub fn get_config_validator_entries(
&self,
@@ -7,8 +7,8 @@
///
/// Wallet
/// - Login
/// -- Account
/// --- Mnemonic
/// -- Account
/// --- Mnemonic
pub(crate) use crate::wallet_storage::account_data::StoredLogin;
pub(crate) use crate::wallet_storage::password::{AccountId, LoginId, UserPassword};
+1
View File
@@ -67,6 +67,7 @@ pub use nym_credential_storage::{
ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage,
models::StoredIssuedCredential, storage::Storage as CredentialStorage,
};
pub use nym_crypto::asymmetric::ed25519;
pub use nym_network_defaults::NymNetworkDetails;
pub use nym_socks5_client_core::config::Socks5;
pub use nym_sphinx::{
+2 -4
View File
@@ -610,8 +610,7 @@ where
///
/// - If the client is already registered with a gateway, use that gateway.
/// - If no gateway is registered, but there is an existing configuration and key, use that.
/// - If no gateway is registered, and there is no pre-existing configuration or key, try to
/// register a new gateway.
/// - If no gateway is registered, and there is no pre-existing configuration or key, try to register a new gateway.
///
/// # Example
///
@@ -691,8 +690,7 @@ where
///
/// - If the client is already registered with a gateway, use that gateway.
/// - If no gateway is registered, but there is an existing configuration and key, use that.
/// - If no gateway is registered, and there is no pre-existing configuration or key, try to
/// register a new gateway.
/// - If no gateway is registered, and there is no pre-existing configuration or key, try to register a new gateway.
///
/// # Example
///
@@ -2,12 +2,13 @@
// SPDX-License-Identifier: GPL-3.0-only
use bytes::Bytes;
use nym_ip_packet_requests::{codec::MultiIpPacketCodec, v6::response::IpPacketResponse};
use nym_ip_packet_requests::codec::MultiIpPacketCodec;
use nym_sdk::mixnet::{MixnetMessageSender, Recipient};
use crate::{
constants::CLIENT_HANDLER_ACTIVITY_TIMEOUT,
error::{IpPacketRouterError, Result},
mixnet_listener::SupportedClientVersion,
util::create_message::create_input_message,
};
@@ -18,13 +19,29 @@ use crate::{
// This handler is spawned as a task, and it listens to IP packets passed from the tun_listener,
// encodes it, and then sends to mixnet.
pub(crate) struct ConnectedClientHandler {
// The address of the client that this handler is connected to
nym_address: Recipient,
// The number of hops the packet should take before reaching the client
mix_hops: Option<u8>,
// Channel to receive packets from the tun_listener
forward_from_tun_rx: tokio::sync::mpsc::UnboundedReceiver<Vec<u8>>,
// Channel to send packets to the mixnet
mixnet_client_sender: nym_sdk::mixnet::MixnetClientSender,
// Channel to receive close signal
close_rx: tokio::sync::oneshot::Receiver<()>,
// Interval to check for activity timeout
activity_timeout: tokio::time::Interval,
// Encoder to bundle multiple packets into a single one
encoder: MultiIpPacketCodec,
// The version of the client
client_version: SupportedClientVersion,
}
impl ConnectedClientHandler {
@@ -32,6 +49,7 @@ impl ConnectedClientHandler {
reply_to: Recipient,
reply_to_hops: Option<u8>,
buffer_timeout: std::time::Duration,
client_version: SupportedClientVersion,
mixnet_client_sender: nym_sdk::mixnet::MixnetClientSender,
) -> (
tokio::sync::mpsc::UnboundedSender<Vec<u8>>,
@@ -55,6 +73,7 @@ impl ConnectedClientHandler {
close_rx,
activity_timeout,
encoder,
client_version,
};
let handle = tokio::spawn(async move {
@@ -67,9 +86,18 @@ impl ConnectedClientHandler {
}
async fn send_packets_to_mixnet(&mut self, packets: Bytes) -> Result<()> {
let response_packet = IpPacketResponse::new_ip_packet(packets)
.to_bytes()
.map_err(|err| IpPacketRouterError::FailedToSerializeResponsePacket { source: err })?;
let response_packet = match self.client_version {
SupportedClientVersion::V6 => {
nym_ip_packet_requests::v6::response::IpPacketResponse::new_ip_packet(packets)
.to_bytes()
}
SupportedClientVersion::V7 => {
nym_ip_packet_requests::v7::response::IpPacketResponse::new_ip_packet(packets)
.to_bytes()
}
}
.map_err(|err| IpPacketRouterError::FailedToSerializeResponsePacket { source: err })?;
let input_message = create_input_message(self.nym_address, response_packet, self.mix_hops);
self.mixnet_client_sender
@@ -96,6 +96,9 @@ pub enum IpPacketRouterError {
FailedToVerifyRequest {
source: nym_ip_packet_requests::v7::signature::SignatureError,
},
#[error("client is connected with an invalid version: {version}")]
InvalidConnectedClientVersion { version: u8 },
}
pub type Result<T> = std::result::Result<T, IpPacketRouterError>;
@@ -4,22 +4,19 @@ use std::{collections::HashMap, net::SocketAddr};
use bytes::{Bytes, BytesMut};
use futures::StreamExt;
use nym_ip_packet_requests::v7::response::{
DynamicConnectFailureReason, InfoLevel, InfoResponseReply, StaticConnectFailureReason,
};
use nym_ip_packet_requests::{
codec::MultiIpPacketCodec,
v6::{
self,
response::{
DynamicConnectFailureReason, InfoLevel, InfoResponseReply, IpPacketResponse,
StaticConnectFailureReason,
},
},
v6,
v7::{
self,
request::{
DataRequest, DisconnectRequest, DynamicConnectRequest, IpPacketRequest,
IpPacketRequestData, StaticConnectRequest,
},
signature::{SignatureError, SignedRequest},
signature::SignedRequest,
},
IpPair,
};
@@ -266,7 +263,132 @@ impl Drop for CloseTx {
}
}
type PacketHandleResult = Result<Option<v6::response::IpPacketResponse>>;
type PacketHandleResult = Result<Option<Response>>;
#[derive(Debug, Clone)]
enum Response {
V6(v6::response::IpPacketResponse),
V7(v7::response::IpPacketResponse),
}
impl Response {
fn recipient(&self) -> Option<&Recipient> {
match self {
Response::V6(response) => response.recipient(),
Response::V7(response) => response.recipient(),
}
}
fn new_static_connect_success(
request_id: u64,
reply_to: Recipient,
client_version: SupportedClientVersion,
) -> Self {
match client_version {
SupportedClientVersion::V6 => Response::V6(
v6::response::IpPacketResponse::new_static_connect_success(request_id, reply_to),
),
SupportedClientVersion::V7 => Response::V7(
v7::response::IpPacketResponse::new_static_connect_success(request_id, reply_to),
),
}
}
fn new_static_connect_failure(
request_id: u64,
reply_to: Recipient,
reason: StaticConnectFailureReason,
client_version: SupportedClientVersion,
) -> Self {
match client_version {
SupportedClientVersion::V6 => {
Response::V6(v6::response::IpPacketResponse::new_static_connect_failure(
request_id,
reply_to,
reason.into(),
))
}
SupportedClientVersion::V7 => {
Response::V7(v7::response::IpPacketResponse::new_static_connect_failure(
request_id, reply_to, reason,
))
}
}
}
fn new_dynamic_connect_success(
request_id: u64,
reply_to: Recipient,
ips: IpPair,
client_version: SupportedClientVersion,
) -> Self {
match client_version {
SupportedClientVersion::V6 => {
Response::V6(v6::response::IpPacketResponse::new_dynamic_connect_success(
request_id, reply_to, ips,
))
}
SupportedClientVersion::V7 => {
Response::V7(v7::response::IpPacketResponse::new_dynamic_connect_success(
request_id, reply_to, ips,
))
}
}
}
fn new_dynamic_connect_failure(
request_id: u64,
reply_to: Recipient,
reason: DynamicConnectFailureReason,
client_version: SupportedClientVersion,
) -> Self {
match client_version {
SupportedClientVersion::V6 => {
Response::V6(v6::response::IpPacketResponse::new_dynamic_connect_failure(
request_id,
reply_to,
reason.into(),
))
}
SupportedClientVersion::V7 => {
Response::V7(v7::response::IpPacketResponse::new_dynamic_connect_failure(
request_id, reply_to, reason,
))
}
}
}
fn new_data_info_response(
reply_to: Recipient,
reply: InfoResponseReply,
level: InfoLevel,
client_version: SupportedClientVersion,
) -> Self {
match client_version {
SupportedClientVersion::V6 => {
Response::V6(v6::response::IpPacketResponse::new_data_info_response(
reply_to,
reply.into(),
level.into(),
))
}
SupportedClientVersion::V7 => Response::V7(
v7::response::IpPacketResponse::new_data_info_response(reply_to, reply, level),
),
}
}
fn to_bytes(&self) -> Result<Vec<u8>> {
match self {
Response::V6(response) => response.to_bytes(),
Response::V7(response) => response.to_bytes(),
}
.map_err(|err| {
log::error!("Failed to serialize response packet");
IpPacketRouterError::FailedToSerializeResponsePacket { source: err }
})
}
}
#[cfg(target_os = "linux")]
pub(crate) struct MixnetListener {
@@ -297,6 +419,7 @@ impl MixnetListener {
async fn on_static_connect_request(
&mut self,
connect_request: StaticConnectRequest,
client_version: SupportedClientVersion,
) -> PacketHandleResult {
log::info!(
"Received static connect request from {sender_address}",
@@ -328,8 +451,10 @@ impl MixnetListener {
{
log::error!("Failed to update activity for client");
};
Ok(Some(IpPacketResponse::new_static_connect_success(
request_id, reply_to,
Ok(Some(Response::new_static_connect_success(
request_id,
reply_to,
client_version,
)))
}
(false, false) => {
@@ -341,6 +466,7 @@ impl MixnetListener {
reply_to,
reply_to_hops,
buffer_timeout,
client_version,
self.mixnet_client.split_sender(),
);
@@ -353,24 +479,28 @@ impl MixnetListener {
close_tx,
handle,
);
Ok(Some(IpPacketResponse::new_static_connect_success(
request_id, reply_to,
Ok(Some(Response::new_static_connect_success(
request_id,
reply_to,
client_version,
)))
}
(true, false) => {
log::info!("Requested IP is not available");
Ok(Some(IpPacketResponse::new_static_connect_failure(
Ok(Some(Response::new_static_connect_failure(
request_id,
reply_to,
StaticConnectFailureReason::RequestedIpAlreadyInUse,
client_version,
)))
}
(false, true) => {
log::info!("Nym address is already registered");
Ok(Some(IpPacketResponse::new_static_connect_failure(
Ok(Some(Response::new_static_connect_failure(
request_id,
reply_to,
StaticConnectFailureReason::RequestedNymAddressAlreadyInUse,
client_version,
)))
}
}
@@ -379,6 +509,7 @@ impl MixnetListener {
async fn on_dynamic_connect_request(
&mut self,
connect_request: DynamicConnectRequest,
client_version: SupportedClientVersion,
) -> PacketHandleResult {
log::info!(
"Received dynamic connect request from {sender_address}",
@@ -406,19 +537,21 @@ impl MixnetListener {
{
log::error!("Failed to update activity for client");
}
return Ok(Some(IpPacketResponse::new_dynamic_connect_success(
return Ok(Some(Response::new_dynamic_connect_success(
request_id,
reply_to,
existing_ips,
client_version,
)));
}
let Some(new_ips) = self.connected_clients.find_new_ip() else {
log::info!("No available IP address");
return Ok(Some(IpPacketResponse::new_dynamic_connect_failure(
return Ok(Some(Response::new_dynamic_connect_failure(
request_id,
reply_to,
DynamicConnectFailureReason::NoAvailableIp,
client_version,
)));
};
@@ -428,6 +561,7 @@ impl MixnetListener {
reply_to,
reply_to_hops,
buffer_timeout,
client_version,
self.mixnet_client.split_sender(),
);
@@ -440,17 +574,28 @@ impl MixnetListener {
close_tx,
handle,
);
Ok(Some(IpPacketResponse::new_dynamic_connect_success(
request_id, reply_to, new_ips,
Ok(Some(Response::new_dynamic_connect_success(
request_id,
reply_to,
new_ips,
client_version,
)))
}
fn on_disconnect_request(&self, _disconnect_request: DisconnectRequest) -> PacketHandleResult {
fn on_disconnect_request(
&self,
_disconnect_request: DisconnectRequest,
_client_version: SupportedClientVersion,
) -> PacketHandleResult {
log::info!("Received disconnect request: not implemented, dropping");
Ok(None)
}
async fn handle_packet(&mut self, ip_packet: &Bytes) -> PacketHandleResult {
async fn handle_packet(
&mut self,
ip_packet: &Bytes,
client_version: SupportedClientVersion,
) -> PacketHandleResult {
log::trace!("Received data request");
// We don't forward packets that we are not able to parse. BUT, there might be a good
@@ -487,12 +632,13 @@ impl MixnetListener {
Ok(None)
} else {
log::info!("Denied filter check: {dst}");
Ok(Some(IpPacketResponse::new_data_info_response(
Ok(Some(Response::new_data_info_response(
connected_client.nym_address,
InfoResponseReply::ExitPolicyFilterCheckFailed {
dst: dst.to_string(),
},
InfoLevel::Warn,
client_version,
)))
}
} else {
@@ -505,13 +651,14 @@ impl MixnetListener {
async fn on_data_request(
&mut self,
data_request: DataRequest,
client_version: SupportedClientVersion,
) -> Result<Vec<PacketHandleResult>> {
let mut responses = Vec::new();
let mut decoder = MultiIpPacketCodec::new(nym_ip_packet_requests::codec::BUFFER_TIMEOUT);
let mut bytes = BytesMut::new();
bytes.extend_from_slice(&data_request.ip_packets);
while let Ok(Some(packet)) = decoder.decode(&mut bytes) {
let result = self.handle_packet(&packet).await;
let result = self.handle_packet(&packet, client_version).await;
responses.push(result);
}
Ok(responses)
@@ -519,26 +666,13 @@ impl MixnetListener {
fn on_version_mismatch(
&self,
version: u8,
reconstructed: &ReconstructedMessage,
_version: u8,
_reconstructed: &ReconstructedMessage,
) -> PacketHandleResult {
// If it's possible to parse, do so and return back a response, otherwise just drop
let (id, recipient) =
v6::request::IpPacketRequest::from_reconstructed_message(reconstructed)
.ok()
.and_then(|request| {
request
.recipient()
.map(|recipient| (request.id().unwrap_or(0), *recipient))
})
.ok_or(IpPacketRouterError::InvalidPacketVersion(version))?;
Ok(Some(IpPacketResponse::new_version_mismatch(
id,
recipient,
version,
nym_ip_packet_requests::CURRENT_VERSION,
)))
// Just drop it. In the future we might want to return a response here, if for example
// the client is connecting with a version that is older than the currently supported
// ones.
Ok(None)
}
async fn on_reconstructed_message(
@@ -550,7 +684,7 @@ impl MixnetListener {
reconstructed.sender_tag
);
let request = match deserialize_request(&reconstructed) {
let (request, client_version) = match deserialize_request(&reconstructed) {
Err(IpPacketRouterError::InvalidPacketVersion(version)) => {
return Ok(vec![self.on_version_mismatch(version, &reconstructed)]);
}
@@ -559,21 +693,31 @@ impl MixnetListener {
match request.data {
IpPacketRequestData::StaticConnect(signed_connect_request) => {
verify_signed_request(&signed_connect_request)?;
verify_signed_request(&signed_connect_request, client_version)?;
let connect_request = signed_connect_request.request;
Ok(vec![self.on_static_connect_request(connect_request).await])
Ok(vec![
self.on_static_connect_request(connect_request, client_version)
.await,
])
}
IpPacketRequestData::DynamicConnect(signed_connect_request) => {
verify_signed_request(&signed_connect_request)?;
verify_signed_request(&signed_connect_request, client_version)?;
let connect_request = signed_connect_request.request;
Ok(vec![self.on_dynamic_connect_request(connect_request).await])
Ok(vec![
self.on_dynamic_connect_request(connect_request, client_version)
.await,
])
}
IpPacketRequestData::Disconnect(signed_disconnect_request) => {
verify_signed_request(&signed_disconnect_request)?;
verify_signed_request(&signed_disconnect_request, client_version)?;
let disconnect_request = signed_disconnect_request.request;
Ok(vec![self.on_disconnect_request(disconnect_request)])
Ok(vec![
self.on_disconnect_request(disconnect_request, client_version)
])
}
IpPacketRequestData::Data(data_request) => {
self.on_data_request(data_request, client_version).await
}
IpPacketRequestData::Data(data_request) => self.on_data_request(data_request).await,
IpPacketRequestData::Ping(_) => {
log::info!("Received ping request: not implemented, dropping");
Ok(vec![])
@@ -605,16 +749,13 @@ impl MixnetListener {
// When an incoming mixnet message triggers a response that we send back, such as during
// connect handshake.
async fn handle_response(&self, response: IpPacketResponse) -> Result<()> {
async fn handle_response(&self, response: Response) -> Result<()> {
let Some(recipient) = response.recipient() else {
log::error!("No recipient in response packet, this should NOT happen!");
return Err(IpPacketRouterError::NoRecipientInResponse);
};
let response_packet = response.to_bytes().map_err(|err| {
log::error!("Failed to serialize response packet");
IpPacketRouterError::FailedToSerializeResponsePacket { source: err }
})?;
let response_packet = response.to_bytes()?;
// We could avoid this lookup if we check this when we create the response.
let mix_hops = if let Some(c) = self
@@ -687,33 +828,65 @@ impl MixnetListener {
}
}
fn deserialize_request(reconstructed: &ReconstructedMessage) -> Result<IpPacketRequest> {
fn deserialize_request(
reconstructed: &ReconstructedMessage,
) -> Result<(IpPacketRequest, SupportedClientVersion)> {
let request_version = *reconstructed
.message
.first()
.ok_or(IpPacketRouterError::EmptyPacket)?;
// Check version of the request and convert to the latest version if necessary
match request_version {
6 => v6::request::IpPacketRequest::from_reconstructed_message(reconstructed)
.map_err(|err| IpPacketRouterError::FailedToDeserializeTaggedPacket { source: err })
.map(|r| r.into()),
7 => v7::request::IpPacketRequest::from_reconstructed_message(reconstructed)
.map_err(|err| IpPacketRouterError::FailedToDeserializeTaggedPacket { source: err }),
let request = match request_version {
6 => nym_ip_packet_requests::v6::request::IpPacketRequest::from_reconstructed_message(
reconstructed,
)
.map_err(|err| IpPacketRouterError::FailedToDeserializeTaggedPacket { source: err })
.map(|r| r.into()),
7 => nym_ip_packet_requests::v7::request::IpPacketRequest::from_reconstructed_message(
reconstructed,
)
.map_err(|err| IpPacketRouterError::FailedToDeserializeTaggedPacket { source: err }),
_ => {
log::info!("Received packet with invalid version: v{request_version}");
Err(IpPacketRouterError::InvalidPacketVersion(request_version))
}
};
let Some(request_version) = SupportedClientVersion::new(request_version) else {
return Err(IpPacketRouterError::InvalidPacketVersion(request_version));
};
// Tag the request with the version of the request
request.map(|r| (r, request_version))
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub(crate) enum SupportedClientVersion {
V6,
V7,
}
impl SupportedClientVersion {
fn new(request_version: u8) -> Option<Self> {
match request_version {
6 => Some(SupportedClientVersion::V6),
7 => Some(SupportedClientVersion::V7),
_ => None,
}
}
}
fn verify_signed_request(request: &impl SignedRequest) -> Result<()> {
fn verify_signed_request(
request: &impl SignedRequest,
client_version: SupportedClientVersion,
) -> Result<()> {
if let Err(err) = request.verify() {
// Once we start to require clients to send v7 requests, we will enfore checking
// signatures. Until then, we only check if they are present.
if !matches!(err, SignatureError::MissingSignature) {
return Err(IpPacketRouterError::FailedToVerifyRequest { source: err });
// If the client is V6, we don't care about missing signature
if client_version == SupportedClientVersion::V6 {
return Ok(());
}
return Err(IpPacketRouterError::FailedToVerifyRequest { source: err });
}
Ok(())
}
@@ -4,7 +4,7 @@
[package]
name = "nym-network-requester"
license = "GPL-3.0"
version = "1.1.39"
version = "1.1.40"
authors.workspace = true
edition.workspace = true
rust-version = "1.70"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-cli"
version = "1.1.39"
version = "1.1.40"
authors.workspace = true
edition = "2021"
license.workspace = true
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nymvisor"
version = "0.1.4"
version = "0.1.5"
authors.workspace = true
repository.workspace = true
homepage.workspace = true