Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c5f264cbf | |||
| 73b74ad4d2 | |||
| 4b4f211cba | |||
| 7a26e2ef57 | |||
| 9782945c92 | |||
| 573a91e015 | |||
| eb06285653 | |||
| 728542181e | |||
| 8f52c2a229 | |||
| 3916bbf632 | |||
| f8ce87a205 | |||
| c9b5ac2abf | |||
| bd5577c0a4 | |||
| 3e9178a664 | |||
| ac822164af | |||
| edc404d6d7 | |||
| e0e5317b44 | |||
| 6711a3bb3c | |||
| 20130fb2a2 | |||
| 59560ac125 | |||
| 893648cad0 | |||
| 27502b9c75 | |||
| 2ab4a445b7 | |||
| 7f5e2f2909 | |||
| d5bc26d2e3 | |||
| aaa965937b | |||
| b3f883e82b |
@@ -107,8 +107,6 @@ jobs:
|
|||||||
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR
|
cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/nym_service_provider_directory.wasm $OUTPUT_DIR
|
|
||||||
cp contracts/target/wasm32-unknown-unknown/release/nym_name_service.wasm $OUTPUT_DIR
|
|
||||||
|
|
||||||
- name: Deploy branch to CI www
|
- name: Deploy branch to CI www
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ jobs:
|
|||||||
"build-tools;$SDK_BUILDTOOLS_VERSION"
|
"build-tools;$SDK_BUILDTOOLS_VERSION"
|
||||||
|
|
||||||
- name: Install Rust toolchain
|
- name: Install Rust toolchain
|
||||||
uses: dtolnay/rust-toolchain@1.70.0
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
- name: Install rust android targets
|
- name: Install rust android targets
|
||||||
run: |
|
run: |
|
||||||
@@ -60,7 +60,6 @@ jobs:
|
|||||||
working-directory: sdk/lib/socks5-listener/
|
working-directory: sdk/lib/socks5-listener/
|
||||||
env:
|
env:
|
||||||
RELEASE: true
|
RELEASE: true
|
||||||
RUSTFLAGS: "-C link-args=-Wl,--hash-style=gnu"
|
|
||||||
# build for arm64 and x86_64
|
# build for arm64 and x86_64
|
||||||
run: ./build-android.sh aarch64 x86_64
|
run: ./build-android.sh aarch64 x86_64
|
||||||
|
|
||||||
@@ -68,27 +67,20 @@ jobs:
|
|||||||
working-directory: nym-connect/native/android
|
working-directory: nym-connect/native/android
|
||||||
env:
|
env:
|
||||||
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
|
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
|
||||||
SENTRY_AUTH_TOKEN: ${{ secrets.NYMS5_ANDROID_SENTRY_AUTH_TOKEN }}
|
|
||||||
# build for arm64 and x86_64
|
# build for arm64 and x86_64
|
||||||
run: |
|
run: ./gradlew :app:assembleArch64Release
|
||||||
echo "auth.token=$SENTRY_AUTH_TOKEN" | tee -a sentry.properties
|
|
||||||
./gradlew :app:assembleArch64Debug
|
|
||||||
./gradlew :app:assembleArch64Release
|
|
||||||
|
|
||||||
- name: Prepare APKs
|
- name: Prepare APKs
|
||||||
run: |
|
run: |
|
||||||
mkdir apk
|
mkdir apk
|
||||||
mv nym-connect/native/android/app/build/outputs/apk/arch64/debug/app-arch64-debug.apk \
|
|
||||||
apk/nyms5-arch64-debug.apk
|
|
||||||
mv nym-connect/native/android/app/build/outputs/apk/arch64/release/app-arch64-release-unsigned.apk \
|
mv nym-connect/native/android/app/build/outputs/apk/arch64/release/app-arch64-release-unsigned.apk \
|
||||||
apk/nyms5-arch64-release.apk
|
apk/nyms5-arch64-release.apk
|
||||||
|
|
||||||
- name: Upload APKs
|
- name: Upload APKs
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: nyms5-apk-arch64
|
name: nyms5-apk-arch64-release
|
||||||
path: |
|
path: |
|
||||||
apk/nyms5-arch64-debug.apk
|
|
||||||
apk/nyms5-arch64-release.apk
|
apk/nyms5-arch64-release.apk
|
||||||
|
|
||||||
gh-release:
|
gh-release:
|
||||||
@@ -101,11 +93,10 @@ jobs:
|
|||||||
- name: Download binary artifact
|
- name: Download binary artifact
|
||||||
uses: actions/download-artifact@v3
|
uses: actions/download-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: nyms5-apk-arch64
|
name: nyms5-apk-arch64-release
|
||||||
path: apk
|
path: apk
|
||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
files: |
|
files: apk/nyms5-arch64-release.apk
|
||||||
apk/nyms5-arch64-debug.apk
|
|
||||||
apk/nyms5-arch64-release.apk
|
|
||||||
|
|||||||
+1
-2
@@ -43,5 +43,4 @@ envs/qwerty.env
|
|||||||
.parcel-cache
|
.parcel-cache
|
||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
cpu-cycles/libcpucycles/build
|
cpu-cycles/libcpucycles/build
|
||||||
foxyfox.env
|
foxyfox.env
|
||||||
gateway/deploy.sh
|
|
||||||
@@ -4,69 +4,6 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
## [v1.1.22] (2023-06-20)
|
|
||||||
|
|
||||||
- CLI tool for querying network-requesters ([#3539])
|
|
||||||
- Statically link OpenSSL ([#3510])
|
|
||||||
- NymConnect - add sentry.io reporting ([#3421])
|
|
||||||
- init command does not change version number in config.toml ([#3336])
|
|
||||||
- [Bug] Config version does not correspond to binary version ([#3434])
|
|
||||||
|
|
||||||
[#3539]: https://github.com/nymtech/nym/issues/3539
|
|
||||||
[#3510]: https://github.com/nymtech/nym/issues/3510
|
|
||||||
[#3421]: https://github.com/nymtech/nym/issues/3421
|
|
||||||
[#3336]: https://github.com/nymtech/nym/issues/3336
|
|
||||||
[#3434]: https://github.com/nymtech/nym/issues/3434
|
|
||||||
|
|
||||||
## [v1.1.21] (2023-06-13)
|
|
||||||
|
|
||||||
- mixFetch: Change socks5 `SendRequest` to include OrderedMessage index as a field rather than making it serialized inside the `data` field
|
|
||||||
([#3534])
|
|
||||||
- Explorer - add more data columns to the Service Provider section: ([#3474])
|
|
||||||
- network-requester: support report if they run an open proxy using `ControlRequest` API ([#3461])
|
|
||||||
- Refactor client configs (London discussion) ([#3444])
|
|
||||||
- Increase `DEFAULT_MAXIMUM_CONNECTION_BUFFER_SIZE` to 2000 to improve reliability ([#3433])
|
|
||||||
- socks5: sender waits for lanes to clear even though the connection is closed ([#3366])
|
|
||||||
- version bump for variables ([#3545])
|
|
||||||
|
|
||||||
[#3534]: https://github.com/nymtech/nym/issues/3534
|
|
||||||
[#3474]: https://github.com/nymtech/nym/issues/3474
|
|
||||||
[#3461]: https://github.com/nymtech/nym/issues/3461
|
|
||||||
[#3444]: https://github.com/nymtech/nym/issues/3444
|
|
||||||
[#3433]: https://github.com/nymtech/nym/issues/3433
|
|
||||||
[#3366]: https://github.com/nymtech/nym/issues/3366
|
|
||||||
[#3545]: https://github.com/nymtech/nym/pull/3545
|
|
||||||
|
|
||||||
## [v1.1.20] (2023-06-06)
|
|
||||||
|
|
||||||
- Explorer - Fix SP supported apps list ([#3458])
|
|
||||||
- Investigate if we need to lower `SHUTDOWN_TIMEOUT` in socks5 to zero (or almost zero) ([#3438])
|
|
||||||
- Explorer - show all gateways in the default view regardless of the version number ([#3427])
|
|
||||||
- service-provider-directory: add signature check when announcing ([#3360])
|
|
||||||
- Support functionality for nym-name-service (nym-api, nym-cli, etc) ([#3355])
|
|
||||||
- Edit the nym-network-requester to support the enabled-credentials-mode flag ([#3101])
|
|
||||||
- [BUG] network requester documentation update ([#3493])
|
|
||||||
- removing hardcoded version numbers ([#3485])
|
|
||||||
- [BUG] network requester documentation update ([#3481])
|
|
||||||
- [BUG] network requester documentation update ([#3469])
|
|
||||||
- Sign when announcing service providers to the directory contract ([#3459])
|
|
||||||
- mixnode documentation update ([#3435])
|
|
||||||
- updated readme with new developer chat links + new docs links ([#3141])
|
|
||||||
|
|
||||||
[#3458]: https://github.com/nymtech/nym/issues/3458
|
|
||||||
[#3438]: https://github.com/nymtech/nym/issues/3438
|
|
||||||
[#3427]: https://github.com/nymtech/nym/issues/3427
|
|
||||||
[#3360]: https://github.com/nymtech/nym/issues/3360
|
|
||||||
[#3355]: https://github.com/nymtech/nym/issues/3355
|
|
||||||
[#3101]: https://github.com/nymtech/nym/issues/3101
|
|
||||||
[#3493]: https://github.com/nymtech/nym/pull/3493
|
|
||||||
[#3485]: https://github.com/nymtech/nym/pull/3485
|
|
||||||
[#3481]: https://github.com/nymtech/nym/pull/3481
|
|
||||||
[#3469]: https://github.com/nymtech/nym/pull/3469
|
|
||||||
[#3459]: https://github.com/nymtech/nym/pull/3459
|
|
||||||
[#3435]: https://github.com/nymtech/nym/pull/3435
|
|
||||||
[#3141]: https://github.com/nymtech/nym/pull/3141
|
|
||||||
|
|
||||||
## [v1.1.19] (2023-05-16)
|
## [v1.1.19] (2023-05-16)
|
||||||
|
|
||||||
- nym-name-service endpoint in nym-api ([#3403])
|
- nym-name-service endpoint in nym-api ([#3403])
|
||||||
|
|||||||
Generated
+291
-1400
File diff suppressed because it is too large
Load Diff
+2
-5
@@ -87,7 +87,6 @@ members = [
|
|||||||
"nym-api/nym-api-requests",
|
"nym-api/nym-api-requests",
|
||||||
"nym-outfox",
|
"nym-outfox",
|
||||||
"tools/nym-cli",
|
"tools/nym-cli",
|
||||||
"tools/nym-nr-query",
|
|
||||||
"tools/ts-rs-cli"
|
"tools/ts-rs-cli"
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -113,24 +112,22 @@ edition = "2021"
|
|||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
anyhow = "1.0.71"
|
|
||||||
async-trait = "0.1.64"
|
async-trait = "0.1.64"
|
||||||
|
anyhow = "1.0.71"
|
||||||
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
cosmwasm-derive = "=1.0.0"
|
cosmwasm-derive = "=1.0.0"
|
||||||
cosmwasm-schema = "=1.0.0"
|
cosmwasm-schema = "=1.0.0"
|
||||||
cosmwasm-std = "=1.0.0"
|
cosmwasm-std = "=1.0.0"
|
||||||
cosmwasm-storage = "=1.0.0"
|
cosmwasm-storage = "=1.0.0"
|
||||||
cw-controllers = "=0.13.4"
|
|
||||||
cw-storage-plus = "=0.13.4"
|
|
||||||
cw-utils = "=0.13.4"
|
cw-utils = "=0.13.4"
|
||||||
|
cw-storage-plus = "=0.13.4"
|
||||||
cw2 = { version = "=0.13.4" }
|
cw2 = { version = "=0.13.4" }
|
||||||
cw3 = { version = "=0.13.4" }
|
cw3 = { version = "=0.13.4" }
|
||||||
cw3-fixed-multisig = { version = "=0.13.4" }
|
cw3-fixed-multisig = { version = "=0.13.4" }
|
||||||
cw4 = { version = "=0.13.4" }
|
cw4 = { version = "=0.13.4" }
|
||||||
dotenvy = "0.15.6"
|
dotenvy = "0.15.6"
|
||||||
generic-array = "0.14.7"
|
generic-array = "0.14.7"
|
||||||
getrandom = "0.2.10"
|
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
once_cell = "1.7.2"
|
once_cell = "1.7.2"
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ The platform is composed of multiple Rust crates. Top-level executable binary cr
|
|||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
Platform build instructions are available on [our docs site](https://nymtech.net/docs/binaries/build-nym.html).
|
Platform build instructions are available on [our docs site](https://nymtech.net/docs/binaries/building-nym.html).
|
||||||
Wallet build instructions are also available on [our docs site](https://nymtech.net/docs/wallet/desktop-wallet.html).
|
Wallet build instructions are also available on [our docs site](https://nymtech.net/docs/stable/nym-apps/wallet#for-developers).
|
||||||
|
|
||||||
### Developing
|
### Developing
|
||||||
|
|
||||||
@@ -32,11 +32,7 @@ For Typescript components, please see [ts-packages](./ts-packages).
|
|||||||
|
|
||||||
### Developer chat
|
### Developer chat
|
||||||
|
|
||||||
> We used to use Keybase for developer chats, but we have since migrated to Matrix and Discord. We no longer check the old **nymtech.friends** Keybase team.
|
You can chat with us in [Keybase](https://keybase.io). Download their chat app, then click **Teams -> Join a team**. Type **nymtech.friends** into the team name and hit **continue**. For general chat, hang out in the **#general** channel. Our development takes place in the **#dev** channel. Node operators should be in the **#node-operators** channel.
|
||||||
|
|
||||||
You can chat to us in two places:
|
|
||||||
* The #dev channel on [Matrix](https://matrix.to/#/#dev:nymtech.chat)
|
|
||||||
* The various developer channels on [Discord](https://discord.gg/nym)
|
|
||||||
|
|
||||||
### Rewards
|
### Rewards
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-client"
|
name = "nym-client"
|
||||||
version = "1.1.22"
|
version = "1.1.19"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||||
description = "Implementation of the Nym Client"
|
description = "Implementation of the Nym Client"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ pub use nym_client_core::config::Config as BaseClientConfig;
|
|||||||
pub use nym_client_core::config::{DebugConfig, GatewayEndpointConfig};
|
pub use nym_client_core::config::{DebugConfig, GatewayEndpointConfig};
|
||||||
|
|
||||||
pub mod old_config_v1_1_13;
|
pub mod old_config_v1_1_13;
|
||||||
pub mod old_config_v1_1_20;
|
pub mod old_config_v1_1_19;
|
||||||
pub mod old_config_v1_1_20_2;
|
|
||||||
mod persistence;
|
mod persistence;
|
||||||
mod template;
|
mod template;
|
||||||
|
|
||||||
@@ -53,6 +52,19 @@ pub fn default_data_directory<P: AsRef<Path>>(id: P) -> PathBuf {
|
|||||||
.join(DEFAULT_DATA_DIR)
|
.join(DEFAULT_DATA_DIR)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone, Copy)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
pub enum SocketType {
|
||||||
|
WebSocket,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SocketType {
|
||||||
|
pub fn is_websocket(&self) -> bool {
|
||||||
|
matches!(self, SocketType::WebSocket)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
@@ -75,7 +87,7 @@ impl NymConfigTemplate for Config {
|
|||||||
impl Config {
|
impl Config {
|
||||||
pub fn new<S: AsRef<str>>(id: S) -> Self {
|
pub fn new<S: AsRef<str>>(id: S) -> Self {
|
||||||
Config {
|
Config {
|
||||||
base: BaseClientConfig::new(id.as_ref(), env!("CARGO_PKG_VERSION")),
|
base: BaseClientConfig::new(id.as_ref()),
|
||||||
storage_paths: ClientPaths::new_default(default_data_directory(id.as_ref())),
|
storage_paths: ClientPaths::new_default(default_data_directory(id.as_ref())),
|
||||||
logging: Default::default(),
|
logging: Default::default(),
|
||||||
socket: Default::default(),
|
socket: Default::default(),
|
||||||
@@ -175,19 +187,6 @@ impl Config {
|
|||||||
|
|
||||||
// define_optional_set_inner!(Config, base, BaseClientConfig);
|
// define_optional_set_inner!(Config, base, BaseClientConfig);
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone, Copy)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub enum SocketType {
|
|
||||||
WebSocket,
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SocketType {
|
|
||||||
pub fn is_websocket(&self) -> bool {
|
|
||||||
matches!(self, SocketType::WebSocket)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
#[serde(default, deny_unknown_fields)]
|
#[serde(default, deny_unknown_fields)]
|
||||||
pub struct Socket {
|
pub struct Socket {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::client::config::old_config_v1_1_20::{ConfigV1_1_20, SocketV1_1_20};
|
use crate::client::config::old_config_v1_1_19::{ConfigV1_1_19, SocketV1_1_19};
|
||||||
use nym_client_core::config::old_config_v1_1_13::OldConfigV1_1_13 as OldBaseConfigV1_1_13;
|
use nym_client_core::config::old_config_v1_1_13::OldConfigV1_1_13 as OldBaseConfigV1_1_13;
|
||||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -13,7 +13,7 @@ pub struct OldConfigV1_1_13 {
|
|||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub base: OldBaseConfigV1_1_13<OldConfigV1_1_13>,
|
pub base: OldBaseConfigV1_1_13<OldConfigV1_1_13>,
|
||||||
|
|
||||||
pub socket: SocketV1_1_20,
|
pub socket: SocketV1_1_19,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MigrationNymConfig for OldConfigV1_1_13 {
|
impl MigrationNymConfig for OldConfigV1_1_13 {
|
||||||
@@ -25,9 +25,9 @@ impl MigrationNymConfig for OldConfigV1_1_13 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OldConfigV1_1_13> for ConfigV1_1_20 {
|
impl From<OldConfigV1_1_13> for ConfigV1_1_19 {
|
||||||
fn from(value: OldConfigV1_1_13) -> Self {
|
fn from(value: OldConfigV1_1_13) -> Self {
|
||||||
ConfigV1_1_20 {
|
ConfigV1_1_19 {
|
||||||
base: value.base.into(),
|
base: value.base.into(),
|
||||||
socket: value.socket,
|
socket: value.socket,
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-32
@@ -1,16 +1,13 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::client::config::old_config_v1_1_20_2::{
|
use crate::client::config::persistence::ClientPaths;
|
||||||
ClientPathsV1_1_20_2, ConfigV1_1_20_2, SocketTypeV1_1_20_2, SocketV1_1_20_2,
|
use crate::client::config::{Config, Socket, SocketType};
|
||||||
};
|
|
||||||
use nym_bin_common::logging::LoggingSettings;
|
use nym_bin_common::logging::LoggingSettings;
|
||||||
use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths;
|
use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths;
|
||||||
use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2;
|
use nym_client_core::config::disk_persistence::CommonClientPaths;
|
||||||
use nym_client_core::config::old_config_v1_1_20::ConfigV1_1_20 as BaseConfigV1_1_20;
|
use nym_client_core::config::old_config_v1_1_19::ConfigV1_1_19 as BaseConfigV1_1_19;
|
||||||
use nym_client_core::config::old_config_v1_1_20_2::{
|
use nym_client_core::config::{Client, Config as BaseConfig};
|
||||||
ClientV1_1_20_2, ConfigV1_1_20_2 as BaseConfigV1_1_20_2,
|
|
||||||
};
|
|
||||||
use nym_config::defaults::DEFAULT_WEBSOCKET_LISTENING_PORT;
|
use nym_config::defaults::DEFAULT_WEBSOCKET_LISTENING_PORT;
|
||||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -20,34 +17,34 @@ use std::path::PathBuf;
|
|||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone, Copy)]
|
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone, Copy)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub enum SocketTypeV1_1_20 {
|
pub enum SocketTypeV1_1_19 {
|
||||||
WebSocket,
|
WebSocket,
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SocketTypeV1_1_20> for SocketTypeV1_1_20_2 {
|
impl From<SocketTypeV1_1_19> for SocketType {
|
||||||
fn from(value: SocketTypeV1_1_20) -> Self {
|
fn from(value: SocketTypeV1_1_19) -> Self {
|
||||||
match value {
|
match value {
|
||||||
SocketTypeV1_1_20::WebSocket => SocketTypeV1_1_20_2::WebSocket,
|
SocketTypeV1_1_19::WebSocket => SocketType::WebSocket,
|
||||||
SocketTypeV1_1_20::None => SocketTypeV1_1_20_2::None,
|
SocketTypeV1_1_19::None => SocketType::None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ConfigV1_1_20 {
|
pub struct ConfigV1_1_19 {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub base: BaseConfigV1_1_20<ConfigV1_1_20>,
|
pub base: BaseConfigV1_1_19<ConfigV1_1_19>,
|
||||||
|
|
||||||
pub socket: SocketV1_1_20,
|
pub socket: SocketV1_1_19,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ConfigV1_1_20> for ConfigV1_1_20_2 {
|
impl From<ConfigV1_1_19> for Config {
|
||||||
fn from(value: ConfigV1_1_20) -> Self {
|
fn from(value: ConfigV1_1_19) -> Self {
|
||||||
ConfigV1_1_20_2 {
|
Config {
|
||||||
base: BaseConfigV1_1_20_2 {
|
base: BaseConfig {
|
||||||
client: ClientV1_1_20_2 {
|
client: Client {
|
||||||
version: value.base.client.version,
|
version: value.base.client.version,
|
||||||
id: value.base.client.id,
|
id: value.base.client.id,
|
||||||
disabled_credentials_mode: value.base.client.disabled_credentials_mode,
|
disabled_credentials_mode: value.base.client.disabled_credentials_mode,
|
||||||
@@ -58,8 +55,8 @@ impl From<ConfigV1_1_20> for ConfigV1_1_20_2 {
|
|||||||
debug: value.base.debug.into(),
|
debug: value.base.debug.into(),
|
||||||
},
|
},
|
||||||
socket: value.socket.into(),
|
socket: value.socket.into(),
|
||||||
storage_paths: ClientPathsV1_1_20_2 {
|
storage_paths: ClientPaths {
|
||||||
common_paths: CommonClientPathsV1_1_20_2 {
|
common_paths: CommonClientPaths {
|
||||||
keys: ClientKeysPaths {
|
keys: ClientKeysPaths {
|
||||||
private_identity_key_file: value.base.client.private_identity_key_file,
|
private_identity_key_file: value.base.client.private_identity_key_file,
|
||||||
public_identity_key_file: value.base.client.public_identity_key_file,
|
public_identity_key_file: value.base.client.public_identity_key_file,
|
||||||
@@ -77,7 +74,7 @@ impl From<ConfigV1_1_20> for ConfigV1_1_20_2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MigrationNymConfig for ConfigV1_1_20 {
|
impl MigrationNymConfig for ConfigV1_1_19 {
|
||||||
fn default_root_directory() -> PathBuf {
|
fn default_root_directory() -> PathBuf {
|
||||||
dirs::home_dir()
|
dirs::home_dir()
|
||||||
.expect("Failed to evaluate $HOME value")
|
.expect("Failed to evaluate $HOME value")
|
||||||
@@ -88,15 +85,15 @@ impl MigrationNymConfig for ConfigV1_1_20 {
|
|||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
#[serde(default, deny_unknown_fields)]
|
#[serde(default, deny_unknown_fields)]
|
||||||
pub struct SocketV1_1_20 {
|
pub struct SocketV1_1_19 {
|
||||||
socket_type: SocketTypeV1_1_20,
|
socket_type: SocketTypeV1_1_19,
|
||||||
host: IpAddr,
|
host: IpAddr,
|
||||||
listening_port: u16,
|
listening_port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SocketV1_1_20> for SocketV1_1_20_2 {
|
impl From<SocketV1_1_19> for Socket {
|
||||||
fn from(value: SocketV1_1_20) -> Self {
|
fn from(value: SocketV1_1_19) -> Self {
|
||||||
SocketV1_1_20_2 {
|
Socket {
|
||||||
socket_type: value.socket_type.into(),
|
socket_type: value.socket_type.into(),
|
||||||
host: value.host,
|
host: value.host,
|
||||||
listening_port: value.listening_port,
|
listening_port: value.listening_port,
|
||||||
@@ -104,10 +101,10 @@ impl From<SocketV1_1_20> for SocketV1_1_20_2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SocketV1_1_20 {
|
impl Default for SocketV1_1_19 {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
SocketV1_1_20 {
|
SocketV1_1_19 {
|
||||||
socket_type: SocketTypeV1_1_20::WebSocket,
|
socket_type: SocketTypeV1_1_19::WebSocket,
|
||||||
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
host: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
||||||
listening_port: DEFAULT_WEBSOCKET_LISTENING_PORT,
|
listening_port: DEFAULT_WEBSOCKET_LISTENING_PORT,
|
||||||
}
|
}
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::client::config::persistence::ClientPaths;
|
|
||||||
use crate::client::config::{default_config_filepath, Config, Socket, SocketType};
|
|
||||||
use nym_bin_common::logging::LoggingSettings;
|
|
||||||
use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2;
|
|
||||||
use nym_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as BaseConfigV1_1_20_2;
|
|
||||||
use nym_client_core::config::GatewayEndpointConfig;
|
|
||||||
use nym_config::read_config_from_toml_file;
|
|
||||||
use nym_network_defaults::DEFAULT_WEBSOCKET_LISTENING_PORT;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::io;
|
|
||||||
use std::net::{IpAddr, Ipv4Addr};
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)]
|
|
||||||
pub struct ClientPathsV1_1_20_2 {
|
|
||||||
#[serde(flatten)]
|
|
||||||
pub common_paths: CommonClientPathsV1_1_20_2,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
|
||||||
pub struct ConfigV1_1_20_2 {
|
|
||||||
#[serde(flatten)]
|
|
||||||
pub base: BaseConfigV1_1_20_2,
|
|
||||||
|
|
||||||
pub socket: SocketV1_1_20_2,
|
|
||||||
|
|
||||||
pub storage_paths: ClientPathsV1_1_20_2,
|
|
||||||
|
|
||||||
pub logging: LoggingSettings,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ConfigV1_1_20_2 {
|
|
||||||
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
|
|
||||||
read_config_from_toml_file(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
|
|
||||||
Self::read_from_toml_file(default_config_filepath(id))
|
|
||||||
}
|
|
||||||
|
|
||||||
// in this upgrade, gateway endpoint configuration was moved out of the config file,
|
|
||||||
// so its returned to be stored elsewhere.
|
|
||||||
pub fn upgrade(self) -> (Config, GatewayEndpointConfig) {
|
|
||||||
let gateway_details = self.base.client.gateway_endpoint.clone().into();
|
|
||||||
let config = Config {
|
|
||||||
base: self.base.into(),
|
|
||||||
socket: self.socket.into(),
|
|
||||||
storage_paths: ClientPaths {
|
|
||||||
common_paths: self.storage_paths.common_paths.upgrade_default(),
|
|
||||||
},
|
|
||||||
logging: self.logging,
|
|
||||||
};
|
|
||||||
|
|
||||||
(config, gateway_details)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone, Copy)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub enum SocketTypeV1_1_20_2 {
|
|
||||||
WebSocket,
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SocketTypeV1_1_20_2> for SocketType {
|
|
||||||
fn from(value: SocketTypeV1_1_20_2) -> Self {
|
|
||||||
match value {
|
|
||||||
SocketTypeV1_1_20_2::WebSocket => SocketType::WebSocket,
|
|
||||||
SocketTypeV1_1_20_2::None => SocketType::None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)]
|
|
||||||
#[serde(default, deny_unknown_fields)]
|
|
||||||
pub struct SocketV1_1_20_2 {
|
|
||||||
pub socket_type: SocketTypeV1_1_20_2,
|
|
||||||
pub host: IpAddr,
|
|
||||||
pub listening_port: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SocketV1_1_20_2> for Socket {
|
|
||||||
fn from(value: SocketV1_1_20_2) -> Self {
|
|
||||||
Socket {
|
|
||||||
socket_type: value.socket_type.into(),
|
|
||||||
host: value.host,
|
|
||||||
listening_port: value.listening_port,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for SocketV1_1_20_2 {
|
|
||||||
fn default() -> Self {
|
|
||||||
SocketV1_1_20_2 {
|
|
||||||
socket_type: SocketTypeV1_1_20_2::WebSocket,
|
|
||||||
host: IpAddr::V4(Ipv4Addr::LOCALHOST),
|
|
||||||
listening_port: DEFAULT_WEBSOCKET_LISTENING_PORT,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -64,9 +64,18 @@ credentials_database = '{{ storage_paths.credentials_database }}'
|
|||||||
# Path to the persistent store for received reply surbs, unused encryption keys and used sender tags.
|
# Path to the persistent store for received reply surbs, unused encryption keys and used sender tags.
|
||||||
reply_surb_database = '{{ storage_paths.reply_surb_database }}'
|
reply_surb_database = '{{ storage_paths.reply_surb_database }}'
|
||||||
|
|
||||||
# Path to the file containing information about gateway used by this client,
|
# DEPRECATED
|
||||||
# i.e. details such as its public key, owner address or the network information.
|
[client.gateway_endpoint]
|
||||||
gateway_details = '{{ storage_paths.gateway_details }}'
|
# ID of the gateway from which the client should be fetching messages.
|
||||||
|
gateway_id = '{{ client.gateway_endpoint.gateway_id }}'
|
||||||
|
|
||||||
|
# Address of the gateway owner to which the client should send messages.
|
||||||
|
gateway_owner = '{{ client.gateway_endpoint.gateway_owner }}'
|
||||||
|
|
||||||
|
# Address of the gateway listener to which all client requests should be sent.
|
||||||
|
gateway_listener = '{{ client.gateway_endpoint.gateway_listener }}'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### socket config options #####
|
##### socket config options #####
|
||||||
|
|
||||||
|
|||||||
@@ -6,15 +6,18 @@ use crate::error::ClientError;
|
|||||||
use crate::websocket;
|
use crate::websocket;
|
||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
use log::*;
|
use log::*;
|
||||||
use nym_client_core::client::base_client::non_wasm_helpers::default_query_dkg_client_from_config;
|
use nym_bandwidth_controller::BandwidthController;
|
||||||
|
use nym_client_core::client::base_client::non_wasm_helpers::create_bandwidth_controller;
|
||||||
use nym_client_core::client::base_client::storage::OnDiskPersistent;
|
use nym_client_core::client::base_client::storage::OnDiskPersistent;
|
||||||
use nym_client_core::client::base_client::{
|
use nym_client_core::client::base_client::{
|
||||||
BaseClientBuilder, ClientInput, ClientOutput, ClientState,
|
non_wasm_helpers, BaseClientBuilder, ClientInput, ClientOutput, ClientState,
|
||||||
};
|
};
|
||||||
use nym_client_core::client::inbound_messages::InputMessage;
|
use nym_client_core::client::inbound_messages::InputMessage;
|
||||||
|
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
|
||||||
use nym_client_core::client::received_buffer::{
|
use nym_client_core::client::received_buffer::{
|
||||||
ReceivedBufferMessage, ReceivedBufferRequestSender, ReconstructedMessagesReceiver,
|
ReceivedBufferMessage, ReceivedBufferRequestSender, ReconstructedMessagesReceiver,
|
||||||
};
|
};
|
||||||
|
use nym_credential_storage::persistent_storage::PersistentStorage;
|
||||||
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
|
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
|
||||||
use nym_sphinx::params::PacketType;
|
use nym_sphinx::params::PacketType;
|
||||||
use nym_task::connections::TransmissionLane;
|
use nym_task::connections::TransmissionLane;
|
||||||
@@ -42,6 +45,17 @@ impl SocketClient {
|
|||||||
SocketClient { config }
|
SocketClient { config }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn create_bandwidth_controller(
|
||||||
|
config: &Config,
|
||||||
|
) -> BandwidthController<Client<QueryNyxdClient>, PersistentStorage> {
|
||||||
|
let storage = nym_credential_storage::initialise_persistent_storage(
|
||||||
|
&config.storage_paths.common_paths.credentials_database,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
create_bandwidth_controller(&config.base, storage)
|
||||||
|
}
|
||||||
|
|
||||||
fn start_websocket_listener(
|
fn start_websocket_listener(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
client_input: ClientInput,
|
client_input: ClientInput,
|
||||||
@@ -91,26 +105,29 @@ impl SocketClient {
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn initialise_storage(&self) -> Result<OnDiskPersistent, ClientError> {
|
fn key_store(&self) -> OnDiskKeys {
|
||||||
Ok(OnDiskPersistent::from_paths(
|
OnDiskKeys::new(self.config.storage_paths.common_paths.keys.clone())
|
||||||
self.config.storage_paths.common_paths.clone(),
|
|
||||||
&self.config.base.debug,
|
|
||||||
)
|
|
||||||
.await?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: see if this could also be shared with socks5 client / nym-sdk maybe
|
// TODO: see if this could also be shared with socks5 client / nym-sdk maybe
|
||||||
async fn create_base_client_builder(&self) -> Result<NativeClientBuilder, ClientError> {
|
async fn create_base_client_builder(&self) -> Result<NativeClientBuilder, ClientError> {
|
||||||
// don't create dkg client for the bandwidth controller if credentials are disabled
|
// don't create bandwidth controller if credentials are disabled
|
||||||
let dkg_query_client = if self.config.base.client.disabled_credentials_mode {
|
let bandwidth_controller = if self.config.base.client.disabled_credentials_mode {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(default_query_dkg_client_from_config(&self.config.base))
|
Some(Self::create_bandwidth_controller(&self.config).await)
|
||||||
};
|
};
|
||||||
|
|
||||||
let storage = self.initialise_storage().await?;
|
let base_client = BaseClientBuilder::new_from_base_config(
|
||||||
|
&self.config.base,
|
||||||
let base_client = BaseClientBuilder::new(&self.config.base, storage, dkg_query_client);
|
self.key_store(),
|
||||||
|
bandwidth_controller,
|
||||||
|
non_wasm_helpers::setup_fs_reply_surb_backend(
|
||||||
|
&self.config.storage_paths.common_paths.reply_surb_database,
|
||||||
|
&self.config.base.debug.reply_surbs,
|
||||||
|
)
|
||||||
|
.await?,
|
||||||
|
);
|
||||||
|
|
||||||
Ok(base_client)
|
Ok(base_client)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use nym_bin_common::output_format::OutputFormat;
|
use nym_bin_common::output_format::OutputFormat;
|
||||||
use nym_client_core::client::base_client::storage::gateway_details::OnDiskGatewayDetails;
|
|
||||||
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
|
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
|
||||||
use nym_client_core::config::GatewayEndpointConfig;
|
|
||||||
use nym_client_core::init::GatewaySetup;
|
|
||||||
use nym_crypto::asymmetric::identity;
|
use nym_crypto::asymmetric::identity;
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
use nym_sphinx::addressing::clients::Recipient;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@@ -108,9 +105,9 @@ pub struct InitResults {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl InitResults {
|
impl InitResults {
|
||||||
fn new(config: &Config, address: &Recipient, gateway: &GatewayEndpointConfig) -> Self {
|
fn new(config: &Config, address: &Recipient) -> Self {
|
||||||
Self {
|
Self {
|
||||||
client_core: nym_client_core::init::InitResults::new(&config.base, address, gateway),
|
client_core: nym_client_core::init::InitResults::new(&config.base, address),
|
||||||
client_listening_port: config.socket.listening_port,
|
client_listening_port: config.socket.listening_port,
|
||||||
client_address: address.to_string(),
|
client_address: address.to_string(),
|
||||||
}
|
}
|
||||||
@@ -160,29 +157,25 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> {
|
|||||||
|
|
||||||
// Attempt to use a user-provided gateway, if possible
|
// Attempt to use a user-provided gateway, if possible
|
||||||
let user_chosen_gateway_id = args.gateway;
|
let user_chosen_gateway_id = args.gateway;
|
||||||
let gateway_setup = GatewaySetup::new_fresh(
|
|
||||||
user_chosen_gateway_id.map(|id| id.to_base58_string()),
|
|
||||||
Some(args.latency_based_selection),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Load and potentially override config
|
// Load and potentially override config
|
||||||
let config = override_config(Config::new(id), OverrideConfig::from(args.clone()));
|
let mut config = override_config(Config::new(id), OverrideConfig::from(args.clone()));
|
||||||
|
|
||||||
// Setup gateway by either registering a new one, or creating a new config from the selected
|
// Setup gateway by either registering a new one, or creating a new config from the selected
|
||||||
// one but with keys kept, or reusing the gateway configuration.
|
// one but with keys kept, or reusing the gateway configuration.
|
||||||
let key_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone());
|
let key_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone());
|
||||||
let details_store =
|
let gateway = nym_client_core::init::setup_gateway_from_config::<_>(
|
||||||
OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details);
|
|
||||||
let init_details = nym_client_core::init::setup_gateway(
|
|
||||||
&gateway_setup,
|
|
||||||
&key_store,
|
&key_store,
|
||||||
&details_store,
|
|
||||||
register_gateway,
|
register_gateway,
|
||||||
Some(&config.base.client.nym_api_urls),
|
user_chosen_gateway_id,
|
||||||
|
&config.base,
|
||||||
|
args.latency_based_selection,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?;
|
.tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?;
|
||||||
|
|
||||||
|
config.base.set_gateway_endpoint(gateway);
|
||||||
|
|
||||||
let config_save_location = config.default_location();
|
let config_save_location = config.default_location();
|
||||||
config.save_to_default_location().tap_err(|_| {
|
config.save_to_default_location().tap_err(|_| {
|
||||||
log::error!("Failed to save the config file");
|
log::error!("Failed to save the config file");
|
||||||
@@ -192,11 +185,14 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> {
|
|||||||
config_save_location.display()
|
config_save_location.display()
|
||||||
);
|
);
|
||||||
|
|
||||||
let address = init_details.client_address()?;
|
let address = nym_client_core::init::get_client_address_from_stored_ondisk_keys(
|
||||||
|
&config.storage_paths.common_paths.keys,
|
||||||
|
&config.base.client.gateway_endpoint,
|
||||||
|
)?;
|
||||||
|
|
||||||
eprintln!("Client configuration completed.\n");
|
eprintln!("Client configuration completed.\n");
|
||||||
|
|
||||||
let init_results = InitResults::new(&config, &address, &init_details.gateway_details);
|
let init_results = InitResults::new(&config, &address);
|
||||||
println!("{}", args.output.format(&init_results));
|
println!("{}", args.output.format(&init_results));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::client::config::old_config_v1_1_13::OldConfigV1_1_13;
|
use crate::client::config::old_config_v1_1_13::OldConfigV1_1_13;
|
||||||
use crate::client::config::old_config_v1_1_20::ConfigV1_1_20;
|
use crate::client::config::old_config_v1_1_19::ConfigV1_1_19;
|
||||||
use crate::client::config::old_config_v1_1_20_2::ConfigV1_1_20_2;
|
|
||||||
use crate::client::config::{BaseClientConfig, Config};
|
use crate::client::config::{BaseClientConfig, Config};
|
||||||
use crate::error::ClientError;
|
use crate::error::ClientError;
|
||||||
use clap::CommandFactory;
|
use clap::CommandFactory;
|
||||||
@@ -12,12 +11,6 @@ use lazy_static::lazy_static;
|
|||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use nym_bin_common::build_information::BinaryBuildInformation;
|
use nym_bin_common::build_information::BinaryBuildInformation;
|
||||||
use nym_bin_common::completions::{fig_generate, ArgShell};
|
use nym_bin_common::completions::{fig_generate, ArgShell};
|
||||||
use nym_client_core::client::base_client::storage::gateway_details::{
|
|
||||||
OnDiskGatewayDetails, PersistedGatewayDetails,
|
|
||||||
};
|
|
||||||
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
|
|
||||||
use nym_client_core::config::GatewayEndpointConfig;
|
|
||||||
use nym_client_core::error::ClientCoreError;
|
|
||||||
use nym_config::OptionalSet;
|
use nym_config::OptionalSet;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
@@ -116,28 +109,6 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn persist_gateway_details(
|
|
||||||
config: &Config,
|
|
||||||
details: GatewayEndpointConfig,
|
|
||||||
) -> Result<(), ClientError> {
|
|
||||||
let details_store =
|
|
||||||
OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details);
|
|
||||||
let keys_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone());
|
|
||||||
let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| {
|
|
||||||
ClientError::ClientCoreError(ClientCoreError::KeyStoreError {
|
|
||||||
source: Box::new(source),
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
let persisted_details = PersistedGatewayDetails::new(details, &shared_keys);
|
|
||||||
details_store
|
|
||||||
.store_to_disk(&persisted_details)
|
|
||||||
.map_err(|source| {
|
|
||||||
ClientError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError {
|
|
||||||
source: Box::new(source),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, ClientError> {
|
fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, ClientError> {
|
||||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||||
|
|
||||||
@@ -150,77 +121,40 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, ClientError> {
|
|||||||
info!("It seems the client is using <= v1.1.13 config template.");
|
info!("It seems the client is using <= v1.1.13 config template.");
|
||||||
info!("It is going to get updated to the current specification.");
|
info!("It is going to get updated to the current specification.");
|
||||||
|
|
||||||
let updated_step1: ConfigV1_1_20 = old_config.into();
|
let updated_step1: ConfigV1_1_19 = old_config.into();
|
||||||
let updated_step2: ConfigV1_1_20_2 = updated_step1.into();
|
let updated: Config = updated_step1.into();
|
||||||
let (updated, gateway_config) = updated_step2.upgrade();
|
|
||||||
persist_gateway_details(&updated, gateway_config)?;
|
|
||||||
|
|
||||||
updated.save_to_default_location()?;
|
updated.save_to_default_location()?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, ClientError> {
|
fn try_upgrade_v1_1_19_config(id: &str) -> Result<bool, ClientError> {
|
||||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||||
|
|
||||||
// explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21)
|
// explicitly load it as v1.1.19 (which is incompatible with the current one, i.e. +1.1.20)
|
||||||
let Ok(old_config) = ConfigV1_1_20::load_from_file(id) else {
|
let Ok(old_config) = ConfigV1_1_19::load_from_file(id) else {
|
||||||
// if we failed to load it, there might have been nothing to upgrade
|
// if we failed to load it, there might have been nothing to upgrade
|
||||||
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
};
|
};
|
||||||
info!("It seems the client is using <= v1.1.20 config template.");
|
info!("It seems the client is using <= v1.1.19 config template.");
|
||||||
info!("It is going to get updated to the current specification.");
|
info!("It is going to get updated to the current specification.");
|
||||||
|
|
||||||
let updated_step1: ConfigV1_1_20_2 = old_config.into();
|
let updated: Config = old_config.into();
|
||||||
let (updated, gateway_config) = updated_step1.upgrade();
|
|
||||||
persist_gateway_details(&updated, gateway_config)?;
|
|
||||||
|
|
||||||
updated.save_to_default_location()?;
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, ClientError> {
|
|
||||||
// explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21)
|
|
||||||
let Ok(old_config) = ConfigV1_1_20_2::read_from_default_path(id) else {
|
|
||||||
// if we failed to load it, there might have been nothing to upgrade
|
|
||||||
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
|
||||||
return Ok(false);
|
|
||||||
};
|
|
||||||
info!("It seems the client is using <= v1.1.20_2 config template.");
|
|
||||||
info!("It is going to get updated to the current specification.");
|
|
||||||
|
|
||||||
let (updated, gateway_config) = old_config.upgrade();
|
|
||||||
persist_gateway_details(&updated, gateway_config)?;
|
|
||||||
|
|
||||||
updated.save_to_default_location()?;
|
updated.save_to_default_location()?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_upgrade_config(id: &str) -> Result<(), ClientError> {
|
fn try_upgrade_config(id: &str) -> Result<(), ClientError> {
|
||||||
if try_upgrade_v1_1_13_config(id)? {
|
let upgraded = try_upgrade_v1_1_13_config(id)?;
|
||||||
return Ok(());
|
if !upgraded {
|
||||||
}
|
try_upgrade_v1_1_19_config(id)?;
|
||||||
if try_upgrade_v1_1_20_config(id)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
if try_upgrade_v1_1_20_2_config(id)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_load_current_config(id: &str) -> Result<Config, ClientError> {
|
fn try_load_current_config(id: &str) -> Result<Config, ClientError> {
|
||||||
// try to load the config as is
|
|
||||||
if let Ok(cfg) = Config::read_from_default_path(id) {
|
|
||||||
return if !cfg.validate() {
|
|
||||||
Err(ClientError::ConfigValidationFailure)
|
|
||||||
} else {
|
|
||||||
Ok(cfg)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// we couldn't load it - try upgrading it from older revisions
|
|
||||||
try_upgrade_config(id)?;
|
try_upgrade_config(id)?;
|
||||||
|
|
||||||
let config = match Config::read_from_default_path(id) {
|
let config = match Config::read_from_default_path(id) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-socks5-client"
|
name = "nym-socks5-client"
|
||||||
version = "1.1.22"
|
version = "1.1.19"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
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"
|
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -11,10 +11,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use nym_bin_common::output_format::OutputFormat;
|
use nym_bin_common::output_format::OutputFormat;
|
||||||
use nym_client_core::client::base_client::storage::gateway_details::OnDiskGatewayDetails;
|
|
||||||
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
|
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
|
||||||
use nym_client_core::config::GatewayEndpointConfig;
|
|
||||||
use nym_client_core::init::GatewaySetup;
|
|
||||||
use nym_crypto::asymmetric::identity;
|
use nym_crypto::asymmetric::identity;
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
use nym_sphinx::addressing::clients::Recipient;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@@ -110,13 +107,9 @@ pub struct InitResults {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl InitResults {
|
impl InitResults {
|
||||||
fn new(config: &Config, address: &Recipient, gateway: &GatewayEndpointConfig) -> Self {
|
fn new(config: &Config, address: &Recipient) -> Self {
|
||||||
Self {
|
Self {
|
||||||
client_core: nym_client_core::init::InitResults::new(
|
client_core: nym_client_core::init::InitResults::new(&config.core.base, address),
|
||||||
&config.core.base,
|
|
||||||
address,
|
|
||||||
gateway,
|
|
||||||
),
|
|
||||||
socks5_listening_port: config.core.socks5.listening_port,
|
socks5_listening_port: config.core.socks5.listening_port,
|
||||||
client_address: address.to_string(),
|
client_address: address.to_string(),
|
||||||
}
|
}
|
||||||
@@ -167,13 +160,9 @@ pub(crate) async fn execute(args: &Init) -> Result<(), Socks5ClientError> {
|
|||||||
|
|
||||||
// Attempt to use a user-provided gateway, if possible
|
// Attempt to use a user-provided gateway, if possible
|
||||||
let user_chosen_gateway_id = args.gateway;
|
let user_chosen_gateway_id = args.gateway;
|
||||||
let gateway_setup = GatewaySetup::new_fresh(
|
|
||||||
user_chosen_gateway_id.map(|id| id.to_base58_string()),
|
|
||||||
Some(args.latency_based_selection),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Load and potentially override config
|
// Load and potentially override config
|
||||||
let config = override_config(
|
let mut config = override_config(
|
||||||
Config::new(id, &provider_address.to_string()),
|
Config::new(id, &provider_address.to_string()),
|
||||||
OverrideConfig::from(args.clone()),
|
OverrideConfig::from(args.clone()),
|
||||||
);
|
);
|
||||||
@@ -181,18 +170,18 @@ pub(crate) async fn execute(args: &Init) -> Result<(), Socks5ClientError> {
|
|||||||
// Setup gateway by either registering a new one, or creating a new config from the selected
|
// Setup gateway by either registering a new one, or creating a new config from the selected
|
||||||
// one but with keys kept, or reusing the gateway configuration.
|
// one but with keys kept, or reusing the gateway configuration.
|
||||||
let key_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone());
|
let key_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone());
|
||||||
let details_store =
|
let gateway = nym_client_core::init::setup_gateway_from_config::<_>(
|
||||||
OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details);
|
|
||||||
let init_details = nym_client_core::init::setup_gateway(
|
|
||||||
&gateway_setup,
|
|
||||||
&key_store,
|
&key_store,
|
||||||
&details_store,
|
|
||||||
register_gateway,
|
register_gateway,
|
||||||
Some(&config.core.base.client.nym_api_urls),
|
user_chosen_gateway_id,
|
||||||
|
&config.core.base,
|
||||||
|
args.latency_based_selection,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?;
|
.tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?;
|
||||||
|
|
||||||
|
config.core.base.set_gateway_endpoint(gateway);
|
||||||
|
|
||||||
// TODO: ask the service provider we specified for its interface version and set it in the config
|
// TODO: ask the service provider we specified for its interface version and set it in the config
|
||||||
|
|
||||||
let config_save_location = config.default_location();
|
let config_save_location = config.default_location();
|
||||||
@@ -204,9 +193,11 @@ pub(crate) async fn execute(args: &Init) -> Result<(), Socks5ClientError> {
|
|||||||
config_save_location.display()
|
config_save_location.display()
|
||||||
);
|
);
|
||||||
|
|
||||||
let address = init_details.client_address()?;
|
let address = nym_client_core::init::get_client_address_from_stored_ondisk_keys(
|
||||||
|
&config.storage_paths.common_paths.keys,
|
||||||
let init_results = InitResults::new(&config, &address, &init_details.gateway_details);
|
&config.core.base.client.gateway_endpoint,
|
||||||
|
)?;
|
||||||
|
let init_results = InitResults::new(&config, &address);
|
||||||
println!("{}", args.output.format(&init_results));
|
println!("{}", args.output.format(&init_results));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::config::old_config_v1_1_13::OldConfigV1_1_13;
|
use crate::config::old_config_v1_1_13::OldConfigV1_1_13;
|
||||||
use crate::config::old_config_v1_1_20::ConfigV1_1_20;
|
use crate::config::old_config_v1_1_19::ConfigV1_1_19;
|
||||||
use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2;
|
|
||||||
use crate::config::{BaseClientConfig, Config};
|
use crate::config::{BaseClientConfig, Config};
|
||||||
use crate::error::Socks5ClientError;
|
use crate::error::Socks5ClientError;
|
||||||
use clap::CommandFactory;
|
use clap::CommandFactory;
|
||||||
@@ -12,12 +11,6 @@ use lazy_static::lazy_static;
|
|||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use nym_bin_common::build_information::BinaryBuildInformation;
|
use nym_bin_common::build_information::BinaryBuildInformation;
|
||||||
use nym_bin_common::completions::{fig_generate, ArgShell};
|
use nym_bin_common::completions::{fig_generate, ArgShell};
|
||||||
use nym_client_core::client::base_client::storage::gateway_details::{
|
|
||||||
OnDiskGatewayDetails, PersistedGatewayDetails,
|
|
||||||
};
|
|
||||||
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
|
|
||||||
use nym_client_core::config::GatewayEndpointConfig;
|
|
||||||
use nym_client_core::error::ClientCoreError;
|
|
||||||
use nym_config::OptionalSet;
|
use nym_config::OptionalSet;
|
||||||
use nym_sphinx::params::PacketType;
|
use nym_sphinx::params::PacketType;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
@@ -123,28 +116,6 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn persist_gateway_details(
|
|
||||||
config: &Config,
|
|
||||||
details: GatewayEndpointConfig,
|
|
||||||
) -> Result<(), Socks5ClientError> {
|
|
||||||
let details_store =
|
|
||||||
OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details);
|
|
||||||
let keys_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone());
|
|
||||||
let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| {
|
|
||||||
Socks5ClientError::ClientCoreError(ClientCoreError::KeyStoreError {
|
|
||||||
source: Box::new(source),
|
|
||||||
})
|
|
||||||
})?;
|
|
||||||
let persisted_details = PersistedGatewayDetails::new(details, &shared_keys);
|
|
||||||
details_store
|
|
||||||
.store_to_disk(&persisted_details)
|
|
||||||
.map_err(|source| {
|
|
||||||
Socks5ClientError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError {
|
|
||||||
source: Box::new(source),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, Socks5ClientError> {
|
fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, Socks5ClientError> {
|
||||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||||
|
|
||||||
@@ -157,77 +128,40 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, Socks5ClientError> {
|
|||||||
info!("It seems the client is using <= v1.1.13 config template.");
|
info!("It seems the client is using <= v1.1.13 config template.");
|
||||||
info!("It is going to get updated to the current specification.");
|
info!("It is going to get updated to the current specification.");
|
||||||
|
|
||||||
let updated_step1: ConfigV1_1_20 = old_config.into();
|
let updated_step1: ConfigV1_1_19 = old_config.into();
|
||||||
let updated_step2: ConfigV1_1_20_2 = updated_step1.into();
|
let updated: Config = updated_step1.into();
|
||||||
let (updated, gateway_config) = updated_step2.upgrade();
|
|
||||||
persist_gateway_details(&updated, gateway_config)?;
|
|
||||||
|
|
||||||
updated.save_to_default_location()?;
|
updated.save_to_default_location()?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, Socks5ClientError> {
|
fn try_upgrade_v1_1_19_config(id: &str) -> Result<bool, Socks5ClientError> {
|
||||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||||
|
|
||||||
// explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21)
|
// explicitly load it as v1.1.19 (which is incompatible with the current one, i.e. +1.1.20)
|
||||||
let Ok(old_config) = ConfigV1_1_20::load_from_file(id) else {
|
let Ok(old_config) = ConfigV1_1_19::load_from_file(id) else {
|
||||||
// if we failed to load it, there might have been nothing to upgrade
|
// if we failed to load it, there might have been nothing to upgrade
|
||||||
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
};
|
};
|
||||||
info!("It seems the client is using <= v1.1.20 config template.");
|
info!("It seems the client is using <= v1.1.19 config template.");
|
||||||
info!("It is going to get updated to the current specification.");
|
info!("It is going to get updated to the current specification.");
|
||||||
|
|
||||||
let updated_step1: ConfigV1_1_20_2 = old_config.into();
|
let updated: Config = old_config.into();
|
||||||
let (updated, gateway_config) = updated_step1.upgrade();
|
|
||||||
persist_gateway_details(&updated, gateway_config)?;
|
|
||||||
|
|
||||||
updated.save_to_default_location()?;
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, Socks5ClientError> {
|
|
||||||
// explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21)
|
|
||||||
let Ok(old_config) = ConfigV1_1_20_2::read_from_default_path(id) else {
|
|
||||||
// if we failed to load it, there might have been nothing to upgrade
|
|
||||||
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
|
||||||
return Ok(false);
|
|
||||||
};
|
|
||||||
info!("It seems the client is using <= v1.1.20_2 config template.");
|
|
||||||
info!("It is going to get updated to the current specification.");
|
|
||||||
|
|
||||||
let (updated, gateway_config) = old_config.upgrade();
|
|
||||||
persist_gateway_details(&updated, gateway_config)?;
|
|
||||||
|
|
||||||
updated.save_to_default_location()?;
|
updated.save_to_default_location()?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_upgrade_config(id: &str) -> Result<(), Socks5ClientError> {
|
fn try_upgrade_config(id: &str) -> Result<(), Socks5ClientError> {
|
||||||
if try_upgrade_v1_1_13_config(id)? {
|
let upgraded = try_upgrade_v1_1_13_config(id)?;
|
||||||
return Ok(());
|
if !upgraded {
|
||||||
}
|
try_upgrade_v1_1_19_config(id)?;
|
||||||
if try_upgrade_v1_1_20_config(id)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
if try_upgrade_v1_1_20_2_config(id)? {
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_load_current_config(id: &str) -> Result<Config, Socks5ClientError> {
|
fn try_load_current_config(id: &str) -> Result<Config, Socks5ClientError> {
|
||||||
// try to load the config as is
|
|
||||||
if let Ok(cfg) = Config::read_from_default_path(id) {
|
|
||||||
return if !cfg.validate() {
|
|
||||||
Err(Socks5ClientError::ConfigValidationFailure)
|
|
||||||
} else {
|
|
||||||
Ok(cfg)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// we couldn't load it - try upgrading it from older revisions
|
|
||||||
try_upgrade_config(id)?;
|
try_upgrade_config(id)?;
|
||||||
|
|
||||||
let config = match Config::read_from_default_path(id) {
|
let config = match Config::read_from_default_path(id) {
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ pub use nym_client_core::config::Config as BaseClientConfig;
|
|||||||
pub use nym_socks5_client_core::config::Config as CoreConfig;
|
pub use nym_socks5_client_core::config::Config as CoreConfig;
|
||||||
|
|
||||||
pub mod old_config_v1_1_13;
|
pub mod old_config_v1_1_13;
|
||||||
pub mod old_config_v1_1_20;
|
pub mod old_config_v1_1_19;
|
||||||
pub mod old_config_v1_1_20_2;
|
|
||||||
mod persistence;
|
mod persistence;
|
||||||
mod template;
|
mod template;
|
||||||
|
|
||||||
@@ -70,11 +69,7 @@ impl NymConfigTemplate for Config {
|
|||||||
impl Config {
|
impl Config {
|
||||||
pub fn new<S: AsRef<str>>(id: S, provider_mix_address: S) -> Self {
|
pub fn new<S: AsRef<str>>(id: S, provider_mix_address: S) -> Self {
|
||||||
Config {
|
Config {
|
||||||
core: CoreConfig::new(
|
core: CoreConfig::new(id.as_ref(), provider_mix_address.as_ref()),
|
||||||
id.as_ref(),
|
|
||||||
env!("CARGO_PKG_VERSION"),
|
|
||||||
provider_mix_address.as_ref(),
|
|
||||||
),
|
|
||||||
storage_paths: SocksClientPaths::new_default(default_data_directory(id.as_ref())),
|
storage_paths: SocksClientPaths::new_default(default_data_directory(id.as_ref())),
|
||||||
logging: Default::default(),
|
logging: Default::default(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::config::old_config_v1_1_20::{ConfigV1_1_20, Socks5V1_1_20};
|
use crate::config::old_config_v1_1_19::{ConfigV1_1_19, Socks5V1_1_19};
|
||||||
use nym_client_core::config::old_config_v1_1_13::OldConfigV1_1_13 as OldBaseConfigV1_1_13;
|
use nym_client_core::config::old_config_v1_1_13::OldConfigV1_1_13 as OldBaseConfigV1_1_13;
|
||||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||||
use nym_config::must_get_home;
|
use nym_config::must_get_home;
|
||||||
@@ -14,7 +14,7 @@ pub struct OldConfigV1_1_13 {
|
|||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub base: OldBaseConfigV1_1_13<OldConfigV1_1_13>,
|
pub base: OldBaseConfigV1_1_13<OldConfigV1_1_13>,
|
||||||
|
|
||||||
pub socks5: Socks5V1_1_20,
|
pub socks5: Socks5V1_1_19,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MigrationNymConfig for OldConfigV1_1_13 {
|
impl MigrationNymConfig for OldConfigV1_1_13 {
|
||||||
@@ -28,9 +28,9 @@ impl MigrationNymConfig for OldConfigV1_1_13 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OldConfigV1_1_13> for ConfigV1_1_20 {
|
impl From<OldConfigV1_1_13> for ConfigV1_1_19 {
|
||||||
fn from(value: OldConfigV1_1_13) -> Self {
|
fn from(value: OldConfigV1_1_13) -> Self {
|
||||||
ConfigV1_1_20 {
|
ConfigV1_1_19 {
|
||||||
base: value.base.into(),
|
base: value.base.into(),
|
||||||
socks5: value.socks5,
|
socks5: value.socks5,
|
||||||
}
|
}
|
||||||
|
|||||||
+30
-32
@@ -1,20 +1,18 @@
|
|||||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::config::old_config_v1_1_20_2::{
|
use crate::config::persistence::SocksClientPaths;
|
||||||
ConfigV1_1_20_2, CoreConfigV1_1_20_2, SocksClientPathsV1_1_20_2,
|
use crate::config::{BaseClientConfig, Config, CoreConfig};
|
||||||
};
|
|
||||||
use nym_bin_common::logging::LoggingSettings;
|
use nym_bin_common::logging::LoggingSettings;
|
||||||
use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths;
|
use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths;
|
||||||
use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2;
|
use nym_client_core::config::disk_persistence::CommonClientPaths;
|
||||||
use nym_client_core::config::old_config_v1_1_20::ConfigV1_1_20 as BaseConfigV1_1_20;
|
use nym_client_core::config::old_config_v1_1_19::ConfigV1_1_19 as BaseConfigV1_1_19;
|
||||||
use nym_client_core::config::old_config_v1_1_20_2::ClientV1_1_20_2;
|
use nym_client_core::config::Client;
|
||||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||||
use nym_config::must_get_home;
|
use nym_config::must_get_home;
|
||||||
use nym_socks5_client_core::config::old_config_v1_1_20_2::{
|
use nym_socks5_client_core::config::{
|
||||||
BaseClientConfigV1_1_20_2, Socks5DebugV1_1_20_2, Socks5V1_1_20_2,
|
ProviderInterfaceVersion, Socks5, Socks5Debug, Socks5ProtocolVersion,
|
||||||
};
|
};
|
||||||
use nym_socks5_client_core::config::{ProviderInterfaceVersion, Socks5ProtocolVersion};
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -24,19 +22,19 @@ const DEFAULT_PER_REQUEST_SURBS: u32 = 3;
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ConfigV1_1_20 {
|
pub struct ConfigV1_1_19 {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub base: BaseConfigV1_1_20<ConfigV1_1_20>,
|
pub base: BaseConfigV1_1_19<ConfigV1_1_19>,
|
||||||
|
|
||||||
pub socks5: Socks5V1_1_20,
|
pub socks5: Socks5V1_1_19,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ConfigV1_1_20> for ConfigV1_1_20_2 {
|
impl From<ConfigV1_1_19> for Config {
|
||||||
fn from(value: ConfigV1_1_20) -> Self {
|
fn from(value: ConfigV1_1_19) -> Self {
|
||||||
ConfigV1_1_20_2 {
|
Config {
|
||||||
core: CoreConfigV1_1_20_2 {
|
core: CoreConfig {
|
||||||
base: BaseClientConfigV1_1_20_2 {
|
base: BaseClientConfig {
|
||||||
client: ClientV1_1_20_2 {
|
client: Client {
|
||||||
version: value.base.client.version,
|
version: value.base.client.version,
|
||||||
id: value.base.client.id,
|
id: value.base.client.id,
|
||||||
disabled_credentials_mode: value.base.client.disabled_credentials_mode,
|
disabled_credentials_mode: value.base.client.disabled_credentials_mode,
|
||||||
@@ -48,8 +46,8 @@ impl From<ConfigV1_1_20> for ConfigV1_1_20_2 {
|
|||||||
},
|
},
|
||||||
socks5: value.socks5.into(),
|
socks5: value.socks5.into(),
|
||||||
},
|
},
|
||||||
storage_paths: SocksClientPathsV1_1_20_2 {
|
storage_paths: SocksClientPaths {
|
||||||
common_paths: CommonClientPathsV1_1_20_2 {
|
common_paths: CommonClientPaths {
|
||||||
keys: ClientKeysPaths {
|
keys: ClientKeysPaths {
|
||||||
private_identity_key_file: value.base.client.private_identity_key_file,
|
private_identity_key_file: value.base.client.private_identity_key_file,
|
||||||
public_identity_key_file: value.base.client.public_identity_key_file,
|
public_identity_key_file: value.base.client.public_identity_key_file,
|
||||||
@@ -67,7 +65,7 @@ impl From<ConfigV1_1_20> for ConfigV1_1_20_2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MigrationNymConfig for ConfigV1_1_20 {
|
impl MigrationNymConfig for ConfigV1_1_19 {
|
||||||
fn default_root_directory() -> PathBuf {
|
fn default_root_directory() -> PathBuf {
|
||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
let base_dir = must_get_home();
|
let base_dir = must_get_home();
|
||||||
@@ -80,7 +78,7 @@ impl MigrationNymConfig for ConfigV1_1_20 {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Socks5V1_1_20 {
|
pub struct Socks5V1_1_19 {
|
||||||
pub listening_port: u16,
|
pub listening_port: u16,
|
||||||
|
|
||||||
pub provider_mix_address: String,
|
pub provider_mix_address: String,
|
||||||
@@ -95,12 +93,12 @@ pub struct Socks5V1_1_20 {
|
|||||||
pub send_anonymously: bool,
|
pub send_anonymously: bool,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub socks5_debug: Socks5DebugV1_1_20,
|
pub socks5_debug: Socks5DebugV1_1_19,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Socks5V1_1_20> for Socks5V1_1_20_2 {
|
impl From<Socks5V1_1_19> for Socks5 {
|
||||||
fn from(value: Socks5V1_1_20) -> Self {
|
fn from(value: Socks5V1_1_19) -> Self {
|
||||||
Socks5V1_1_20_2 {
|
Socks5 {
|
||||||
listening_port: value.listening_port,
|
listening_port: value.listening_port,
|
||||||
provider_mix_address: value.provider_mix_address,
|
provider_mix_address: value.provider_mix_address,
|
||||||
provider_interface_version: value.provider_interface_version,
|
provider_interface_version: value.provider_interface_version,
|
||||||
@@ -113,23 +111,23 @@ impl From<Socks5V1_1_20> for Socks5V1_1_20_2 {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Socks5DebugV1_1_20 {
|
pub struct Socks5DebugV1_1_19 {
|
||||||
connection_start_surbs: u32,
|
connection_start_surbs: u32,
|
||||||
per_request_surbs: u32,
|
per_request_surbs: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Socks5DebugV1_1_20> for Socks5DebugV1_1_20_2 {
|
impl From<Socks5DebugV1_1_19> for Socks5Debug {
|
||||||
fn from(value: Socks5DebugV1_1_20) -> Self {
|
fn from(value: Socks5DebugV1_1_19) -> Self {
|
||||||
Socks5DebugV1_1_20_2 {
|
Socks5Debug {
|
||||||
connection_start_surbs: value.connection_start_surbs,
|
connection_start_surbs: value.connection_start_surbs,
|
||||||
per_request_surbs: value.per_request_surbs,
|
per_request_surbs: value.per_request_surbs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Socks5DebugV1_1_20 {
|
impl Default for Socks5DebugV1_1_19 {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Socks5DebugV1_1_20 {
|
Socks5DebugV1_1_19 {
|
||||||
connection_start_surbs: DEFAULT_CONNECTION_START_SURBS,
|
connection_start_surbs: DEFAULT_CONNECTION_START_SURBS,
|
||||||
per_request_surbs: DEFAULT_PER_REQUEST_SURBS,
|
per_request_surbs: DEFAULT_PER_REQUEST_SURBS,
|
||||||
}
|
}
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::config::persistence::SocksClientPaths;
|
|
||||||
use crate::config::{default_config_filepath, Config};
|
|
||||||
use nym_bin_common::logging::LoggingSettings;
|
|
||||||
use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2;
|
|
||||||
use nym_client_core::config::GatewayEndpointConfig;
|
|
||||||
use nym_config::read_config_from_toml_file;
|
|
||||||
pub use nym_socks5_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as CoreConfigV1_1_20_2;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::io;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)]
|
|
||||||
pub struct SocksClientPathsV1_1_20_2 {
|
|
||||||
#[serde(flatten)]
|
|
||||||
pub common_paths: CommonClientPathsV1_1_20_2,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct ConfigV1_1_20_2 {
|
|
||||||
pub core: CoreConfigV1_1_20_2,
|
|
||||||
|
|
||||||
pub storage_paths: SocksClientPathsV1_1_20_2,
|
|
||||||
|
|
||||||
pub logging: LoggingSettings,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ConfigV1_1_20_2 {
|
|
||||||
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
|
|
||||||
read_config_from_toml_file(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
|
|
||||||
Self::read_from_toml_file(default_config_filepath(id))
|
|
||||||
}
|
|
||||||
|
|
||||||
// in this upgrade, gateway endpoint configuration was moved out of the config file,
|
|
||||||
// so its returned to be stored elsewhere.
|
|
||||||
pub fn upgrade(self) -> (Config, GatewayEndpointConfig) {
|
|
||||||
let gateway_details = self.core.base.client.gateway_endpoint.clone().into();
|
|
||||||
let config = Config {
|
|
||||||
core: self.core.into(),
|
|
||||||
storage_paths: SocksClientPaths {
|
|
||||||
common_paths: self.storage_paths.common_paths.upgrade_default(),
|
|
||||||
},
|
|
||||||
logging: self.logging,
|
|
||||||
};
|
|
||||||
|
|
||||||
(config, gateway_details)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -64,9 +64,17 @@ credentials_database = '{{ storage_paths.credentials_database }}'
|
|||||||
# Path to the persistent store for received reply surbs, unused encryption keys and used sender tags.
|
# Path to the persistent store for received reply surbs, unused encryption keys and used sender tags.
|
||||||
reply_surb_database = '{{ storage_paths.reply_surb_database }}'
|
reply_surb_database = '{{ storage_paths.reply_surb_database }}'
|
||||||
|
|
||||||
# Path to the file containing information about gateway used by this client,
|
# DEPRECATED
|
||||||
# i.e. details such as its public key, owner address or the network information.
|
[core.client.gateway_endpoint]
|
||||||
gateway_details = '{{ storage_paths.gateway_details }}'
|
# ID of the gateway from which the client should be fetching messages.
|
||||||
|
gateway_id = '{{ core.client.gateway_endpoint.gateway_id }}'
|
||||||
|
|
||||||
|
# Address of the gateway owner to which the client should send messages.
|
||||||
|
gateway_owner = '{{ core.client.gateway_endpoint.gateway_owner }}'
|
||||||
|
|
||||||
|
# Address of the gateway listener to which all client requests should be sent.
|
||||||
|
gateway_listener = '{{ core.client.gateway_endpoint.gateway_listener }}'
|
||||||
|
|
||||||
|
|
||||||
##### socket config options #####
|
##### socket config options #####
|
||||||
|
|
||||||
|
|||||||
Generated
+25
-59
@@ -62,7 +62,7 @@ version = "0.7.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.9",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
@@ -225,9 +225,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.21.2"
|
version = "0.21.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
|
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64ct"
|
name = "base64ct"
|
||||||
@@ -622,7 +622,7 @@ dependencies = [
|
|||||||
"cosmos-sdk-proto",
|
"cosmos-sdk-proto",
|
||||||
"ecdsa",
|
"ecdsa",
|
||||||
"eyre",
|
"eyre",
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.9",
|
||||||
"k256",
|
"k256",
|
||||||
"prost",
|
"prost",
|
||||||
"prost-types",
|
"prost-types",
|
||||||
@@ -865,20 +865,6 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cw-controllers"
|
|
||||||
version = "0.13.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa"
|
|
||||||
dependencies = [
|
|
||||||
"cosmwasm-std",
|
|
||||||
"cw-storage-plus",
|
|
||||||
"cw-utils",
|
|
||||||
"schemars",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cw-storage-plus"
|
name = "cw-storage-plus"
|
||||||
version = "0.13.4"
|
version = "0.13.4"
|
||||||
@@ -1442,9 +1428,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.10"
|
version = "0.2.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
|
checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
@@ -2240,7 +2226,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-bin-common"
|
name = "nym-bin-common"
|
||||||
version = "0.6.0"
|
version = "0.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"clap",
|
"clap",
|
||||||
@@ -2255,10 +2241,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-client-core"
|
name = "nym-client-core"
|
||||||
version = "1.1.15"
|
version = "1.1.14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.21.2",
|
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"dirs 4.0.0",
|
"dirs 4.0.0",
|
||||||
"futures",
|
"futures",
|
||||||
@@ -2281,7 +2266,6 @@ dependencies = [
|
|||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sha2 0.10.6",
|
|
||||||
"sqlx 0.6.3",
|
"sqlx 0.6.3",
|
||||||
"tap",
|
"tap",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -2300,7 +2284,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-client-wasm"
|
name = "nym-client-wasm"
|
||||||
version = "1.1.1"
|
version = "1.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -2345,7 +2329,7 @@ dependencies = [
|
|||||||
"bs58",
|
"bs58",
|
||||||
"digest 0.9.0",
|
"digest 0.9.0",
|
||||||
"ff 0.11.1",
|
"ff 0.11.1",
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.9",
|
||||||
"group 0.11.0",
|
"group 0.11.0",
|
||||||
"itertools",
|
"itertools",
|
||||||
"nym-dkg",
|
"nym-dkg",
|
||||||
@@ -2405,7 +2389,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-contracts-common"
|
name = "nym-contracts-common"
|
||||||
version = "0.5.0"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bs58",
|
"bs58",
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
@@ -2440,7 +2424,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-crypto"
|
name = "nym-crypto"
|
||||||
version = "0.4.0"
|
version = "0.3.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes 0.8.2",
|
"aes 0.8.2",
|
||||||
"blake3",
|
"blake3",
|
||||||
@@ -2489,7 +2473,7 @@ name = "nym-gateway-client"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.9",
|
||||||
"log",
|
"log",
|
||||||
"nym-bandwidth-controller",
|
"nym-bandwidth-controller",
|
||||||
"nym-coconut-interface",
|
"nym-coconut-interface",
|
||||||
@@ -2547,7 +2531,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-mixnet-contract-common"
|
name = "nym-mixnet-contract-common"
|
||||||
version = "0.6.0"
|
version = "0.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bs58",
|
"bs58",
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
@@ -2636,7 +2620,7 @@ dependencies = [
|
|||||||
"chacha20",
|
"chacha20",
|
||||||
"chacha20poly1305",
|
"chacha20poly1305",
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.9",
|
||||||
"log",
|
"log",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"rayon",
|
"rayon",
|
||||||
@@ -2647,7 +2631,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-pemstore"
|
name = "nym-pemstore"
|
||||||
version = "0.3.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pem",
|
"pem",
|
||||||
]
|
]
|
||||||
@@ -2657,12 +2641,8 @@ name = "nym-service-provider-directory-common"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
"cw-controllers",
|
|
||||||
"cw-utils",
|
|
||||||
"nym-contracts-common",
|
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2697,7 +2677,6 @@ dependencies = [
|
|||||||
"nym-pemstore",
|
"nym-pemstore",
|
||||||
"nym-sphinx-addressing",
|
"nym-sphinx-addressing",
|
||||||
"nym-sphinx-params",
|
"nym-sphinx-params",
|
||||||
"nym-sphinx-routing",
|
|
||||||
"nym-sphinx-types",
|
"nym-sphinx-types",
|
||||||
"nym-topology",
|
"nym-topology",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
@@ -2724,7 +2703,6 @@ dependencies = [
|
|||||||
"nym-crypto",
|
"nym-crypto",
|
||||||
"nym-sphinx-addressing",
|
"nym-sphinx-addressing",
|
||||||
"nym-sphinx-params",
|
"nym-sphinx-params",
|
||||||
"nym-sphinx-routing",
|
|
||||||
"nym-sphinx-types",
|
"nym-sphinx-types",
|
||||||
"nym-topology",
|
"nym-topology",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
@@ -2755,7 +2733,6 @@ dependencies = [
|
|||||||
"nym-sphinx-chunking",
|
"nym-sphinx-chunking",
|
||||||
"nym-sphinx-forwarding",
|
"nym-sphinx-forwarding",
|
||||||
"nym-sphinx-params",
|
"nym-sphinx-params",
|
||||||
"nym-sphinx-routing",
|
|
||||||
"nym-sphinx-types",
|
"nym-sphinx-types",
|
||||||
"nym-topology",
|
"nym-topology",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
@@ -2819,7 +2796,7 @@ dependencies = [
|
|||||||
"aes-gcm",
|
"aes-gcm",
|
||||||
"argon2",
|
"argon2",
|
||||||
"generic-array 0.14.7",
|
"generic-array 0.14.7",
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.9",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -2887,7 +2864,6 @@ dependencies = [
|
|||||||
"nym-service-provider-directory-common",
|
"nym-service-provider-directory-common",
|
||||||
"nym-vesting-contract",
|
"nym-vesting-contract",
|
||||||
"nym-vesting-contract-common",
|
"nym-vesting-contract-common",
|
||||||
"openssl",
|
|
||||||
"prost",
|
"prost",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -2919,7 +2895,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-vesting-contract-common"
|
name = "nym-vesting-contract-common"
|
||||||
version = "0.7.0"
|
version = "0.6.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
"nym-contracts-common",
|
"nym-contracts-common",
|
||||||
@@ -2978,15 +2954,6 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "openssl-src"
|
|
||||||
version = "111.26.0+1.1.1u"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.87"
|
version = "0.9.87"
|
||||||
@@ -2995,7 +2962,6 @@ checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
"openssl-src",
|
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
@@ -3416,7 +3382,7 @@ version = "0.6.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3484,7 +3450,7 @@ version = "0.4.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.9",
|
||||||
"redox_syscall 0.2.16",
|
"redox_syscall 0.2.16",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
@@ -3512,7 +3478,7 @@ version = "0.11.18"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55"
|
checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.2",
|
"base64 0.21.0",
|
||||||
"bytes",
|
"bytes",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@@ -3646,7 +3612,7 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
|
checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.21.2",
|
"base64 0.21.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4402,7 +4368,7 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
"flex-error",
|
"flex-error",
|
||||||
"futures",
|
"futures",
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.9",
|
||||||
"http",
|
"http",
|
||||||
"hyper",
|
"hyper",
|
||||||
"hyper-proxy",
|
"hyper-proxy",
|
||||||
@@ -4802,7 +4768,7 @@ version = "1.3.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2"
|
checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.9",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -4978,7 +4944,7 @@ name = "wasm-utils"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures",
|
"futures",
|
||||||
"getrandom 0.2.10",
|
"getrandom 0.2.9",
|
||||||
"indexed_db_futures",
|
"indexed_db_futures",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"nym-store-cipher",
|
"nym-store-cipher",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-client-wasm"
|
name = "nym-client-wasm"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jedrzej Stuczynski <andrew@nymtech.net>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jedrzej Stuczynski <andrew@nymtech.net>"]
|
||||||
version = "1.1.1"
|
version = "1.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy", "client"]
|
keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy", "client"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|||||||
@@ -116,11 +116,11 @@ async function testWithTester() {
|
|||||||
// B) first get topology directly from nym-api
|
// B) first get topology directly from nym-api
|
||||||
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||||
// const topology = await current_network_topology(validator)
|
// const topology = await current_network_topology(validator)
|
||||||
// const nodeTester = await new NymNodeTester(topology, undefined, preferredGateway);
|
// const nodeTester = await new NymNodeTester(topology, preferredGateway);
|
||||||
//
|
//
|
||||||
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
|
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
|
||||||
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||||
// const nodeTester = await NymNodeTester.new_with_api(validator, undefined, preferredGateway)
|
// const nodeTester = await NymNodeTester.new_with_api(validator, preferredGateway)
|
||||||
|
|
||||||
// D, E, F) you also don't have to specify the gateway. if you don't, a random one (from your topology) will be used
|
// D, E, F) you also don't have to specify the gateway. if you don't, a random one (from your topology) will be used
|
||||||
// const topology = dummyTopology()
|
// const topology = dummyTopology()
|
||||||
@@ -139,40 +139,6 @@ async function testWithTester() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
async function testerReconnection() {
|
|
||||||
const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
|
||||||
const nodeTester = await NymNodeTester.new_with_api(validator);
|
|
||||||
|
|
||||||
self.onmessage = async event => {
|
|
||||||
if (event.data && event.data.kind) {
|
|
||||||
switch (event.data.kind) {
|
|
||||||
case 'TestPacket': {
|
|
||||||
const {mixnodeIdentity} = event.data.args;
|
|
||||||
console.log("starting node test...");
|
|
||||||
|
|
||||||
let result1 = await nodeTester.test_node(mixnodeIdentity);
|
|
||||||
console.log("sleeping for 5s");
|
|
||||||
await new Promise(r => setTimeout(r, 5000));
|
|
||||||
await nodeTester.disconnect_from_gateway();
|
|
||||||
|
|
||||||
console.log("sleeping for 5s");
|
|
||||||
await new Promise(r => setTimeout(r, 5000));
|
|
||||||
|
|
||||||
await nodeTester.reconnect_to_gateway();
|
|
||||||
let result2 = await nodeTester.test_node(mixnodeIdentity);
|
|
||||||
|
|
||||||
printAndDisplayTestResult(result1)
|
|
||||||
printAndDisplayTestResult(result2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testWithNymClient() {
|
async function testWithNymClient() {
|
||||||
@@ -364,17 +330,14 @@ async function main() {
|
|||||||
// sets up better stack traces in case of in-rust panics
|
// sets up better stack traces in case of in-rust panics
|
||||||
set_panic_hook();
|
set_panic_hook();
|
||||||
|
|
||||||
// show reconnection capabilities
|
|
||||||
// await testerReconnection()
|
|
||||||
|
|
||||||
// run test on simplified and dedicated tester:
|
// run test on simplified and dedicated tester:
|
||||||
await testWithTester()
|
// await testWithTester()
|
||||||
|
|
||||||
// hook-up the whole client for testing
|
// hook-up the whole client for testing
|
||||||
// await testWithNymClient()
|
// await testWithNymClient()
|
||||||
|
|
||||||
// 'Normal' client setup (to send 'normal' messages)
|
// 'Normal' client setup (to send 'normal' messages)
|
||||||
// await normalNymClientUsage()
|
await normalNymClientUsage()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's get started!
|
// Let's get started!
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ impl Config {
|
|||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new(id: String, validator_server: String, debug: Option<DebugWasm>) -> Self {
|
pub fn new(id: String, validator_server: String, debug: Option<DebugWasm>) -> Self {
|
||||||
Config {
|
Config {
|
||||||
base: BaseClientConfig::new(id, env!("CARGO_PKG_VERSION").to_string())
|
base: BaseClientConfig::new(id)
|
||||||
.with_custom_nyxd(vec![validator_server
|
.with_custom_nyxd(vec![validator_server
|
||||||
.parse()
|
.parse()
|
||||||
.expect("provided url was malformed")])
|
.expect("provided url was malformed")])
|
||||||
@@ -39,7 +39,7 @@ impl Config {
|
|||||||
|
|
||||||
pub(crate) fn new_tester_config<S: Into<String>>(id: S) -> Self {
|
pub(crate) fn new_tester_config<S: Into<String>>(id: S) -> Self {
|
||||||
Config {
|
Config {
|
||||||
base: BaseClientConfig::new(id.into(), env!("CARGO_PKG_VERSION").to_string())
|
base: BaseClientConfig::new(id)
|
||||||
.with_disabled_credentials(true)
|
.with_disabled_credentials(true)
|
||||||
.with_disabled_cover_traffic(true)
|
.with_disabled_cover_traffic(true)
|
||||||
.with_disabled_topology_refresh(true),
|
.with_disabled_topology_refresh(true),
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::client::response_pusher::ResponsePusher;
|
|||||||
use crate::constants::NODE_TESTER_CLIENT_ID;
|
use crate::constants::NODE_TESTER_CLIENT_ID;
|
||||||
use crate::error::WasmClientError;
|
use crate::error::WasmClientError;
|
||||||
use crate::helpers::{
|
use crate::helpers::{
|
||||||
parse_recipient, parse_sender_tag, setup_from_topology, setup_gateway_from_api,
|
choose_gateway, gateway_from_topology, parse_recipient, parse_sender_tag,
|
||||||
setup_reply_surb_storage_backend,
|
setup_reply_surb_storage_backend,
|
||||||
};
|
};
|
||||||
use crate::storage::traits::FullWasmClientStorage;
|
use crate::storage::traits::FullWasmClientStorage;
|
||||||
@@ -15,11 +15,13 @@ use crate::storage::ClientStorage;
|
|||||||
use crate::topology::WasmNymTopology;
|
use crate::topology::WasmNymTopology;
|
||||||
use js_sys::Promise;
|
use js_sys::Promise;
|
||||||
use nym_bandwidth_controller::wasm_mockups::{Client as FakeClient, DirectSigningNyxdClient};
|
use nym_bandwidth_controller::wasm_mockups::{Client as FakeClient, DirectSigningNyxdClient};
|
||||||
|
use nym_bandwidth_controller::BandwidthController;
|
||||||
use nym_client_core::client::base_client::{
|
use nym_client_core::client::base_client::{
|
||||||
BaseClientBuilder, ClientInput, ClientOutput, ClientState,
|
BaseClientBuilder, ClientInput, ClientOutput, ClientState, CredentialsToggle,
|
||||||
};
|
};
|
||||||
use nym_client_core::client::inbound_messages::InputMessage;
|
use nym_client_core::client::inbound_messages::InputMessage;
|
||||||
use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage;
|
use nym_client_core::client::replies::reply_storage::browser_backend;
|
||||||
|
use nym_credential_storage::ephemeral_storage::EphemeralStorage;
|
||||||
use nym_sphinx::params::PacketType;
|
use nym_sphinx::params::PacketType;
|
||||||
use nym_task::connections::TransmissionLane;
|
use nym_task::connections::TransmissionLane;
|
||||||
use nym_task::TaskManager;
|
use nym_task::TaskManager;
|
||||||
@@ -27,7 +29,7 @@ use nym_topology::provider_trait::{HardcodedTopologyProvider, TopologyProvider};
|
|||||||
use nym_topology::NymTopology;
|
use nym_topology::NymTopology;
|
||||||
use nym_validator_client::client::IdentityKey;
|
use nym_validator_client::client::IdentityKey;
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use rand::RngCore;
|
use rand::{thread_rng, RngCore};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen_futures::future_to_promise;
|
use wasm_bindgen_futures::future_to_promise;
|
||||||
@@ -61,7 +63,14 @@ pub struct NymClientBuilder {
|
|||||||
preferred_gateway: Option<IdentityKey>,
|
preferred_gateway: Option<IdentityKey>,
|
||||||
|
|
||||||
storage_passphrase: Option<String>,
|
storage_passphrase: Option<String>,
|
||||||
|
reply_surb_storage_backend: browser_backend::Backend,
|
||||||
|
|
||||||
on_message: js_sys::Function,
|
on_message: js_sys::Function,
|
||||||
|
|
||||||
|
// unimplemented:
|
||||||
|
bandwidth_controller:
|
||||||
|
Option<BandwidthController<FakeClient<DirectSigningNyxdClient>, EphemeralStorage>>,
|
||||||
|
disabled_credentials: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@@ -74,10 +83,15 @@ impl NymClientBuilder {
|
|||||||
storage_passphrase: Option<String>,
|
storage_passphrase: Option<String>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
NymClientBuilder {
|
NymClientBuilder {
|
||||||
|
reply_surb_storage_backend: setup_reply_surb_storage_backend(
|
||||||
|
config.base.debug.reply_surbs,
|
||||||
|
),
|
||||||
config,
|
config,
|
||||||
custom_topology: None,
|
custom_topology: None,
|
||||||
storage_passphrase,
|
storage_passphrase,
|
||||||
on_message,
|
on_message,
|
||||||
|
bandwidth_controller: None,
|
||||||
|
disabled_credentials: true,
|
||||||
preferred_gateway,
|
preferred_gateway,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,9 +114,14 @@ impl NymClientBuilder {
|
|||||||
let full_config = Config::new_tester_config(NODE_TESTER_CLIENT_ID);
|
let full_config = Config::new_tester_config(NODE_TESTER_CLIENT_ID);
|
||||||
|
|
||||||
NymClientBuilder {
|
NymClientBuilder {
|
||||||
|
reply_surb_storage_backend: setup_reply_surb_storage_backend(
|
||||||
|
full_config.base.debug.reply_surbs,
|
||||||
|
),
|
||||||
config: full_config,
|
config: full_config,
|
||||||
custom_topology: Some(topology.into()),
|
custom_topology: Some(topology.into()),
|
||||||
on_message,
|
on_message,
|
||||||
|
bandwidth_controller: None,
|
||||||
|
disabled_credentials: true,
|
||||||
storage_passphrase: None,
|
storage_passphrase: None,
|
||||||
preferred_gateway: gateway,
|
preferred_gateway: gateway,
|
||||||
}
|
}
|
||||||
@@ -120,17 +139,15 @@ impl NymClientBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialise_storage(config: &Config, base_storage: ClientStorage) -> FullWasmClientStorage {
|
|
||||||
FullWasmClientStorage {
|
|
||||||
keys_and_gateway_store: base_storage,
|
|
||||||
reply_storage: setup_reply_surb_storage_backend(config.base.debug.reply_surbs),
|
|
||||||
credential_storage: EphemeralCredentialStorage::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn start_client_async(mut self) -> Result<NymClient, WasmClientError> {
|
async fn start_client_async(mut self) -> Result<NymClient, WasmClientError> {
|
||||||
console_log!("Starting the wasm client");
|
console_log!("Starting the wasm client");
|
||||||
|
|
||||||
|
let disabled_credentials = if self.disabled_credentials {
|
||||||
|
CredentialsToggle::Disabled
|
||||||
|
} else {
|
||||||
|
CredentialsToggle::Enabled
|
||||||
|
};
|
||||||
|
|
||||||
let nym_api_endpoints = self.config.base.client.nym_api_urls.clone();
|
let nym_api_endpoints = self.config.base.client.nym_api_urls.clone();
|
||||||
|
|
||||||
// TODO: this will have to be re-used for surbs. but this is a problem for another PR.
|
// TODO: this will have to be re-used for surbs. but this is a problem for another PR.
|
||||||
@@ -138,25 +155,35 @@ impl NymClientBuilder {
|
|||||||
ClientStorage::new_async(&self.config.base.client.id, self.storage_passphrase.take())
|
ClientStorage::new_async(&self.config.base.client.id, self.storage_passphrase.take())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let user_chosen = self.preferred_gateway.clone();
|
|
||||||
|
|
||||||
// if we provided hardcoded topology, get gateway from it, otherwise get it the 'standard' way
|
// if we provided hardcoded topology, get gateway from it, otherwise get it the 'standard' way
|
||||||
if let Some(topology) = &self.custom_topology {
|
let gateway_endpoint = if let Some(topology) = &self.custom_topology {
|
||||||
setup_from_topology(user_chosen, topology, &client_store).await?
|
gateway_from_topology(
|
||||||
|
&mut thread_rng(),
|
||||||
|
self.preferred_gateway.as_deref(),
|
||||||
|
topology,
|
||||||
|
&client_store,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
} else {
|
} else {
|
||||||
setup_gateway_from_api(&client_store, user_chosen, &nym_api_endpoints).await?
|
choose_gateway(
|
||||||
|
&client_store,
|
||||||
|
self.preferred_gateway.clone(),
|
||||||
|
&nym_api_endpoints,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
};
|
};
|
||||||
|
|
||||||
let packet_type = self.config.base.debug.traffic.packet_type;
|
|
||||||
let storage = Self::initialise_storage(&self.config, client_store);
|
|
||||||
let maybe_topology_provider = self.topology_provider();
|
let maybe_topology_provider = self.topology_provider();
|
||||||
|
|
||||||
let mut base_builder: BaseClientBuilder<_, FullWasmClientStorage> =
|
let mut base_builder: BaseClientBuilder<_, FullWasmClientStorage> = BaseClientBuilder::new(
|
||||||
BaseClientBuilder::<FakeClient<DirectSigningNyxdClient>, _>::new(
|
&gateway_endpoint,
|
||||||
&self.config.base,
|
&self.config.base.debug,
|
||||||
storage,
|
client_store,
|
||||||
None,
|
self.bandwidth_controller,
|
||||||
);
|
self.reply_surb_storage_backend,
|
||||||
|
disabled_credentials,
|
||||||
|
nym_api_endpoints,
|
||||||
|
);
|
||||||
if let Some(topology_provider) = maybe_topology_provider {
|
if let Some(topology_provider) = maybe_topology_provider {
|
||||||
base_builder = base_builder.with_topology_provider(topology_provider);
|
base_builder = base_builder.with_topology_provider(topology_provider);
|
||||||
}
|
}
|
||||||
@@ -175,7 +202,7 @@ impl NymClientBuilder {
|
|||||||
client_state: Arc::new(started_client.client_state),
|
client_state: Arc::new(started_client.client_state),
|
||||||
_full_topology: None,
|
_full_topology: None,
|
||||||
_task_manager: started_client.task_manager,
|
_task_manager: started_client.task_manager,
|
||||||
packet_type,
|
packet_type: self.config.base.debug.traffic.packet_type,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,18 +7,19 @@ use crate::topology::WasmNymTopology;
|
|||||||
use js_sys::Promise;
|
use js_sys::Promise;
|
||||||
use nym_client_core::client::replies::reply_storage::browser_backend;
|
use nym_client_core::client::replies::reply_storage::browser_backend;
|
||||||
use nym_client_core::config;
|
use nym_client_core::config;
|
||||||
use nym_client_core::init::helpers::current_gateways;
|
use nym_client_core::config::GatewayEndpointConfig;
|
||||||
use nym_client_core::init::{setup_gateway_from, GatewaySetup, InitialisationDetails};
|
use nym_client_core::init::GatewaySetup;
|
||||||
|
use nym_crypto::asymmetric::identity;
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
use nym_sphinx::addressing::clients::Recipient;
|
||||||
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
|
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
|
||||||
use nym_topology::{gateway, NymTopology};
|
use nym_topology::NymTopology;
|
||||||
use nym_validator_client::client::IdentityKey;
|
use nym_validator_client::client::{IdentityKey, IdentityKeyRef};
|
||||||
use nym_validator_client::NymApiClient;
|
use nym_validator_client::NymApiClient;
|
||||||
use rand::thread_rng;
|
use rand::{CryptoRng, Rng};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use wasm_bindgen::prelude::wasm_bindgen;
|
use wasm_bindgen::prelude::wasm_bindgen;
|
||||||
use wasm_bindgen_futures::future_to_promise;
|
use wasm_bindgen_futures::future_to_promise;
|
||||||
use wasm_utils::PromisableResult;
|
use wasm_utils::{console_log, PromisableResult};
|
||||||
|
|
||||||
// don't get too excited about the name, under the hood it's just a big fat placeholder
|
// don't get too excited about the name, under the hood it's just a big fat placeholder
|
||||||
// with no disk_persistence
|
// with no disk_persistence
|
||||||
@@ -78,37 +79,87 @@ pub fn current_network_topology(nym_api_url: String) -> Promise {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn setup_gateway(
|
pub(crate) async fn choose_gateway(
|
||||||
client_store: &ClientStorage,
|
|
||||||
chosen_gateway: Option<IdentityKey>,
|
|
||||||
gateways: &[gateway::Node],
|
|
||||||
) -> Result<InitialisationDetails, WasmClientError> {
|
|
||||||
let setup = if client_store.has_full_gateway_info().await? {
|
|
||||||
GatewaySetup::MustLoad
|
|
||||||
} else {
|
|
||||||
GatewaySetup::new_fresh(chosen_gateway.clone(), None)
|
|
||||||
};
|
|
||||||
|
|
||||||
setup_gateway_from(&setup, client_store, client_store, false, Some(gateways))
|
|
||||||
.await
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn setup_gateway_from_api(
|
|
||||||
client_store: &ClientStorage,
|
client_store: &ClientStorage,
|
||||||
chosen_gateway: Option<IdentityKey>,
|
chosen_gateway: Option<IdentityKey>,
|
||||||
nym_apis: &[Url],
|
nym_apis: &[Url],
|
||||||
) -> Result<InitialisationDetails, WasmClientError> {
|
) -> Result<GatewayEndpointConfig, WasmClientError> {
|
||||||
let mut rng = thread_rng();
|
let existing_gateway_config = client_store.read_gateway_config().await?;
|
||||||
let gateways = current_gateways(&mut rng, nym_apis).await?;
|
|
||||||
setup_gateway(client_store, chosen_gateway, &gateways).await
|
console_log!("loaded: {:?}", existing_gateway_config);
|
||||||
|
|
||||||
|
if let Some(existing) = existing_gateway_config {
|
||||||
|
if let Some(provided) = &chosen_gateway {
|
||||||
|
if provided != &existing.gateway_id {
|
||||||
|
return Err(WasmClientError::AlreadyRegistered {
|
||||||
|
gateway_config: existing,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ok(existing);
|
||||||
|
};
|
||||||
|
|
||||||
|
// if NOTHING is specified nor available, choose gateway randomly.
|
||||||
|
let setup = GatewaySetup::new(None, chosen_gateway, None);
|
||||||
|
let config = setup.try_get_gateway_details(nym_apis).await?;
|
||||||
|
|
||||||
|
// perform registration + persist the new gateway info
|
||||||
|
// TODO: this is actually quite bad. we shouldn't be persisting gateway info here since we did not have persisted
|
||||||
|
// the shared key yet. this will only happen when we start the base client itself.
|
||||||
|
// but unfortunately, we can't do much more until we do a bit more refactoring.
|
||||||
|
client_store.store_gateway_config(&config).await?;
|
||||||
|
|
||||||
|
console_log!("stored: {:?}", config);
|
||||||
|
|
||||||
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn setup_from_topology(
|
pub(crate) async fn gateway_from_topology<R: Rng + CryptoRng>(
|
||||||
explicit_gateway: Option<IdentityKey>,
|
rng: &mut R,
|
||||||
|
explicit_gateway: Option<IdentityKeyRef<'_>>,
|
||||||
topology: &NymTopology,
|
topology: &NymTopology,
|
||||||
client_store: &ClientStorage,
|
client_store: &ClientStorage,
|
||||||
) -> Result<InitialisationDetails, WasmClientError> {
|
) -> Result<GatewayEndpointConfig, WasmClientError> {
|
||||||
let gateways = topology.gateways();
|
let existing_gateway_config = client_store.read_gateway_config().await?;
|
||||||
setup_gateway(client_store, explicit_gateway, gateways).await
|
console_log!("loaded: {:?}", existing_gateway_config);
|
||||||
|
|
||||||
|
let new_gateway: GatewayEndpointConfig = if let Some(provided) = explicit_gateway {
|
||||||
|
if let Some(existing) = existing_gateway_config {
|
||||||
|
// we have stored gateway info and explicitly provided identity key
|
||||||
|
//
|
||||||
|
// check if they match, otherwise return an error
|
||||||
|
return if provided != existing.gateway_id {
|
||||||
|
Err(WasmClientError::AlreadyRegistered {
|
||||||
|
gateway_config: existing,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Ok(existing)
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// we have explicitly provided identity key and didn't have any prior stored data
|
||||||
|
//
|
||||||
|
// try to grab details from the topology
|
||||||
|
let gateway_identity = identity::PublicKey::from_base58_string(provided)
|
||||||
|
.map_err(|source| WasmClientError::InvalidGatewayIdentity { source })?;
|
||||||
|
if let Some(gateway) = topology.get_gateway(&gateway_identity) {
|
||||||
|
gateway.clone().into()
|
||||||
|
} else {
|
||||||
|
return Err(WasmClientError::NonExistentGateway {
|
||||||
|
gateway_identity: gateway_identity.to_base58_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let Some(existing) = existing_gateway_config {
|
||||||
|
// we have stored data and didn't provide anything separately - use what's stored!
|
||||||
|
return Ok(existing);
|
||||||
|
} else {
|
||||||
|
// we don't have anything stored nor we have provided anything
|
||||||
|
//
|
||||||
|
// just grab random gateway from our topology
|
||||||
|
topology.random_gateway(rng)?.clone().into()
|
||||||
|
};
|
||||||
|
|
||||||
|
console_log!("storing: {:?}", new_gateway);
|
||||||
|
client_store.store_gateway_config(&new_gateway).await?;
|
||||||
|
Ok(new_gateway)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,6 @@ pub enum ClientStorageError {
|
|||||||
|
|
||||||
#[error("{typ} cryptographic key is not available in storage")]
|
#[error("{typ} cryptographic key is not available in storage")]
|
||||||
CryptoKeyNotInStorage { typ: String },
|
CryptoKeyNotInStorage { typ: String },
|
||||||
|
|
||||||
#[error("the prior gateway details are not available in the storage")]
|
|
||||||
GatewayDetailsNotInStorage,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ClientStorageError> for JsValue {
|
impl From<ClientStorageError> for JsValue {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::client::config::Config;
|
|
||||||
use crate::storage::errors::ClientStorageError;
|
use crate::storage::errors::ClientStorageError;
|
||||||
use js_sys::Promise;
|
use js_sys::Promise;
|
||||||
use nym_client_core::client::base_client::storage::gateway_details::PersistedGatewayDetails;
|
use nym_client_core::config::GatewayEndpointConfig;
|
||||||
use nym_crypto::asymmetric::{encryption, identity};
|
use nym_crypto::asymmetric::{encryption, identity};
|
||||||
use nym_gateway_client::SharedKeys;
|
use nym_gateway_client::SharedKeys;
|
||||||
use nym_sphinx::acknowledgements::AckKey;
|
use nym_sphinx::acknowledgements::AckKey;
|
||||||
@@ -28,8 +27,8 @@ mod v1 {
|
|||||||
pub const CORE_STORE: &str = "core";
|
pub const CORE_STORE: &str = "core";
|
||||||
|
|
||||||
// keys
|
// keys
|
||||||
pub const CONFIG: &str = "config";
|
// TODO: to replace with FULL config
|
||||||
pub const GATEWAY_DETAILS: &str = "gateway_details";
|
pub const GATEWAY_CONFIG: &str = "gateway_config";
|
||||||
|
|
||||||
pub const ED25519_IDENTITY_KEYPAIR: &str = "ed25519_identity_keypair";
|
pub const ED25519_IDENTITY_KEYPAIR: &str = "ed25519_identity_keypair";
|
||||||
pub const X25519_ENCRYPTION_KEYPAIR: &str = "x25519_encryption_keypair";
|
pub const X25519_ENCRYPTION_KEYPAIR: &str = "x25519_encryption_keypair";
|
||||||
@@ -111,32 +110,15 @@ impl ClientStorage {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: persist client's config
|
pub(crate) async fn read_gateway_config(
|
||||||
#[allow(dead_code)]
|
&self,
|
||||||
pub(crate) async fn read_config(&self) -> Result<Option<Config>, ClientStorageError> {
|
) -> Result<Option<GatewayEndpointConfig>, ClientStorageError> {
|
||||||
self.inner
|
self.inner
|
||||||
.read_value(v1::CORE_STORE, JsValue::from_str(v1::CONFIG))
|
.read_value(v1::CORE_STORE, JsValue::from_str(v1::GATEWAY_CONFIG))
|
||||||
.await
|
.await
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn may_read_gateway_details(
|
|
||||||
&self,
|
|
||||||
) -> Result<Option<PersistedGatewayDetails>, ClientStorageError> {
|
|
||||||
self.inner
|
|
||||||
.read_value(v1::CORE_STORE, JsValue::from_str(v1::GATEWAY_DETAILS))
|
|
||||||
.await
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn must_read_gateway_details(
|
|
||||||
&self,
|
|
||||||
) -> Result<PersistedGatewayDetails, ClientStorageError> {
|
|
||||||
self.may_read_gateway_details()
|
|
||||||
.await?
|
|
||||||
.ok_or(ClientStorageError::GatewayDetailsNotInStorage)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn may_read_identity_keypair(
|
async fn may_read_identity_keypair(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<Option<identity::KeyPair>, ClientStorageError> {
|
) -> Result<Option<identity::KeyPair>, ClientStorageError> {
|
||||||
@@ -262,33 +244,17 @@ impl ClientStorage {
|
|||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn store_gateway_details(
|
pub(crate) async fn store_gateway_config(
|
||||||
&self,
|
&self,
|
||||||
gateway_endpoint: &PersistedGatewayDetails,
|
gateway_endpoint: &GatewayEndpointConfig,
|
||||||
) -> Result<(), ClientStorageError> {
|
) -> Result<(), ClientStorageError> {
|
||||||
self.inner
|
self.inner
|
||||||
.store_value(
|
.store_value(
|
||||||
v1::CORE_STORE,
|
v1::CORE_STORE,
|
||||||
JsValue::from_str(v1::GATEWAY_DETAILS),
|
JsValue::from_str(v1::GATEWAY_CONFIG),
|
||||||
gateway_endpoint,
|
gateway_endpoint,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: persist client's config
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub(crate) async fn store_config(&self, config: &Config) -> Result<(), ClientStorageError> {
|
|
||||||
self.inner
|
|
||||||
.store_value(v1::CORE_STORE, JsValue::from_str(v1::CONFIG), config)
|
|
||||||
.await
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn has_full_gateway_info(&self) -> Result<bool, ClientStorageError> {
|
|
||||||
let has_keys = self.may_read_gateway_shared_key().await?.is_some();
|
|
||||||
let has_details = self.may_read_gateway_details().await?.is_some();
|
|
||||||
|
|
||||||
Ok(has_keys && has_details)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,6 @@
|
|||||||
use crate::storage::errors::ClientStorageError;
|
use crate::storage::errors::ClientStorageError;
|
||||||
use crate::storage::ClientStorage;
|
use crate::storage::ClientStorage;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use nym_client_core::client::base_client::storage::gateway_details::{
|
|
||||||
GatewayDetailsStore, PersistedGatewayDetails,
|
|
||||||
};
|
|
||||||
use nym_client_core::client::base_client::storage::MixnetClientStorage;
|
use nym_client_core::client::base_client::storage::MixnetClientStorage;
|
||||||
use nym_client_core::client::key_manager::persistence::KeyStore;
|
use nym_client_core::client::key_manager::persistence::KeyStore;
|
||||||
use nym_client_core::client::key_manager::KeyManager;
|
use nym_client_core::client::key_manager::KeyManager;
|
||||||
@@ -17,9 +14,9 @@ use wasm_utils::console_log;
|
|||||||
// temporary until other variants are properly implemented (probably it should get changed into `ClientStorage`
|
// temporary until other variants are properly implemented (probably it should get changed into `ClientStorage`
|
||||||
// implementing all traits and everything getting combined
|
// implementing all traits and everything getting combined
|
||||||
pub struct FullWasmClientStorage {
|
pub struct FullWasmClientStorage {
|
||||||
pub(crate) keys_and_gateway_store: ClientStorage,
|
key_store: ClientStorage,
|
||||||
pub(crate) reply_storage: browser_backend::Backend,
|
reply_storage: browser_backend::Backend,
|
||||||
pub(crate) credential_storage: EphemeralCredentialStorage,
|
credential_storage: EphemeralCredentialStorage,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MixnetClientStorage for FullWasmClientStorage {
|
impl MixnetClientStorage for FullWasmClientStorage {
|
||||||
@@ -27,14 +24,12 @@ impl MixnetClientStorage for FullWasmClientStorage {
|
|||||||
type ReplyStore = browser_backend::Backend;
|
type ReplyStore = browser_backend::Backend;
|
||||||
type CredentialStore = EphemeralCredentialStorage;
|
type CredentialStore = EphemeralCredentialStorage;
|
||||||
|
|
||||||
type GatewayDetailsStore = ClientStorage;
|
fn into_split(self) -> (Self::KeyStore, Self::ReplyStore, Self::CredentialStore) {
|
||||||
|
(self.key_store, self.reply_storage, self.credential_storage)
|
||||||
fn into_runtime_stores(self) -> (Self::ReplyStore, Self::CredentialStore) {
|
|
||||||
(self.reply_storage, self.credential_storage)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_store(&self) -> &Self::KeyStore {
|
fn key_store(&self) -> &Self::KeyStore {
|
||||||
&self.keys_and_gateway_store
|
&self.key_store
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reply_store(&self) -> &Self::ReplyStore {
|
fn reply_store(&self) -> &Self::ReplyStore {
|
||||||
@@ -44,10 +39,6 @@ impl MixnetClientStorage for FullWasmClientStorage {
|
|||||||
fn credential_store(&self) -> &Self::CredentialStore {
|
fn credential_store(&self) -> &Self::CredentialStore {
|
||||||
&self.credential_storage
|
&self.credential_storage
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gateway_details_store(&self) -> &Self::GatewayDetailsStore {
|
|
||||||
&self.keys_and_gateway_store
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
#[async_trait(?Send)]
|
||||||
@@ -83,19 +74,3 @@ impl KeyStore for ClientStorage {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait(?Send)]
|
|
||||||
impl GatewayDetailsStore for ClientStorage {
|
|
||||||
type StorageError = ClientStorageError;
|
|
||||||
|
|
||||||
async fn load_gateway_details(&self) -> Result<PersistedGatewayDetails, Self::StorageError> {
|
|
||||||
self.must_read_gateway_details().await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn store_gateway_details(
|
|
||||||
&self,
|
|
||||||
details: &PersistedGatewayDetails,
|
|
||||||
) -> Result<(), Self::StorageError> {
|
|
||||||
self.store_gateway_details(details).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,9 +4,6 @@
|
|||||||
// due to expansion of #[wasm_bindgen] macro on NodeTestResult
|
// due to expansion of #[wasm_bindgen] macro on NodeTestResult
|
||||||
#![allow(clippy::drop_non_drop)]
|
#![allow(clippy::drop_non_drop)]
|
||||||
|
|
||||||
use crate::error::WasmClientError;
|
|
||||||
use crate::tester::LockedGatewayClient;
|
|
||||||
use js_sys::Promise;
|
|
||||||
use nym_node_tester_utils::processor::Received;
|
use nym_node_tester_utils::processor::Received;
|
||||||
use nym_node_tester_utils::receiver::ReceivedReceiver;
|
use nym_node_tester_utils::receiver::ReceivedReceiver;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -15,7 +12,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard};
|
use tokio::sync::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen_futures::future_to_promise;
|
|
||||||
use wasm_utils::{console_log, console_warn};
|
use wasm_utils::{console_log, console_warn};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -111,37 +107,3 @@ impl Drop for TestMarker {
|
|||||||
self.value.store(false, Ordering::SeqCst)
|
self.value.store(false, Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait GatewayReconnection {
|
|
||||||
fn disconnect_from_gateway(&self) -> Promise;
|
|
||||||
|
|
||||||
fn reconnect_to_gateway(&self) -> Promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GatewayReconnection for LockedGatewayClient {
|
|
||||||
fn disconnect_from_gateway(&self) -> Promise {
|
|
||||||
let this = self.clone();
|
|
||||||
|
|
||||||
future_to_promise(async move {
|
|
||||||
let mut guard = this.lock().await;
|
|
||||||
guard
|
|
||||||
.disconnect()
|
|
||||||
.await
|
|
||||||
.map_err(|err| JsValue::from(WasmClientError::from(err)))?;
|
|
||||||
Ok(JsValue::undefined())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn reconnect_to_gateway(&self) -> Promise {
|
|
||||||
let this = self.clone();
|
|
||||||
|
|
||||||
future_to_promise(async move {
|
|
||||||
let mut guard = this.lock().await;
|
|
||||||
guard
|
|
||||||
.try_reconnect()
|
|
||||||
.await
|
|
||||||
.map_err(|err| JsValue::from(WasmClientError::from(err)))?;
|
|
||||||
Ok(JsValue::undefined())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
use crate::constants::NODE_TESTER_ID;
|
use crate::constants::NODE_TESTER_ID;
|
||||||
use crate::error::WasmClientError;
|
use crate::error::WasmClientError;
|
||||||
use crate::helpers::{current_network_topology_async, setup_from_topology};
|
use crate::helpers::{current_network_topology_async, gateway_from_topology};
|
||||||
use crate::storage::ClientStorage;
|
use crate::storage::ClientStorage;
|
||||||
use crate::tester::ephemeral_receiver::EphemeralTestReceiver;
|
use crate::tester::ephemeral_receiver::EphemeralTestReceiver;
|
||||||
use crate::tester::helpers::{
|
use crate::tester::helpers::{
|
||||||
GatewayReconnection, NodeTestResult, ReceivedReceiverWrapper, TestMarker, WasmTestMessageExt,
|
NodeTestResult, ReceivedReceiverWrapper, TestMarker, WasmTestMessageExt,
|
||||||
};
|
};
|
||||||
use crate::topology::WasmNymTopology;
|
use crate::topology::WasmNymTopology;
|
||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
@@ -15,7 +15,7 @@ use js_sys::Promise;
|
|||||||
use nym_bandwidth_controller::wasm_mockups::{Client as FakeClient, DirectSigningNyxdClient};
|
use nym_bandwidth_controller::wasm_mockups::{Client as FakeClient, DirectSigningNyxdClient};
|
||||||
use nym_bandwidth_controller::BandwidthController;
|
use nym_bandwidth_controller::BandwidthController;
|
||||||
use nym_client_core::client::key_manager::ManagedKeys;
|
use nym_client_core::client::key_manager::ManagedKeys;
|
||||||
use nym_client_core::init::InitialisationDetails;
|
use nym_client_core::config::GatewayEndpointConfig;
|
||||||
use nym_credential_storage::ephemeral_storage::EphemeralStorage;
|
use nym_credential_storage::ephemeral_storage::EphemeralStorage;
|
||||||
use nym_gateway_client::GatewayClient;
|
use nym_gateway_client::GatewayClient;
|
||||||
use nym_node_tester_utils::receiver::SimpleMessageReceiver;
|
use nym_node_tester_utils::receiver::SimpleMessageReceiver;
|
||||||
@@ -28,6 +28,7 @@ use nym_task::TaskManager;
|
|||||||
use nym_topology::NymTopology;
|
use nym_topology::NymTopology;
|
||||||
use nym_validator_client::client::IdentityKey;
|
use nym_validator_client::client::IdentityKey;
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
|
use rand::{CryptoRng, Rng};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
|
||||||
use std::sync::{Arc, Mutex as SyncMutex};
|
use std::sync::{Arc, Mutex as SyncMutex};
|
||||||
@@ -73,7 +74,6 @@ pub struct NymNodeTester {
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct NymNodeTesterBuilder {
|
pub struct NymNodeTesterBuilder {
|
||||||
gateway: Option<IdentityKey>,
|
gateway: Option<IdentityKey>,
|
||||||
id: Option<String>,
|
|
||||||
|
|
||||||
base_topology: NymTopology,
|
base_topology: NymTopology,
|
||||||
|
|
||||||
@@ -95,11 +95,9 @@ impl NymNodeTesterBuilder {
|
|||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
base_topology: WasmNymTopology,
|
base_topology: WasmNymTopology,
|
||||||
id: Option<String>,
|
|
||||||
gateway: Option<IdentityKey>,
|
gateway: Option<IdentityKey>,
|
||||||
) -> NymNodeTesterBuilder {
|
) -> NymNodeTesterBuilder {
|
||||||
NymNodeTesterBuilder {
|
NymNodeTesterBuilder {
|
||||||
id,
|
|
||||||
gateway,
|
gateway,
|
||||||
base_topology: base_topology.into(),
|
base_topology: base_topology.into(),
|
||||||
bandwidth_controller: None,
|
bandwidth_controller: None,
|
||||||
@@ -108,51 +106,43 @@ impl NymNodeTesterBuilder {
|
|||||||
|
|
||||||
async fn _new_with_api(
|
async fn _new_with_api(
|
||||||
api_url: String,
|
api_url: String,
|
||||||
id: Option<String>,
|
|
||||||
gateway: Option<IdentityKey>,
|
gateway: Option<IdentityKey>,
|
||||||
) -> Result<Self, WasmClientError> {
|
) -> Result<Self, WasmClientError> {
|
||||||
let topology = current_network_topology_async(api_url).await?;
|
let topology = current_network_topology_async(api_url).await?;
|
||||||
Ok(NymNodeTesterBuilder::new(topology, id, gateway))
|
Ok(NymNodeTesterBuilder::new(topology, gateway))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_api(
|
pub fn new_with_api(gateway: Option<IdentityKey>, api_url: String) -> Promise {
|
||||||
api_url: String,
|
|
||||||
id: Option<String>,
|
|
||||||
gateway: Option<IdentityKey>,
|
|
||||||
) -> Promise {
|
|
||||||
future_to_promise(async move {
|
future_to_promise(async move {
|
||||||
Self::_new_with_api(api_url, id, gateway)
|
Self::_new_with_api(api_url, gateway)
|
||||||
.await
|
.await
|
||||||
.into_promise_result()
|
.into_promise_result()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn gateway_info(
|
async fn gateway_info<R: Rng + CryptoRng>(
|
||||||
&self,
|
&self,
|
||||||
|
rng: &mut R,
|
||||||
client_store: &ClientStorage,
|
client_store: &ClientStorage,
|
||||||
) -> Result<InitialisationDetails, WasmClientError> {
|
) -> Result<GatewayEndpointConfig, WasmClientError> {
|
||||||
if let Ok(loaded) = InitialisationDetails::try_load(client_store, client_store).await {
|
gateway_from_topology(
|
||||||
Ok(loaded)
|
rng,
|
||||||
} else {
|
self.gateway.as_deref(),
|
||||||
setup_from_topology(self.gateway.clone(), &self.base_topology, client_store).await
|
&self.base_topology,
|
||||||
}
|
client_store,
|
||||||
|
)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn _setup_client(mut self) -> Result<NymNodeTester, WasmClientError> {
|
async fn _setup_client(mut self) -> Result<NymNodeTester, WasmClientError> {
|
||||||
|
let mut rng = OsRng;
|
||||||
let task_manager = TaskManager::default();
|
let task_manager = TaskManager::default();
|
||||||
|
|
||||||
let storage_id = if let Some(client_id) = &self.id {
|
let client_store = ClientStorage::new_async(NODE_TESTER_ID, None).await?;
|
||||||
format!("{NODE_TESTER_ID}-{client_id}")
|
|
||||||
} else {
|
|
||||||
NODE_TESTER_ID.to_owned()
|
|
||||||
};
|
|
||||||
|
|
||||||
let client_store = ClientStorage::new_async(&storage_id, None).await?;
|
let gateway_endpoint = self.gateway_info(&mut rng, &client_store).await?;
|
||||||
|
|
||||||
let init_details = self.gateway_info(&client_store).await?;
|
|
||||||
let gateway_endpoint = init_details.gateway_details;
|
|
||||||
let gateway_identity = gateway_endpoint.try_get_gateway_identity_key()?;
|
let gateway_identity = gateway_endpoint.try_get_gateway_identity_key()?;
|
||||||
let managed_keys = init_details.managed_keys;
|
let mut managed_keys = ManagedKeys::load_or_generate(&mut rng, &client_store).await;
|
||||||
|
|
||||||
let (mixnet_message_sender, mixnet_message_receiver) = mpsc::unbounded();
|
let (mixnet_message_sender, mixnet_message_receiver) = mpsc::unbounded();
|
||||||
let (ack_sender, ack_receiver) = mpsc::unbounded();
|
let (ack_sender, ack_receiver) = mpsc::unbounded();
|
||||||
@@ -161,7 +151,7 @@ impl NymNodeTesterBuilder {
|
|||||||
gateway_endpoint.gateway_listener,
|
gateway_endpoint.gateway_listener,
|
||||||
managed_keys.identity_keypair(),
|
managed_keys.identity_keypair(),
|
||||||
gateway_identity,
|
gateway_identity,
|
||||||
Some(managed_keys.must_get_gateway_shared_key()),
|
managed_keys.gateway_shared_key(),
|
||||||
mixnet_message_sender,
|
mixnet_message_sender,
|
||||||
ack_sender,
|
ack_sender,
|
||||||
Duration::from_secs(10),
|
Duration::from_secs(10),
|
||||||
@@ -170,11 +160,14 @@ impl NymNodeTesterBuilder {
|
|||||||
);
|
);
|
||||||
|
|
||||||
gateway_client.set_disabled_credentials_mode(true);
|
gateway_client.set_disabled_credentials_mode(true);
|
||||||
gateway_client.authenticate_and_start().await?;
|
let shared_keys = gateway_client.authenticate_and_start().await?;
|
||||||
|
managed_keys
|
||||||
|
.deal_with_gateway_key(shared_keys, &client_store)
|
||||||
|
.await?;
|
||||||
|
|
||||||
// TODO: make those values configurable later
|
// TODO: make those values configurable later
|
||||||
let tester = NodeTester::new(
|
let tester = NodeTester::new(
|
||||||
OsRng,
|
rng,
|
||||||
self.base_topology,
|
self.base_topology,
|
||||||
Some(address(&managed_keys, gateway_identity)),
|
Some(address(&managed_keys, gateway_identity)),
|
||||||
PacketSize::default(),
|
PacketSize::default(),
|
||||||
@@ -248,46 +241,29 @@ async fn test_mixnode(
|
|||||||
impl NymNodeTester {
|
impl NymNodeTester {
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
pub fn new(
|
pub fn new(topology: WasmNymTopology, gateway: Option<IdentityKey>) -> Promise {
|
||||||
topology: WasmNymTopology,
|
|
||||||
id: Option<String>,
|
|
||||||
gateway: Option<IdentityKey>,
|
|
||||||
) -> Promise {
|
|
||||||
console_log!("constructing node tester!");
|
console_log!("constructing node tester!");
|
||||||
NymNodeTesterBuilder::new(topology, id, gateway).setup_client()
|
NymNodeTesterBuilder::new(topology, gateway).setup_client()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn _new_with_api(
|
async fn _new_with_api(
|
||||||
api_url: String,
|
api_url: String,
|
||||||
id: Option<String>,
|
|
||||||
gateway: Option<IdentityKey>,
|
gateway: Option<IdentityKey>,
|
||||||
) -> Result<Self, WasmClientError> {
|
) -> Result<Self, WasmClientError> {
|
||||||
NymNodeTesterBuilder::_new_with_api(api_url, id, gateway)
|
NymNodeTesterBuilder::_new_with_api(api_url, gateway)
|
||||||
.await?
|
.await?
|
||||||
._setup_client()
|
._setup_client()
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_api(
|
pub fn new_with_api(api_url: String, gateway: Option<IdentityKey>) -> Promise {
|
||||||
api_url: String,
|
|
||||||
id: Option<String>,
|
|
||||||
gateway: Option<IdentityKey>,
|
|
||||||
) -> Promise {
|
|
||||||
future_to_promise(async move {
|
future_to_promise(async move {
|
||||||
Self::_new_with_api(api_url, id, gateway)
|
Self::_new_with_api(api_url, gateway)
|
||||||
.await
|
.await
|
||||||
.into_promise_result()
|
.into_promise_result()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disconnect_from_gateway(&self) -> Promise {
|
|
||||||
self.gateway_client.disconnect_from_gateway()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reconnect_to_gateway(&self) -> Promise {
|
|
||||||
self.gateway_client.reconnect_to_gateway()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prepare_test_packets(
|
fn prepare_test_packets(
|
||||||
&self,
|
&self,
|
||||||
mixnode_identity: String,
|
mixnode_identity: String,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-bin-common"
|
name = "nym-bin-common"
|
||||||
version = "0.6.0"
|
version = "0.5.0"
|
||||||
description = "Common code for nym binaries"
|
description = "Common code for nym binaries"
|
||||||
edition = { workspace = true }
|
edition = { workspace = true }
|
||||||
authors = { workspace = true }
|
authors = { workspace = true }
|
||||||
@@ -19,17 +19,11 @@ serde = { workspace = true, features = ["derive"] }
|
|||||||
serde_json = { workspace = true, optional = true }
|
serde_json = { workspace = true, optional = true }
|
||||||
|
|
||||||
## tracing
|
## tracing
|
||||||
|
tracing-appender = { version = "0.2.2", optional = true }
|
||||||
tracing-subscriber = { version = "0.3.16", features = [
|
tracing-subscriber = { version = "0.3.16", features = [
|
||||||
"env-filter",
|
"env-filter",
|
||||||
], optional = true }
|
], optional = true }
|
||||||
tracing-tree = { version = "0.2.2", optional = true }
|
tracing-tree = { version = "0.2.2", optional = true }
|
||||||
opentelemetry-jaeger = { version = "0.18.0", optional = true, features = [
|
|
||||||
"rt-tokio",
|
|
||||||
"collector_client",
|
|
||||||
"isahc_collector_client",
|
|
||||||
] }
|
|
||||||
tracing-opentelemetry = { version = "0.19.0", optional = true }
|
|
||||||
opentelemetry = { version = "0.19.0", optional = true, features = ["rt-tokio"] }
|
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
@@ -43,10 +37,4 @@ vergen = { version = "=7.4.3", default-features = false, features = [
|
|||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
output_format = ["serde_json"]
|
output_format = ["serde_json"]
|
||||||
tracing = [
|
tracing = ["tracing-appender", "tracing-subscriber", "tracing-tree"]
|
||||||
"tracing-subscriber",
|
|
||||||
"tracing-tree",
|
|
||||||
"opentelemetry-jaeger",
|
|
||||||
"tracing-opentelemetry",
|
|
||||||
"opentelemetry",
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ impl BinaryBuildInformation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct BinaryBuildInformationOwned {
|
pub struct BinaryBuildInformationOwned {
|
||||||
// VERGEN_BUILD_TIMESTAMP
|
// VERGEN_BUILD_TIMESTAMP
|
||||||
/// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.
|
/// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.
|
||||||
|
|||||||
@@ -4,11 +4,7 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
pub use opentelemetry;
|
pub use tracing_appender;
|
||||||
#[cfg(feature = "tracing")]
|
|
||||||
pub use opentelemetry_jaeger;
|
|
||||||
#[cfg(feature = "tracing")]
|
|
||||||
pub use tracing_opentelemetry;
|
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
pub use tracing_subscriber;
|
pub use tracing_subscriber;
|
||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
@@ -47,35 +43,27 @@ pub fn setup_logging() {
|
|||||||
#[cfg(feature = "tracing")]
|
#[cfg(feature = "tracing")]
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! setup_tracing {
|
macro_rules! setup_tracing {
|
||||||
($service_name: expr) => {
|
($file_name: expr) => {
|
||||||
use nym_bin_common::logging::tracing_subscriber::layer::SubscriberExt;
|
use nym_bin_common::logging::tracing_subscriber::layer::SubscriberExt;
|
||||||
use nym_bin_common::logging::tracing_subscriber::util::SubscriberInitExt;
|
use nym_bin_common::logging::tracing_subscriber::util::SubscriberInitExt;
|
||||||
|
|
||||||
let registry = nym_bin_common::logging::tracing_subscriber::Registry::default()
|
let file_appender =
|
||||||
|
nym_bin_common::logging::tracing_appender::rolling::hourly($file_name, "log");
|
||||||
|
let (non_blocking, _guard) =
|
||||||
|
nym_bin_common::logging::tracing_appender::non_blocking(file_appender);
|
||||||
|
let appender_layer = nym_bin_common::logging::tracing_subscriber::fmt::Layer::new()
|
||||||
|
.with_ansi(false)
|
||||||
|
.with_writer(non_blocking);
|
||||||
|
|
||||||
|
nym_bin_common::logging::tracing_subscriber::Registry::default()
|
||||||
.with(nym_bin_common::logging::tracing_subscriber::EnvFilter::from_default_env())
|
.with(nym_bin_common::logging::tracing_subscriber::EnvFilter::from_default_env())
|
||||||
|
.with(appender_layer)
|
||||||
.with(
|
.with(
|
||||||
nym_bin_common::logging::tracing_tree::HierarchicalLayer::new(4)
|
nym_bin_common::logging::tracing_tree::HierarchicalLayer::new(4)
|
||||||
.with_targets(true)
|
.with_targets(true)
|
||||||
.with_bracketed_fields(true),
|
.with_bracketed_fields(true),
|
||||||
);
|
|
||||||
|
|
||||||
let tracer = nym_bin_common::logging::opentelemetry_jaeger::new_collector_pipeline()
|
|
||||||
.with_endpoint("http://44.199.230.10:14268/api/traces")
|
|
||||||
.with_service_name($service_name)
|
|
||||||
.with_isahc()
|
|
||||||
.with_trace_config(
|
|
||||||
nym_bin_common::logging::opentelemetry::sdk::trace::config().with_sampler(
|
|
||||||
nym_bin_common::logging::opentelemetry::sdk::trace::Sampler::TraceIdRatioBased(
|
|
||||||
0.1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.install_batch(nym_bin_common::logging::opentelemetry::runtime::Tokio)
|
.init();
|
||||||
.expect("Could not init tracer");
|
|
||||||
|
|
||||||
let telemetry = nym_bin_common::logging::tracing_opentelemetry::layer().with_tracer(tracer);
|
|
||||||
|
|
||||||
registry.with(telemetry).init();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-client-core"
|
name = "nym-client-core"
|
||||||
version = "1.1.15"
|
version = "1.1.14"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.66"
|
rust-version = "1.66"
|
||||||
@@ -9,7 +9,6 @@ rust-version = "1.66"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait = { workspace = true }
|
async-trait = { workspace = true }
|
||||||
base64 = "0.21.2"
|
|
||||||
dirs = "4.0"
|
dirs = "4.0"
|
||||||
dashmap = "5.4.0"
|
dashmap = "5.4.0"
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
@@ -18,7 +17,6 @@ log = { workspace = true }
|
|||||||
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
sha2 = "0.10.6"
|
|
||||||
tap = "1.0.1"
|
tap = "1.0.1"
|
||||||
thiserror = "1.0.34"
|
thiserror = "1.0.34"
|
||||||
url = { version ="2.2", features = ["serde"] }
|
url = { version ="2.2", features = ["serde"] }
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ use nym_sphinx::receiver::{ReconstructedMessage, SphinxMessageReceiver};
|
|||||||
use nym_task::connections::{ConnectionCommandReceiver, ConnectionCommandSender, LaneQueueLengths};
|
use nym_task::connections::{ConnectionCommandReceiver, ConnectionCommandSender, LaneQueueLengths};
|
||||||
use nym_task::{TaskClient, TaskManager};
|
use nym_task::{TaskClient, TaskManager};
|
||||||
use nym_topology::provider_trait::TopologyProvider;
|
use nym_topology::provider_trait::TopologyProvider;
|
||||||
|
use rand::rngs::OsRng;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tap::TapFallible;
|
use tap::TapFallible;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
@@ -49,8 +50,6 @@ use url::Url;
|
|||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use nym_bandwidth_controller::wasm_mockups::DkgQueryClient;
|
use nym_bandwidth_controller::wasm_mockups::DkgQueryClient;
|
||||||
|
|
||||||
use crate::client::base_client::storage::gateway_details::GatewayDetailsStore;
|
|
||||||
use crate::init::{setup_gateway, GatewaySetup, InitialisationDetails};
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use nym_validator_client::nyxd::traits::DkgQueryClient;
|
use nym_validator_client::nyxd::traits::DkgQueryClient;
|
||||||
|
|
||||||
@@ -158,11 +157,17 @@ impl From<bool> for CredentialsToggle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct BaseClientBuilder<'a, C, S: MixnetClientStorage> {
|
pub struct BaseClientBuilder<'a, C, S: MixnetClientStorage> {
|
||||||
config: &'a Config,
|
// due to wasm limitations I had to split it like this : (
|
||||||
client_store: S,
|
gateway_config: &'a GatewayEndpointConfig,
|
||||||
dkg_query_client: Option<C>,
|
debug_config: &'a DebugConfig,
|
||||||
|
disabled_credentials: bool,
|
||||||
|
nym_api_endpoints: Vec<Url>,
|
||||||
|
reply_storage_backend: S::ReplyStore,
|
||||||
|
key_store: S::KeyStore,
|
||||||
|
|
||||||
custom_topology_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
|
custom_topology_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
|
||||||
setup_method: GatewaySetup,
|
bandwidth_controller: Option<BandwidthController<C, S::CredentialStore>>,
|
||||||
|
managed_keys: ManagedKeys,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C, S> BaseClientBuilder<'a, C, S>
|
impl<'a, C, S> BaseClientBuilder<'a, C, S>
|
||||||
@@ -170,23 +175,47 @@ where
|
|||||||
S: MixnetClientStorage + 'static,
|
S: MixnetClientStorage + 'static,
|
||||||
C: DkgQueryClient + Send + Sync + 'static,
|
C: DkgQueryClient + Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
pub fn new(
|
// TODO: combine all storages
|
||||||
|
pub fn new_from_base_config(
|
||||||
base_config: &'a Config,
|
base_config: &'a Config,
|
||||||
client_store: S,
|
key_store: S::KeyStore,
|
||||||
dkg_query_client: Option<C>,
|
bandwidth_controller: Option<BandwidthController<C, S::CredentialStore>>,
|
||||||
|
reply_storage_backend: S::ReplyStore,
|
||||||
) -> BaseClientBuilder<'a, C, S> {
|
) -> BaseClientBuilder<'a, C, S> {
|
||||||
BaseClientBuilder {
|
BaseClientBuilder {
|
||||||
config: base_config,
|
gateway_config: base_config.get_gateway_endpoint_config(),
|
||||||
client_store,
|
debug_config: &base_config.debug,
|
||||||
dkg_query_client,
|
disabled_credentials: base_config.get_disabled_credentials_mode(),
|
||||||
|
nym_api_endpoints: base_config.get_nym_api_endpoints(),
|
||||||
|
bandwidth_controller,
|
||||||
|
reply_storage_backend,
|
||||||
|
key_store,
|
||||||
|
managed_keys: ManagedKeys::Invalidated,
|
||||||
custom_topology_provider: None,
|
custom_topology_provider: None,
|
||||||
setup_method: GatewaySetup::MustLoad,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_gateway_setup(mut self, setup: GatewaySetup) -> Self {
|
// TODO: combine all storages
|
||||||
self.setup_method = setup;
|
pub fn new(
|
||||||
self
|
gateway_config: &'a GatewayEndpointConfig,
|
||||||
|
debug_config: &'a DebugConfig,
|
||||||
|
key_store: S::KeyStore,
|
||||||
|
bandwidth_controller: Option<BandwidthController<C, S::CredentialStore>>,
|
||||||
|
reply_storage_backend: S::ReplyStore,
|
||||||
|
credentials_toggle: CredentialsToggle,
|
||||||
|
nym_api_endpoints: Vec<Url>,
|
||||||
|
) -> BaseClientBuilder<'a, C, S> {
|
||||||
|
BaseClientBuilder {
|
||||||
|
gateway_config,
|
||||||
|
debug_config,
|
||||||
|
disabled_credentials: credentials_toggle.is_disabled(),
|
||||||
|
nym_api_endpoints,
|
||||||
|
reply_storage_backend,
|
||||||
|
custom_topology_provider: None,
|
||||||
|
bandwidth_controller,
|
||||||
|
key_store,
|
||||||
|
managed_keys: ManagedKeys::Invalidated,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_topology_provider(
|
pub fn with_topology_provider(
|
||||||
@@ -199,16 +228,13 @@ where
|
|||||||
|
|
||||||
// note: do **NOT** make this method public as its only valid usage is from within `start_base`
|
// note: do **NOT** make this method public as its only valid usage is from within `start_base`
|
||||||
// because it relies on the crypto keys being already loaded
|
// because it relies on the crypto keys being already loaded
|
||||||
fn mix_address(
|
fn as_mix_recipient(&self) -> Recipient {
|
||||||
managed_keys: &ManagedKeys,
|
|
||||||
gateway_config: &GatewayEndpointConfig,
|
|
||||||
) -> Recipient {
|
|
||||||
Recipient::new(
|
Recipient::new(
|
||||||
*managed_keys.identity_public_key(),
|
*self.managed_keys.identity_public_key(),
|
||||||
*managed_keys.encryption_public_key(),
|
*self.managed_keys.encryption_public_key(),
|
||||||
// TODO: below only works under assumption that gateway address == gateway id
|
// TODO: below only works under assumption that gateway address == gateway id
|
||||||
// (which currently is true)
|
// (which currently is true)
|
||||||
NodeIdentity::from_base58_string(&gateway_config.gateway_id).unwrap(),
|
NodeIdentity::from_base58_string(&self.gateway_config.gateway_id).unwrap(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,10 +318,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn start_gateway_client(
|
async fn start_gateway_client(
|
||||||
config: &Config,
|
&mut self,
|
||||||
gateway_config: GatewayEndpointConfig,
|
|
||||||
managed_keys: &ManagedKeys,
|
|
||||||
bandwidth_controller: Option<BandwidthController<C, S::CredentialStore>>,
|
|
||||||
mixnet_message_sender: MixnetMessageSender,
|
mixnet_message_sender: MixnetMessageSender,
|
||||||
ack_sender: AcknowledgementSender,
|
ack_sender: AcknowledgementSender,
|
||||||
shutdown: TaskClient,
|
shutdown: TaskClient,
|
||||||
@@ -304,26 +327,33 @@ where
|
|||||||
<S::KeyStore as KeyStore>::StorageError: Send + Sync + 'static,
|
<S::KeyStore as KeyStore>::StorageError: Send + Sync + 'static,
|
||||||
<S::CredentialStore as CredentialStorage>::StorageError: Send + Sync + 'static,
|
<S::CredentialStore as CredentialStorage>::StorageError: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
let gateway_address = gateway_config.gateway_listener.clone();
|
let gateway_id = self.gateway_config.gateway_id.clone();
|
||||||
let gateway_id = gateway_config.gateway_id;
|
if gateway_id.is_empty() {
|
||||||
|
return Err(ClientCoreError::GatewayIdUnknown);
|
||||||
|
}
|
||||||
|
let gateway_address = self.gateway_config.gateway_listener.clone();
|
||||||
|
if gateway_address.is_empty() {
|
||||||
|
return Err(ClientCoreError::GatewayAddressUnknown);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: in theory, at this point, this should be infallible
|
|
||||||
let gateway_identity = identity::PublicKey::from_base58_string(gateway_id)
|
let gateway_identity = identity::PublicKey::from_base58_string(gateway_id)
|
||||||
.map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?;
|
.map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?;
|
||||||
|
|
||||||
let mut gateway_client = GatewayClient::new(
|
let mut gateway_client = GatewayClient::new(
|
||||||
gateway_address,
|
gateway_address,
|
||||||
managed_keys.identity_keypair(),
|
self.managed_keys.identity_keypair(),
|
||||||
gateway_identity,
|
gateway_identity,
|
||||||
Some(managed_keys.must_get_gateway_shared_key()),
|
self.managed_keys.gateway_shared_key(),
|
||||||
mixnet_message_sender,
|
mixnet_message_sender,
|
||||||
ack_sender,
|
ack_sender,
|
||||||
config.debug.gateway_connection.gateway_response_timeout,
|
self.debug_config
|
||||||
bandwidth_controller,
|
.gateway_connection
|
||||||
|
.gateway_response_timeout,
|
||||||
|
self.bandwidth_controller.take(),
|
||||||
shutdown,
|
shutdown,
|
||||||
);
|
);
|
||||||
|
|
||||||
gateway_client.set_disabled_credentials_mode(config.client.disabled_credentials_mode);
|
gateway_client.set_disabled_credentials_mode(self.disabled_credentials);
|
||||||
|
|
||||||
let shared_key = gateway_client
|
let shared_key = gateway_client
|
||||||
.authenticate_and_start()
|
.authenticate_and_start()
|
||||||
@@ -332,7 +362,12 @@ where
|
|||||||
log::error!("Could not authenticate and start up the gateway connection - {err}")
|
log::error!("Could not authenticate and start up the gateway connection - {err}")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
managed_keys.ensure_gateway_key(shared_key);
|
self.managed_keys
|
||||||
|
.deal_with_gateway_key(shared_key, &self.key_store)
|
||||||
|
.await
|
||||||
|
.map_err(|source| ClientCoreError::KeyStoreError {
|
||||||
|
source: Box::new(source),
|
||||||
|
})?;
|
||||||
|
|
||||||
Ok(gateway_client)
|
Ok(gateway_client)
|
||||||
}
|
}
|
||||||
@@ -438,41 +473,21 @@ where
|
|||||||
Ok(mem_store)
|
Ok(mem_store)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn initialise_keys_and_gateway(&self) -> Result<InitialisationDetails, ClientCoreError>
|
async fn initial_key_setup(&mut self) {
|
||||||
where
|
assert!(!self.managed_keys.is_valid());
|
||||||
<S::KeyStore as KeyStore>::StorageError: Sync + Send,
|
let mut rng = OsRng;
|
||||||
<S::GatewayDetailsStore as GatewayDetailsStore>::StorageError: Sync + Send,
|
self.managed_keys = ManagedKeys::load_or_generate(&mut rng, &self.key_store).await;
|
||||||
{
|
|
||||||
setup_gateway(
|
|
||||||
&self.setup_method,
|
|
||||||
self.client_store.key_store(),
|
|
||||||
self.client_store.gateway_details_store(),
|
|
||||||
false,
|
|
||||||
Some(&self.config.client.nym_api_urls),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start_base(mut self) -> Result<BaseClient, ClientCoreError>
|
pub async fn start_base(mut self) -> Result<BaseClient, ClientCoreError>
|
||||||
where
|
where
|
||||||
|
<S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send,
|
||||||
S::ReplyStore: Send + Sync,
|
S::ReplyStore: Send + Sync,
|
||||||
<S::KeyStore as KeyStore>::StorageError: Send + Sync,
|
<S::KeyStore as KeyStore>::StorageError: Send + Sync,
|
||||||
<S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send,
|
|
||||||
<S::CredentialStore as CredentialStorage>::StorageError: Send + Sync + 'static,
|
<S::CredentialStore as CredentialStorage>::StorageError: Send + Sync + 'static,
|
||||||
<S::GatewayDetailsStore as GatewayDetailsStore>::StorageError: Sync + Send,
|
|
||||||
{
|
{
|
||||||
info!("Starting nym client");
|
info!("Starting nym client");
|
||||||
|
self.initial_key_setup().await;
|
||||||
// derive (or load) client keys and gateway configuration
|
|
||||||
let details = self.initialise_keys_and_gateway().await?;
|
|
||||||
let gateway_config = details.gateway_details;
|
|
||||||
let managed_keys = details.managed_keys;
|
|
||||||
|
|
||||||
let (reply_storage_backend, credential_store) = self.client_store.into_runtime_stores();
|
|
||||||
|
|
||||||
let bandwidth_controller = self
|
|
||||||
.dkg_query_client
|
|
||||||
.map(|client| BandwidthController::new(credential_store, client));
|
|
||||||
|
|
||||||
// channels for inter-component communication
|
// channels for inter-component communication
|
||||||
// TODO: make the channels be internally created by the relevant components
|
// TODO: make the channels be internally created by the relevant components
|
||||||
@@ -500,39 +515,34 @@ where
|
|||||||
let (reply_controller_sender, reply_controller_receiver) =
|
let (reply_controller_sender, reply_controller_receiver) =
|
||||||
reply_controller::requests::new_control_channels();
|
reply_controller::requests::new_control_channels();
|
||||||
|
|
||||||
let self_address = Self::mix_address(&managed_keys, &gateway_config);
|
let self_address = self.as_mix_recipient();
|
||||||
|
|
||||||
// the components are started in very specific order. Unless you know what you are doing,
|
// the components are started in very specific order. Unless you know what you are doing,
|
||||||
// do not change that.
|
// do not change that.
|
||||||
let gateway_client = Self::start_gateway_client(
|
let gateway_client = self
|
||||||
self.config,
|
.start_gateway_client(mixnet_messages_sender, ack_sender, task_manager.subscribe())
|
||||||
gateway_config,
|
.await?;
|
||||||
&managed_keys,
|
|
||||||
bandwidth_controller,
|
let reply_storage = Self::setup_persistent_reply_storage(
|
||||||
mixnet_messages_sender,
|
self.reply_storage_backend,
|
||||||
ack_sender,
|
|
||||||
task_manager.subscribe(),
|
task_manager.subscribe(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let reply_storage =
|
|
||||||
Self::setup_persistent_reply_storage(reply_storage_backend, task_manager.subscribe())
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let topology_provider = Self::setup_topology_provider(
|
let topology_provider = Self::setup_topology_provider(
|
||||||
self.custom_topology_provider.take(),
|
self.custom_topology_provider.take(),
|
||||||
self.config.get_nym_api_endpoints(),
|
self.nym_api_endpoints,
|
||||||
);
|
);
|
||||||
Self::start_topology_refresher(
|
Self::start_topology_refresher(
|
||||||
topology_provider,
|
topology_provider,
|
||||||
self.config.debug.topology,
|
self.debug_config.topology,
|
||||||
shared_topology_accessor.clone(),
|
shared_topology_accessor.clone(),
|
||||||
task_manager.subscribe(),
|
task_manager.subscribe(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Self::start_received_messages_buffer_controller(
|
Self::start_received_messages_buffer_controller(
|
||||||
managed_keys.encryption_keypair(),
|
self.managed_keys.encryption_keypair(),
|
||||||
received_buffer_request_receiver,
|
received_buffer_request_receiver,
|
||||||
mixnet_messages_receiver,
|
mixnet_messages_receiver,
|
||||||
reply_storage.key_storage(),
|
reply_storage.key_storage(),
|
||||||
@@ -556,8 +566,8 @@ where
|
|||||||
let shared_lane_queue_lengths = LaneQueueLengths::new();
|
let shared_lane_queue_lengths = LaneQueueLengths::new();
|
||||||
|
|
||||||
let controller_config = real_messages_control::Config::new(
|
let controller_config = real_messages_control::Config::new(
|
||||||
&self.config.debug,
|
self.debug_config,
|
||||||
managed_keys.ack_key(),
|
self.managed_keys.ack_key(),
|
||||||
self_address,
|
self_address,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -573,18 +583,17 @@ where
|
|||||||
shared_lane_queue_lengths.clone(),
|
shared_lane_queue_lengths.clone(),
|
||||||
client_connection_rx,
|
client_connection_rx,
|
||||||
task_manager.subscribe(),
|
task_manager.subscribe(),
|
||||||
self.config.debug.traffic.packet_type,
|
self.debug_config.traffic.packet_type,
|
||||||
);
|
);
|
||||||
|
|
||||||
if !self
|
if !self
|
||||||
.config
|
.debug_config
|
||||||
.debug
|
|
||||||
.cover_traffic
|
.cover_traffic
|
||||||
.disable_loop_cover_traffic_stream
|
.disable_loop_cover_traffic_stream
|
||||||
{
|
{
|
||||||
Self::start_cover_traffic_stream(
|
Self::start_cover_traffic_stream(
|
||||||
&self.config.debug,
|
self.debug_config,
|
||||||
managed_keys.ack_key(),
|
self.managed_keys.ack_key(),
|
||||||
self_address,
|
self_address,
|
||||||
shared_topology_accessor.clone(),
|
shared_topology_accessor.clone(),
|
||||||
message_sender,
|
message_sender,
|
||||||
|
|||||||
@@ -122,30 +122,13 @@ pub fn create_bandwidth_controller_with_urls<St: CredentialStorage>(
|
|||||||
nym_api_url: Url,
|
nym_api_url: Url,
|
||||||
storage: St,
|
storage: St,
|
||||||
) -> BandwidthController<Client<QueryNyxdClient>, St> {
|
) -> BandwidthController<Client<QueryNyxdClient>, St> {
|
||||||
let client = default_query_dkg_client(nyxd_url, nym_api_url);
|
|
||||||
|
|
||||||
BandwidthController::new(storage, client)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_query_dkg_client_from_config(config: &Config) -> Client<QueryNyxdClient> {
|
|
||||||
let nyxd_url = config
|
|
||||||
.get_validator_endpoints()
|
|
||||||
.pop()
|
|
||||||
.expect("No nyxd validator endpoint provided");
|
|
||||||
let api_url = config
|
|
||||||
.get_nym_api_endpoints()
|
|
||||||
.pop()
|
|
||||||
.expect("No validator api endpoint provided");
|
|
||||||
|
|
||||||
default_query_dkg_client(nyxd_url, api_url)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_query_dkg_client(nyxd_url: Url, nym_api_url: Url) -> Client<QueryNyxdClient> {
|
|
||||||
let details = nym_network_defaults::NymNetworkDetails::new_from_env();
|
let details = nym_network_defaults::NymNetworkDetails::new_from_env();
|
||||||
let mut client_config = nym_validator_client::Config::try_from_nym_network_details(&details)
|
let mut client_config = nym_validator_client::Config::try_from_nym_network_details(&details)
|
||||||
.expect("failed to construct validator client config");
|
.expect("failed to construct validator client config");
|
||||||
// overwrite env configuration with config URLs
|
// overwrite env configuration with config URLs
|
||||||
client_config = client_config.with_urls(nyxd_url, nym_api_url);
|
client_config = client_config.with_urls(nyxd_url, nym_api_url);
|
||||||
nym_validator_client::Client::new_query(client_config)
|
let client = nym_validator_client::Client::new_query(client_config)
|
||||||
.expect("Could not construct query client")
|
.expect("Could not construct query client");
|
||||||
|
|
||||||
|
BandwidthController::new(storage, client)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,201 +0,0 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::config::GatewayEndpointConfig;
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use nym_gateway_requests::registration::handshake::SharedKeys;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use sha2::{Digest, Sha256};
|
|
||||||
use std::error::Error;
|
|
||||||
use std::ops::Deref;
|
|
||||||
use tokio::sync::Mutex;
|
|
||||||
use zeroize::Zeroizing;
|
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
|
||||||
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
|
|
||||||
pub trait GatewayDetailsStore {
|
|
||||||
type StorageError: Error;
|
|
||||||
|
|
||||||
async fn load_gateway_details(&self) -> Result<PersistedGatewayDetails, Self::StorageError>;
|
|
||||||
|
|
||||||
async fn store_gateway_details(
|
|
||||||
&self,
|
|
||||||
details: &PersistedGatewayDetails,
|
|
||||||
) -> Result<(), Self::StorageError>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub struct PersistedGatewayDetails {
|
|
||||||
// TODO: should we also verify correctness of the details themselves?
|
|
||||||
// i.e. we could include a checksum or tag (via the shared keys)
|
|
||||||
// counterargument: if we wanted to modify, say, the host information in the stored file on disk,
|
|
||||||
// in order to actually use it, we'd have to recompute the whole checksum which would be a huge pain.
|
|
||||||
/// The hash of the shared keys to ensure the correct ones are used with those gateway details.
|
|
||||||
#[serde(with = "base64")]
|
|
||||||
key_hash: Vec<u8>,
|
|
||||||
|
|
||||||
/// Actual gateway details being persisted.
|
|
||||||
pub(crate) details: GatewayEndpointConfig,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<PersistedGatewayDetails> for GatewayEndpointConfig {
|
|
||||||
fn from(value: PersistedGatewayDetails) -> Self {
|
|
||||||
value.details
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PersistedGatewayDetails {
|
|
||||||
pub fn new(details: GatewayEndpointConfig, shared_key: &SharedKeys) -> Self {
|
|
||||||
let key_bytes = Zeroizing::new(shared_key.to_bytes());
|
|
||||||
|
|
||||||
let mut key_hasher = Sha256::new();
|
|
||||||
key_hasher.update(&key_bytes);
|
|
||||||
let key_hash = key_hasher.finalize().to_vec();
|
|
||||||
|
|
||||||
PersistedGatewayDetails { key_hash, details }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn verify(&self, shared_key: &SharedKeys) -> bool {
|
|
||||||
let key_bytes = Zeroizing::new(shared_key.to_bytes());
|
|
||||||
|
|
||||||
let mut key_hasher = Sha256::new();
|
|
||||||
key_hasher.update(&key_bytes);
|
|
||||||
let key_hash = key_hasher.finalize();
|
|
||||||
|
|
||||||
self.key_hash == key_hash.deref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper to make Vec<u8> serialization use base64 representation to make it human readable
|
|
||||||
// so that it would be easier for users to copy contents from the disk if they wanted to use it elsewhere
|
|
||||||
mod base64 {
|
|
||||||
use base64::{engine::general_purpose::STANDARD, Engine as _};
|
|
||||||
use serde::{Deserialize, Deserializer, Serializer};
|
|
||||||
|
|
||||||
pub fn serialize<S: Serializer>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
|
|
||||||
serializer.serialize_str(&STANDARD.encode(bytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
|
|
||||||
let s = <String>::deserialize(deserializer)?;
|
|
||||||
STANDARD.decode(s).map_err(serde::de::Error::custom)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
|
||||||
pub enum OnDiskGatewayDetailsError {
|
|
||||||
#[error("JSON failure: {0}")]
|
|
||||||
SerializationFailure(#[from] serde_json::Error),
|
|
||||||
|
|
||||||
#[error("failed to store gateway details to {path}: {err}")]
|
|
||||||
StoreFailure {
|
|
||||||
path: String,
|
|
||||||
#[source]
|
|
||||||
err: std::io::Error,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[error("failed to load gateway details from {path}: {err}")]
|
|
||||||
LoadFailure {
|
|
||||||
path: String,
|
|
||||||
#[source]
|
|
||||||
err: std::io::Error,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
pub struct OnDiskGatewayDetails {
|
|
||||||
file_location: std::path::PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
impl OnDiskGatewayDetails {
|
|
||||||
pub fn new<P: AsRef<std::path::Path>>(path: P) -> Self {
|
|
||||||
OnDiskGatewayDetails {
|
|
||||||
file_location: path.as_ref().to_owned(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_from_disk(&self) -> Result<PersistedGatewayDetails, OnDiskGatewayDetailsError> {
|
|
||||||
let file = std::fs::File::open(&self.file_location).map_err(|err| {
|
|
||||||
OnDiskGatewayDetailsError::LoadFailure {
|
|
||||||
path: self.file_location.display().to_string(),
|
|
||||||
err,
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(serde_json::from_reader(file)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn store_to_disk(
|
|
||||||
&self,
|
|
||||||
details: &PersistedGatewayDetails,
|
|
||||||
) -> Result<(), OnDiskGatewayDetailsError> {
|
|
||||||
// ensure the whole directory structure exists
|
|
||||||
if let Some(parent_dir) = &self.file_location.parent() {
|
|
||||||
std::fs::create_dir_all(parent_dir).map_err(|err| {
|
|
||||||
OnDiskGatewayDetailsError::StoreFailure {
|
|
||||||
path: self.file_location.display().to_string(),
|
|
||||||
err,
|
|
||||||
}
|
|
||||||
})?
|
|
||||||
}
|
|
||||||
|
|
||||||
let file = std::fs::File::create(&self.file_location).map_err(|err| {
|
|
||||||
OnDiskGatewayDetailsError::StoreFailure {
|
|
||||||
path: self.file_location.display().to_string(),
|
|
||||||
err,
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(serde_json::to_writer_pretty(file, details)?)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
|
|
||||||
impl GatewayDetailsStore for OnDiskGatewayDetails {
|
|
||||||
type StorageError = OnDiskGatewayDetailsError;
|
|
||||||
|
|
||||||
async fn load_gateway_details(&self) -> Result<PersistedGatewayDetails, Self::StorageError> {
|
|
||||||
self.load_from_disk()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn store_gateway_details(
|
|
||||||
&self,
|
|
||||||
gateway_details: &PersistedGatewayDetails,
|
|
||||||
) -> Result<(), Self::StorageError> {
|
|
||||||
self.store_to_disk(gateway_details)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct InMemGatewayDetails {
|
|
||||||
details: Mutex<Option<PersistedGatewayDetails>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
|
||||||
#[error("old ephemeral gateway details can't be loaded from storage")]
|
|
||||||
pub struct EphemeralGatewayDetailsError;
|
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
|
||||||
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
|
|
||||||
impl GatewayDetailsStore for InMemGatewayDetails {
|
|
||||||
type StorageError = EphemeralGatewayDetailsError;
|
|
||||||
|
|
||||||
async fn load_gateway_details(&self) -> Result<PersistedGatewayDetails, Self::StorageError> {
|
|
||||||
self.details
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.clone()
|
|
||||||
.ok_or(EphemeralGatewayDetailsError)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn store_gateway_details(
|
|
||||||
&self,
|
|
||||||
gateway_details: &PersistedGatewayDetails,
|
|
||||||
) -> Result<(), Self::StorageError> {
|
|
||||||
*self.details.lock().await = Some(gateway_details.clone());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,20 +4,17 @@
|
|||||||
// TODO: combine those more closely. Perhaps into a single underlying store.
|
// TODO: combine those more closely. Perhaps into a single underlying store.
|
||||||
// Like for persistent, on-disk, storage, what's the point of having 3 different databases?
|
// Like for persistent, on-disk, storage, what's the point of having 3 different databases?
|
||||||
|
|
||||||
use crate::client::base_client::storage::gateway_details::{
|
|
||||||
GatewayDetailsStore, InMemGatewayDetails,
|
|
||||||
};
|
|
||||||
use crate::client::key_manager::persistence::{InMemEphemeralKeys, KeyStore};
|
use crate::client::key_manager::persistence::{InMemEphemeralKeys, KeyStore};
|
||||||
use crate::client::replies::reply_storage;
|
use crate::client::replies::reply_storage;
|
||||||
use crate::client::replies::reply_storage::ReplyStorageBackend;
|
use crate::client::replies::reply_storage::ReplyStorageBackend;
|
||||||
use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage;
|
use nym_credential_storage::ephemeral_storage::{
|
||||||
|
EphemeralStorage as EphemeralCredentialStorage, EphemeralStorage,
|
||||||
|
};
|
||||||
use nym_credential_storage::storage::Storage as CredentialStorage;
|
use nym_credential_storage::storage::Storage as CredentialStorage;
|
||||||
|
|
||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||||
use crate::client::base_client::non_wasm_helpers;
|
use crate::client::base_client::non_wasm_helpers;
|
||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||||
use crate::client::base_client::storage::gateway_details::OnDiskGatewayDetails;
|
|
||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
|
||||||
use crate::client::key_manager::persistence::OnDiskKeys;
|
use crate::client::key_manager::persistence::OnDiskKeys;
|
||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||||
use crate::client::replies::reply_storage::fs_backend;
|
use crate::client::replies::reply_storage::fs_backend;
|
||||||
@@ -28,33 +25,24 @@ use crate::error::ClientCoreError;
|
|||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||||
use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage;
|
use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage;
|
||||||
|
|
||||||
pub mod gateway_details;
|
|
||||||
|
|
||||||
// TODO: ideally this should be changed into
|
|
||||||
// `MixnetClientStorage: KeyStore + ReplyStorageBackend + CredentialStorage + GatewayDetailsStore`
|
|
||||||
pub trait MixnetClientStorage {
|
pub trait MixnetClientStorage {
|
||||||
type KeyStore: KeyStore;
|
type KeyStore: KeyStore;
|
||||||
type ReplyStore: ReplyStorageBackend;
|
type ReplyStore: ReplyStorageBackend;
|
||||||
type CredentialStore: CredentialStorage;
|
type CredentialStore: CredentialStorage;
|
||||||
type GatewayDetailsStore: GatewayDetailsStore;
|
|
||||||
|
|
||||||
// this is a TERRIBLE name...
|
// this is a TERRIBLE name...
|
||||||
// fn into_split(self) -> (Self::KeyStore, Self::ReplyStore, Self::CredentialStore, Self::GatewayDetailsStore);
|
fn into_split(self) -> (Self::KeyStore, Self::ReplyStore, Self::CredentialStore);
|
||||||
|
|
||||||
fn into_runtime_stores(self) -> (Self::ReplyStore, Self::CredentialStore);
|
|
||||||
|
|
||||||
fn key_store(&self) -> &Self::KeyStore;
|
fn key_store(&self) -> &Self::KeyStore;
|
||||||
fn reply_store(&self) -> &Self::ReplyStore;
|
fn reply_store(&self) -> &Self::ReplyStore;
|
||||||
fn credential_store(&self) -> &Self::CredentialStore;
|
fn credential_store(&self) -> &Self::CredentialStore;
|
||||||
fn gateway_details_store(&self) -> &Self::GatewayDetailsStore;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Ephemeral {
|
pub struct Ephemeral {
|
||||||
key_store: InMemEphemeralKeys,
|
key_store: InMemEphemeralKeys,
|
||||||
reply_store: reply_storage::Empty,
|
reply_store: reply_storage::Empty,
|
||||||
credential_store: EphemeralCredentialStorage,
|
credential_store: EphemeralStorage,
|
||||||
gateway_details_store: InMemGatewayDetails,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ephemeral {
|
impl Ephemeral {
|
||||||
@@ -67,10 +55,9 @@ impl MixnetClientStorage for Ephemeral {
|
|||||||
type KeyStore = InMemEphemeralKeys;
|
type KeyStore = InMemEphemeralKeys;
|
||||||
type ReplyStore = reply_storage::Empty;
|
type ReplyStore = reply_storage::Empty;
|
||||||
type CredentialStore = EphemeralCredentialStorage;
|
type CredentialStore = EphemeralCredentialStorage;
|
||||||
type GatewayDetailsStore = InMemGatewayDetails;
|
|
||||||
|
|
||||||
fn into_runtime_stores(self) -> (Self::ReplyStore, Self::CredentialStore) {
|
fn into_split(self) -> (Self::KeyStore, Self::ReplyStore, Self::CredentialStore) {
|
||||||
(self.reply_store, self.credential_store)
|
(self.key_store, self.reply_store, self.credential_store)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_store(&self) -> &Self::KeyStore {
|
fn key_store(&self) -> &Self::KeyStore {
|
||||||
@@ -84,10 +71,6 @@ impl MixnetClientStorage for Ephemeral {
|
|||||||
fn credential_store(&self) -> &Self::CredentialStore {
|
fn credential_store(&self) -> &Self::CredentialStore {
|
||||||
&self.credential_store
|
&self.credential_store
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gateway_details_store(&self) -> &Self::GatewayDetailsStore {
|
|
||||||
&self.gateway_details_store
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||||
@@ -95,7 +78,6 @@ pub struct OnDiskPersistent {
|
|||||||
pub(crate) key_store: OnDiskKeys,
|
pub(crate) key_store: OnDiskKeys,
|
||||||
pub(crate) reply_store: fs_backend::Backend,
|
pub(crate) reply_store: fs_backend::Backend,
|
||||||
pub(crate) credential_store: PersistentCredentialStorage,
|
pub(crate) credential_store: PersistentCredentialStorage,
|
||||||
pub(crate) gateway_details_store: OnDiskGatewayDetails,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||||
@@ -104,13 +86,11 @@ impl OnDiskPersistent {
|
|||||||
key_store: OnDiskKeys,
|
key_store: OnDiskKeys,
|
||||||
reply_store: fs_backend::Backend,
|
reply_store: fs_backend::Backend,
|
||||||
credential_store: PersistentCredentialStorage,
|
credential_store: PersistentCredentialStorage,
|
||||||
gateway_details_store: OnDiskGatewayDetails,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
key_store,
|
key_store,
|
||||||
reply_store,
|
reply_store,
|
||||||
credential_store,
|
credential_store,
|
||||||
gateway_details_store,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,13 +109,10 @@ impl OnDiskPersistent {
|
|||||||
let credential_store =
|
let credential_store =
|
||||||
nym_credential_storage::initialise_persistent_storage(paths.credentials_database).await;
|
nym_credential_storage::initialise_persistent_storage(paths.credentials_database).await;
|
||||||
|
|
||||||
let gateway_details_store = OnDiskGatewayDetails::new(paths.gateway_details);
|
|
||||||
|
|
||||||
Ok(OnDiskPersistent {
|
Ok(OnDiskPersistent {
|
||||||
key_store,
|
key_store,
|
||||||
reply_store,
|
reply_store,
|
||||||
credential_store,
|
credential_store,
|
||||||
gateway_details_store,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,10 +122,9 @@ impl MixnetClientStorage for OnDiskPersistent {
|
|||||||
type KeyStore = OnDiskKeys;
|
type KeyStore = OnDiskKeys;
|
||||||
type ReplyStore = fs_backend::Backend;
|
type ReplyStore = fs_backend::Backend;
|
||||||
type CredentialStore = PersistentCredentialStorage;
|
type CredentialStore = PersistentCredentialStorage;
|
||||||
type GatewayDetailsStore = OnDiskGatewayDetails;
|
|
||||||
|
|
||||||
fn into_runtime_stores(self) -> (Self::ReplyStore, Self::CredentialStore) {
|
fn into_split(self) -> (Self::KeyStore, Self::ReplyStore, Self::CredentialStore) {
|
||||||
(self.reply_store, self.credential_store)
|
(self.key_store, self.reply_store, self.credential_store)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_store(&self) -> &Self::KeyStore {
|
fn key_store(&self) -> &Self::KeyStore {
|
||||||
@@ -162,8 +138,4 @@ impl MixnetClientStorage for OnDiskPersistent {
|
|||||||
fn credential_store(&self) -> &Self::CredentialStore {
|
fn credential_store(&self) -> &Self::CredentialStore {
|
||||||
&self.credential_store
|
&self.credential_store
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gateway_details_store(&self) -> &Self::GatewayDetailsStore {
|
|
||||||
&self.gateway_details_store
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use log::*;
|
|||||||
use nym_sphinx::acknowledgements::AckKey;
|
use nym_sphinx::acknowledgements::AckKey;
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
use nym_sphinx::addressing::clients::Recipient;
|
||||||
use nym_sphinx::cover::generate_loop_cover_packet;
|
use nym_sphinx::cover::generate_loop_cover_packet;
|
||||||
use nym_sphinx::params::{PacketSize, PacketType};
|
use nym_sphinx::params::PacketSize;
|
||||||
use nym_sphinx::utils::sample_poisson_duration;
|
use nym_sphinx::utils::sample_poisson_duration;
|
||||||
use rand::{rngs::OsRng, CryptoRng, Rng};
|
use rand::{rngs::OsRng, CryptoRng, Rng};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
@@ -63,8 +63,6 @@ where
|
|||||||
|
|
||||||
/// Optional secondary predefined packet size used for the loop cover messages.
|
/// Optional secondary predefined packet size used for the loop cover messages.
|
||||||
secondary_packet_size: Option<PacketSize>,
|
secondary_packet_size: Option<PacketSize>,
|
||||||
|
|
||||||
packet_type: PacketType,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R> Stream for LoopCoverTrafficStream<R>
|
impl<R> Stream for LoopCoverTrafficStream<R>
|
||||||
@@ -137,7 +135,6 @@ impl LoopCoverTrafficStream<OsRng> {
|
|||||||
topology_access,
|
topology_access,
|
||||||
primary_packet_size: traffic_config.primary_packet_size,
|
primary_packet_size: traffic_config.primary_packet_size,
|
||||||
secondary_packet_size: traffic_config.secondary_packet_size,
|
secondary_packet_size: traffic_config.secondary_packet_size,
|
||||||
packet_type: traffic_config.packet_type,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +194,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
|||||||
self.average_ack_delay,
|
self.average_ack_delay,
|
||||||
self.cover_traffic.loop_cover_traffic_average_delay,
|
self.cover_traffic.loop_cover_traffic_average_delay,
|
||||||
cover_traffic_packet_size,
|
cover_traffic_packet_size,
|
||||||
self.packet_type,
|
nym_sphinx::params::PacketType::Mix,
|
||||||
)
|
)
|
||||||
.expect("Somehow failed to generate a loop cover message with a valid topology");
|
.expect("Somehow failed to generate a loop cover message with a valid topology");
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ use nym_crypto::asymmetric::{encryption, identity};
|
|||||||
use nym_gateway_requests::registration::handshake::SharedKeys;
|
use nym_gateway_requests::registration::handshake::SharedKeys;
|
||||||
use nym_sphinx::acknowledgements::AckKey;
|
use nym_sphinx::acknowledgements::AckKey;
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use std::fmt::{Debug, Formatter};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use zeroize::ZeroizeOnDrop;
|
use zeroize::ZeroizeOnDrop;
|
||||||
|
|
||||||
@@ -21,16 +20,6 @@ pub enum ManagedKeys {
|
|||||||
Invalidated,
|
Invalidated,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for ManagedKeys {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
ManagedKeys::Initial(_) => write!(f, "initial"),
|
|
||||||
ManagedKeys::FullyDerived(_) => write!(f, "fully derived"),
|
|
||||||
ManagedKeys::Invalidated => write!(f, "invalidated"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<KeyManagerBuilder> for ManagedKeys {
|
impl From<KeyManagerBuilder> for ManagedKeys {
|
||||||
fn from(value: KeyManagerBuilder) -> Self {
|
fn from(value: KeyManagerBuilder) -> Self {
|
||||||
ManagedKeys::Initial(value)
|
ManagedKeys::Initial(value)
|
||||||
@@ -95,11 +84,6 @@ impl ManagedKeys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn must_get_gateway_shared_key(&self) -> Arc<SharedKeys> {
|
|
||||||
self.gateway_shared_key()
|
|
||||||
.expect("failed to extract gateway shared key")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gateway_shared_key(&self) -> Option<Arc<SharedKeys>> {
|
pub fn gateway_shared_key(&self) -> Option<Arc<SharedKeys>> {
|
||||||
match self {
|
match self {
|
||||||
ManagedKeys::Initial(_) => None,
|
ManagedKeys::Initial(_) => None,
|
||||||
@@ -124,17 +108,6 @@ impl ManagedKeys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ensure_gateway_key(&self, gateway_shared_key: Arc<SharedKeys>) {
|
|
||||||
if let ManagedKeys::FullyDerived(key_manager) = &self {
|
|
||||||
if !Arc::ptr_eq(&key_manager.gateway_shared_key, &gateway_shared_key)
|
|
||||||
|| key_manager.gateway_shared_key != gateway_shared_key
|
|
||||||
{
|
|
||||||
// this should NEVER happen thus panic here
|
|
||||||
panic!("derived fresh gateway shared key whilst already holding one!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn deal_with_gateway_key<S: KeyStore>(
|
pub async fn deal_with_gateway_key<S: KeyStore>(
|
||||||
&mut self,
|
&mut self,
|
||||||
gateway_shared_key: Arc<SharedKeys>,
|
gateway_shared_key: Arc<SharedKeys>,
|
||||||
@@ -147,7 +120,12 @@ impl ManagedKeys {
|
|||||||
key_manager
|
key_manager
|
||||||
}
|
}
|
||||||
ManagedKeys::FullyDerived(key_manager) => {
|
ManagedKeys::FullyDerived(key_manager) => {
|
||||||
self.ensure_gateway_key(gateway_shared_key);
|
if !Arc::ptr_eq(&key_manager.gateway_shared_key, &gateway_shared_key)
|
||||||
|
|| key_manager.gateway_shared_key != gateway_shared_key
|
||||||
|
{
|
||||||
|
// this should NEVER happen thus panic here
|
||||||
|
panic!("derived fresh gateway shared key whilst already holding one!")
|
||||||
|
}
|
||||||
key_manager
|
key_manager
|
||||||
}
|
}
|
||||||
ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"),
|
ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"),
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
use crate::client::key_manager::KeyManager;
|
use crate::client::key_manager::KeyManager;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use tokio::sync::Mutex;
|
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use crate::config::disk_persistence::keys_paths::ClientKeysPaths;
|
use crate::config::disk_persistence::keys_paths::ClientKeysPaths;
|
||||||
@@ -37,7 +36,6 @@ pub enum OnDiskKeysError {
|
|||||||
KeyPairLoadFailure {
|
KeyPairLoadFailure {
|
||||||
keys: String,
|
keys: String,
|
||||||
paths: nym_pemstore::KeyPairPath,
|
paths: nym_pemstore::KeyPairPath,
|
||||||
#[source]
|
|
||||||
err: std::io::Error,
|
err: std::io::Error,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -45,7 +43,6 @@ pub enum OnDiskKeysError {
|
|||||||
KeyPairStoreFailure {
|
KeyPairStoreFailure {
|
||||||
keys: String,
|
keys: String,
|
||||||
paths: nym_pemstore::KeyPairPath,
|
paths: nym_pemstore::KeyPairPath,
|
||||||
#[source]
|
|
||||||
err: std::io::Error,
|
err: std::io::Error,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -53,7 +50,6 @@ pub enum OnDiskKeysError {
|
|||||||
KeyLoadFailure {
|
KeyLoadFailure {
|
||||||
key: String,
|
key: String,
|
||||||
path: String,
|
path: String,
|
||||||
#[source]
|
|
||||||
err: std::io::Error,
|
err: std::io::Error,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -61,7 +57,6 @@ pub enum OnDiskKeysError {
|
|||||||
KeyStoreFailure {
|
KeyStoreFailure {
|
||||||
key: String,
|
key: String,
|
||||||
path: String,
|
path: String,
|
||||||
#[source]
|
|
||||||
err: std::io::Error,
|
err: std::io::Error,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -84,26 +79,6 @@ impl OnDiskKeys {
|
|||||||
OnDiskKeys { paths }
|
OnDiskKeys { paths }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn ephemeral_load_gateway_keys(
|
|
||||||
&self,
|
|
||||||
) -> Result<zeroize::Zeroizing<SharedKeys>, OnDiskKeysError> {
|
|
||||||
self.load_key(self.paths.gateway_shared_key(), "gateway shared keys")
|
|
||||||
.map(zeroize::Zeroizing::new)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn load_encryption_keypair(&self) -> Result<encryption::KeyPair, OnDiskKeysError> {
|
|
||||||
let encryption_paths = self.paths.encryption_key_pair_path();
|
|
||||||
self.load_keypair(encryption_paths, "encryption keys")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn load_identity_keypair(&self) -> Result<identity::KeyPair, OnDiskKeysError> {
|
|
||||||
let identity_paths = self.paths.identity_key_pair_path();
|
|
||||||
self.load_keypair(identity_paths, "identity keys")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_key<T: PemStorableKey>(
|
fn load_key<T: PemStorableKey>(
|
||||||
&self,
|
&self,
|
||||||
path: &std::path::Path,
|
path: &std::path::Path,
|
||||||
@@ -157,8 +132,13 @@ impl OnDiskKeys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn load_keys(&self) -> Result<KeyManager, OnDiskKeysError> {
|
fn load_keys(&self) -> Result<KeyManager, OnDiskKeysError> {
|
||||||
let identity_keypair = self.load_identity_keypair()?;
|
let identity_paths = self.paths.identity_key_pair_path();
|
||||||
let encryption_keypair = self.load_encryption_keypair()?;
|
let encryption_paths = self.paths.encryption_key_pair_path();
|
||||||
|
|
||||||
|
let identity_keypair: identity::KeyPair =
|
||||||
|
self.load_keypair(identity_paths, "identity keys")?;
|
||||||
|
let encryption_keypair: encryption::KeyPair =
|
||||||
|
self.load_keypair(encryption_paths, "encryption keys")?;
|
||||||
|
|
||||||
let ack_key: AckKey = self.load_key(self.paths.ack_key(), "ack key")?;
|
let ack_key: AckKey = self.load_key(self.paths.ack_key(), "ack key")?;
|
||||||
let gateway_shared_key: SharedKeys =
|
let gateway_shared_key: SharedKeys =
|
||||||
@@ -213,12 +193,10 @@ impl KeyStore for OnDiskKeys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct InMemEphemeralKeys {
|
pub struct InMemEphemeralKeys;
|
||||||
keys: Mutex<Option<KeyManager>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
#[error("old ephemeral keys can't be loaded from storage")]
|
#[error("ephemeral keys can't be loaded from storage")]
|
||||||
pub struct EphemeralKeysError;
|
pub struct EphemeralKeysError;
|
||||||
|
|
||||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
||||||
@@ -227,11 +205,10 @@ impl KeyStore for InMemEphemeralKeys {
|
|||||||
type StorageError = EphemeralKeysError;
|
type StorageError = EphemeralKeysError;
|
||||||
|
|
||||||
async fn load_keys(&self) -> Result<KeyManager, Self::StorageError> {
|
async fn load_keys(&self) -> Result<KeyManager, Self::StorageError> {
|
||||||
self.keys.lock().await.clone().ok_or(EphemeralKeysError)
|
Err(EphemeralKeysError)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn store_keys(&self, keys: &KeyManager) -> Result<(), Self::StorageError> {
|
async fn store_keys(&self, _keys: &KeyManager) -> Result<(), Self::StorageError> {
|
||||||
*self.keys.lock().await = Some(keys.clone());
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -565,7 +565,7 @@ where
|
|||||||
fragments: Vec<Fragment>,
|
fragments: Vec<Fragment>,
|
||||||
reply_surbs: Vec<ReplySurb>,
|
reply_surbs: Vec<ReplySurb>,
|
||||||
) -> Result<Vec<PreparedFragment>, SurbWrappedPreparationError> {
|
) -> Result<Vec<PreparedFragment>, SurbWrappedPreparationError> {
|
||||||
debug_assert_eq!(
|
debug_assert_ne!(
|
||||||
fragments.len(),
|
fragments.len(),
|
||||||
reply_surbs.len(),
|
reply_surbs.len(),
|
||||||
"attempted to send {} fragments with {} reply surbs",
|
"attempted to send {} fragments with {} reply surbs",
|
||||||
|
|||||||
@@ -6,21 +6,16 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
pub mod keys_paths;
|
pub mod keys_paths;
|
||||||
pub mod old_v1_1_20_2;
|
|
||||||
|
|
||||||
pub const DEFAULT_GATEWAY_DETAILS_FILENAME: &str = "gateway_details.json";
|
|
||||||
pub const DEFAULT_REPLY_SURB_DB_FILENAME: &str = "persistent_reply_store.sqlite";
|
pub const DEFAULT_REPLY_SURB_DB_FILENAME: &str = "persistent_reply_store.sqlite";
|
||||||
pub const DEFAULT_CREDENTIALS_DB_FILENAME: &str = "credentials_database.db";
|
pub const DEFAULT_CREDENTIALS_DB_FILENAME: &str = "credentials_database.db";
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct CommonClientPaths {
|
pub struct CommonClientPaths {
|
||||||
pub keys: ClientKeysPaths,
|
pub keys: ClientKeysPaths,
|
||||||
|
|
||||||
/// Path to the file containing information about gateway used by this client,
|
// TODO:
|
||||||
/// i.e. details such as its public key, owner address or the network information.
|
// pub gateway_config_pathfinder: (),
|
||||||
pub gateway_details: PathBuf,
|
|
||||||
|
|
||||||
/// Path to the database containing bandwidth credentials of this client.
|
/// Path to the database containing bandwidth credentials of this client.
|
||||||
pub credentials_database: PathBuf,
|
pub credentials_database: PathBuf,
|
||||||
|
|
||||||
@@ -35,7 +30,6 @@ impl CommonClientPaths {
|
|||||||
CommonClientPaths {
|
CommonClientPaths {
|
||||||
credentials_database: base_dir.join(DEFAULT_CREDENTIALS_DB_FILENAME),
|
credentials_database: base_dir.join(DEFAULT_CREDENTIALS_DB_FILENAME),
|
||||||
reply_surb_database: base_dir.join(DEFAULT_REPLY_SURB_DB_FILENAME),
|
reply_surb_database: base_dir.join(DEFAULT_REPLY_SURB_DB_FILENAME),
|
||||||
gateway_details: base_dir.join(DEFAULT_GATEWAY_DETAILS_FILENAME),
|
|
||||||
keys: ClientKeysPaths::new_default(base_data_directory),
|
keys: ClientKeysPaths::new_default(base_data_directory),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::config::disk_persistence::keys_paths::ClientKeysPaths;
|
|
||||||
use crate::config::disk_persistence::{CommonClientPaths, DEFAULT_GATEWAY_DETAILS_FILENAME};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct CommonClientPathsV1_1_20_2 {
|
|
||||||
pub keys: ClientKeysPaths,
|
|
||||||
pub credentials_database: PathBuf,
|
|
||||||
pub reply_surb_database: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CommonClientPathsV1_1_20_2 {
|
|
||||||
pub fn upgrade_default(self) -> CommonClientPaths {
|
|
||||||
let data_dir = self
|
|
||||||
.reply_surb_database
|
|
||||||
.parent()
|
|
||||||
.expect("client paths upgrade failure");
|
|
||||||
CommonClientPaths {
|
|
||||||
keys: self.keys,
|
|
||||||
gateway_details: data_dir.join(DEFAULT_GATEWAY_DETAILS_FILENAME),
|
|
||||||
credentials_database: self.credentials_database,
|
|
||||||
reply_surb_database: self.reply_surb_database,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -14,8 +14,7 @@ use wasm_bindgen::prelude::*;
|
|||||||
|
|
||||||
pub mod disk_persistence;
|
pub mod disk_persistence;
|
||||||
pub mod old_config_v1_1_13;
|
pub mod old_config_v1_1_13;
|
||||||
pub mod old_config_v1_1_20;
|
pub mod old_config_v1_1_19;
|
||||||
pub mod old_config_v1_1_20_2;
|
|
||||||
|
|
||||||
// 'DEBUG'
|
// 'DEBUG'
|
||||||
const DEFAULT_ACK_WAIT_MULTIPLIER: f64 = 1.5;
|
const DEFAULT_ACK_WAIT_MULTIPLIER: f64 = 1.5;
|
||||||
@@ -66,19 +65,15 @@ pub struct Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn new<S: Into<String>>(id: S, version: S) -> Self {
|
pub fn new<S: Into<String>>(id: S) -> Self {
|
||||||
Config {
|
Config {
|
||||||
client: Client::new_default(id, version),
|
client: Client::new_default(id),
|
||||||
debug: Default::default(),
|
debug: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_client_config(client: Client, debug: DebugConfig) -> Self {
|
|
||||||
Config { client, debug }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn validate(&self) -> bool {
|
pub fn validate(&self) -> bool {
|
||||||
self.debug.validate()
|
self.client.validate() && self.debug.validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_debug_config(mut self, debug: DebugConfig) -> Self {
|
pub fn with_debug_config(mut self, debug: DebugConfig) -> Self {
|
||||||
@@ -91,6 +86,19 @@ impl Config {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_gateway_endpoint(&mut self, gateway_endpoint: GatewayEndpointConfig) {
|
||||||
|
self.client.gateway_endpoint = gateway_endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_gateway_endpoint(mut self, gateway_endpoint: GatewayEndpointConfig) -> Self {
|
||||||
|
self.client.gateway_endpoint = gateway_endpoint;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_gateway_id<S: Into<String>>(&mut self, id: S) {
|
||||||
|
self.client.gateway_endpoint.gateway_id = id.into();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn with_custom_nyxd(mut self, urls: Vec<Url>) -> Self {
|
pub fn with_custom_nyxd(mut self, urls: Vec<Url>) -> Self {
|
||||||
self.client.nyxd_urls = urls;
|
self.client.nyxd_urls = urls;
|
||||||
self
|
self
|
||||||
@@ -166,6 +174,22 @@ impl Config {
|
|||||||
pub fn get_nym_api_endpoints(&self) -> Vec<Url> {
|
pub fn get_nym_api_endpoints(&self) -> Vec<Url> {
|
||||||
self.client.nym_api_urls.clone()
|
self.client.nym_api_urls.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_gateway_id(&self) -> String {
|
||||||
|
self.client.gateway_endpoint.gateway_id.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_gateway_owner(&self) -> String {
|
||||||
|
self.client.gateway_endpoint.gateway_owner.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_gateway_listener(&self) -> String {
|
||||||
|
self.client.gateway_endpoint.gateway_listener.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_gateway_endpoint_config(&self) -> &GatewayEndpointConfig {
|
||||||
|
&self.client.gateway_endpoint
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
@@ -218,8 +242,6 @@ impl From<nym_topology::gateway::Node> for GatewayEndpointConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
// note: the deny_unknown_fields is VITAL here to allow upgrades from v1.1.20_2
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
/// Version of the client for which this configuration was created.
|
/// Version of the client for which this configuration was created.
|
||||||
pub version: String,
|
pub version: String,
|
||||||
@@ -229,7 +251,6 @@ pub struct Client {
|
|||||||
|
|
||||||
/// Indicates whether this client is running in a disabled credentials mode, thus attempting
|
/// Indicates whether this client is running in a disabled credentials mode, thus attempting
|
||||||
/// to claim bandwidth without presenting bandwidth credentials.
|
/// to claim bandwidth without presenting bandwidth credentials.
|
||||||
// TODO: this should be moved to `debug.gateway_connection`
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub disabled_credentials_mode: bool,
|
pub disabled_credentials_mode: bool,
|
||||||
|
|
||||||
@@ -240,10 +261,15 @@ pub struct Client {
|
|||||||
/// Addresses to APIs running on validator from which the client gets the view of the network.
|
/// Addresses to APIs running on validator from which the client gets the view of the network.
|
||||||
#[serde(alias = "validator_api_urls")]
|
#[serde(alias = "validator_api_urls")]
|
||||||
pub nym_api_urls: Vec<Url>,
|
pub nym_api_urls: Vec<Url>,
|
||||||
|
|
||||||
|
/// Information regarding how the client should send data to gateway.
|
||||||
|
// #[deprecated(note = "this shall be moved to separate file because it doesn't belong here...")]
|
||||||
|
// TODO: this should be removed from config files and be moved to separate file instead
|
||||||
|
pub gateway_endpoint: GatewayEndpointConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
pub fn new_default<S: Into<String>>(id: S, version: S) -> Self {
|
pub fn new_default<S: Into<String>>(id: S) -> Self {
|
||||||
let network = NymNetworkDetails::new_mainnet();
|
let network = NymNetworkDetails::new_mainnet();
|
||||||
let nyxd_urls = network
|
let nyxd_urls = network
|
||||||
.endpoints
|
.endpoints
|
||||||
@@ -257,27 +283,19 @@ impl Client {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
Client {
|
Client {
|
||||||
version: version.into(),
|
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||||
id: id.into(),
|
id: id.into(),
|
||||||
disabled_credentials_mode: true,
|
disabled_credentials_mode: true,
|
||||||
nyxd_urls,
|
nyxd_urls,
|
||||||
nym_api_urls,
|
nym_api_urls,
|
||||||
|
gateway_endpoint: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new<S: Into<String>>(
|
pub fn validate(&self) -> bool {
|
||||||
id: S,
|
!self.gateway_endpoint.gateway_id.is_empty()
|
||||||
disabled_credentials_mode: bool,
|
&& !self.gateway_endpoint.gateway_owner.is_empty()
|
||||||
nyxd_urls: Vec<Url>,
|
&& !self.gateway_endpoint.gateway_owner.is_empty()
|
||||||
nym_api_urls: Vec<Url>,
|
|
||||||
) -> Self {
|
|
||||||
Client {
|
|
||||||
version: env!("CARGO_PKG_VERSION").to_string(),
|
|
||||||
id: id.into(),
|
|
||||||
disabled_credentials_mode,
|
|
||||||
nyxd_urls,
|
|
||||||
nym_api_urls,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::config::old_config_v1_1_20::{
|
use crate::config::old_config_v1_1_19::{
|
||||||
AcknowledgementsV1_1_20, ClientV1_1_20, ConfigV1_1_20, CoverTrafficV1_1_20, DebugConfigV1_1_20,
|
AcknowledgementsV1_1_19, ClientV1_1_19, ConfigV1_1_19, CoverTrafficV1_1_19, DebugConfigV1_1_19,
|
||||||
GatewayConnectionV1_1_20, LoggingV1_1_20, ReplySurbsV1_1_20, TopologyV1_1_20, TrafficV1_1_20,
|
GatewayConnectionV1_1_19, LoggingV1_1_19, ReplySurbsV1_1_19, TopologyV1_1_19, TrafficV1_1_19,
|
||||||
DEFAULT_ACK_WAIT_ADDITION, DEFAULT_ACK_WAIT_MULTIPLIER, DEFAULT_AVERAGE_PACKET_DELAY,
|
DEFAULT_ACK_WAIT_ADDITION, DEFAULT_ACK_WAIT_MULTIPLIER, DEFAULT_AVERAGE_PACKET_DELAY,
|
||||||
DEFAULT_GATEWAY_RESPONSE_TIMEOUT, DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY,
|
DEFAULT_GATEWAY_RESPONSE_TIMEOUT, DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY,
|
||||||
DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE, DEFAULT_MAXIMUM_REPLY_KEY_AGE,
|
DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE, DEFAULT_MAXIMUM_REPLY_KEY_AGE,
|
||||||
@@ -39,7 +39,7 @@ impl From<ExtendedPacketSize> for PacketSize {
|
|||||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct OldConfigV1_1_13<T> {
|
pub struct OldConfigV1_1_13<T> {
|
||||||
pub client: ClientV1_1_20<T>,
|
pub client: ClientV1_1_19<T>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub logging: OldLoggingV1_1_13,
|
pub logging: OldLoggingV1_1_13,
|
||||||
@@ -51,9 +51,9 @@ pub struct OldConfigV1_1_13<T> {
|
|||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct OldLoggingV1_1_13 {}
|
pub struct OldLoggingV1_1_13 {}
|
||||||
|
|
||||||
impl From<OldLoggingV1_1_13> for LoggingV1_1_20 {
|
impl From<OldLoggingV1_1_13> for LoggingV1_1_19 {
|
||||||
fn from(_value: OldLoggingV1_1_13) -> Self {
|
fn from(_value: OldLoggingV1_1_13) -> Self {
|
||||||
LoggingV1_1_20 {}
|
LoggingV1_1_19 {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,10 +114,10 @@ pub struct OldDebugConfigV1_1_13 {
|
|||||||
pub maximum_reply_key_age: Duration,
|
pub maximum_reply_key_age: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OldDebugConfigV1_1_13> for DebugConfigV1_1_20 {
|
impl From<OldDebugConfigV1_1_13> for DebugConfigV1_1_19 {
|
||||||
fn from(value: OldDebugConfigV1_1_13) -> Self {
|
fn from(value: OldDebugConfigV1_1_13) -> Self {
|
||||||
DebugConfigV1_1_20 {
|
DebugConfigV1_1_19 {
|
||||||
traffic: TrafficV1_1_20 {
|
traffic: TrafficV1_1_19 {
|
||||||
average_packet_delay: value.average_packet_delay,
|
average_packet_delay: value.average_packet_delay,
|
||||||
message_sending_average_delay: value.message_sending_average_delay,
|
message_sending_average_delay: value.message_sending_average_delay,
|
||||||
disable_main_poisson_packet_distribution: value
|
disable_main_poisson_packet_distribution: value
|
||||||
@@ -125,25 +125,25 @@ impl From<OldDebugConfigV1_1_13> for DebugConfigV1_1_20 {
|
|||||||
primary_packet_size: PacketSize::RegularPacket,
|
primary_packet_size: PacketSize::RegularPacket,
|
||||||
secondary_packet_size: value.use_extended_packet_size.map(Into::into),
|
secondary_packet_size: value.use_extended_packet_size.map(Into::into),
|
||||||
},
|
},
|
||||||
cover_traffic: CoverTrafficV1_1_20 {
|
cover_traffic: CoverTrafficV1_1_19 {
|
||||||
loop_cover_traffic_average_delay: value.loop_cover_traffic_average_delay,
|
loop_cover_traffic_average_delay: value.loop_cover_traffic_average_delay,
|
||||||
disable_loop_cover_traffic_stream: value.disable_loop_cover_traffic_stream,
|
disable_loop_cover_traffic_stream: value.disable_loop_cover_traffic_stream,
|
||||||
..CoverTrafficV1_1_20::default()
|
..CoverTrafficV1_1_19::default()
|
||||||
},
|
},
|
||||||
gateway_connection: GatewayConnectionV1_1_20 {
|
gateway_connection: GatewayConnectionV1_1_19 {
|
||||||
gateway_response_timeout: value.gateway_response_timeout,
|
gateway_response_timeout: value.gateway_response_timeout,
|
||||||
},
|
},
|
||||||
acknowledgements: AcknowledgementsV1_1_20 {
|
acknowledgements: AcknowledgementsV1_1_19 {
|
||||||
average_ack_delay: value.average_ack_delay,
|
average_ack_delay: value.average_ack_delay,
|
||||||
ack_wait_multiplier: value.ack_wait_multiplier,
|
ack_wait_multiplier: value.ack_wait_multiplier,
|
||||||
ack_wait_addition: value.ack_wait_addition,
|
ack_wait_addition: value.ack_wait_addition,
|
||||||
},
|
},
|
||||||
topology: TopologyV1_1_20 {
|
topology: TopologyV1_1_19 {
|
||||||
topology_refresh_rate: value.topology_refresh_rate,
|
topology_refresh_rate: value.topology_refresh_rate,
|
||||||
topology_resolution_timeout: value.topology_resolution_timeout,
|
topology_resolution_timeout: value.topology_resolution_timeout,
|
||||||
disable_refreshing: false,
|
disable_refreshing: false,
|
||||||
},
|
},
|
||||||
reply_surbs: ReplySurbsV1_1_20 {
|
reply_surbs: ReplySurbsV1_1_19 {
|
||||||
minimum_reply_surb_storage_threshold: value.minimum_reply_surb_storage_threshold,
|
minimum_reply_surb_storage_threshold: value.minimum_reply_surb_storage_threshold,
|
||||||
maximum_reply_surb_storage_threshold: value.maximum_reply_surb_storage_threshold,
|
maximum_reply_surb_storage_threshold: value.maximum_reply_surb_storage_threshold,
|
||||||
minimum_reply_surb_request_size: value.minimum_reply_surb_request_size,
|
minimum_reply_surb_request_size: value.minimum_reply_surb_request_size,
|
||||||
@@ -190,10 +190,10 @@ impl Default for OldDebugConfigV1_1_13 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, U> From<OldConfigV1_1_13<T>> for ConfigV1_1_20<U> {
|
impl<T, U> From<OldConfigV1_1_13<T>> for ConfigV1_1_19<U> {
|
||||||
fn from(value: OldConfigV1_1_13<T>) -> Self {
|
fn from(value: OldConfigV1_1_13<T>) -> Self {
|
||||||
ConfigV1_1_20 {
|
ConfigV1_1_19 {
|
||||||
client: ClientV1_1_20 {
|
client: ClientV1_1_19 {
|
||||||
version: value.client.version,
|
version: value.client.version,
|
||||||
id: value.client.id,
|
id: value.client.id,
|
||||||
disabled_credentials_mode: value.client.disabled_credentials_mode,
|
disabled_credentials_mode: value.client.disabled_credentials_mode,
|
||||||
|
|||||||
+77
-62
@@ -1,10 +1,9 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::config::old_config_v1_1_20_2::{
|
use crate::config::{
|
||||||
AcknowledgementsV1_1_20_2, CoverTrafficV1_1_20_2, DebugConfigV1_1_20_2,
|
Acknowledgements, CoverTraffic, DebugConfig, GatewayConnection, GatewayEndpointConfig,
|
||||||
GatewayConnectionV1_1_20_2, GatewayEndpointConfigV1_1_20_2, ReplySurbsV1_1_20_2,
|
ReplySurbs, Topology, Traffic,
|
||||||
TopologyV1_1_20_2, TrafficV1_1_20_2,
|
|
||||||
};
|
};
|
||||||
use nym_sphinx::params::{PacketSize, PacketType};
|
use nym_sphinx::params::{PacketSize, PacketType};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -56,25 +55,25 @@ pub(crate) const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(2
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct ConfigV1_1_20<T> {
|
pub struct ConfigV1_1_19<T> {
|
||||||
pub client: ClientV1_1_20<T>,
|
pub client: ClientV1_1_19<T>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub logging: LoggingV1_1_20,
|
pub logging: LoggingV1_1_19,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub debug: DebugConfigV1_1_20,
|
pub debug: DebugConfigV1_1_19,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
pub struct GatewayEndpointConfigV1_1_20 {
|
pub struct GatewayEndpointConfigV1_1_19 {
|
||||||
pub gateway_id: String,
|
pub gateway_id: String,
|
||||||
pub gateway_owner: String,
|
pub gateway_owner: String,
|
||||||
pub gateway_listener: String,
|
pub gateway_listener: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<GatewayEndpointConfigV1_1_20> for GatewayEndpointConfigV1_1_20_2 {
|
impl From<GatewayEndpointConfigV1_1_19> for GatewayEndpointConfig {
|
||||||
fn from(value: GatewayEndpointConfigV1_1_20) -> Self {
|
fn from(value: GatewayEndpointConfigV1_1_19) -> Self {
|
||||||
GatewayEndpointConfigV1_1_20_2 {
|
GatewayEndpointConfig {
|
||||||
gateway_id: value.gateway_id,
|
gateway_id: value.gateway_id,
|
||||||
gateway_owner: value.gateway_owner,
|
gateway_owner: value.gateway_owner,
|
||||||
gateway_listener: value.gateway_listener,
|
gateway_listener: value.gateway_listener,
|
||||||
@@ -83,7 +82,7 @@ impl From<GatewayEndpointConfigV1_1_20> for GatewayEndpointConfigV1_1_20_2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
pub struct ClientV1_1_20<T> {
|
pub struct ClientV1_1_19<T> {
|
||||||
pub version: String,
|
pub version: String,
|
||||||
pub id: String,
|
pub id: String,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
@@ -98,7 +97,7 @@ pub struct ClientV1_1_20<T> {
|
|||||||
pub public_encryption_key_file: PathBuf,
|
pub public_encryption_key_file: PathBuf,
|
||||||
pub gateway_shared_key_file: PathBuf,
|
pub gateway_shared_key_file: PathBuf,
|
||||||
pub ack_key_file: PathBuf,
|
pub ack_key_file: PathBuf,
|
||||||
pub gateway_endpoint: GatewayEndpointConfigV1_1_20,
|
pub gateway_endpoint: GatewayEndpointConfigV1_1_19,
|
||||||
pub database_path: PathBuf,
|
pub database_path: PathBuf,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub reply_surb_database_path: PathBuf,
|
pub reply_surb_database_path: PathBuf,
|
||||||
@@ -110,11 +109,11 @@ pub struct ClientV1_1_20<T> {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Debug, Clone, Default, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct LoggingV1_1_20 {}
|
pub struct LoggingV1_1_19 {}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct TrafficV1_1_20 {
|
pub struct TrafficV1_1_19 {
|
||||||
#[serde(with = "humantime_serde")]
|
#[serde(with = "humantime_serde")]
|
||||||
pub average_packet_delay: Duration,
|
pub average_packet_delay: Duration,
|
||||||
#[serde(with = "humantime_serde")]
|
#[serde(with = "humantime_serde")]
|
||||||
@@ -124,9 +123,9 @@ pub struct TrafficV1_1_20 {
|
|||||||
pub secondary_packet_size: Option<PacketSize>,
|
pub secondary_packet_size: Option<PacketSize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TrafficV1_1_20> for TrafficV1_1_20_2 {
|
impl From<TrafficV1_1_19> for Traffic {
|
||||||
fn from(value: TrafficV1_1_20) -> Self {
|
fn from(value: TrafficV1_1_19) -> Self {
|
||||||
TrafficV1_1_20_2 {
|
Traffic {
|
||||||
average_packet_delay: value.average_packet_delay,
|
average_packet_delay: value.average_packet_delay,
|
||||||
message_sending_average_delay: value.message_sending_average_delay,
|
message_sending_average_delay: value.message_sending_average_delay,
|
||||||
disable_main_poisson_packet_distribution: value
|
disable_main_poisson_packet_distribution: value
|
||||||
@@ -138,9 +137,9 @@ impl From<TrafficV1_1_20> for TrafficV1_1_20_2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TrafficV1_1_20 {
|
impl Default for TrafficV1_1_19 {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
TrafficV1_1_20 {
|
TrafficV1_1_19 {
|
||||||
average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY,
|
average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY,
|
||||||
message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY,
|
message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY,
|
||||||
disable_main_poisson_packet_distribution: false,
|
disable_main_poisson_packet_distribution: false,
|
||||||
@@ -152,16 +151,16 @@ impl Default for TrafficV1_1_20 {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(default, deny_unknown_fields)]
|
#[serde(default, deny_unknown_fields)]
|
||||||
pub struct CoverTrafficV1_1_20 {
|
pub struct CoverTrafficV1_1_19 {
|
||||||
#[serde(with = "humantime_serde")]
|
#[serde(with = "humantime_serde")]
|
||||||
pub loop_cover_traffic_average_delay: Duration,
|
pub loop_cover_traffic_average_delay: Duration,
|
||||||
pub cover_traffic_primary_size_ratio: f64,
|
pub cover_traffic_primary_size_ratio: f64,
|
||||||
pub disable_loop_cover_traffic_stream: bool,
|
pub disable_loop_cover_traffic_stream: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<CoverTrafficV1_1_20> for CoverTrafficV1_1_20_2 {
|
impl From<CoverTrafficV1_1_19> for CoverTraffic {
|
||||||
fn from(value: CoverTrafficV1_1_20) -> Self {
|
fn from(value: CoverTrafficV1_1_19) -> Self {
|
||||||
CoverTrafficV1_1_20_2 {
|
CoverTraffic {
|
||||||
loop_cover_traffic_average_delay: value.loop_cover_traffic_average_delay,
|
loop_cover_traffic_average_delay: value.loop_cover_traffic_average_delay,
|
||||||
cover_traffic_primary_size_ratio: value.cover_traffic_primary_size_ratio,
|
cover_traffic_primary_size_ratio: value.cover_traffic_primary_size_ratio,
|
||||||
disable_loop_cover_traffic_stream: value.disable_loop_cover_traffic_stream,
|
disable_loop_cover_traffic_stream: value.disable_loop_cover_traffic_stream,
|
||||||
@@ -169,9 +168,9 @@ impl From<CoverTrafficV1_1_20> for CoverTrafficV1_1_20_2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CoverTrafficV1_1_20 {
|
impl Default for CoverTrafficV1_1_19 {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
CoverTrafficV1_1_20 {
|
CoverTrafficV1_1_19 {
|
||||||
loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY,
|
loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY,
|
||||||
cover_traffic_primary_size_ratio: DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO,
|
cover_traffic_primary_size_ratio: DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO,
|
||||||
disable_loop_cover_traffic_stream: false,
|
disable_loop_cover_traffic_stream: false,
|
||||||
@@ -181,22 +180,22 @@ impl Default for CoverTrafficV1_1_20 {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(default, deny_unknown_fields)]
|
#[serde(default, deny_unknown_fields)]
|
||||||
pub struct GatewayConnectionV1_1_20 {
|
pub struct GatewayConnectionV1_1_19 {
|
||||||
#[serde(with = "humantime_serde")]
|
#[serde(with = "humantime_serde")]
|
||||||
pub gateway_response_timeout: Duration,
|
pub gateway_response_timeout: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<GatewayConnectionV1_1_20> for GatewayConnectionV1_1_20_2 {
|
impl From<GatewayConnectionV1_1_19> for GatewayConnection {
|
||||||
fn from(value: GatewayConnectionV1_1_20) -> Self {
|
fn from(value: GatewayConnectionV1_1_19) -> Self {
|
||||||
GatewayConnectionV1_1_20_2 {
|
GatewayConnection {
|
||||||
gateway_response_timeout: value.gateway_response_timeout,
|
gateway_response_timeout: value.gateway_response_timeout,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for GatewayConnectionV1_1_20 {
|
impl Default for GatewayConnectionV1_1_19 {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
GatewayConnectionV1_1_20 {
|
GatewayConnectionV1_1_19 {
|
||||||
gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT,
|
gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,7 +203,7 @@ impl Default for GatewayConnectionV1_1_20 {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(default, deny_unknown_fields)]
|
#[serde(default, deny_unknown_fields)]
|
||||||
pub struct AcknowledgementsV1_1_20 {
|
pub struct AcknowledgementsV1_1_19 {
|
||||||
#[serde(with = "humantime_serde")]
|
#[serde(with = "humantime_serde")]
|
||||||
pub average_ack_delay: Duration,
|
pub average_ack_delay: Duration,
|
||||||
pub ack_wait_multiplier: f64,
|
pub ack_wait_multiplier: f64,
|
||||||
@@ -212,9 +211,9 @@ pub struct AcknowledgementsV1_1_20 {
|
|||||||
pub ack_wait_addition: Duration,
|
pub ack_wait_addition: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AcknowledgementsV1_1_20> for AcknowledgementsV1_1_20_2 {
|
impl From<AcknowledgementsV1_1_19> for Acknowledgements {
|
||||||
fn from(value: AcknowledgementsV1_1_20) -> Self {
|
fn from(value: AcknowledgementsV1_1_19) -> Self {
|
||||||
AcknowledgementsV1_1_20_2 {
|
Acknowledgements {
|
||||||
average_ack_delay: value.average_ack_delay,
|
average_ack_delay: value.average_ack_delay,
|
||||||
ack_wait_multiplier: value.ack_wait_multiplier,
|
ack_wait_multiplier: value.ack_wait_multiplier,
|
||||||
ack_wait_addition: value.ack_wait_addition,
|
ack_wait_addition: value.ack_wait_addition,
|
||||||
@@ -222,9 +221,9 @@ impl From<AcknowledgementsV1_1_20> for AcknowledgementsV1_1_20_2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AcknowledgementsV1_1_20 {
|
impl Default for AcknowledgementsV1_1_19 {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
AcknowledgementsV1_1_20 {
|
AcknowledgementsV1_1_19 {
|
||||||
average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY,
|
average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY,
|
||||||
ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER,
|
ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER,
|
||||||
ack_wait_addition: DEFAULT_ACK_WAIT_ADDITION,
|
ack_wait_addition: DEFAULT_ACK_WAIT_ADDITION,
|
||||||
@@ -234,7 +233,7 @@ impl Default for AcknowledgementsV1_1_20 {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(default, deny_unknown_fields)]
|
#[serde(default, deny_unknown_fields)]
|
||||||
pub struct TopologyV1_1_20 {
|
pub struct TopologyV1_1_19 {
|
||||||
#[serde(with = "humantime_serde")]
|
#[serde(with = "humantime_serde")]
|
||||||
pub topology_refresh_rate: Duration,
|
pub topology_refresh_rate: Duration,
|
||||||
#[serde(with = "humantime_serde")]
|
#[serde(with = "humantime_serde")]
|
||||||
@@ -242,9 +241,9 @@ pub struct TopologyV1_1_20 {
|
|||||||
pub disable_refreshing: bool,
|
pub disable_refreshing: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<TopologyV1_1_20> for TopologyV1_1_20_2 {
|
impl From<TopologyV1_1_19> for Topology {
|
||||||
fn from(value: TopologyV1_1_20) -> Self {
|
fn from(value: TopologyV1_1_19) -> Self {
|
||||||
TopologyV1_1_20_2 {
|
Topology {
|
||||||
topology_refresh_rate: value.topology_refresh_rate,
|
topology_refresh_rate: value.topology_refresh_rate,
|
||||||
topology_resolution_timeout: value.topology_resolution_timeout,
|
topology_resolution_timeout: value.topology_resolution_timeout,
|
||||||
disable_refreshing: value.disable_refreshing,
|
disable_refreshing: value.disable_refreshing,
|
||||||
@@ -252,9 +251,9 @@ impl From<TopologyV1_1_20> for TopologyV1_1_20_2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TopologyV1_1_20 {
|
impl Default for TopologyV1_1_19 {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
TopologyV1_1_20 {
|
TopologyV1_1_19 {
|
||||||
topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE,
|
topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE,
|
||||||
topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT,
|
topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT,
|
||||||
disable_refreshing: false,
|
disable_refreshing: false,
|
||||||
@@ -264,7 +263,7 @@ impl Default for TopologyV1_1_20 {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(default, deny_unknown_fields)]
|
#[serde(default, deny_unknown_fields)]
|
||||||
pub struct ReplySurbsV1_1_20 {
|
pub struct ReplySurbsV1_1_19 {
|
||||||
pub minimum_reply_surb_storage_threshold: usize,
|
pub minimum_reply_surb_storage_threshold: usize,
|
||||||
pub maximum_reply_surb_storage_threshold: usize,
|
pub maximum_reply_surb_storage_threshold: usize,
|
||||||
pub minimum_reply_surb_request_size: u32,
|
pub minimum_reply_surb_request_size: u32,
|
||||||
@@ -280,9 +279,9 @@ pub struct ReplySurbsV1_1_20 {
|
|||||||
pub maximum_reply_key_age: Duration,
|
pub maximum_reply_key_age: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ReplySurbsV1_1_20> for ReplySurbsV1_1_20_2 {
|
impl From<ReplySurbsV1_1_19> for ReplySurbs {
|
||||||
fn from(value: ReplySurbsV1_1_20) -> Self {
|
fn from(value: ReplySurbsV1_1_19) -> Self {
|
||||||
ReplySurbsV1_1_20_2 {
|
ReplySurbs {
|
||||||
minimum_reply_surb_storage_threshold: value.minimum_reply_surb_storage_threshold,
|
minimum_reply_surb_storage_threshold: value.minimum_reply_surb_storage_threshold,
|
||||||
maximum_reply_surb_storage_threshold: value.maximum_reply_surb_storage_threshold,
|
maximum_reply_surb_storage_threshold: value.maximum_reply_surb_storage_threshold,
|
||||||
minimum_reply_surb_request_size: value.minimum_reply_surb_request_size,
|
minimum_reply_surb_request_size: value.minimum_reply_surb_request_size,
|
||||||
@@ -297,9 +296,9 @@ impl From<ReplySurbsV1_1_20> for ReplySurbsV1_1_20_2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ReplySurbsV1_1_20 {
|
impl Default for ReplySurbsV1_1_19 {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
ReplySurbsV1_1_20 {
|
ReplySurbsV1_1_19 {
|
||||||
minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD,
|
minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD,
|
||||||
maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD,
|
maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD,
|
||||||
minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE,
|
minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE,
|
||||||
@@ -314,20 +313,20 @@ impl Default for ReplySurbsV1_1_20 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(default, deny_unknown_fields)]
|
#[serde(default, deny_unknown_fields)]
|
||||||
pub struct DebugConfigV1_1_20 {
|
pub struct DebugConfigV1_1_19 {
|
||||||
pub traffic: TrafficV1_1_20,
|
pub traffic: TrafficV1_1_19,
|
||||||
pub cover_traffic: CoverTrafficV1_1_20,
|
pub cover_traffic: CoverTrafficV1_1_19,
|
||||||
pub gateway_connection: GatewayConnectionV1_1_20,
|
pub gateway_connection: GatewayConnectionV1_1_19,
|
||||||
pub acknowledgements: AcknowledgementsV1_1_20,
|
pub acknowledgements: AcknowledgementsV1_1_19,
|
||||||
pub topology: TopologyV1_1_20,
|
pub topology: TopologyV1_1_19,
|
||||||
pub reply_surbs: ReplySurbsV1_1_20,
|
pub reply_surbs: ReplySurbsV1_1_19,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DebugConfigV1_1_20> for DebugConfigV1_1_20_2 {
|
impl From<DebugConfigV1_1_19> for DebugConfig {
|
||||||
fn from(value: DebugConfigV1_1_20) -> Self {
|
fn from(value: DebugConfigV1_1_19) -> Self {
|
||||||
DebugConfigV1_1_20_2 {
|
DebugConfig {
|
||||||
traffic: value.traffic.into(),
|
traffic: value.traffic.into(),
|
||||||
cover_traffic: value.cover_traffic.into(),
|
cover_traffic: value.cover_traffic.into(),
|
||||||
gateway_connection: value.gateway_connection.into(),
|
gateway_connection: value.gateway_connection.into(),
|
||||||
@@ -337,3 +336,19 @@ impl From<DebugConfigV1_1_20> for DebugConfigV1_1_20_2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// it could be derived, sure, but I'd rather have an explicit implementation in case we had to change
|
||||||
|
// something manually at some point
|
||||||
|
#[allow(clippy::derivable_impls)]
|
||||||
|
impl Default for DebugConfigV1_1_19 {
|
||||||
|
fn default() -> Self {
|
||||||
|
DebugConfigV1_1_19 {
|
||||||
|
traffic: Default::default(),
|
||||||
|
cover_traffic: Default::default(),
|
||||||
|
gateway_connection: Default::default(),
|
||||||
|
acknowledgements: Default::default(),
|
||||||
|
topology: Default::default(),
|
||||||
|
reply_surbs: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,348 +0,0 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::config::{
|
|
||||||
Acknowledgements, Client, Config, CoverTraffic, DebugConfig, GatewayConnection,
|
|
||||||
GatewayEndpointConfig, ReplySurbs, Topology, Traffic,
|
|
||||||
};
|
|
||||||
use nym_sphinx::params::{PacketSize, PacketType};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::time::Duration;
|
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
// 'DEBUG'
|
|
||||||
const DEFAULT_ACK_WAIT_MULTIPLIER: f64 = 1.5;
|
|
||||||
|
|
||||||
const DEFAULT_ACK_WAIT_ADDITION: Duration = Duration::from_millis(1_500);
|
|
||||||
const DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(200);
|
|
||||||
const DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(20);
|
|
||||||
const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(50);
|
|
||||||
const DEFAULT_TOPOLOGY_REFRESH_RATE: Duration = Duration::from_secs(5 * 60); // every 5min
|
|
||||||
const DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT: Duration = Duration::from_millis(5_000);
|
|
||||||
// Set this to a high value for now, so that we don't risk sporadic timeouts that might cause
|
|
||||||
// bought bandwidth tokens to not have time to be spent; Once we remove the gateway from the
|
|
||||||
// bandwidth bridging protocol, we can come back to a smaller timeout value
|
|
||||||
const DEFAULT_GATEWAY_RESPONSE_TIMEOUT: Duration = Duration::from_secs(5 * 60);
|
|
||||||
|
|
||||||
const DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO: f64 = 0.70;
|
|
||||||
|
|
||||||
// reply-surbs related:
|
|
||||||
|
|
||||||
// define when to request
|
|
||||||
// clients/client-core/src/client/replies/reply_storage/surb_storage.rs
|
|
||||||
const DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 10;
|
|
||||||
const DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 200;
|
|
||||||
|
|
||||||
// define how much to request at once
|
|
||||||
// clients/client-core/src/client/replies/reply_controller.rs
|
|
||||||
const DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 10;
|
|
||||||
const DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 100;
|
|
||||||
|
|
||||||
const DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE: u32 = 500;
|
|
||||||
|
|
||||||
const DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD: Duration = Duration::from_secs(10);
|
|
||||||
const DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD: Duration = Duration::from_secs(5 * 60);
|
|
||||||
|
|
||||||
// 12 hours
|
|
||||||
const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 60);
|
|
||||||
|
|
||||||
// 24 hours
|
|
||||||
const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct ConfigV1_1_20_2 {
|
|
||||||
pub client: ClientV1_1_20_2,
|
|
||||||
|
|
||||||
#[serde(default)]
|
|
||||||
pub debug: DebugConfigV1_1_20_2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ConfigV1_1_20_2> for Config {
|
|
||||||
fn from(value: ConfigV1_1_20_2) -> Self {
|
|
||||||
Config {
|
|
||||||
client: value.client.into(),
|
|
||||||
debug: value.debug.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)]
|
|
||||||
pub struct GatewayEndpointConfigV1_1_20_2 {
|
|
||||||
/// gateway_id specifies ID of the gateway to which the client should send messages.
|
|
||||||
/// If initially omitted, a random gateway will be chosen from the available topology.
|
|
||||||
pub gateway_id: String,
|
|
||||||
|
|
||||||
/// Address of the gateway owner to which the client should send messages.
|
|
||||||
pub gateway_owner: String,
|
|
||||||
|
|
||||||
/// Address of the gateway listener to which all client requests should be sent.
|
|
||||||
pub gateway_listener: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<GatewayEndpointConfigV1_1_20_2> for GatewayEndpointConfig {
|
|
||||||
fn from(value: GatewayEndpointConfigV1_1_20_2) -> Self {
|
|
||||||
GatewayEndpointConfig {
|
|
||||||
gateway_id: value.gateway_id,
|
|
||||||
gateway_owner: value.gateway_owner,
|
|
||||||
gateway_listener: value.gateway_listener,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
|
||||||
pub struct ClientV1_1_20_2 {
|
|
||||||
pub version: String,
|
|
||||||
|
|
||||||
pub id: String,
|
|
||||||
|
|
||||||
#[serde(default)]
|
|
||||||
pub disabled_credentials_mode: bool,
|
|
||||||
|
|
||||||
#[serde(alias = "validator_urls")]
|
|
||||||
pub nyxd_urls: Vec<Url>,
|
|
||||||
|
|
||||||
#[serde(alias = "validator_api_urls")]
|
|
||||||
pub nym_api_urls: Vec<Url>,
|
|
||||||
pub gateway_endpoint: GatewayEndpointConfigV1_1_20_2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ClientV1_1_20_2> for Client {
|
|
||||||
fn from(value: ClientV1_1_20_2) -> Self {
|
|
||||||
Client {
|
|
||||||
version: value.version,
|
|
||||||
id: value.id,
|
|
||||||
disabled_credentials_mode: value.disabled_credentials_mode,
|
|
||||||
nyxd_urls: value.nyxd_urls,
|
|
||||||
nym_api_urls: value.nym_api_urls,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(default)]
|
|
||||||
pub struct TrafficV1_1_20_2 {
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub average_packet_delay: Duration,
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub message_sending_average_delay: Duration,
|
|
||||||
pub disable_main_poisson_packet_distribution: bool,
|
|
||||||
pub primary_packet_size: PacketSize,
|
|
||||||
pub secondary_packet_size: Option<PacketSize>,
|
|
||||||
pub packet_type: PacketType,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<TrafficV1_1_20_2> for Traffic {
|
|
||||||
fn from(value: TrafficV1_1_20_2) -> Self {
|
|
||||||
Traffic {
|
|
||||||
average_packet_delay: value.average_packet_delay,
|
|
||||||
message_sending_average_delay: value.message_sending_average_delay,
|
|
||||||
disable_main_poisson_packet_distribution: value
|
|
||||||
.disable_main_poisson_packet_distribution,
|
|
||||||
primary_packet_size: value.primary_packet_size,
|
|
||||||
secondary_packet_size: value.secondary_packet_size,
|
|
||||||
packet_type: PacketType::Mix,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for TrafficV1_1_20_2 {
|
|
||||||
fn default() -> Self {
|
|
||||||
TrafficV1_1_20_2 {
|
|
||||||
average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY,
|
|
||||||
message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY,
|
|
||||||
disable_main_poisson_packet_distribution: false,
|
|
||||||
primary_packet_size: PacketSize::RegularPacket,
|
|
||||||
secondary_packet_size: None,
|
|
||||||
packet_type: PacketType::Mix,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(default, deny_unknown_fields)]
|
|
||||||
pub struct CoverTrafficV1_1_20_2 {
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub loop_cover_traffic_average_delay: Duration,
|
|
||||||
pub cover_traffic_primary_size_ratio: f64,
|
|
||||||
pub disable_loop_cover_traffic_stream: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<CoverTrafficV1_1_20_2> for CoverTraffic {
|
|
||||||
fn from(value: CoverTrafficV1_1_20_2) -> Self {
|
|
||||||
CoverTraffic {
|
|
||||||
loop_cover_traffic_average_delay: value.loop_cover_traffic_average_delay,
|
|
||||||
cover_traffic_primary_size_ratio: value.cover_traffic_primary_size_ratio,
|
|
||||||
disable_loop_cover_traffic_stream: value.disable_loop_cover_traffic_stream,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for CoverTrafficV1_1_20_2 {
|
|
||||||
fn default() -> Self {
|
|
||||||
CoverTrafficV1_1_20_2 {
|
|
||||||
loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY,
|
|
||||||
cover_traffic_primary_size_ratio: DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO,
|
|
||||||
disable_loop_cover_traffic_stream: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(default, deny_unknown_fields)]
|
|
||||||
pub struct GatewayConnectionV1_1_20_2 {
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub gateway_response_timeout: Duration,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<GatewayConnectionV1_1_20_2> for GatewayConnection {
|
|
||||||
fn from(value: GatewayConnectionV1_1_20_2) -> Self {
|
|
||||||
GatewayConnection {
|
|
||||||
gateway_response_timeout: value.gateway_response_timeout,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for GatewayConnectionV1_1_20_2 {
|
|
||||||
fn default() -> Self {
|
|
||||||
GatewayConnectionV1_1_20_2 {
|
|
||||||
gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(default, deny_unknown_fields)]
|
|
||||||
pub struct AcknowledgementsV1_1_20_2 {
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub average_ack_delay: Duration,
|
|
||||||
pub ack_wait_multiplier: f64,
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub ack_wait_addition: Duration,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<AcknowledgementsV1_1_20_2> for Acknowledgements {
|
|
||||||
fn from(value: AcknowledgementsV1_1_20_2) -> Self {
|
|
||||||
Acknowledgements {
|
|
||||||
average_ack_delay: value.average_ack_delay,
|
|
||||||
ack_wait_multiplier: value.ack_wait_multiplier,
|
|
||||||
ack_wait_addition: value.ack_wait_addition,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for AcknowledgementsV1_1_20_2 {
|
|
||||||
fn default() -> Self {
|
|
||||||
AcknowledgementsV1_1_20_2 {
|
|
||||||
average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY,
|
|
||||||
ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER,
|
|
||||||
ack_wait_addition: DEFAULT_ACK_WAIT_ADDITION,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(default, deny_unknown_fields)]
|
|
||||||
pub struct TopologyV1_1_20_2 {
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub topology_refresh_rate: Duration,
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub topology_resolution_timeout: Duration,
|
|
||||||
pub disable_refreshing: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for TopologyV1_1_20_2 {
|
|
||||||
fn default() -> Self {
|
|
||||||
TopologyV1_1_20_2 {
|
|
||||||
topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE,
|
|
||||||
topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT,
|
|
||||||
disable_refreshing: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<TopologyV1_1_20_2> for Topology {
|
|
||||||
fn from(value: TopologyV1_1_20_2) -> Self {
|
|
||||||
Topology {
|
|
||||||
topology_refresh_rate: value.topology_refresh_rate,
|
|
||||||
topology_resolution_timeout: value.topology_resolution_timeout,
|
|
||||||
disable_refreshing: value.disable_refreshing,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(default, deny_unknown_fields)]
|
|
||||||
pub struct ReplySurbsV1_1_20_2 {
|
|
||||||
pub minimum_reply_surb_storage_threshold: usize,
|
|
||||||
pub maximum_reply_surb_storage_threshold: usize,
|
|
||||||
pub minimum_reply_surb_request_size: u32,
|
|
||||||
pub maximum_reply_surb_request_size: u32,
|
|
||||||
pub maximum_allowed_reply_surb_request_size: u32,
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub maximum_reply_surb_rerequest_waiting_period: Duration,
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub maximum_reply_surb_drop_waiting_period: Duration,
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub maximum_reply_surb_age: Duration,
|
|
||||||
#[serde(with = "humantime_serde")]
|
|
||||||
pub maximum_reply_key_age: Duration,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ReplySurbsV1_1_20_2 {
|
|
||||||
fn default() -> Self {
|
|
||||||
ReplySurbsV1_1_20_2 {
|
|
||||||
minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD,
|
|
||||||
maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD,
|
|
||||||
minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE,
|
|
||||||
maximum_reply_surb_request_size: DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE,
|
|
||||||
maximum_allowed_reply_surb_request_size: DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE,
|
|
||||||
maximum_reply_surb_rerequest_waiting_period:
|
|
||||||
DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD,
|
|
||||||
maximum_reply_surb_drop_waiting_period: DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD,
|
|
||||||
maximum_reply_surb_age: DEFAULT_MAXIMUM_REPLY_SURB_AGE,
|
|
||||||
maximum_reply_key_age: DEFAULT_MAXIMUM_REPLY_KEY_AGE,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ReplySurbsV1_1_20_2> for ReplySurbs {
|
|
||||||
fn from(value: ReplySurbsV1_1_20_2) -> Self {
|
|
||||||
ReplySurbs {
|
|
||||||
minimum_reply_surb_storage_threshold: value.minimum_reply_surb_storage_threshold,
|
|
||||||
maximum_reply_surb_storage_threshold: value.maximum_reply_surb_storage_threshold,
|
|
||||||
minimum_reply_surb_request_size: value.minimum_reply_surb_request_size,
|
|
||||||
maximum_reply_surb_request_size: value.maximum_reply_surb_request_size,
|
|
||||||
maximum_allowed_reply_surb_request_size: value.maximum_allowed_reply_surb_request_size,
|
|
||||||
maximum_reply_surb_rerequest_waiting_period: value
|
|
||||||
.maximum_reply_surb_rerequest_waiting_period,
|
|
||||||
maximum_reply_surb_drop_waiting_period: value.maximum_reply_surb_drop_waiting_period,
|
|
||||||
maximum_reply_surb_age: value.maximum_reply_surb_age,
|
|
||||||
maximum_reply_key_age: value.maximum_reply_key_age,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(default, deny_unknown_fields)]
|
|
||||||
pub struct DebugConfigV1_1_20_2 {
|
|
||||||
pub traffic: TrafficV1_1_20_2,
|
|
||||||
pub cover_traffic: CoverTrafficV1_1_20_2,
|
|
||||||
pub gateway_connection: GatewayConnectionV1_1_20_2,
|
|
||||||
pub acknowledgements: AcknowledgementsV1_1_20_2,
|
|
||||||
pub topology: TopologyV1_1_20_2,
|
|
||||||
pub reply_surbs: ReplySurbsV1_1_20_2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<DebugConfigV1_1_20_2> for DebugConfig {
|
|
||||||
fn from(value: DebugConfigV1_1_20_2) -> Self {
|
|
||||||
DebugConfig {
|
|
||||||
traffic: value.traffic.into(),
|
|
||||||
cover_traffic: value.cover_traffic.into(),
|
|
||||||
gateway_connection: value.gateway_connection.into(),
|
|
||||||
acknowledgements: value.acknowledgements.into(),
|
|
||||||
topology: value.topology.into(),
|
|
||||||
reply_surbs: value.reply_surbs.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -50,11 +50,6 @@ pub enum ClientCoreError {
|
|||||||
source: Box<dyn Error + Send + Sync>,
|
source: Box<dyn Error + Send + Sync>,
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("experienced a failure with our gateway details storage: {source}")]
|
|
||||||
GatewayDetailsStoreError {
|
|
||||||
source: Box<dyn Error + Send + Sync>,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[error("The gateway id is invalid - {0}")]
|
#[error("The gateway id is invalid - {0}")]
|
||||||
UnableToCreatePublicKeyFromGatewayId(Ed25519RecoveryError),
|
UnableToCreatePublicKeyFromGatewayId(Ed25519RecoveryError),
|
||||||
|
|
||||||
@@ -102,20 +97,6 @@ pub enum ClientCoreError {
|
|||||||
"This operation would have resulted in clients keys being overwritten without permission"
|
"This operation would have resulted in clients keys being overwritten without permission"
|
||||||
)]
|
)]
|
||||||
ForbiddenKeyOverwrite,
|
ForbiddenKeyOverwrite,
|
||||||
|
|
||||||
#[error("gateway details are unavailable")]
|
|
||||||
UnavailableGatewayDetails {
|
|
||||||
source: Box<dyn Error + Send + Sync>,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[error("gateway shared key is unavailable whilst we have full node information")]
|
|
||||||
UnavailableSharedKey,
|
|
||||||
|
|
||||||
#[error("attempted to obtain fresh gateway details whilst already knowing about one")]
|
|
||||||
UnexpectedGatewayDetails,
|
|
||||||
|
|
||||||
#[error("the provided gateway details (for gateway {gateway_id}) do not correspond to the shared keys")]
|
|
||||||
MismatchedGatewayDetails { gateway_id: String },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set of messages that the client can send to listeners via the task manager
|
/// Set of messages that the client can send to listeners via the task manager
|
||||||
|
|||||||
@@ -44,18 +44,18 @@ const MEASUREMENTS: usize = 3;
|
|||||||
const CONN_TIMEOUT: Duration = Duration::from_millis(1500);
|
const CONN_TIMEOUT: Duration = Duration::from_millis(1500);
|
||||||
const PING_TIMEOUT: Duration = Duration::from_millis(1000);
|
const PING_TIMEOUT: Duration = Duration::from_millis(1000);
|
||||||
|
|
||||||
struct GatewayWithLatency<'a> {
|
struct GatewayWithLatency {
|
||||||
gateway: &'a gateway::Node,
|
gateway: gateway::Node,
|
||||||
latency: Duration,
|
latency: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> GatewayWithLatency<'a> {
|
impl GatewayWithLatency {
|
||||||
fn new(gateway: &'a gateway::Node, latency: Duration) -> Self {
|
fn new(gateway: gateway::Node, latency: Duration) -> Self {
|
||||||
GatewayWithLatency { gateway, latency }
|
GatewayWithLatency { gateway, latency }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn current_gateways<R: Rng>(
|
pub(super) async fn current_gateways<R: Rng>(
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
nym_apis: &[Url],
|
nym_apis: &[Url],
|
||||||
) -> Result<Vec<gateway::Node>, ClientCoreError> {
|
) -> Result<Vec<gateway::Node>, ClientCoreError> {
|
||||||
@@ -64,7 +64,7 @@ pub async fn current_gateways<R: Rng>(
|
|||||||
.ok_or(ClientCoreError::ListOfNymApisIsEmpty)?;
|
.ok_or(ClientCoreError::ListOfNymApisIsEmpty)?;
|
||||||
let client = nym_validator_client::client::NymApiClient::new(nym_api.clone());
|
let client = nym_validator_client::client::NymApiClient::new(nym_api.clone());
|
||||||
|
|
||||||
log::trace!("Fetching list of gateways from: {nym_api}");
|
log::trace!("Fetching list of gateways from: {}", nym_api);
|
||||||
|
|
||||||
let gateways = client.get_cached_gateways().await?;
|
let gateways = client.get_cached_gateways().await?;
|
||||||
let valid_gateways = gateways
|
let valid_gateways = gateways
|
||||||
@@ -91,7 +91,7 @@ async fn connect(endpoint: &str) -> Result<WsConn, ClientCoreError> {
|
|||||||
JSWebsocket::new(endpoint).map_err(|_| ClientCoreError::GatewayJsConnectionFailure)
|
JSWebsocket::new(endpoint).map_err(|_| ClientCoreError::GatewayJsConnectionFailure)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn measure_latency(gateway: &gateway::Node) -> Result<GatewayWithLatency, ClientCoreError> {
|
async fn measure_latency(gateway: gateway::Node) -> Result<GatewayWithLatency, ClientCoreError> {
|
||||||
let addr = gateway.clients_address();
|
let addr = gateway.clients_address();
|
||||||
trace!(
|
trace!(
|
||||||
"establishing connection to {} ({addr})...",
|
"establishing connection to {} ({addr})...",
|
||||||
@@ -156,7 +156,7 @@ async fn measure_latency(gateway: &gateway::Node) -> Result<GatewayWithLatency,
|
|||||||
|
|
||||||
pub(super) async fn choose_gateway_by_latency<R: Rng>(
|
pub(super) async fn choose_gateway_by_latency<R: Rng>(
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
gateways: &[gateway::Node],
|
gateways: Vec<gateway::Node>,
|
||||||
) -> Result<gateway::Node, ClientCoreError> {
|
) -> Result<gateway::Node, ClientCoreError> {
|
||||||
info!("choosing gateway by latency...");
|
info!("choosing gateway by latency...");
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ pub(super) async fn choose_gateway_by_latency<R: Rng>(
|
|||||||
|
|
||||||
pub(super) fn uniformly_random_gateway<R: Rng>(
|
pub(super) fn uniformly_random_gateway<R: Rng>(
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
gateways: &[gateway::Node],
|
gateways: Vec<gateway::Node>,
|
||||||
) -> Result<gateway::Node, ClientCoreError> {
|
) -> Result<gateway::Node, ClientCoreError> {
|
||||||
gateways
|
gateways
|
||||||
.choose(rng)
|
.choose(rng)
|
||||||
|
|||||||
+146
-274
@@ -3,82 +3,26 @@
|
|||||||
|
|
||||||
//! Collection of initialization steps used by client implementations
|
//! Collection of initialization steps used by client implementations
|
||||||
|
|
||||||
use crate::client::base_client::storage::gateway_details::{
|
use crate::client::base_client::storage::MixnetClientStorage;
|
||||||
GatewayDetailsStore, PersistedGatewayDetails,
|
|
||||||
};
|
|
||||||
use crate::client::key_manager::persistence::KeyStore;
|
use crate::client::key_manager::persistence::KeyStore;
|
||||||
use crate::client::key_manager::ManagedKeys;
|
use crate::client::key_manager::{KeyManager, ManagedKeys};
|
||||||
use crate::init::helpers::{choose_gateway_by_latency, current_gateways, uniformly_random_gateway};
|
use crate::init::helpers::{choose_gateway_by_latency, current_gateways, uniformly_random_gateway};
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{Config, GatewayEndpointConfig},
|
config::{disk_persistence::keys_paths::ClientKeysPaths, Config, GatewayEndpointConfig},
|
||||||
error::ClientCoreError,
|
error::ClientCoreError,
|
||||||
};
|
};
|
||||||
use nym_crypto::asymmetric::identity;
|
use nym_crypto::asymmetric::{encryption, identity};
|
||||||
use nym_sphinx::addressing::{clients::Recipient, nodes::NodeIdentity};
|
use nym_sphinx::addressing::{clients::Recipient, nodes::NodeIdentity};
|
||||||
use nym_topology::gateway;
|
|
||||||
use nym_validator_client::client::IdentityKey;
|
use nym_validator_client::client::IdentityKey;
|
||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub mod helpers;
|
mod helpers;
|
||||||
|
|
||||||
// TODO: rename to something better...
|
#[derive(Clone)]
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct InitialisationDetails {
|
|
||||||
pub gateway_details: GatewayEndpointConfig,
|
|
||||||
pub managed_keys: ManagedKeys,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InitialisationDetails {
|
|
||||||
pub fn new(gateway_details: GatewayEndpointConfig, managed_keys: ManagedKeys) -> Self {
|
|
||||||
InitialisationDetails {
|
|
||||||
gateway_details,
|
|
||||||
managed_keys,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn try_load<K, D>(key_store: &K, details_store: &D) -> Result<Self, ClientCoreError>
|
|
||||||
where
|
|
||||||
K: KeyStore,
|
|
||||||
D: GatewayDetailsStore,
|
|
||||||
K::StorageError: Send + Sync + 'static,
|
|
||||||
D::StorageError: Send + Sync + 'static,
|
|
||||||
{
|
|
||||||
let loaded_details = _load_gateway_details(details_store).await?;
|
|
||||||
let loaded_keys = _load_managed_keys(key_store).await?;
|
|
||||||
|
|
||||||
if !loaded_details.verify(&loaded_keys.must_get_gateway_shared_key()) {
|
|
||||||
return Err(ClientCoreError::MismatchedGatewayDetails {
|
|
||||||
gateway_id: loaded_details.details.gateway_id,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(InitialisationDetails {
|
|
||||||
gateway_details: loaded_details.into(),
|
|
||||||
managed_keys: loaded_keys,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn client_address(&self) -> Result<Recipient, ClientCoreError> {
|
|
||||||
let client_recipient = Recipient::new(
|
|
||||||
*self.managed_keys.identity_public_key(),
|
|
||||||
*self.managed_keys.encryption_public_key(),
|
|
||||||
// TODO: below only works under assumption that gateway address == gateway id
|
|
||||||
// (which currently is true)
|
|
||||||
NodeIdentity::from_base58_string(&self.gateway_details.gateway_id)?,
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(client_recipient)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub enum GatewaySetup {
|
pub enum GatewaySetup {
|
||||||
/// The gateway specification MUST BE loaded from the underlying storage.
|
|
||||||
MustLoad,
|
|
||||||
|
|
||||||
/// Specifies usage of a new, random, gateway.
|
/// Specifies usage of a new, random, gateway.
|
||||||
New {
|
New {
|
||||||
/// Should the new gateway be selected based on latency.
|
/// Should the new gateway be selected based on latency.
|
||||||
@@ -90,13 +34,13 @@ pub enum GatewaySetup {
|
|||||||
},
|
},
|
||||||
Predefined {
|
Predefined {
|
||||||
/// Full gateway configuration
|
/// Full gateway configuration
|
||||||
details: PersistedGatewayDetails,
|
config: GatewayEndpointConfig,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PersistedGatewayDetails> for GatewaySetup {
|
impl From<GatewayEndpointConfig> for GatewaySetup {
|
||||||
fn from(details: PersistedGatewayDetails) -> Self {
|
fn from(config: GatewayEndpointConfig) -> Self {
|
||||||
GatewaySetup::Predefined { details }
|
GatewaySetup::Predefined { config }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,11 +57,14 @@ impl Default for GatewaySetup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GatewaySetup {
|
impl GatewaySetup {
|
||||||
pub fn new_fresh(
|
pub fn new(
|
||||||
gateway_identity: Option<String>,
|
full_config: Option<GatewayEndpointConfig>,
|
||||||
|
gateway_identity: Option<IdentityKey>,
|
||||||
latency_based_selection: Option<bool>,
|
latency_based_selection: Option<bool>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
if let Some(gateway_identity) = gateway_identity {
|
if let Some(config) = full_config {
|
||||||
|
GatewaySetup::Predefined { config }
|
||||||
|
} else if let Some(gateway_identity) = gateway_identity {
|
||||||
GatewaySetup::Specified { gateway_identity }
|
GatewaySetup::Specified { gateway_identity }
|
||||||
} else {
|
} else {
|
||||||
GatewaySetup::New {
|
GatewaySetup::New {
|
||||||
@@ -126,22 +73,15 @@ impl GatewaySetup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_must_load(&self) -> bool {
|
pub async fn try_get_gateway_details(
|
||||||
matches!(self, GatewaySetup::MustLoad)
|
self,
|
||||||
}
|
validator_servers: &[Url],
|
||||||
|
|
||||||
pub fn has_full_details(&self) -> bool {
|
|
||||||
matches!(self, GatewaySetup::Predefined { .. }) || self.is_must_load()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn choose_gateway(
|
|
||||||
&self,
|
|
||||||
gateways: &[gateway::Node],
|
|
||||||
) -> Result<GatewayEndpointConfig, ClientCoreError> {
|
) -> Result<GatewayEndpointConfig, ClientCoreError> {
|
||||||
match self {
|
match self {
|
||||||
GatewaySetup::New { by_latency } => {
|
GatewaySetup::New { by_latency } => {
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
if *by_latency {
|
let gateways = current_gateways(&mut rng, validator_servers).await?;
|
||||||
|
if by_latency {
|
||||||
choose_gateway_by_latency(&mut rng, gateways).await
|
choose_gateway_by_latency(&mut rng, gateways).await
|
||||||
} else {
|
} else {
|
||||||
uniformly_random_gateway(&mut rng, gateways)
|
uniformly_random_gateway(&mut rng, gateways)
|
||||||
@@ -149,28 +89,20 @@ impl GatewaySetup {
|
|||||||
}
|
}
|
||||||
.map(Into::into),
|
.map(Into::into),
|
||||||
GatewaySetup::Specified { gateway_identity } => {
|
GatewaySetup::Specified { gateway_identity } => {
|
||||||
let user_gateway = identity::PublicKey::from_base58_string(gateway_identity)
|
let user_gateway = identity::PublicKey::from_base58_string(&gateway_identity)
|
||||||
.map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?;
|
.map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?;
|
||||||
|
|
||||||
|
let mut rng = OsRng;
|
||||||
|
let gateways = current_gateways(&mut rng, validator_servers).await?;
|
||||||
gateways
|
gateways
|
||||||
.iter()
|
.into_iter()
|
||||||
.find(|gateway| gateway.identity_key == user_gateway)
|
.find(|gateway| gateway.identity_key == user_gateway)
|
||||||
.ok_or_else(|| ClientCoreError::NoGatewayWithId(gateway_identity.to_string()))
|
.ok_or_else(|| ClientCoreError::NoGatewayWithId(gateway_identity.to_string()))
|
||||||
.cloned()
|
|
||||||
}
|
}
|
||||||
.map(Into::into),
|
.map(Into::into),
|
||||||
_ => Err(ClientCoreError::UnexpectedGatewayDetails),
|
GatewaySetup::Predefined { config } => Ok(config),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn try_get_new_gateway_details(
|
|
||||||
&self,
|
|
||||||
validator_servers: &[Url],
|
|
||||||
) -> Result<GatewayEndpointConfig, ClientCoreError> {
|
|
||||||
let mut rng = OsRng;
|
|
||||||
let gateways = current_gateways(&mut rng, validator_servers).await?;
|
|
||||||
self.choose_gateway(&gateways).await
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Struct describing the results of the client initialization procedure.
|
/// Struct describing the results of the client initialization procedure.
|
||||||
@@ -185,14 +117,14 @@ pub struct InitResults {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl InitResults {
|
impl InitResults {
|
||||||
pub fn new(config: &Config, address: &Recipient, gateway: &GatewayEndpointConfig) -> Self {
|
pub fn new(config: &Config, address: &Recipient) -> Self {
|
||||||
Self {
|
Self {
|
||||||
version: config.client.version.clone(),
|
version: config.client.version.clone(),
|
||||||
id: config.client.id.clone(),
|
id: config.client.id.clone(),
|
||||||
identity_key: address.identity().to_base58_string(),
|
identity_key: address.identity().to_base58_string(),
|
||||||
encryption_key: address.encryption_key().to_base58_string(),
|
encryption_key: address.encryption_key().to_base58_string(),
|
||||||
gateway_id: gateway.gateway_id.clone(),
|
gateway_id: config.get_gateway_id(),
|
||||||
gateway_listener: gateway.gateway_listener.clone(),
|
gateway_listener: config.get_gateway_listener(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -208,164 +140,38 @@ impl Display for InitResults {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// helpers for error wrapping
|
/// Recovers the already present gateway information or attempts to register with new gateway
|
||||||
async fn _store_gateway_details<D>(
|
/// and stores the newly obtained key
|
||||||
details_store: &D,
|
pub async fn get_registered_gateway<S>(
|
||||||
details: &PersistedGatewayDetails,
|
validator_servers: Vec<Url>,
|
||||||
) -> Result<(), ClientCoreError>
|
key_store: &S::KeyStore,
|
||||||
|
setup: GatewaySetup,
|
||||||
|
overwrite_keys: bool,
|
||||||
|
) -> Result<GatewayEndpointConfig, ClientCoreError>
|
||||||
where
|
where
|
||||||
D: GatewayDetailsStore,
|
S: MixnetClientStorage,
|
||||||
D::StorageError: Send + Sync + 'static,
|
<S::KeyStore as KeyStore>::StorageError: Send + Sync + 'static,
|
||||||
{
|
|
||||||
details_store
|
|
||||||
.store_gateway_details(details)
|
|
||||||
.await
|
|
||||||
.map_err(|source| ClientCoreError::GatewayDetailsStoreError {
|
|
||||||
source: Box::new(source),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn _load_gateway_details<D>(
|
|
||||||
details_store: &D,
|
|
||||||
) -> Result<PersistedGatewayDetails, ClientCoreError>
|
|
||||||
where
|
|
||||||
D: GatewayDetailsStore,
|
|
||||||
D::StorageError: Send + Sync + 'static,
|
|
||||||
{
|
|
||||||
details_store
|
|
||||||
.load_gateway_details()
|
|
||||||
.await
|
|
||||||
.map_err(|source| ClientCoreError::UnavailableGatewayDetails {
|
|
||||||
source: Box::new(source),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn _load_managed_keys<K>(key_store: &K) -> Result<ManagedKeys, ClientCoreError>
|
|
||||||
where
|
|
||||||
K: KeyStore,
|
|
||||||
K::StorageError: Send + Sync + 'static,
|
|
||||||
{
|
|
||||||
ManagedKeys::try_load(key_store)
|
|
||||||
.await
|
|
||||||
.map_err(|source| ClientCoreError::KeyStoreError {
|
|
||||||
source: Box::new(source),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ensure_valid_details(
|
|
||||||
details: &PersistedGatewayDetails,
|
|
||||||
loaded_keys: &ManagedKeys,
|
|
||||||
) -> Result<(), ClientCoreError> {
|
|
||||||
if !details.verify(&loaded_keys.must_get_gateway_shared_key()) {
|
|
||||||
Err(ClientCoreError::MismatchedGatewayDetails {
|
|
||||||
gateway_id: details.details.gateway_id.clone(),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn setup_gateway_from<K, D>(
|
|
||||||
setup: &GatewaySetup,
|
|
||||||
key_store: &K,
|
|
||||||
details_store: &D,
|
|
||||||
overwrite_data: bool,
|
|
||||||
gateways: Option<&[gateway::Node]>,
|
|
||||||
) -> Result<InitialisationDetails, ClientCoreError>
|
|
||||||
where
|
|
||||||
K: KeyStore,
|
|
||||||
D: GatewayDetailsStore,
|
|
||||||
K::StorageError: Send + Sync + 'static,
|
|
||||||
D::StorageError: Send + Sync + 'static,
|
|
||||||
{
|
{
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
|
|
||||||
// try load gateway details
|
// try load keys
|
||||||
let loaded_details = _load_gateway_details(details_store).await;
|
|
||||||
|
|
||||||
// try load keys and decide what to do based on the GatewaySetup
|
|
||||||
let mut managed_keys = match ManagedKeys::try_load(key_store).await {
|
let mut managed_keys = match ManagedKeys::try_load(key_store).await {
|
||||||
Ok(loaded_keys) => {
|
Ok(_) => {
|
||||||
match setup {
|
// if we loaded something and we don't have full gateway details, check if we can overwrite the data
|
||||||
GatewaySetup::MustLoad => {
|
if let GatewaySetup::Predefined { config } = setup {
|
||||||
// get EVERYTHING from the storage
|
// we already have defined gateway details AND a shared key, so nothing more for us to do
|
||||||
let details = loaded_details?;
|
return Ok(config);
|
||||||
ensure_valid_details(&details, &loaded_keys)?;
|
} else if overwrite_keys {
|
||||||
|
ManagedKeys::generate_new(&mut rng)
|
||||||
// no need to persist anything as we got everything from the storage
|
} else {
|
||||||
return Ok(InitialisationDetails::new(details.into(), loaded_keys));
|
return Err(ClientCoreError::ForbiddenKeyOverwrite);
|
||||||
}
|
|
||||||
GatewaySetup::Predefined { details } => {
|
|
||||||
// we already have defined gateway details AND a shared key
|
|
||||||
ensure_valid_details(details, &loaded_keys)?;
|
|
||||||
|
|
||||||
// if nothing was stored or we're allowed to overwrite what's there, just persist the passed data
|
|
||||||
if overwrite_data || loaded_details.is_err() {
|
|
||||||
_store_gateway_details(details_store, details).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(InitialisationDetails::new(
|
|
||||||
details.clone().into(),
|
|
||||||
loaded_keys,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
GatewaySetup::Specified { gateway_identity } => {
|
|
||||||
// if that data was already stored...
|
|
||||||
if let Ok(existing_gateway) = loaded_details {
|
|
||||||
ensure_valid_details(&existing_gateway, &loaded_keys)?;
|
|
||||||
if &existing_gateway.details.gateway_id != gateway_identity
|
|
||||||
&& !overwrite_data
|
|
||||||
{
|
|
||||||
// if our loaded details don't match requested value and we CANT overwrite it...
|
|
||||||
return Err(ClientCoreError::UnexpectedGatewayDetails);
|
|
||||||
} else if &existing_gateway.details.gateway_id == gateway_identity {
|
|
||||||
// if they do match up, just return it
|
|
||||||
return Ok(InitialisationDetails::new(
|
|
||||||
existing_gateway.into(),
|
|
||||||
loaded_keys,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we didn't get full details from the store and we have loaded some keys
|
|
||||||
// so we can only continue if we're allowed to overwrite keys
|
|
||||||
if overwrite_data {
|
|
||||||
ManagedKeys::generate_new(&mut rng)
|
|
||||||
} else {
|
|
||||||
return Err(ClientCoreError::ForbiddenKeyOverwrite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
GatewaySetup::New { .. } => {
|
|
||||||
if let Ok(existing_gateway) = loaded_details {
|
|
||||||
ensure_valid_details(&existing_gateway, &loaded_keys)?;
|
|
||||||
return Ok(InitialisationDetails::new(
|
|
||||||
existing_gateway.into(),
|
|
||||||
loaded_keys,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// we didn't get full details from the store and we have loaded some keys
|
|
||||||
// so we can only continue if we're allowed to overwrite keys
|
|
||||||
if overwrite_data {
|
|
||||||
ManagedKeys::generate_new(&mut rng)
|
|
||||||
} else {
|
|
||||||
return Err(ClientCoreError::ForbiddenKeyOverwrite);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => ManagedKeys::generate_new(&mut rng),
|
||||||
// if we failed to load the keys, ensure we didn't provide gateway details in some form
|
|
||||||
// (in that case we CAN'T generate new keys
|
|
||||||
if setup.has_full_details() {
|
|
||||||
return Err(ClientCoreError::UnavailableSharedKey);
|
|
||||||
}
|
|
||||||
ManagedKeys::generate_new(&mut rng)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// choose gateway
|
// choose gateway
|
||||||
let gateway_details = setup.choose_gateway(gateways.unwrap_or_default()).await?;
|
let gateway_details = setup.try_get_gateway_details(&validator_servers).await?;
|
||||||
|
|
||||||
// get our identity key
|
// get our identity key
|
||||||
let our_identity = managed_keys.identity_keypair();
|
let our_identity = managed_keys.identity_keypair();
|
||||||
@@ -373,9 +179,6 @@ where
|
|||||||
// Establish connection, authenticate and generate keys for talking with the gateway
|
// Establish connection, authenticate and generate keys for talking with the gateway
|
||||||
let shared_keys = helpers::register_with_gateway(&gateway_details, our_identity).await?;
|
let shared_keys = helpers::register_with_gateway(&gateway_details, our_identity).await?;
|
||||||
|
|
||||||
let persisted_details = PersistedGatewayDetails::new(gateway_details, &shared_keys);
|
|
||||||
|
|
||||||
// persist gateway keys
|
|
||||||
managed_keys
|
managed_keys
|
||||||
.deal_with_gateway_key(shared_keys, key_store)
|
.deal_with_gateway_key(shared_keys, key_store)
|
||||||
.await
|
.await
|
||||||
@@ -383,39 +186,108 @@ where
|
|||||||
source: Box::new(source),
|
source: Box::new(source),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// persist gateway config
|
// TODO: here we should be probably persisting gateway details as opposed to returning them
|
||||||
_store_gateway_details(details_store, &persisted_details).await?;
|
|
||||||
|
|
||||||
Ok(InitialisationDetails::new(
|
Ok(gateway_details)
|
||||||
persisted_details.into(),
|
|
||||||
managed_keys,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn setup_gateway<K, D>(
|
/// Convenience function for setting up the gateway for a client given a `Config`. Depending on the
|
||||||
setup: &GatewaySetup,
|
/// arguments given it will do the sensible thing. Either it will
|
||||||
key_store: &K,
|
///
|
||||||
details_store: &D,
|
/// a. Reuse existing gateway configuration from storage.
|
||||||
overwrite_data: bool,
|
/// b. Create a new gateway configuration but keep existing keys. This assumes that the caller
|
||||||
validator_servers: Option<&[Url]>,
|
/// knows what they are doing and that the keys match the requested gateway.
|
||||||
) -> Result<InitialisationDetails, ClientCoreError>
|
/// c. Create a new gateway configuration with a newly registered gateway and keys.
|
||||||
|
pub async fn setup_gateway_from_config<KSt>(
|
||||||
|
key_store: &KSt,
|
||||||
|
register_gateway: bool,
|
||||||
|
user_chosen_gateway_id: Option<identity::PublicKey>,
|
||||||
|
config: &Config,
|
||||||
|
by_latency: bool,
|
||||||
|
) -> Result<GatewayEndpointConfig, ClientCoreError>
|
||||||
where
|
where
|
||||||
K: KeyStore,
|
KSt: KeyStore,
|
||||||
D: GatewayDetailsStore,
|
<KSt as KeyStore>::StorageError: Send + Sync + 'static,
|
||||||
K::StorageError: Send + Sync + 'static,
|
|
||||||
D::StorageError: Send + Sync + 'static,
|
|
||||||
{
|
{
|
||||||
let mut rng = OsRng;
|
// If we are not going to register gateway, and an explicitly chosen gateway is not passed in,
|
||||||
let gateways = current_gateways(&mut rng, validator_servers.unwrap_or_default()).await?;
|
// load the existing configuration file
|
||||||
|
if !register_gateway && user_chosen_gateway_id.is_none() {
|
||||||
|
eprintln!("Not registering gateway, will reuse existing config and keys");
|
||||||
|
return Ok(config.client.gateway_endpoint.clone());
|
||||||
|
}
|
||||||
|
|
||||||
setup_gateway_from(
|
let gateway_setup = GatewaySetup::new(
|
||||||
setup,
|
None,
|
||||||
key_store,
|
user_chosen_gateway_id.map(|id| id.to_base58_string()),
|
||||||
details_store,
|
Some(by_latency),
|
||||||
overwrite_data,
|
);
|
||||||
Some(&gateways),
|
// Else, we proceed by querying the nym-api
|
||||||
|
let gateway = gateway_setup
|
||||||
|
.try_get_gateway_details(&config.get_nym_api_endpoints())
|
||||||
|
.await?;
|
||||||
|
log::debug!("Querying gateway gives: {:?}", gateway);
|
||||||
|
|
||||||
|
// If we are not registering, just return this and assume the caller has the keys already and
|
||||||
|
// wants to keep the,
|
||||||
|
if !register_gateway && user_chosen_gateway_id.is_some() {
|
||||||
|
eprintln!("Using gateway provided by user, keeping existing keys");
|
||||||
|
return Ok(gateway);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut rng = OsRng;
|
||||||
|
let mut managed_keys =
|
||||||
|
crate::client::key_manager::ManagedKeys::load_or_generate(&mut rng, key_store).await;
|
||||||
|
|
||||||
|
// Create new keys and derive our identity
|
||||||
|
let our_identity = managed_keys.identity_keypair();
|
||||||
|
|
||||||
|
// Establish connection, authenticate and generate keys for talking with the gateway
|
||||||
|
eprintln!("Registering with new gateway");
|
||||||
|
let shared_keys = helpers::register_with_gateway(&gateway, our_identity).await?;
|
||||||
|
managed_keys
|
||||||
|
.deal_with_gateway_key(shared_keys, key_store)
|
||||||
|
.await
|
||||||
|
.map_err(|source| ClientCoreError::KeyStoreError {
|
||||||
|
source: Box::new(source),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(gateway)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the full client address from the client keys and the gateway identity
|
||||||
|
pub fn get_client_address(
|
||||||
|
key_manager: &KeyManager,
|
||||||
|
gateway_config: &GatewayEndpointConfig,
|
||||||
|
) -> Recipient {
|
||||||
|
Recipient::new(
|
||||||
|
*key_manager.identity_keypair().public_key(),
|
||||||
|
*key_manager.encryption_keypair().public_key(),
|
||||||
|
// TODO: below only works under assumption that gateway address == gateway id
|
||||||
|
// (which currently is true)
|
||||||
|
NodeIdentity::from_base58_string(&gateway_config.gateway_id).unwrap(),
|
||||||
)
|
)
|
||||||
.await
|
}
|
||||||
|
|
||||||
|
/// Get the client address by loading the keys from stored files.
|
||||||
|
// TODO: rethink that sucker
|
||||||
|
pub fn get_client_address_from_stored_ondisk_keys(
|
||||||
|
keys_paths: &ClientKeysPaths,
|
||||||
|
gateway_config: &GatewayEndpointConfig,
|
||||||
|
) -> Result<Recipient, ClientCoreError> {
|
||||||
|
let public_identity: identity::PublicKey =
|
||||||
|
nym_pemstore::load_key(&keys_paths.public_identity_key_file)?;
|
||||||
|
let public_encryption: encryption::PublicKey =
|
||||||
|
nym_pemstore::load_key(&keys_paths.public_encryption_key_file)?;
|
||||||
|
|
||||||
|
let client_recipient = Recipient::new(
|
||||||
|
public_identity,
|
||||||
|
public_encryption,
|
||||||
|
// TODO: below only works under assumption that gateway address == gateway id
|
||||||
|
// (which currently is true)
|
||||||
|
NodeIdentity::from_base58_string(&gateway_config.gateway_id)?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(client_recipient)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn output_to_json<T: Serialize>(init_results: &T, output_file: &str) {
|
pub fn output_to_json<T: Serialize>(init_results: &T, output_file: &str) {
|
||||||
|
|||||||
@@ -724,7 +724,7 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn try_reconnect(&mut self) -> Result<(), GatewayClientError> {
|
async fn try_reconnect(&mut self) -> Result<(), GatewayClientError> {
|
||||||
if !self.connection.is_established() {
|
if !self.connection.is_established() {
|
||||||
self.establish_connection().await?;
|
self.establish_connection().await?;
|
||||||
}
|
}
|
||||||
@@ -738,12 +738,6 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn disconnect(&mut self) -> Result<(), GatewayClientError> {
|
|
||||||
self.recover_socket_connection().await?;
|
|
||||||
self.connection = SocketState::NotConnected;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn authenticate_and_start(&mut self) -> Result<Arc<SharedKeys>, GatewayClientError>
|
pub async fn authenticate_and_start(&mut self) -> Result<Arc<SharedKeys>, GatewayClientError>
|
||||||
where
|
where
|
||||||
C: DkgQueryClient + Send + Sync,
|
C: DkgQueryClient + Send + Sync,
|
||||||
|
|||||||
@@ -48,21 +48,17 @@ impl PacketRouter {
|
|||||||
// data he takes the SURB-ACK and first hop address.
|
// data he takes the SURB-ACK and first hop address.
|
||||||
// currently SURB-ACKs are attached in EVERY packet, even cover, so this is always true
|
// currently SURB-ACKs are attached in EVERY packet, even cover, so this is always true
|
||||||
let ack_overhead = PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN;
|
let ack_overhead = PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN;
|
||||||
let outfox_ack_overhead =
|
|
||||||
PacketSize::OutfoxAckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN;
|
|
||||||
|
|
||||||
for received_packet in unwrapped_packets {
|
for received_packet in unwrapped_packets {
|
||||||
if received_packet.len() == PacketSize::AckPacket.plaintext_size()
|
if received_packet.len() == PacketSize::AckPacket.plaintext_size()
|
||||||
// we don't know the real size of the payload, it could be anything <= 48 bytes
|
|| received_packet.len() == PacketSize::OutfoxAckPacket.plaintext_size()
|
||||||
|| received_packet.len() <= PacketSize::OutfoxAckPacket.plaintext_size()
|
|
||||||
{
|
{
|
||||||
received_acks.push(received_packet);
|
received_acks.push(received_packet);
|
||||||
} else if received_packet.len()
|
} else if received_packet.len()
|
||||||
== PacketSize::RegularPacket.plaintext_size() - ack_overhead
|
== PacketSize::RegularPacket.plaintext_size() - ack_overhead
|
||||||
|| received_packet.len()
|
|| received_packet.len()
|
||||||
== PacketSize::OutfoxRegularPacket.plaintext_size() - outfox_ack_overhead
|
== PacketSize::OutfoxRegularPacket.plaintext_size() - ack_overhead
|
||||||
|| received_packet.len()
|
|| received_packet.len() == PacketSize::OutfoxRegularPacket.size() - 6
|
||||||
== PacketSize::OutfoxRegularPacket.size() - outfox_ack_overhead
|
|
||||||
{
|
{
|
||||||
trace!("routing regular packet");
|
trace!("routing regular packet");
|
||||||
received_messages.push(received_packet);
|
received_messages.push(received_packet);
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ log = { workspace = true }
|
|||||||
url = { version = "2.2", features = ["serde"] }
|
url = { version = "2.2", features = ["serde"] }
|
||||||
tokio = { version = "1.24.1", features = ["sync", "time"] }
|
tokio = { version = "1.24.1", features = ["sync", "time"] }
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
openssl = { version = "0.10", features = ["vendored"], optional = true }
|
|
||||||
|
|
||||||
nym-coconut-interface = { path = "../../coconut-interface" }
|
nym-coconut-interface = { path = "../../coconut-interface" }
|
||||||
nym-network-defaults = { path = "../../network-defaults" }
|
nym-network-defaults = { path = "../../network-defaults" }
|
||||||
@@ -78,14 +77,13 @@ required-features = ["nyxd-client"]
|
|||||||
nyxd-client = [
|
nyxd-client = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"cosmrs",
|
"cosmrs",
|
||||||
"cosmwasm-std",
|
|
||||||
"cw3",
|
"cw3",
|
||||||
"cw4",
|
"cw4",
|
||||||
"flate2",
|
|
||||||
"itertools",
|
|
||||||
"openssl",
|
|
||||||
"prost",
|
"prost",
|
||||||
|
"flate2",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
"itertools",
|
||||||
|
"cosmwasm-std",
|
||||||
"signing"
|
"signing"
|
||||||
]
|
]
|
||||||
signing = [
|
signing = [
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use cosmrs::AccountId;
|
use cosmrs::AccountId;
|
||||||
use nym_contracts_common::{signing::Nonce, ContractBuildInformation};
|
use nym_contracts_common::ContractBuildInformation;
|
||||||
use nym_service_provider_directory_common::{
|
use nym_service_provider_directory_common::{
|
||||||
msg::QueryMsg as SpQueryMsg,
|
msg::QueryMsg as SpQueryMsg,
|
||||||
response::{
|
response::{
|
||||||
ConfigResponse, PagedServicesListResponse, ServiceInfoResponse, ServicesListResponse,
|
ConfigResponse, PagedServicesListResponse, ServiceInfoResponse, ServicesListResponse,
|
||||||
},
|
},
|
||||||
NymAddress, Service, ServiceId,
|
NymAddress, ServiceId, ServiceInfo,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@@ -63,14 +63,17 @@ pub trait SpDirectoryQueryClient {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_all_services(&self) -> Result<Vec<Service>, NyxdError> {
|
async fn get_all_services(&self) -> Result<Vec<ServiceInfo>, NyxdError> {
|
||||||
let mut services = Vec::new();
|
let mut services = Vec::new();
|
||||||
let mut start_after = None;
|
let mut start_after = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut paged_response = self.get_services_paged(start_after.take(), None).await?;
|
let mut paged_response = self.get_services_paged(start_after.take(), None).await?;
|
||||||
|
|
||||||
|
let last_id = paged_response.services.last().map(|serv| serv.service_id);
|
||||||
services.append(&mut paged_response.services);
|
services.append(&mut paged_response.services);
|
||||||
|
|
||||||
if let Some(start_after_res) = paged_response.start_next_after {
|
if let Some(start_after_res) = last_id {
|
||||||
start_after = Some(start_after_res)
|
start_after = Some(start_after_res)
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@@ -79,13 +82,6 @@ pub trait SpDirectoryQueryClient {
|
|||||||
|
|
||||||
Ok(services)
|
Ok(services)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_service_signing_nonce(&self, address: &AccountId) -> Result<Nonce, NyxdError> {
|
|
||||||
self.query_service_provider_contract(SpQueryMsg::SigningNonce {
|
|
||||||
address: address.to_string(),
|
|
||||||
})
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use nym_contracts_common::signing::MessageSignature;
|
|
||||||
use nym_service_provider_directory_common::{
|
use nym_service_provider_directory_common::{
|
||||||
msg::ExecuteMsg as SpExecuteMsg, NymAddress, ServiceDetails, ServiceId,
|
msg::ExecuteMsg as SpExecuteMsg, NymAddress, ServiceId, ServiceType,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::nyxd::{
|
use crate::nyxd::{
|
||||||
@@ -23,16 +22,16 @@ pub trait SpDirectorySigningClient {
|
|||||||
|
|
||||||
async fn announce_service_provider(
|
async fn announce_service_provider(
|
||||||
&self,
|
&self,
|
||||||
service: ServiceDetails,
|
nym_address: NymAddress,
|
||||||
owner_signature: MessageSignature,
|
service_type: ServiceType,
|
||||||
deposit: Coin,
|
deposit: Coin,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError> {
|
) -> Result<ExecuteResult, NyxdError> {
|
||||||
self.execute_service_provider_directory_contract(
|
self.execute_service_provider_directory_contract(
|
||||||
fee,
|
fee,
|
||||||
SpExecuteMsg::Announce {
|
SpExecuteMsg::Announce {
|
||||||
service,
|
nym_address,
|
||||||
owner_signature,
|
service_type,
|
||||||
},
|
},
|
||||||
vec![deposit],
|
vec![deposit],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -40,7 +40,3 @@ nym-coconut-dkg-common = { path = "../cosmwasm-smart-contracts/coconut-dkg" }
|
|||||||
nym-multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-contract" }
|
nym-multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-contract" }
|
||||||
nym-service-provider-directory-common = { path = "../cosmwasm-smart-contracts/service-provider-directory" }
|
nym-service-provider-directory-common = { path = "../cosmwasm-smart-contracts/service-provider-directory" }
|
||||||
nym-name-service-common = { path = "../cosmwasm-smart-contracts/name-service" }
|
nym-name-service-common = { path = "../cosmwasm-smart-contracts/name-service" }
|
||||||
nym-sphinx = { path = "../../common/nymsphinx" }
|
|
||||||
|
|
||||||
nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
|
|
||||||
nym-types = { path = "../../common/types" }
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ pub struct Mixnet {
|
|||||||
pub command: MixnetCommands,
|
pub command: MixnetCommands,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
|
||||||
#[derive(Debug, Subcommand)]
|
#[derive(Debug, Subcommand)]
|
||||||
pub enum MixnetCommands {
|
pub enum MixnetCommands {
|
||||||
/// Query the mixnet directory
|
/// Query the mixnet directory
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
use clap::{Args, Parser, Subcommand};
|
|
||||||
use nym_bin_common::output_format::OutputFormat;
|
|
||||||
use nym_crypto::asymmetric::identity;
|
|
||||||
use nym_types::helpers::ConsoleSigningOutput;
|
|
||||||
use nym_validator_client::nyxd::error::NyxdError;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
#[derive(Debug, Args)]
|
|
||||||
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
|
|
||||||
pub struct MixnetOperatorsIdentityKey {
|
|
||||||
#[clap(subcommand)]
|
|
||||||
pub command: MixnetOperatorsIdentityKeyCommands,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Subcommand)]
|
|
||||||
pub enum MixnetOperatorsIdentityKeyCommands {
|
|
||||||
/// Register a name alias for a nym address
|
|
||||||
Sign(SignArgs),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
|
||||||
pub struct SignArgs {
|
|
||||||
/// Path to private identity key (example: private_identity_key.pem)
|
|
||||||
#[clap(long)]
|
|
||||||
private_key: PathBuf,
|
|
||||||
|
|
||||||
/// Base58 encoded message to sign
|
|
||||||
#[clap(long)]
|
|
||||||
base58_msg: String,
|
|
||||||
|
|
||||||
#[clap(short, long, default_value_t = OutputFormat::default())]
|
|
||||||
output: OutputFormat,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn sign(args: SignArgs) -> Result<(), NyxdError> {
|
|
||||||
eprintln!(">>> loading: {}", args.private_key.display());
|
|
||||||
let private_identity_key: identity::PrivateKey =
|
|
||||||
nym_pemstore::load_key(args.private_key).expect("failed to load key");
|
|
||||||
|
|
||||||
print_signed_msg(&private_identity_key, &args.base58_msg, args.output);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print_signed_msg(private_key: &identity::PrivateKey, raw_msg: &str, output: OutputFormat) {
|
|
||||||
let trimmed = raw_msg.trim();
|
|
||||||
eprintln!(">>> attempting to sign: {trimmed}");
|
|
||||||
|
|
||||||
let Ok(decoded) = bs58::decode(trimmed).into_vec() else {
|
|
||||||
println!("failed to base58 decode the message, did you copy it correctly?");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
eprintln!(">>> decoding the message...");
|
|
||||||
|
|
||||||
// we don't really care about what particular information is embedded inside of it,
|
|
||||||
// we just want to know if user correctly copied the string, i.e. whether it's a valid bs58 encoded json
|
|
||||||
if serde_json::from_slice::<serde_json::Value>(&decoded).is_err() {
|
|
||||||
println!("failed to parse the message after decoding, did you copy it correctly?");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// if this is a valid json, it MUST be a valid string
|
|
||||||
let decoded_string = String::from_utf8(decoded.clone()).unwrap();
|
|
||||||
let signature = private_key.sign(&decoded).to_base58_string();
|
|
||||||
|
|
||||||
let sign_output = ConsoleSigningOutput::new(decoded_string, signature);
|
|
||||||
println!("{}", output.format(&sign_output));
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,6 @@
|
|||||||
use clap::{Args, Subcommand};
|
use clap::{Args, Subcommand};
|
||||||
|
|
||||||
pub mod gateway;
|
pub mod gateway;
|
||||||
pub mod identity_key;
|
|
||||||
pub mod mixnode;
|
pub mod mixnode;
|
||||||
pub mod name;
|
pub mod name;
|
||||||
pub mod service;
|
pub mod service;
|
||||||
@@ -16,7 +15,6 @@ pub struct MixnetOperators {
|
|||||||
pub command: MixnetOperatorsCommands,
|
pub command: MixnetOperatorsCommands,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
|
||||||
#[derive(Debug, Subcommand)]
|
#[derive(Debug, Subcommand)]
|
||||||
pub enum MixnetOperatorsCommands {
|
pub enum MixnetOperatorsCommands {
|
||||||
/// Manage your mixnode
|
/// Manage your mixnode
|
||||||
@@ -27,6 +25,4 @@ pub enum MixnetOperatorsCommands {
|
|||||||
ServiceProvider(service::MixnetOperatorsService),
|
ServiceProvider(service::MixnetOperatorsService),
|
||||||
/// Manage your registered name
|
/// Manage your registered name
|
||||||
Name(name::MixnetOperatorsName),
|
Name(name::MixnetOperatorsName),
|
||||||
/// Sign messages using your private identity key
|
|
||||||
IdentityKey(identity_key::MixnetOperatorsIdentityKey),
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use log::info;
|
use log::info;
|
||||||
use nym_contracts_common::signing::MessageSignature;
|
use nym_service_provider_directory_common::{Coin, NymAddress, ServiceType};
|
||||||
use nym_service_provider_directory_common::{Coin, NymAddress, ServiceDetails, ServiceType};
|
|
||||||
use nym_validator_client::nyxd::traits::SpDirectorySigningClient;
|
use nym_validator_client::nyxd::traits::SpDirectorySigningClient;
|
||||||
|
|
||||||
use crate::context::SigningClient;
|
use crate::context::SigningClient;
|
||||||
@@ -11,15 +10,9 @@ pub struct Args {
|
|||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub nym_address: String,
|
pub nym_address: String,
|
||||||
|
|
||||||
#[clap(long)]
|
|
||||||
pub signature: MessageSignature,
|
|
||||||
|
|
||||||
/// Deposit to be made to the service provider directory, in curent DENOMINATION (e.g. 'unym')
|
/// Deposit to be made to the service provider directory, in curent DENOMINATION (e.g. 'unym')
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub deposit: u128,
|
pub deposit: u128,
|
||||||
|
|
||||||
#[clap(long)]
|
|
||||||
pub identity_key: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn announce(args: Args, client: SigningClient) {
|
pub async fn announce(args: Args, client: SigningClient) {
|
||||||
@@ -27,17 +20,12 @@ pub async fn announce(args: Args, client: SigningClient) {
|
|||||||
|
|
||||||
let nym_address = NymAddress::Address(args.nym_address);
|
let nym_address = NymAddress::Address(args.nym_address);
|
||||||
let service_type = ServiceType::NetworkRequester;
|
let service_type = ServiceType::NetworkRequester;
|
||||||
let service = ServiceDetails {
|
|
||||||
nym_address,
|
|
||||||
service_type,
|
|
||||||
identity_key: args.identity_key,
|
|
||||||
};
|
|
||||||
|
|
||||||
let denom = client.current_chain_details().mix_denom.base.as_str();
|
let denom = client.current_chain_details().mix_denom.base.as_str();
|
||||||
let deposit = Coin::new(args.deposit, denom);
|
let deposit = Coin::new(args.deposit, denom);
|
||||||
|
|
||||||
let res = client
|
let res = client
|
||||||
.announce_service_provider(service, args.signature, deposit.into(), None)
|
.announce_service_provider(nym_address, service_type, deposit.into(), None)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to announce service provider");
|
.expect("Failed to announce service provider");
|
||||||
|
|
||||||
|
|||||||
@@ -1,61 +0,0 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
context::SigningClient,
|
|
||||||
utils::{account_id_to_cw_addr, DataWrapper},
|
|
||||||
};
|
|
||||||
|
|
||||||
use clap::Parser;
|
|
||||||
use cosmwasm_std::Coin;
|
|
||||||
|
|
||||||
use nym_bin_common::output_format::OutputFormat;
|
|
||||||
use nym_service_provider_directory_common::{
|
|
||||||
signing_types::construct_service_provider_announce_sign_payload, NymAddress,
|
|
||||||
ServiceType::NetworkRequester,
|
|
||||||
};
|
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
|
||||||
use nym_validator_client::nyxd::traits::SpDirectoryQueryClient;
|
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
|
||||||
pub struct Args {
|
|
||||||
#[clap(long)]
|
|
||||||
pub nym_address: Recipient,
|
|
||||||
|
|
||||||
#[clap(long)]
|
|
||||||
pub amount: u128,
|
|
||||||
|
|
||||||
#[clap(long)]
|
|
||||||
pub identity_key: String,
|
|
||||||
|
|
||||||
#[clap(short, long, default_value_t = OutputFormat::default())]
|
|
||||||
output: OutputFormat,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn create_payload(args: Args, client: SigningClient) {
|
|
||||||
let service = nym_service_provider_directory_common::ServiceDetails {
|
|
||||||
nym_address: NymAddress::new(&args.nym_address.to_string()),
|
|
||||||
service_type: NetworkRequester,
|
|
||||||
identity_key: args.identity_key,
|
|
||||||
};
|
|
||||||
|
|
||||||
let denom = client.current_chain_details().mix_denom.base.as_str();
|
|
||||||
let deposit = Coin::new(args.amount, denom);
|
|
||||||
|
|
||||||
let nonce = match client.get_service_signing_nonce(client.address()).await {
|
|
||||||
Ok(nonce) => nonce,
|
|
||||||
Err(err) => {
|
|
||||||
eprint!(
|
|
||||||
"failed to query for the signing nonce of {}: {err}",
|
|
||||||
client.address()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let address = account_id_to_cw_addr(client.address());
|
|
||||||
let payload =
|
|
||||||
construct_service_provider_announce_sign_payload(nonce, address, deposit, service);
|
|
||||||
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
|
|
||||||
println!("{}", args.output.format(&wrapper))
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
use clap::{Args, Subcommand};
|
use clap::{Args, Subcommand};
|
||||||
|
|
||||||
pub mod announce;
|
pub mod announce;
|
||||||
pub mod announce_sign_payload;
|
|
||||||
pub mod delete;
|
pub mod delete;
|
||||||
|
|
||||||
#[derive(Debug, Args)]
|
#[derive(Debug, Args)]
|
||||||
@@ -11,13 +10,10 @@ pub struct MixnetOperatorsService {
|
|||||||
pub command: MixnetOperatorsServiceCommands,
|
pub command: MixnetOperatorsServiceCommands,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
|
||||||
#[derive(Debug, Subcommand)]
|
#[derive(Debug, Subcommand)]
|
||||||
pub enum MixnetOperatorsServiceCommands {
|
pub enum MixnetOperatorsServiceCommands {
|
||||||
/// Announce service provider to the world
|
/// Announce service provider to the world
|
||||||
Announce(announce::Args),
|
Announce(announce::Args),
|
||||||
/// Delete entry for service provider from the directory
|
/// Delete entry for service provider from the directory
|
||||||
Delete(delete::Args),
|
Delete(delete::Args),
|
||||||
/// Create base58-encoded payload required for producing valid announce signature.
|
|
||||||
CreateServiceAnnounceSignPayload(announce_sign_payload::Args),
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ pub async fn query(args: Args, client: &QueryClientWithNyxd) {
|
|||||||
for service in res.services {
|
for service in res.services {
|
||||||
table.add_row(vec![
|
table.add_row(vec![
|
||||||
service.service_id.to_string(),
|
service.service_id.to_string(),
|
||||||
service.announcer.to_string(),
|
service.service.announcer.to_string(),
|
||||||
service.service.service_type.to_string(),
|
service.service.service_type.to_string(),
|
||||||
service.service.nym_address.to_string(),
|
service.service.nym_address.to_string(),
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-contracts-common"
|
name = "nym-contracts-common"
|
||||||
version = "0.5.0"
|
version = "0.4.0"
|
||||||
description = "Common library for Nym cosmwasm contracts"
|
description = "Common library for Nym cosmwasm contracts"
|
||||||
edition = { workspace = true }
|
edition = { workspace = true }
|
||||||
authors = { workspace = true }
|
authors = { workspace = true }
|
||||||
|
|||||||
@@ -11,9 +11,6 @@ use std::ops::Mul;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub type IdentityKey = String;
|
|
||||||
pub type IdentityKeyRef<'a> = &'a str;
|
|
||||||
|
|
||||||
pub fn truncate_decimal(amount: Decimal) -> Uint128 {
|
pub fn truncate_decimal(amount: Decimal) -> Uint128 {
|
||||||
amount * Uint128::new(1)
|
amount * Uint128::new(1)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-mixnet-contract-common"
|
name = "nym-mixnet-contract-common"
|
||||||
version = "0.6.0"
|
version = "0.5.0"
|
||||||
description = "Common library for the Nym mixnet contract"
|
description = "Common library for the Nym mixnet contract"
|
||||||
rust-version = "1.62"
|
rust-version = "1.62"
|
||||||
edition = { workspace = true }
|
edition = { workspace = true }
|
||||||
@@ -15,7 +15,7 @@ serde = { version = "1.0", features = ["derive"] }
|
|||||||
serde_repr = "0.1"
|
serde_repr = "0.1"
|
||||||
schemars = "0.8"
|
schemars = "0.8"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" }
|
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.4.0" }
|
||||||
# use 0.4.1 as that's the version used by cosmwasm-std 1.0.0
|
# use 0.4.1 as that's the version used by cosmwasm-std 1.0.0
|
||||||
# (and ideally we don't want to pull the same dependency twice)
|
# (and ideally we don't want to pull the same dependency twice)
|
||||||
serde-json-wasm = "=0.4.1"
|
serde-json-wasm = "=0.4.1"
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
use crate::error::MixnetContractError;
|
use crate::error::MixnetContractError;
|
||||||
use crate::families::{Family, FamilyHead};
|
use crate::families::{Family, FamilyHead};
|
||||||
use crate::{Layer, RewardedSetNodeStatus};
|
use crate::{Layer, RewardedSetNodeStatus};
|
||||||
use contracts_common::IdentityKey;
|
|
||||||
use cosmwasm_std::Addr;
|
use cosmwasm_std::Addr;
|
||||||
use cosmwasm_std::Coin;
|
use cosmwasm_std::Coin;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
@@ -12,6 +11,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
|
|
||||||
// type aliases for better reasoning about available data
|
// type aliases for better reasoning about available data
|
||||||
|
pub type IdentityKey = String;
|
||||||
|
pub type IdentityKeyRef<'a> = &'a str;
|
||||||
pub type SphinxKey = String;
|
pub type SphinxKey = String;
|
||||||
pub type SphinxKeyRef<'a> = &'a str;
|
pub type SphinxKeyRef<'a> = &'a str;
|
||||||
pub type EpochId = u32;
|
pub type EpochId = u32;
|
||||||
|
|||||||
@@ -7,9 +7,5 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cosmwasm-std = { workspace = true }
|
cosmwasm-std = { workspace = true }
|
||||||
nym-contracts-common = { path = "../contracts-common", version = "0.5.0" }
|
|
||||||
schemars = "0.8"
|
schemars = "0.8"
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
thiserror = { workspace = true }
|
|
||||||
cw-utils = { workspace = true }
|
|
||||||
cw-controllers = { workspace = true }
|
|
||||||
|
|||||||
@@ -39,16 +39,16 @@ pub fn new_announce_event(service_id: ServiceId, service: Service) -> Event {
|
|||||||
Event::new(ServiceProviderEventType::Announce)
|
Event::new(ServiceProviderEventType::Announce)
|
||||||
.add_attribute(ACTION, ServiceProviderEventType::Announce)
|
.add_attribute(ACTION, ServiceProviderEventType::Announce)
|
||||||
.add_attribute(SERVICE_ID, service_id.to_string())
|
.add_attribute(SERVICE_ID, service_id.to_string())
|
||||||
.add_attribute(SERVICE_TYPE, service.service.service_type.to_string())
|
.add_attribute(SERVICE_TYPE, service.service_type.to_string())
|
||||||
.add_attribute(NYM_ADDRESS, service.service.nym_address.to_string())
|
.add_attribute(NYM_ADDRESS, service.nym_address.to_string())
|
||||||
.add_attribute(OWNER, service.announcer.to_string())
|
.add_attribute(OWNER, service.announcer.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_delete_id_event(service: Service) -> Event {
|
pub fn new_delete_id_event(service_id: ServiceId, service: Service) -> Event {
|
||||||
Event::new(ServiceProviderEventType::DeleteId)
|
Event::new(ServiceProviderEventType::DeleteId)
|
||||||
.add_attribute(ACTION, ServiceProviderEventType::DeleteId)
|
.add_attribute(ACTION, ServiceProviderEventType::DeleteId)
|
||||||
.add_attribute(SERVICE_ID, service.service_id.to_string())
|
.add_attribute(SERVICE_ID, service_id.to_string())
|
||||||
.add_attribute(NYM_ADDRESS, service.service.nym_address.to_string())
|
.add_attribute(NYM_ADDRESS, service.nym_address.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_update_deposit_required_event(deposit_required: Coin) -> Event {
|
pub fn new_update_deposit_required_event(deposit_required: Coin) -> Event {
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
pub mod error;
|
|
||||||
pub mod events;
|
pub mod events;
|
||||||
pub mod msg;
|
pub mod msg;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
pub mod signing_types;
|
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
// Re-export all types at the top-level
|
// Re-export all types at the top-level
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use crate::{NymAddress, ServiceDetails, ServiceId};
|
use crate::{NymAddress, ServiceId, ServiceType};
|
||||||
use cosmwasm_std::Coin;
|
use cosmwasm_std::Coin;
|
||||||
use nym_contracts_common::signing::MessageSignature;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||||
@@ -23,8 +22,8 @@ pub struct MigrateMsg {}
|
|||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum ExecuteMsg {
|
pub enum ExecuteMsg {
|
||||||
Announce {
|
Announce {
|
||||||
service: ServiceDetails,
|
nym_address: NymAddress,
|
||||||
owner_signature: MessageSignature,
|
service_type: ServiceType,
|
||||||
},
|
},
|
||||||
DeleteId {
|
DeleteId {
|
||||||
service_id: ServiceId,
|
service_id: ServiceId,
|
||||||
@@ -45,12 +44,9 @@ impl ExecuteMsg {
|
|||||||
pub fn default_memo(&self) -> String {
|
pub fn default_memo(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
ExecuteMsg::Announce {
|
ExecuteMsg::Announce {
|
||||||
service,
|
nym_address,
|
||||||
owner_signature: _,
|
service_type,
|
||||||
} => format!(
|
} => format!("announcing {nym_address} as type {service_type}"),
|
||||||
"announcing {} as type {}",
|
|
||||||
service.nym_address, service.service_type
|
|
||||||
),
|
|
||||||
ExecuteMsg::DeleteId { service_id } => {
|
ExecuteMsg::DeleteId { service_id } => {
|
||||||
format!("deleting service with service id {service_id}")
|
format!("deleting service with service id {service_id}")
|
||||||
}
|
}
|
||||||
@@ -80,9 +76,6 @@ pub enum QueryMsg {
|
|||||||
limit: Option<u32>,
|
limit: Option<u32>,
|
||||||
start_after: Option<ServiceId>,
|
start_after: Option<ServiceId>,
|
||||||
},
|
},
|
||||||
SigningNonce {
|
|
||||||
address: String,
|
|
||||||
},
|
|
||||||
Config {},
|
Config {},
|
||||||
GetContractVersion {},
|
GetContractVersion {},
|
||||||
#[serde(rename = "get_cw2_contract_version")]
|
#[serde(rename = "get_cw2_contract_version")]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::{Service, ServiceId};
|
use crate::{msg::ExecuteMsg, Service, ServiceId, ServiceInfo};
|
||||||
use cosmwasm_std::Coin;
|
use cosmwasm_std::Coin;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -13,17 +13,22 @@ pub struct ServiceInfoResponse {
|
|||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct ServicesListResponse {
|
pub struct ServicesListResponse {
|
||||||
pub services: Vec<Service>,
|
pub services: Vec<ServiceInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServicesListResponse {
|
impl ServicesListResponse {
|
||||||
pub fn new(services: Vec<Service>) -> ServicesListResponse {
|
pub fn new(services: Vec<(ServiceId, Service)>) -> ServicesListResponse {
|
||||||
ServicesListResponse { services }
|
ServicesListResponse {
|
||||||
|
services: services
|
||||||
|
.into_iter()
|
||||||
|
.map(|(service_id, service)| ServiceInfo::new(service_id, service))
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&[Service]> for ServicesListResponse {
|
impl From<&[ServiceInfo]> for ServicesListResponse {
|
||||||
fn from(services: &[Service]) -> Self {
|
fn from(services: &[ServiceInfo]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
services: services.to_vec(),
|
services: services.to_vec(),
|
||||||
}
|
}
|
||||||
@@ -33,17 +38,21 @@ impl From<&[Service]> for ServicesListResponse {
|
|||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct PagedServicesListResponse {
|
pub struct PagedServicesListResponse {
|
||||||
pub services: Vec<Service>,
|
pub services: Vec<ServiceInfo>,
|
||||||
pub per_page: usize,
|
pub per_page: usize,
|
||||||
pub start_next_after: Option<ServiceId>,
|
pub start_next_after: Option<ServiceId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PagedServicesListResponse {
|
impl PagedServicesListResponse {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
services: Vec<Service>,
|
services: Vec<(ServiceId, Service)>,
|
||||||
per_page: usize,
|
per_page: usize,
|
||||||
start_next_after: Option<ServiceId>,
|
start_next_after: Option<ServiceId>,
|
||||||
) -> PagedServicesListResponse {
|
) -> PagedServicesListResponse {
|
||||||
|
let services = services
|
||||||
|
.into_iter()
|
||||||
|
.map(|(service_id, service)| ServiceInfo::new(service_id, service))
|
||||||
|
.collect();
|
||||||
PagedServicesListResponse {
|
PagedServicesListResponse {
|
||||||
services,
|
services,
|
||||||
per_page,
|
per_page,
|
||||||
@@ -57,3 +66,12 @@ impl PagedServicesListResponse {
|
|||||||
pub struct ConfigResponse {
|
pub struct ConfigResponse {
|
||||||
pub deposit_required: Coin,
|
pub deposit_required: Coin,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Service> for ExecuteMsg {
|
||||||
|
fn from(service: Service) -> Self {
|
||||||
|
ExecuteMsg::Announce {
|
||||||
|
nym_address: service.nym_address,
|
||||||
|
service_type: service.service_type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
use cosmwasm_std::{Addr, Coin};
|
|
||||||
use nym_contracts_common::signing::{
|
|
||||||
ContractMessageContent, MessageType, Nonce, SignableMessage, SigningPurpose,
|
|
||||||
};
|
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
use crate::ServiceDetails;
|
|
||||||
|
|
||||||
pub type SignableServiceProviderAnnounceMsg =
|
|
||||||
SignableMessage<ContractMessageContent<ServiceProviderAnnounce>>;
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
|
||||||
pub struct ServiceProviderAnnounce {
|
|
||||||
service: ServiceDetails,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SigningPurpose for ServiceProviderAnnounce {
|
|
||||||
fn message_type() -> MessageType {
|
|
||||||
MessageType::new("service-provider-announce")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn construct_service_provider_announce_sign_payload(
|
|
||||||
nonce: Nonce,
|
|
||||||
sender: Addr,
|
|
||||||
deposit: Coin,
|
|
||||||
service: ServiceDetails,
|
|
||||||
) -> SignableServiceProviderAnnounceMsg {
|
|
||||||
let payload = ServiceProviderAnnounce { service };
|
|
||||||
let proxy = None;
|
|
||||||
let content = ContractMessageContent::new(sender, proxy, vec![deposit], payload);
|
|
||||||
SignableMessage::new(nonce, content)
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
use cosmwasm_std::{Addr, Coin};
|
use cosmwasm_std::{Addr, Coin};
|
||||||
use nym_contracts_common::IdentityKey;
|
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@@ -10,11 +9,11 @@ pub type ServiceId = u32;
|
|||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)]
|
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)]
|
||||||
pub struct Service {
|
pub struct Service {
|
||||||
/// Unique id assigned to the anounced service.
|
/// The address of the service.
|
||||||
pub service_id: ServiceId,
|
pub nym_address: NymAddress,
|
||||||
/// The announced service.
|
/// The service type.
|
||||||
pub service: ServiceDetails,
|
pub service_type: ServiceType,
|
||||||
/// Address of the service owner.
|
/// Service owner.
|
||||||
pub announcer: Addr,
|
pub announcer: Addr,
|
||||||
/// Block height at which the service was added.
|
/// Block height at which the service was added.
|
||||||
pub block_height: u64,
|
pub block_height: u64,
|
||||||
@@ -22,16 +21,6 @@ pub struct Service {
|
|||||||
pub deposit: Coin,
|
pub deposit: Coin,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)]
|
|
||||||
pub struct ServiceDetails {
|
|
||||||
/// The address of the service.
|
|
||||||
pub nym_address: NymAddress,
|
|
||||||
/// The service type.
|
|
||||||
pub service_type: ServiceType,
|
|
||||||
/// The identity key of the service.
|
|
||||||
pub identity_key: IdentityKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The types of addresses supported.
|
/// The types of addresses supported.
|
||||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, JsonSchema)]
|
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, JsonSchema)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
@@ -39,7 +28,7 @@ pub enum NymAddress {
|
|||||||
/// String representation of a nym address, which is of the form
|
/// String representation of a nym address, which is of the form
|
||||||
/// client_id.client_enc@gateway_id.
|
/// client_id.client_enc@gateway_id.
|
||||||
Address(String),
|
Address(String),
|
||||||
// String name that can looked up in the nym-name-service contract (once it exists)
|
// For the future when we have a nym-dns contract
|
||||||
//Name(String),
|
//Name(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +41,6 @@ impl NymAddress {
|
|||||||
pub fn as_str(&self) -> &str {
|
pub fn as_str(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
NymAddress::Address(address) => address,
|
NymAddress::Address(address) => address,
|
||||||
//NymAddress::Name(name) => name,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,3 +66,19 @@ impl std::fmt::Display for ServiceType {
|
|||||||
write!(f, "{service_type}")
|
write!(f, "{service_type}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub struct ServiceInfo {
|
||||||
|
pub service_id: ServiceId,
|
||||||
|
pub service: Service,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ServiceInfo {
|
||||||
|
pub fn new(service_id: ServiceId, service: Service) -> Self {
|
||||||
|
Self {
|
||||||
|
service_id,
|
||||||
|
service,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-vesting-contract-common"
|
name = "nym-vesting-contract-common"
|
||||||
version = "0.7.0"
|
version = "0.6.0"
|
||||||
description = "Common library for the Nym vesting contract"
|
description = "Common library for the Nym vesting contract"
|
||||||
edition = { workspace = true }
|
edition = { workspace = true }
|
||||||
authors = { workspace = true }
|
authors = { workspace = true }
|
||||||
@@ -9,8 +9,8 @@ repository = { workspace = true }
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cosmwasm-std = { workspace = true }
|
cosmwasm-std = { workspace = true }
|
||||||
mixnet-contract-common = { path = "../mixnet-contract", package = "nym-mixnet-contract-common", version = "0.6.0" }
|
mixnet-contract-common = { path = "../mixnet-contract", package = "nym-mixnet-contract-common", version = "0.5.0" }
|
||||||
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" }
|
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.4.0" }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
schemars = "0.8"
|
schemars = "0.8"
|
||||||
ts-rs = {version = "6.1.2", optional = true}
|
ts-rs = {version = "6.1.2", optional = true}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-crypto"
|
name = "nym-crypto"
|
||||||
version = "0.4.0"
|
version = "0.3.0"
|
||||||
description = "Crypto library for the nym mixnet"
|
description = "Crypto library for the nym mixnet"
|
||||||
edition = { workspace = true }
|
edition = { workspace = true }
|
||||||
authors = { workspace = true }
|
authors = { workspace = true }
|
||||||
@@ -28,7 +28,7 @@ zeroize = { workspace = true, optional = true, features = ["zeroize_derive"] }
|
|||||||
|
|
||||||
# internal
|
# internal
|
||||||
nym-sphinx-types = { path = "../nymsphinx/types", version = "0.2.0" }
|
nym-sphinx-types = { path = "../nymsphinx/types", version = "0.2.0" }
|
||||||
nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
|
nym-pemstore = { path = "../../common/pemstore", version = "0.2.0" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand_chacha = "0.2"
|
rand_chacha = "0.2"
|
||||||
|
|||||||
@@ -19,20 +19,20 @@ macro_rules! measure {
|
|||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(feature = "cpucycles")] {
|
if #[cfg(feature = "cpucycles")] {
|
||||||
let start_cycles = $crate::cpu_cycles();
|
let start_cycles = $crate::cpu_cycles();
|
||||||
// if the block needs to return something, we can return it
|
// if the block needs to return something, we can return it
|
||||||
let r = $x;
|
let r = $x;
|
||||||
let end_cycles = $crate::cpu_cycles();
|
let end_cycles = $crate::cpu_cycles();
|
||||||
let name = if let Some(meta) = tracing::Span::current().metadata() {
|
let name = if let Some(meta) = tracing::Span::current().metadata() {
|
||||||
meta.name()
|
meta.name()
|
||||||
} else {
|
} else {
|
||||||
"measure"
|
"measure"
|
||||||
};
|
};
|
||||||
match (start_cycles, end_cycles) {
|
match (start_cycles, end_cycles) {
|
||||||
(Ok(start), Ok(end)) => log::trace!("{} cpucycles: {}", name, end - start),
|
(Ok(start), Ok(end)) => info!("{} cpucycles: {}", name, end - start),
|
||||||
(Err(e), _) => error!("{e}"),
|
(Err(e), _) => error!("{e}"),
|
||||||
(_, Err(e)) => error!("{e}"),
|
(_, Err(e)) => error!("{e}"),
|
||||||
}
|
}
|
||||||
r
|
r
|
||||||
} else {
|
} else {
|
||||||
$x
|
$x
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use nym_sphinx_acknowledgements::surb_ack::SurbAckRecoveryError;
|
use nym_sphinx_acknowledgements::surb_ack::SurbAckRecoveryError;
|
||||||
use nym_sphinx_addressing::nodes::NymNodeRoutingAddressError;
|
use nym_sphinx_addressing::nodes::NymNodeRoutingAddressError;
|
||||||
use nym_sphinx_types::{NymPacketError, OutfoxError, SphinxError};
|
use nym_sphinx_types::{NymPacketError, SphinxError};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
@@ -25,7 +25,4 @@ pub enum MixProcessingError {
|
|||||||
|
|
||||||
#[error("the received packet was set to use the very old and very much deprecated 'VPN' mode")]
|
#[error("the received packet was set to use the very old and very much deprecated 'VPN' mode")]
|
||||||
ReceivedOldTypeVpnPacket,
|
ReceivedOldTypeVpnPacket,
|
||||||
|
|
||||||
#[error("failed to process received outfox packet: {0}")]
|
|
||||||
OutfoxProcessingError(#[from] OutfoxError),
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,14 +20,12 @@ use tracing::instrument;
|
|||||||
|
|
||||||
type ForwardAck = MixPacket;
|
type ForwardAck = MixPacket;
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ProcessedFinalHop {
|
pub struct ProcessedFinalHop {
|
||||||
pub destination: DestinationAddressBytes,
|
pub destination: DestinationAddressBytes,
|
||||||
pub forward_ack: Option<ForwardAck>,
|
pub forward_ack: Option<ForwardAck>,
|
||||||
pub message: Vec<u8>,
|
pub message: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum MixProcessingResult {
|
pub enum MixProcessingResult {
|
||||||
/// Contains unwrapped data that should first get delayed before being sent to next hop.
|
/// Contains unwrapped data that should first get delayed before being sent to next hop.
|
||||||
ForwardHop(MixPacket, Option<SphinxDelay>),
|
ForwardHop(MixPacket, Option<SphinxDelay>),
|
||||||
@@ -143,7 +141,7 @@ impl SphinxPacketProcessor {
|
|||||||
match SurbAck::try_recover_first_hop_packet(&ack_data, packet_type) {
|
match SurbAck::try_recover_first_hop_packet(&ack_data, packet_type) {
|
||||||
Ok((first_hop, packet)) => (first_hop, packet),
|
Ok((first_hop, packet)) => (first_hop, packet),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
info!("Failed to recover first hop from ack data: {err}");
|
debug!("Failed to recover first hop from ack data: {err}");
|
||||||
return Err(err.into());
|
return Err(err.into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -207,7 +205,7 @@ impl SphinxPacketProcessor {
|
|||||||
if packet.is_final_hop() {
|
if packet.is_final_hop() {
|
||||||
self.process_final_hop(
|
self.process_final_hop(
|
||||||
DestinationAddressBytes::from_bytes(next_address),
|
DestinationAddressBytes::from_bytes(next_address),
|
||||||
packet.recover_plaintext()?.to_vec(),
|
packet.recover_plaintext().to_vec(),
|
||||||
packet_size,
|
packet_size,
|
||||||
packet_type,
|
packet_type,
|
||||||
)
|
)
|
||||||
@@ -241,14 +239,7 @@ impl SphinxPacketProcessor {
|
|||||||
|
|
||||||
// for forward packets, extract next hop and set delay (but do NOT delay here)
|
// for forward packets, extract next hop and set delay (but do NOT delay here)
|
||||||
// for final packets, extract SURBAck
|
// for final packets, extract SURBAck
|
||||||
let final_processing_result =
|
self.perform_final_processing(processed_packet, packet_size, packet_type)
|
||||||
self.perform_final_processing(processed_packet, packet_size, packet_type);
|
|
||||||
|
|
||||||
if final_processing_result.is_err() {
|
|
||||||
error!("{:?}", final_processing_result)
|
|
||||||
}
|
|
||||||
|
|
||||||
final_processing_result
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,12 +25,12 @@ nym-sphinx-types = { path = "types" }
|
|||||||
|
|
||||||
# those dependencies are due to intriducing preparer and receiver. Perpaphs that indicates they should be moved
|
# those dependencies are due to intriducing preparer and receiver. Perpaphs that indicates they should be moved
|
||||||
# to separate crate?
|
# to separate crate?
|
||||||
nym-crypto = { path = "../crypto", version = "0.4.0" }
|
nym-crypto = { path = "../crypto", version = "0.3.0" }
|
||||||
nym-topology = { path = "../topology" }
|
nym-topology = { path = "../topology" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
|
nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
|
||||||
nym-crypto = { path = "../crypto", version = "0.4.0", features = ["asymmetric"] }
|
nym-crypto = { path = "../crypto", version = "0.3.0", features = ["asymmetric"] }
|
||||||
|
|
||||||
# do not include this when compiling into wasm as it somehow when combined together with reqwest, it will require
|
# do not include this when compiling into wasm as it somehow when combined together with reqwest, it will require
|
||||||
# net2 via tokio-util -> tokio -> mio -> net2
|
# net2 via tokio-util -> tokio -> mio -> net2
|
||||||
|
|||||||
@@ -15,12 +15,11 @@ thiserror = { workspace = true }
|
|||||||
zeroize = { workspace = true }
|
zeroize = { workspace = true }
|
||||||
|
|
||||||
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
|
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
|
||||||
nym-pemstore = { path = "../../pemstore" }
|
|
||||||
nym-sphinx-addressing = { path = "../addressing" }
|
nym-sphinx-addressing = { path = "../addressing" }
|
||||||
nym-sphinx-params = { path = "../params" }
|
nym-sphinx-params = { path = "../params" }
|
||||||
nym-sphinx-routing = { path = "../routing" }
|
|
||||||
nym-sphinx-types = { path = "../types" }
|
nym-sphinx-types = { path = "../types" }
|
||||||
|
nym-pemstore = { path = "../../pemstore" }
|
||||||
nym-topology = { path = "../../topology" }
|
nym-topology = { path = "../../topology" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
serde = ["serde_crate", "generic-array"]
|
serde = ["serde_crate", "generic-array"]
|
||||||
@@ -9,7 +9,7 @@ use nym_sphinx_addressing::nodes::{
|
|||||||
};
|
};
|
||||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||||
use nym_sphinx_params::{PacketType, DEFAULT_NUM_MIX_HOPS};
|
use nym_sphinx_params::{PacketType, DEFAULT_NUM_MIX_HOPS};
|
||||||
use nym_sphinx_types::delays::Delay;
|
use nym_sphinx_types::delays::{self, Delay};
|
||||||
use nym_sphinx_types::{NymPacket, NymPacketError, MIN_PACKET_SIZE};
|
use nym_sphinx_types::{NymPacket, NymPacketError, MIN_PACKET_SIZE};
|
||||||
use nym_topology::{NymTopology, NymTopologyError};
|
use nym_topology::{NymTopology, NymTopologyError};
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
@@ -51,7 +51,7 @@ impl SurbAck {
|
|||||||
{
|
{
|
||||||
let route =
|
let route =
|
||||||
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
|
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
|
||||||
let delays = nym_sphinx_routing::generate_hop_delays(average_delay, route.len());
|
let delays = delays::generate_from_average_duration(route.len(), average_delay);
|
||||||
let destination = recipient.as_sphinx_destination();
|
let destination = recipient.as_sphinx_destination();
|
||||||
|
|
||||||
let surb_ack_payload = prepare_identifier(rng, ack_key, marshaled_fragment_id);
|
let surb_ack_payload = prepare_identifier(rng, ack_key, marshaled_fragment_id);
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ thiserror = "1"
|
|||||||
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
|
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
|
||||||
nym-sphinx-addressing = { path = "../addressing" }
|
nym-sphinx-addressing = { path = "../addressing" }
|
||||||
nym-sphinx-params = { path = "../params" }
|
nym-sphinx-params = { path = "../params" }
|
||||||
nym-sphinx-routing = { path = "../routing" }
|
|
||||||
nym-sphinx-types = { path = "../types" }
|
nym-sphinx-types = { path = "../types" }
|
||||||
nym-topology = { path = "../../topology" }
|
nym-topology = { path = "../../topology" }
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use nym_sphinx_addressing::clients::Recipient;
|
|||||||
use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN};
|
use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN};
|
||||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||||
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
||||||
use nym_sphinx_types::{NymPacket, SURBMaterial, SphinxError, SURB};
|
use nym_sphinx_types::{delays, NymPacket, SURBMaterial, SphinxError, SURB};
|
||||||
use nym_topology::{NymTopology, NymTopologyError};
|
use nym_topology::{NymTopology, NymTopologyError};
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use serde::de::{Error as SerdeError, Visitor};
|
use serde::de::{Error as SerdeError, Visitor};
|
||||||
@@ -96,7 +96,7 @@ impl ReplySurb {
|
|||||||
{
|
{
|
||||||
let route =
|
let route =
|
||||||
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
|
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
|
||||||
let delays = nym_sphinx_routing::generate_hop_delays(average_delay, route.len());
|
let delays = delays::generate_from_average_duration(route.len(), average_delay);
|
||||||
let destination = recipient.as_sphinx_destination();
|
let destination = recipient.as_sphinx_destination();
|
||||||
|
|
||||||
let surb_material = SURBMaterial::new(route, delays, destination);
|
let surb_material = SURBMaterial::new(route, delays, destination);
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ nym-crypto = { path = "../../crypto" }
|
|||||||
nym-sphinx-acknowledgements = { path = "../acknowledgements" }
|
nym-sphinx-acknowledgements = { path = "../acknowledgements" }
|
||||||
nym-sphinx-addressing = { path = "../addressing" }
|
nym-sphinx-addressing = { path = "../addressing" }
|
||||||
nym-sphinx-chunking = { path = "../chunking" }
|
nym-sphinx-chunking = { path = "../chunking" }
|
||||||
nym-sphinx-forwarding = { path = "../forwarding" }
|
|
||||||
nym-sphinx-params = { path = "../params" }
|
nym-sphinx-params = { path = "../params" }
|
||||||
nym-sphinx-routing = { path = "../routing" }
|
nym-sphinx-forwarding = { path = "../forwarding" }
|
||||||
nym-sphinx-types = { path = "../types" }
|
nym-sphinx-types = { path = "../types" }
|
||||||
nym-topology = { path = "../../topology" }
|
nym-topology = { path = "../../topology" }
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use nym_sphinx_params::packet_sizes::PacketSize;
|
|||||||
use nym_sphinx_params::{
|
use nym_sphinx_params::{
|
||||||
PacketEncryptionAlgorithm, PacketHkdfAlgorithm, PacketType, DEFAULT_NUM_MIX_HOPS,
|
PacketEncryptionAlgorithm, PacketHkdfAlgorithm, PacketType, DEFAULT_NUM_MIX_HOPS,
|
||||||
};
|
};
|
||||||
use nym_sphinx_types::NymPacket;
|
use nym_sphinx_types::{delays, NymPacket};
|
||||||
use nym_topology::{NymTopology, NymTopologyError};
|
use nym_topology::{NymTopology, NymTopologyError};
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
@@ -91,7 +91,6 @@ where
|
|||||||
>(rng, full_address.encryption_key());
|
>(rng, full_address.encryption_key());
|
||||||
|
|
||||||
let public_key_bytes = ephemeral_keypair.public_key().to_bytes();
|
let public_key_bytes = ephemeral_keypair.public_key().to_bytes();
|
||||||
|
|
||||||
let cover_size = packet_size.plaintext_size() - public_key_bytes.len() - ack_bytes.len();
|
let cover_size = packet_size.plaintext_size() - public_key_bytes.len() - ack_bytes.len();
|
||||||
|
|
||||||
let mut cover_content: Vec<_> = LOOP_COVER_MESSAGE_PAYLOAD
|
let mut cover_content: Vec<_> = LOOP_COVER_MESSAGE_PAYLOAD
|
||||||
@@ -120,38 +119,22 @@ where
|
|||||||
|
|
||||||
let route =
|
let route =
|
||||||
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, full_address.gateway())?;
|
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, full_address.gateway())?;
|
||||||
let delays = nym_sphinx_routing::generate_hop_delays(average_packet_delay, route.len());
|
let delays = delays::generate_from_average_duration(route.len(), average_packet_delay);
|
||||||
let destination = full_address.as_sphinx_destination();
|
let destination = full_address.as_sphinx_destination();
|
||||||
|
|
||||||
|
// once merged, that's an easy rng injection point for sphinx packets : )
|
||||||
|
let packet = NymPacket::sphinx_build(
|
||||||
|
packet_size.payload_size(),
|
||||||
|
packet_payload,
|
||||||
|
&route,
|
||||||
|
&destination,
|
||||||
|
&delays,
|
||||||
|
)?;
|
||||||
|
|
||||||
let first_hop_address =
|
let first_hop_address =
|
||||||
NymNodeRoutingAddress::try_from(route.first().unwrap().address).unwrap();
|
NymNodeRoutingAddress::try_from(route.first().unwrap().address).unwrap();
|
||||||
|
|
||||||
// once merged, that's an easy rng injection point for sphinx packets : )
|
Ok(MixPacket::new(first_hop_address, packet, PacketType::Mix))
|
||||||
let packet = match packet_type {
|
|
||||||
PacketType::Mix => NymPacket::sphinx_build(
|
|
||||||
packet_size.payload_size(),
|
|
||||||
packet_payload,
|
|
||||||
&route,
|
|
||||||
&destination,
|
|
||||||
&delays,
|
|
||||||
)?,
|
|
||||||
#[allow(deprecated)]
|
|
||||||
PacketType::Vpn => NymPacket::sphinx_build(
|
|
||||||
packet_size.payload_size(),
|
|
||||||
packet_payload,
|
|
||||||
&route,
|
|
||||||
&destination,
|
|
||||||
&delays,
|
|
||||||
)?,
|
|
||||||
PacketType::Outfox => NymPacket::outfox_build(
|
|
||||||
packet_payload,
|
|
||||||
&route,
|
|
||||||
&destination,
|
|
||||||
Some(packet_size.plaintext_size()),
|
|
||||||
)?,
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(MixPacket::new(first_hop_address, packet, packet_type))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function used to determine if given message represents a loop cover message.
|
/// Helper function used to determine if given message represents a loop cover message.
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use nym_sphinx_addressing::clients::Recipient;
|
use nym_sphinx_addressing::clients::Recipient;
|
||||||
use nym_sphinx_types::{delays, Delay, Node};
|
use nym_sphinx_types::Node;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub trait SphinxRouteMaker {
|
pub trait SphinxRouteMaker {
|
||||||
@@ -43,11 +41,3 @@ impl SphinxRouteMaker for Vec<Node> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_hop_delays(average_packet_delay: Duration, num_hops: usize) -> Vec<Delay> {
|
|
||||||
if average_packet_delay.is_zero() {
|
|
||||||
vec![nym_sphinx_types::Delay::new_from_millis(0); num_hops]
|
|
||||||
} else {
|
|
||||||
delays::generate_from_average_duration(num_hops, average_packet_delay)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use nym_sphinx_chunking::fragment::{Fragment, FragmentIdentifier};
|
|||||||
use nym_sphinx_forwarding::packet::MixPacket;
|
use nym_sphinx_forwarding::packet::MixPacket;
|
||||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||||
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
||||||
use nym_sphinx_types::{Delay, NymPacket};
|
use nym_sphinx_types::{delays, Delay, NymPacket};
|
||||||
use nym_topology::{NymTopology, NymTopologyError};
|
use nym_topology::{NymTopology, NymTopologyError};
|
||||||
use rand::{CryptoRng, Rng};
|
use rand::{CryptoRng, Rng};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
@@ -233,7 +233,7 @@ pub trait FragmentPreparer {
|
|||||||
|
|
||||||
// including set of delays
|
// including set of delays
|
||||||
let delays =
|
let delays =
|
||||||
nym_sphinx_routing::generate_hop_delays(self.average_packet_delay(), route.len());
|
delays::generate_from_average_duration(route.len(), self.average_packet_delay());
|
||||||
|
|
||||||
// create the actual sphinx packet here. With valid route and correct payload size,
|
// create the actual sphinx packet here. With valid route and correct payload size,
|
||||||
// there's absolutely no reason for this call to fail.
|
// there's absolutely no reason for this call to fail.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-pemstore"
|
name = "nym-pemstore"
|
||||||
description = "Store private-public keypairs in PEM format"
|
description = "Store private-public keypairs in PEM format"
|
||||||
version = "0.3.0"
|
version = "0.2.0"
|
||||||
edition = { workspace = true }
|
edition = { workspace = true }
|
||||||
authors = { workspace = true }
|
authors = { workspace = true }
|
||||||
license = { workspace = true }
|
license = { workspace = true }
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
pub mod old_config_v1_1_20_2;
|
|
||||||
|
|
||||||
pub use nym_service_providers_common::interface::ProviderInterfaceVersion;
|
pub use nym_service_providers_common::interface::ProviderInterfaceVersion;
|
||||||
pub use nym_socks5_requests::Socks5ProtocolVersion;
|
pub use nym_socks5_requests::Socks5ProtocolVersion;
|
||||||
|
|
||||||
@@ -27,9 +25,9 @@ pub struct Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn new<S: Into<String>>(id: S, version: S, provider_mix_address: S) -> Self {
|
pub fn new<S: Into<String>>(id: S, provider_mix_address: S) -> Self {
|
||||||
Config {
|
Config {
|
||||||
base: BaseClientConfig::new(id, version),
|
base: BaseClientConfig::new(id),
|
||||||
socks5: Socks5::new(provider_mix_address),
|
socks5: Socks5::new(provider_mix_address),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,87 +0,0 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
pub use nym_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as BaseClientConfigV1_1_20_2;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
use crate::config::{Config, Socks5, Socks5Debug};
|
|
||||||
pub use nym_service_providers_common::interface::ProviderInterfaceVersion;
|
|
||||||
pub use nym_socks5_requests::Socks5ProtocolVersion;
|
|
||||||
|
|
||||||
const DEFAULT_CONNECTION_START_SURBS: u32 = 20;
|
|
||||||
const DEFAULT_PER_REQUEST_SURBS: u32 = 3;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct ConfigV1_1_20_2 {
|
|
||||||
#[serde(flatten)]
|
|
||||||
pub base: BaseClientConfigV1_1_20_2,
|
|
||||||
|
|
||||||
pub socks5: Socks5V1_1_20_2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ConfigV1_1_20_2> for Config {
|
|
||||||
fn from(value: ConfigV1_1_20_2) -> Self {
|
|
||||||
Config {
|
|
||||||
base: value.base.into(),
|
|
||||||
socks5: value.socks5.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct Socks5V1_1_20_2 {
|
|
||||||
pub listening_port: u16,
|
|
||||||
pub provider_mix_address: String,
|
|
||||||
#[serde(default = "ProviderInterfaceVersion::new_legacy")]
|
|
||||||
pub provider_interface_version: ProviderInterfaceVersion,
|
|
||||||
#[serde(default = "Socks5ProtocolVersion::new_legacy")]
|
|
||||||
pub socks5_protocol_version: Socks5ProtocolVersion,
|
|
||||||
#[serde(default)]
|
|
||||||
pub send_anonymously: bool,
|
|
||||||
#[serde(default)]
|
|
||||||
pub socks5_debug: Socks5DebugV1_1_20_2,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Socks5V1_1_20_2> for Socks5 {
|
|
||||||
fn from(value: Socks5V1_1_20_2) -> Self {
|
|
||||||
Socks5 {
|
|
||||||
listening_port: value.listening_port,
|
|
||||||
provider_mix_address: value.provider_mix_address,
|
|
||||||
provider_interface_version: value.provider_interface_version,
|
|
||||||
socks5_protocol_version: value.socks5_protocol_version,
|
|
||||||
send_anonymously: value.send_anonymously,
|
|
||||||
socks5_debug: value.socks5_debug.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)]
|
|
||||||
#[serde(deny_unknown_fields)]
|
|
||||||
pub struct Socks5DebugV1_1_20_2 {
|
|
||||||
/// Number of reply SURBs attached to each `Request::Connect` message.
|
|
||||||
pub connection_start_surbs: u32,
|
|
||||||
|
|
||||||
/// Number of reply SURBs attached to each `Request::Send` message.
|
|
||||||
pub per_request_surbs: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Socks5DebugV1_1_20_2> for Socks5Debug {
|
|
||||||
fn from(value: Socks5DebugV1_1_20_2) -> Self {
|
|
||||||
Socks5Debug {
|
|
||||||
connection_start_surbs: value.connection_start_surbs,
|
|
||||||
per_request_surbs: value.per_request_surbs,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Socks5DebugV1_1_20_2 {
|
|
||||||
fn default() -> Self {
|
|
||||||
Socks5DebugV1_1_20_2 {
|
|
||||||
connection_start_surbs: DEFAULT_CONNECTION_START_SURBS,
|
|
||||||
per_request_surbs: DEFAULT_PER_REQUEST_SURBS,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,16 +10,13 @@ use crate::socks::{
|
|||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use log::*;
|
use log::*;
|
||||||
use nym_client_core::client::base_client::non_wasm_helpers::default_query_dkg_client_from_config;
|
|
||||||
use nym_client_core::client::base_client::storage::gateway_details::GatewayDetailsStore;
|
|
||||||
use nym_client_core::client::base_client::storage::MixnetClientStorage;
|
use nym_client_core::client::base_client::storage::MixnetClientStorage;
|
||||||
use nym_client_core::client::base_client::{
|
use nym_client_core::client::base_client::{
|
||||||
BaseClientBuilder, ClientInput, ClientOutput, ClientState,
|
non_wasm_helpers, BaseClientBuilder, ClientInput, ClientOutput, ClientState,
|
||||||
};
|
};
|
||||||
use nym_client_core::client::key_manager::persistence::KeyStore;
|
use nym_client_core::client::key_manager::persistence::KeyStore;
|
||||||
use nym_client_core::client::replies::reply_storage::ReplyStorageBackend;
|
use nym_client_core::client::replies::reply_storage::ReplyStorageBackend;
|
||||||
use nym_client_core::config::DebugConfig;
|
use nym_client_core::config::DebugConfig;
|
||||||
use nym_client_core::init::GatewaySetup;
|
|
||||||
use nym_credential_storage::storage::Storage as CredentialStorage;
|
use nym_credential_storage::storage::Storage as CredentialStorage;
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
use nym_sphinx::addressing::clients::Recipient;
|
||||||
use nym_sphinx::params::PacketType;
|
use nym_sphinx::params::PacketType;
|
||||||
@@ -54,8 +51,6 @@ pub struct NymClient<S> {
|
|||||||
config: Config,
|
config: Config,
|
||||||
|
|
||||||
storage: S,
|
storage: S,
|
||||||
|
|
||||||
setup_method: GatewaySetup,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S> NymClient<S>
|
impl<S> NymClient<S>
|
||||||
@@ -64,20 +59,10 @@ where
|
|||||||
S::ReplyStore: Send + Sync,
|
S::ReplyStore: Send + Sync,
|
||||||
<S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send,
|
<S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send,
|
||||||
<S::CredentialStore as CredentialStorage>::StorageError: Send + Sync,
|
<S::CredentialStore as CredentialStorage>::StorageError: Send + Sync,
|
||||||
<S::GatewayDetailsStore as GatewayDetailsStore>::StorageError: Sync + Send,
|
|
||||||
<S::KeyStore as KeyStore>::StorageError: Send + Sync,
|
<S::KeyStore as KeyStore>::StorageError: Send + Sync,
|
||||||
{
|
{
|
||||||
pub fn new(config: Config, storage: S) -> Self {
|
pub fn new(config: Config, storage: S) -> Self {
|
||||||
NymClient {
|
NymClient { config, storage }
|
||||||
config,
|
|
||||||
storage,
|
|
||||||
setup_method: GatewaySetup::MustLoad,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_gateway_setup(mut self, setup: GatewaySetup) -> Self {
|
|
||||||
self.setup_method = setup;
|
|
||||||
self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
@@ -202,16 +187,24 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn start(self) -> Result<StartedSocks5Client, Socks5ClientCoreError> {
|
pub async fn start(self) -> Result<StartedSocks5Client, Socks5ClientCoreError> {
|
||||||
// don't create dkg client for the bandwidth controller if credentials are disabled
|
let (key_store, reply_storage_backend, credential_store) = self.storage.into_split();
|
||||||
let dkg_query_client = if self.config.base.client.disabled_credentials_mode {
|
|
||||||
|
// don't create bandwidth controller if credentials are disabled
|
||||||
|
let bandwidth_controller = if self.config.base.client.disabled_credentials_mode {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(default_query_dkg_client_from_config(&self.config.base))
|
Some(non_wasm_helpers::create_bandwidth_controller(
|
||||||
|
&self.config.base,
|
||||||
|
credential_store,
|
||||||
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
let base_builder =
|
let base_builder = BaseClientBuilder::<_, S>::new_from_base_config(
|
||||||
BaseClientBuilder::new(&self.config.base, self.storage, dkg_query_client)
|
&self.config.base,
|
||||||
.with_gateway_setup(self.setup_method);
|
key_store,
|
||||||
|
bandwidth_controller,
|
||||||
|
reply_storage_backend,
|
||||||
|
);
|
||||||
|
|
||||||
let packet_type = self.config.base.debug.traffic.packet_type;
|
let packet_type = self.config.base.debug.traffic.packet_type;
|
||||||
let mut started_client = base_builder.start_base().await?;
|
let mut started_client = base_builder.start_base().await?;
|
||||||
|
|||||||
@@ -428,14 +428,18 @@ impl SocksClient {
|
|||||||
Some(self.lane_queue_lengths.clone()),
|
Some(self.lane_queue_lengths.clone()),
|
||||||
self.shutdown_listener.clone(),
|
self.shutdown_listener.clone(),
|
||||||
)
|
)
|
||||||
.run(move |socket_data| {
|
.run(move |conn_id, read_data, socket_closed| {
|
||||||
let lane = TransmissionLane::ConnectionId(socket_data.header.connection_id);
|
let provider_request = Socks5Request::new_send(
|
||||||
let provider_request =
|
request_version.provider_protocol,
|
||||||
Socks5Request::new_send(request_version.provider_protocol, socket_data);
|
conn_id,
|
||||||
|
read_data,
|
||||||
|
socket_closed,
|
||||||
|
);
|
||||||
let provider_message = Socks5ProviderRequest::new_provider_data(
|
let provider_message = Socks5ProviderRequest::new_provider_data(
|
||||||
request_version.provider_interface,
|
request_version.provider_interface,
|
||||||
provider_request,
|
provider_request,
|
||||||
);
|
);
|
||||||
|
let lane = TransmissionLane::ConnectionId(conn_id);
|
||||||
if anonymous {
|
if anonymous {
|
||||||
InputMessage::new_anonymous(
|
InputMessage::new_anonymous(
|
||||||
recipient,
|
recipient,
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::error::Socks5ClientCoreError;
|
|
||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use log::*;
|
use log::*;
|
||||||
|
|
||||||
use nym_client_core::client::received_buffer::ReconstructedMessagesReceiver;
|
use nym_client_core::client::received_buffer::ReconstructedMessagesReceiver;
|
||||||
use nym_client_core::client::received_buffer::{
|
use nym_client_core::client::received_buffer::{
|
||||||
ReceivedBufferMessage, ReceivedBufferRequestSender,
|
ReceivedBufferMessage, ReceivedBufferRequestSender,
|
||||||
};
|
};
|
||||||
use nym_service_providers_common::interface::{ControlResponse, ResponseContent};
|
use nym_service_providers_common::interface::{ControlResponse, ResponseContent};
|
||||||
use nym_socks5_proxy_helpers::connection_controller::{ControllerCommand, ControllerSender};
|
use nym_socks5_proxy_helpers::connection_controller::ControllerSender;
|
||||||
use nym_socks5_requests::{Socks5ProviderResponse, Socks5Response, Socks5ResponseContent};
|
use nym_socks5_requests::{Socks5ProviderResponse, Socks5Response, Socks5ResponseContent};
|
||||||
use nym_sphinx::receiver::ReconstructedMessage;
|
use nym_sphinx::receiver::ReconstructedMessage;
|
||||||
use nym_task::TaskClient;
|
use nym_task::TaskClient;
|
||||||
|
|
||||||
|
use crate::error::Socks5ClientCoreError;
|
||||||
|
|
||||||
pub(crate) struct MixnetResponseListener {
|
pub(crate) struct MixnetResponseListener {
|
||||||
buffer_requester: ReceivedBufferRequestSender,
|
buffer_requester: ReceivedBufferRequestSender,
|
||||||
mix_response_receiver: ReconstructedMessagesReceiver,
|
mix_response_receiver: ReconstructedMessagesReceiver,
|
||||||
@@ -80,20 +79,12 @@ impl MixnetResponseListener {
|
|||||||
);
|
);
|
||||||
Err(err_response.into())
|
Err(err_response.into())
|
||||||
}
|
}
|
||||||
Socks5ResponseContent::NetworkData { content } => {
|
Socks5ResponseContent::NetworkData(response) => {
|
||||||
self.controller_sender
|
self.controller_sender
|
||||||
.unbounded_send(ControllerCommand::new_send(content))
|
.unbounded_send(response.into())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Socks5ResponseContent::Query(response) => {
|
|
||||||
error!("received a query response which we don't know how to handle yet!");
|
|
||||||
error!("got: {:?}", response);
|
|
||||||
|
|
||||||
// I guess we'd need another channel here to forward those to where they need to go
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user