Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2bc7448b08 | |||
| 42acbfe806 | |||
| 7c55483585 | |||
| c04cc9a4cf | |||
| 17258d1445 | |||
| 8f3d7606f5 | |||
| fd97f0e8ca | |||
| d4ce1635a8 | |||
| 2bc564ad01 | |||
| 5910bcbc02 | |||
| 8c63fe9d0d | |||
| 6e5a1973da | |||
| 1aa11887aa | |||
| 07740cbf08 | |||
| 87cb8a6b20 | |||
| 2977b8f25f | |||
| 9ae4fd04ac | |||
| 4470969bec | |||
| 1a4c3a7709 | |||
| 99b31920d5 | |||
| 019b3299f2 | |||
| d684957423 | |||
| cb4eda4c62 | |||
| ac5f380ee2 | |||
| 4e278ca07d | |||
| cd6a725875 | |||
| 62ccb6b4cd | |||
| 365e0134b4 | |||
| d5514a060c | |||
| 8432c30f6c | |||
| c2764f90b3 | |||
| 958b6d37ee | |||
| 5e36bb014c | |||
| 8d821881ae | |||
| fca9761145 | |||
| 11481e4d13 | |||
| a6a39d1234 | |||
| 5f35d54fcb | |||
| c8b82a9553 | |||
| 00c2f5359c | |||
| 1a4e0f4e08 | |||
| 69230a10cb | |||
| 3a0c8f3f4e |
@@ -63,7 +63,7 @@ jobs:
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: 1.69.0
|
||||
|
||||
- name: Build all binaries
|
||||
uses: actions-rs/cargo@v1
|
||||
@@ -74,7 +74,7 @@ jobs:
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
toolchain: 1.69.0
|
||||
target: wasm32-unknown-unknown
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
@@ -107,6 +107,8 @@ jobs:
|
||||
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/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
|
||||
continue-on-error: true
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
name: Nym Connect - Android APK Build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- "release/nc-android-v[0-9].[0-9].[0-9]*"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build APK
|
||||
runs-on: custom-runner-linux
|
||||
env:
|
||||
ANDROID_HOME: ${{ github.workspace }}/android-sdk
|
||||
NDK_VERSION: 25.1.8937393
|
||||
NDK_HOME: ${{ github.workspace }}/android-sdk/ndk/25.1.8937393
|
||||
SDK_PLATFORM_VERSION: android-33
|
||||
SDK_BUILDTOOLS_VERSION: 33.0.1
|
||||
|
||||
steps:
|
||||
- name: Install Dependencies (Linux)
|
||||
# https://next--tauri.netlify.app/next/guides/getting-started/prerequisites/linux/#1-system-dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install \
|
||||
build-essential \
|
||||
unzip \
|
||||
curl \
|
||||
wget \
|
||||
libssl-dev \
|
||||
squashfs-tools \
|
||||
librsvg2-dev
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Java
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: "17"
|
||||
|
||||
- name: Install Android SDK manager
|
||||
# https://developer.android.com/studio/command-line/sdkmanager
|
||||
run: |
|
||||
curl -sS https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -o cmdline-tools.zip
|
||||
unzip cmdline-tools.zip
|
||||
mkdir -p $ANDROID_HOME/cmdline-tools/latest
|
||||
mv cmdline-tools/* $ANDROID_HOME/cmdline-tools/latest
|
||||
rm -rf cmdline-tools
|
||||
|
||||
- name: Install Android S/NDK
|
||||
run: |
|
||||
echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses
|
||||
echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager \
|
||||
"platforms;$SDK_PLATFORM_VERSION" \
|
||||
"platform-tools" \
|
||||
"ndk;$NDK_VERSION" \
|
||||
"build-tools;$SDK_BUILDTOOLS_VERSION"
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
# TODO this step takes a considerable amount of time
|
||||
# We could avoid to compile from source tauri-cli and use instead
|
||||
# pre-compiled binary provided by the node package `@tauri-apps/cli`
|
||||
# But when using the later the build fails for some reason
|
||||
# so keep installing and using tauri-cli
|
||||
- name: Install tauri cli
|
||||
run: cargo install tauri-cli --version "^2.0.0-alpha.2"
|
||||
|
||||
- name: Install rust android targets
|
||||
run: |
|
||||
rustup target add aarch64-linux-android \
|
||||
armv7-linux-androideabi \
|
||||
i686-linux-android \
|
||||
x86_64-linux-android
|
||||
|
||||
- name: Setup Nodejs
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Install yarn
|
||||
run: |
|
||||
npm i -g yarn
|
||||
yarn --version
|
||||
|
||||
- name: Build frontend code
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
yarn build
|
||||
yarn workspace @nym/nym-connect-mobile webpack:prod
|
||||
|
||||
- name: Build APK
|
||||
working-directory: nym-connect/mobile
|
||||
env:
|
||||
# NODE_TAURI_CLI=${{ github.workspace }}/nym-connect/mobile/node_modules/.bin/tauri
|
||||
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
|
||||
WRY_ANDROID_PACKAGE: net.nymtech.nym_connect
|
||||
WRY_ANDROID_LIBRARY: nym_connect
|
||||
# TODO build with release profile (--release), it will requires
|
||||
# to sign the APK. For now build with debug profile to avoid that
|
||||
# TODO build using `yarn tauri`, provide NODE_TAURI_CLI, see TODO notes above
|
||||
run: cargo tauri android build --debug --apk --split-per-abi -t aarch64
|
||||
|
||||
# TODO add the version number to APK name
|
||||
- name: Rename APK artifact
|
||||
run: |
|
||||
mkdir apk/
|
||||
mv nym-connect/mobile/src-tauri/gen/android/nym_connect/app/build/outputs/apk/arm64/debug/app-arm64-debug.apk \
|
||||
apk/nym-connect-arm64-debug.apk
|
||||
mv nym-connect/mobile/src-tauri/gen/android/nym_connect/app/build/outputs/apk/x86_64/debug/app-x86_64-debug.apk \
|
||||
apk/nym-connect-x86_64-debug.apk
|
||||
|
||||
- name: Upload APK artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: nc-apk-debug
|
||||
path: |
|
||||
apk/nym-connect-arm64-debug.apk
|
||||
apk/nym-connect-x86_64-debug.apk
|
||||
|
||||
# publish:
|
||||
# name: Publish APK
|
||||
# needs: build
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - name: Checkout
|
||||
# uses: actions/checkout@v3
|
||||
# - name: Download binary artifact
|
||||
# uses: actions/download-artifact@v3
|
||||
# with:
|
||||
# name: nc-apk-debug
|
||||
# path: apk
|
||||
# # TODO add a step to upload the APK somewhere
|
||||
# - name: Publish
|
||||
# uses: ???
|
||||
@@ -0,0 +1,102 @@
|
||||
name: Nyms5 Android
|
||||
# unsigned APKs only, supported archs:
|
||||
# - arm64-v8a (arm64)
|
||||
# - x86_64
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
tags:
|
||||
- nyms5-android-v*
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build APK
|
||||
runs-on: custom-runner-linux
|
||||
env:
|
||||
ANDROID_HOME: ${{ github.workspace }}/android-sdk
|
||||
NDK_VERSION: 25.2.9519653
|
||||
NDK_HOME: ${{ github.workspace }}/android-sdk/ndk/25.2.9519653
|
||||
SDK_PLATFORM_VERSION: android-33
|
||||
SDK_BUILDTOOLS_VERSION: 33.0.2
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Java
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: "temurin"
|
||||
java-version: "17"
|
||||
|
||||
- name: Install Android SDK manager
|
||||
# https://developer.android.com/studio/command-line/sdkmanager
|
||||
run: |
|
||||
curl -sS https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -o cmdline-tools.zip
|
||||
unzip cmdline-tools.zip
|
||||
mkdir -p $ANDROID_HOME/cmdline-tools/latest
|
||||
mv cmdline-tools/* $ANDROID_HOME/cmdline-tools/latest
|
||||
rm -rf cmdline-tools
|
||||
|
||||
- name: Install Android S/NDK
|
||||
run: |
|
||||
echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses
|
||||
echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager \
|
||||
"platforms;$SDK_PLATFORM_VERSION" \
|
||||
"platform-tools" \
|
||||
"ndk;$NDK_VERSION" \
|
||||
"build-tools;$SDK_BUILDTOOLS_VERSION"
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Install rust android targets
|
||||
run: |
|
||||
rustup target add aarch64-linux-android \
|
||||
x86_64-linux-android
|
||||
|
||||
- name: Build lib nym-socks5-listener
|
||||
working-directory: sdk/lib/socks5-listener/
|
||||
env:
|
||||
RELEASE: true
|
||||
# build for arm64 and x86_64
|
||||
run: ./build-android.sh aarch64 x86_64
|
||||
|
||||
- name: Build APKs (unsigned)
|
||||
working-directory: nym-connect/native/android
|
||||
env:
|
||||
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
|
||||
# build for arm64 and x86_64
|
||||
run: ./gradlew :app:assembleArch64Release
|
||||
|
||||
- name: Prepare APKs
|
||||
run: |
|
||||
mkdir apk
|
||||
mv nym-connect/native/android/app/build/outputs/apk/arch64/release/app-arch64-release-unsigned.apk \
|
||||
apk/nyms5-arch64-release.apk
|
||||
|
||||
- name: Upload APKs
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: nyms5-apk-arch64-release
|
||||
path: |
|
||||
apk/nyms5-arch64-release.apk
|
||||
|
||||
gh-release:
|
||||
name: Publish APK (GH release)
|
||||
needs: build
|
||||
runs-on: custom-runner-linux
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Download binary artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: nyms5-apk-arch64-release
|
||||
path: apk
|
||||
- name: Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: apk/nyms5-arch64-release.apk
|
||||
|
||||
+2
-1
@@ -42,4 +42,5 @@ storybook-static
|
||||
envs/qwerty.env
|
||||
.parcel-cache
|
||||
**/.DS_Store
|
||||
cpu-cycles/libcpucycles/build
|
||||
cpu-cycles/libcpucycles/build
|
||||
foxyfox.env
|
||||
@@ -4,6 +4,36 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [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)
|
||||
|
||||
- nym-name-service endpoint in nym-api ([#3403])
|
||||
|
||||
Generated
+252
-3321
File diff suppressed because it is too large
Load Diff
+11
-13
@@ -116,21 +116,19 @@ async-trait = "0.1.64"
|
||||
anyhow = "1.0.71"
|
||||
bip39 = { version = "2.0.0", features = ["zeroize"] }
|
||||
cfg-if = "1.0.0"
|
||||
cosmwasm-derive = "=1.2.5"
|
||||
cosmwasm-schema = "=1.2.5"
|
||||
cosmwasm-std = "=1.2.5"
|
||||
cosmwasm-storage = "=1.2.5"
|
||||
cosmrs = "=0.8.0"
|
||||
cw-utils = "=1.0.1"
|
||||
cw-storage-plus = "=1.0.1"
|
||||
cw2 = { version = "=1.0.1" }
|
||||
cw3 = { version = "=1.0.1" }
|
||||
cw3-fixed-multisig = { version = "=1.0.1" }
|
||||
cw4 = { version = "=1.0.1" }
|
||||
cw-controllers = { version = "=1.0.1" }
|
||||
cosmwasm-derive = "=1.0.0"
|
||||
cosmwasm-schema = "=1.0.0"
|
||||
cosmwasm-std = "=1.0.0"
|
||||
cosmwasm-storage = "=1.0.0"
|
||||
cw-controllers = "=0.13.4"
|
||||
cw-storage-plus = "=0.13.4"
|
||||
cw-utils = "=0.13.4"
|
||||
cw2 = { version = "=0.13.4" }
|
||||
cw3 = { version = "=0.13.4" }
|
||||
cw3-fixed-multisig = { version = "=0.13.4" }
|
||||
cw4 = { version = "=0.13.4" }
|
||||
dotenvy = "0.15.6"
|
||||
generic-array = "0.14.7"
|
||||
k256 = "0.11"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4"
|
||||
once_cell = "1.7.2"
|
||||
|
||||
@@ -22,7 +22,7 @@ The platform is composed of multiple Rust crates. Top-level executable binary cr
|
||||
### Building
|
||||
|
||||
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/stable/nym-apps/wallet#for-developers).
|
||||
Wallet build instructions are also available on [our docs site](https://nymtech.net/docs/wallet/desktop-wallet.html).
|
||||
|
||||
### Developing
|
||||
|
||||
@@ -32,7 +32,11 @@ For Typescript components, please see [ts-packages](./ts-packages).
|
||||
|
||||
### Developer chat
|
||||
|
||||
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.
|
||||
> 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 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
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-client"
|
||||
version = "1.1.19"
|
||||
version = "1.1.20"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
description = "Implementation of the Nym Client"
|
||||
edition = "2021"
|
||||
|
||||
@@ -20,6 +20,7 @@ use nym_client_core::client::received_buffer::{
|
||||
use nym_client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
|
||||
use nym_credential_storage::persistent_storage::PersistentStorage;
|
||||
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_task::connections::TransmissionLane;
|
||||
use nym_task::TaskManager;
|
||||
use nym_validator_client::nyxd::QueryNyxdClient;
|
||||
@@ -63,6 +64,7 @@ impl SocketClient {
|
||||
client_state: ClientState,
|
||||
self_address: &Recipient,
|
||||
shutdown: nym_task::TaskClient,
|
||||
packet_type: PacketType,
|
||||
) {
|
||||
info!("Starting websocket listener...");
|
||||
|
||||
@@ -88,6 +90,7 @@ impl SocketClient {
|
||||
self_address,
|
||||
shared_lane_queue_lengths,
|
||||
reply_controller_sender,
|
||||
Some(packet_type),
|
||||
);
|
||||
|
||||
websocket::Listener::new(config.get_listening_ip(), config.get_listening_port())
|
||||
@@ -137,7 +140,8 @@ impl SocketClient {
|
||||
}
|
||||
|
||||
let base_builder = self.create_base_client_builder().await?;
|
||||
let mut started_client = base_builder.start_base().await?;
|
||||
let packet_type = self.config.get_base().get_packet_type();
|
||||
let mut started_client = base_builder.start_base(packet_type).await?;
|
||||
let self_address = started_client.address;
|
||||
let client_input = started_client.client_input.register_producer();
|
||||
let client_output = started_client.client_output.register_consumer();
|
||||
@@ -150,6 +154,7 @@ impl SocketClient {
|
||||
client_state,
|
||||
&self_address,
|
||||
started_client.task_manager.subscribe(),
|
||||
packet_type,
|
||||
);
|
||||
|
||||
info!("Client startup finished!");
|
||||
@@ -164,7 +169,8 @@ impl SocketClient {
|
||||
}
|
||||
|
||||
let base_builder = self.create_base_client_builder().await?;
|
||||
let mut started_client = base_builder.start_base().await?;
|
||||
let packet_type = self.config.get_base().get_packet_type();
|
||||
let mut started_client = base_builder.start_base(packet_type).await?;
|
||||
let address = started_client.address;
|
||||
let client_input = started_client.client_input.register_producer();
|
||||
let client_output = started_client.client_output.register_consumer();
|
||||
@@ -186,6 +192,7 @@ impl SocketClient {
|
||||
reconstructed_receiver,
|
||||
address,
|
||||
shutdown_notifier: started_client.task_manager,
|
||||
packet_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -199,6 +206,7 @@ pub struct DirectClient {
|
||||
|
||||
// we need to keep reference to this guy otherwise things will start dropping
|
||||
shutdown_notifier: TaskManager,
|
||||
packet_type: PacketType,
|
||||
}
|
||||
|
||||
impl DirectClient {
|
||||
@@ -219,7 +227,7 @@ impl DirectClient {
|
||||
/// well enough in local tests)
|
||||
pub async fn send_regular_message(&mut self, recipient: Recipient, message: Vec<u8>) {
|
||||
let lane = TransmissionLane::General;
|
||||
let input_msg = InputMessage::new_regular(recipient, message, lane);
|
||||
let input_msg = InputMessage::new_regular(recipient, message, lane, Some(self.packet_type));
|
||||
|
||||
self.client_input
|
||||
.input_sender
|
||||
@@ -238,7 +246,13 @@ impl DirectClient {
|
||||
reply_surbs: u32,
|
||||
) {
|
||||
let lane = TransmissionLane::General;
|
||||
let input_msg = InputMessage::new_anonymous(recipient, message, reply_surbs, lane);
|
||||
let input_msg = InputMessage::new_anonymous(
|
||||
recipient,
|
||||
message,
|
||||
reply_surbs,
|
||||
lane,
|
||||
Some(self.packet_type),
|
||||
);
|
||||
|
||||
self.client_input
|
||||
.input_sender
|
||||
@@ -252,7 +266,8 @@ impl DirectClient {
|
||||
/// well enough in local tests)
|
||||
pub async fn send_reply(&mut self, recipient_tag: AnonymousSenderTag, message: Vec<u8>) {
|
||||
let lane = TransmissionLane::General;
|
||||
let input_msg = InputMessage::new_reply(recipient_tag, message, lane);
|
||||
let input_msg =
|
||||
InputMessage::new_reply(recipient_tag, message, lane, Some(self.packet_type));
|
||||
|
||||
self.client_input
|
||||
.input_sender
|
||||
|
||||
@@ -14,6 +14,7 @@ use nym_client_core::client::{
|
||||
use nym_client_websocket_requests::{requests::ClientRequest, responses::ServerResponse};
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_sphinx::receiver::ReconstructedMessage;
|
||||
use nym_task::connections::{
|
||||
ConnectionCommand, ConnectionCommandSender, ConnectionId, LaneQueueLengths, TransmissionLane,
|
||||
@@ -41,6 +42,7 @@ pub(crate) struct HandlerBuilder {
|
||||
self_full_address: Recipient,
|
||||
lane_queue_lengths: LaneQueueLengths,
|
||||
reply_controller_sender: ReplyControllerSender,
|
||||
packet_type: Option<PacketType>,
|
||||
}
|
||||
|
||||
impl HandlerBuilder {
|
||||
@@ -51,6 +53,7 @@ impl HandlerBuilder {
|
||||
self_full_address: &Recipient,
|
||||
lane_queue_lengths: LaneQueueLengths,
|
||||
reply_controller_sender: ReplyControllerSender,
|
||||
packet_type: Option<PacketType>,
|
||||
) -> Self {
|
||||
Self {
|
||||
msg_input,
|
||||
@@ -59,6 +62,7 @@ impl HandlerBuilder {
|
||||
self_full_address: *self_full_address,
|
||||
lane_queue_lengths,
|
||||
reply_controller_sender,
|
||||
packet_type,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +77,7 @@ impl HandlerBuilder {
|
||||
received_response_type: Default::default(),
|
||||
lane_queue_lengths: self.lane_queue_lengths.clone(),
|
||||
reply_controller_sender: self.reply_controller_sender.clone(),
|
||||
packet_type: self.packet_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,6 +91,7 @@ pub(crate) struct Handler {
|
||||
received_response_type: ReceivedResponseType,
|
||||
lane_queue_lengths: LaneQueueLengths,
|
||||
reply_controller_sender: ReplyControllerSender,
|
||||
packet_type: Option<PacketType>,
|
||||
}
|
||||
|
||||
impl Drop for Handler {
|
||||
@@ -160,7 +166,7 @@ impl Handler {
|
||||
});
|
||||
|
||||
// the ack control is now responsible for chunking, etc.
|
||||
let input_msg = InputMessage::new_regular(recipient, message, lane);
|
||||
let input_msg = InputMessage::new_regular(recipient, message, lane, self.packet_type);
|
||||
self.msg_input
|
||||
.send(input_msg)
|
||||
.await
|
||||
@@ -191,7 +197,8 @@ impl Handler {
|
||||
TransmissionLane::ConnectionId(id)
|
||||
});
|
||||
|
||||
let input_msg = InputMessage::new_anonymous(recipient, message, reply_surbs, lane);
|
||||
let input_msg =
|
||||
InputMessage::new_anonymous(recipient, message, reply_surbs, lane, self.packet_type);
|
||||
self.msg_input
|
||||
.send(input_msg)
|
||||
.await
|
||||
@@ -218,7 +225,7 @@ impl Handler {
|
||||
TransmissionLane::ConnectionId(id)
|
||||
});
|
||||
|
||||
let input_msg = InputMessage::new_reply(recipient_tag, message, lane);
|
||||
let input_msg = InputMessage::new_reply(recipient_tag, message, lane, self.packet_type);
|
||||
self.msg_input
|
||||
.send(input_msg)
|
||||
.await
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.19"
|
||||
version = "1.1.20"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||
edition = "2021"
|
||||
|
||||
@@ -91,6 +91,7 @@ impl From<Init> for OverrideConfig {
|
||||
no_cover: init_config.no_cover,
|
||||
nyxd_urls: init_config.nyxd_urls,
|
||||
enabled_credentials_mode: init_config.enabled_credentials_mode,
|
||||
outfox: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ use nym_bin_common::completions::{fig_generate, ArgShell};
|
||||
use nym_config::{NymConfig, OptionalSet};
|
||||
use nym_socks5_client_core::config::old_config_v1_1_13::OldConfigV1_1_13;
|
||||
use nym_socks5_client_core::config::{BaseConfig, Config};
|
||||
use nym_sphinx::params::PacketType;
|
||||
use std::error::Error;
|
||||
|
||||
pub mod init;
|
||||
@@ -64,6 +65,7 @@ pub(crate) struct OverrideConfig {
|
||||
no_cover: bool,
|
||||
nyxd_urls: Option<Vec<url::Url>>,
|
||||
enabled_credentials_mode: Option<bool>,
|
||||
outfox: bool,
|
||||
}
|
||||
|
||||
pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
@@ -80,9 +82,15 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Syn
|
||||
}
|
||||
|
||||
pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
||||
let packet_type = if args.outfox {
|
||||
PacketType::Outfox
|
||||
} else {
|
||||
PacketType::Mix
|
||||
};
|
||||
config
|
||||
.with_base(BaseConfig::with_high_default_traffic_volume, args.fastmode)
|
||||
.with_base(BaseConfig::with_disabled_cover_traffic, args.no_cover)
|
||||
.with_base(BaseConfig::with_packet_type, packet_type)
|
||||
.with_optional(Config::with_anonymous_replies, args.use_anonymous_replies)
|
||||
.with_optional(Config::with_port, args.port)
|
||||
.with_optional_custom_env_ext(
|
||||
|
||||
@@ -68,6 +68,9 @@ pub(crate) struct Run {
|
||||
/// with bandwidth credential requirement.
|
||||
#[clap(long, hide = true)]
|
||||
enabled_credentials_mode: Option<bool>,
|
||||
|
||||
#[clap(long, hide = true, action)]
|
||||
outfox: bool,
|
||||
}
|
||||
|
||||
impl From<Run> for OverrideConfig {
|
||||
@@ -80,6 +83,7 @@ impl From<Run> for OverrideConfig {
|
||||
no_cover: run_config.no_cover,
|
||||
nyxd_urls: run_config.nyxd_urls,
|
||||
enabled_credentials_mode: run_config.enabled_credentials_mode,
|
||||
outfox: run_config.outfox,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
||||
bin/
|
||||
pkg/
|
||||
wasm-pack.log
|
||||
|
||||
Generated
+91
-185
@@ -237,18 +237,18 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||
|
||||
[[package]]
|
||||
name = "bip32"
|
||||
version = "0.4.0"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b"
|
||||
checksum = "873faa4363bfc54c36a48321da034c92a0645a363eed34d948683ffc1706e37f"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"hmac 0.12.1",
|
||||
"hmac 0.11.0",
|
||||
"k256",
|
||||
"once_cell",
|
||||
"pbkdf2",
|
||||
"rand_core 0.6.4",
|
||||
"ripemd",
|
||||
"sha2 0.10.6",
|
||||
"ripemd160",
|
||||
"sha2 0.9.9",
|
||||
"subtle 2.4.1",
|
||||
"zeroize",
|
||||
]
|
||||
@@ -332,6 +332,7 @@ version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"generic-array 0.14.7",
|
||||
]
|
||||
|
||||
@@ -344,6 +345,12 @@ dependencies = [
|
||||
"generic-array 0.14.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae"
|
||||
|
||||
[[package]]
|
||||
name = "bls12_381"
|
||||
version = "0.5.0"
|
||||
@@ -570,9 +577,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "const-oid"
|
||||
version = "0.9.2"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913"
|
||||
checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3"
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
@@ -598,9 +605,8 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
|
||||
|
||||
[[package]]
|
||||
name = "cosmos-sdk-proto"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bb61f3d2224c90ea78e1fa7444787761a549170c46b6b0ed09b93f9b7e4076a"
|
||||
version = "0.12.3"
|
||||
source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d"
|
||||
dependencies = [
|
||||
"prost",
|
||||
"prost-types",
|
||||
@@ -609,9 +615,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cosmrs"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20d5890dac07a62337e5841adb8f2074a66a962a098a48df9460f64d483beaf4"
|
||||
version = "0.7.1"
|
||||
source = "git+https://github.com/neacsu/cosmos-rust?branch=neacsu/feegrant_support#f63ded63ec13e753ebe8bdafe9dc503df265d67d"
|
||||
dependencies = [
|
||||
"bip32",
|
||||
"cosmos-sdk-proto",
|
||||
@@ -632,11 +637,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cosmwasm-crypto"
|
||||
version = "1.2.5"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75836a10cb9654c54e77ee56da94d592923092a10b369cdb0dbd56acefc16340"
|
||||
checksum = "970d1d705862179b5d7a233ae36f02f21c4ec1b8075fe60c77fc5b43471331fa"
|
||||
dependencies = [
|
||||
"digest 0.10.6",
|
||||
"digest 0.9.0",
|
||||
"ed25519-zebra",
|
||||
"k256",
|
||||
"rand_core 0.6.4",
|
||||
@@ -645,53 +650,26 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cosmwasm-derive"
|
||||
version = "1.2.5"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c9f7f0e51bfc7295f7b2664fe8513c966428642aa765dad8a74acdab5e0c773"
|
||||
checksum = "4b36e527620a2a3e00e46b6e731ab6c9b68d11069c986f7d7be8eba79ef081a4"
|
||||
dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmwasm-schema"
|
||||
version = "1.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f00b363610218eea83f24bbab09e1a7c3920b79f068334fdfcc62f6129ef9fc"
|
||||
dependencies = [
|
||||
"cosmwasm-schema-derive",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmwasm-schema-derive"
|
||||
version = "1.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae38f909b2822d32b275c9e2db9728497aa33ffe67dd463bc67c6a3b7092785c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cosmwasm-std"
|
||||
version = "1.2.5"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a49b85345e811c8e80ec55d0d091e4fcb4f00f97ab058f9be5f614c444a730cb"
|
||||
checksum = "875994993c2082a6fcd406937bf0fca21c349e4a624f3810253a14fa83a3a195"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"cosmwasm-crypto",
|
||||
"cosmwasm-derive",
|
||||
"derivative",
|
||||
"forward_ref",
|
||||
"hex",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde-json-wasm 0.5.1",
|
||||
"sha2 0.10.6",
|
||||
"serde-json-wasm",
|
||||
"thiserror",
|
||||
"uint",
|
||||
]
|
||||
@@ -805,9 +783,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-bigint"
|
||||
version = "0.4.9"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef"
|
||||
checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21"
|
||||
dependencies = [
|
||||
"generic-array 0.14.7",
|
||||
"rand_core 0.6.4",
|
||||
@@ -889,11 +867,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cw-controllers"
|
||||
version = "1.0.1"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91440ce8ec4f0642798bc8c8cb6b9b53c1926c6dadaf0eed267a5145cd529071"
|
||||
checksum = "4f0bc6019b4d3d81e11f5c384bcce7173e2210bd654d75c6c9668e12cca05dfa"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cw-storage-plus",
|
||||
"cw-utils",
|
||||
@@ -904,9 +881,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cw-storage-plus"
|
||||
version = "1.0.1"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053a5083c258acd68386734f428a5a171b29f7d733151ae83090c6fcc9417ffa"
|
||||
checksum = "648b1507290bbc03a8d88463d7cd9b04b1fa0155e5eef366c4fa052b9caaac7a"
|
||||
dependencies = [
|
||||
"cosmwasm-std",
|
||||
"schemars",
|
||||
@@ -915,67 +892,46 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cw-utils"
|
||||
version = "1.0.1"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7"
|
||||
checksum = "9dbaecb78c8e8abfd6b4258c7f4fbeb5c49a5e45ee4d910d3240ee8e1d714e1b"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cw2",
|
||||
"schemars",
|
||||
"semver 1.0.17",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cw2"
|
||||
version = "1.0.1"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fb70cee2cf0b4a8ff7253e6bc6647107905e8eb37208f87d54f67810faa62f8"
|
||||
checksum = "04cf4639517490dd36b333bbd6c4fbd92e325fd0acf4683b41753bc5eb63bfc1"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cw-storage-plus",
|
||||
"schemars",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cw20"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91666da6c7b40c8dd5ff94df655a28114efc10c79b70b4d06f13c31e37d60609"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cw-utils",
|
||||
"schemars",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cw3"
|
||||
version = "1.0.1"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fe0b587008aa221cd2a2579a21990a28c4347dc53ad43167c68ad765f5b6efa"
|
||||
checksum = "fe19462a7f644ba60c19d3443cb90d00c50d9b6b3b0a3a7fca93df8261af979b"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cw-utils",
|
||||
"cw20",
|
||||
"schemars",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cw4"
|
||||
version = "1.0.1"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c236e0bae02ce97e89235a681dd0e07d099524b369f1ef908d704db3e6b049b"
|
||||
checksum = "0acc3549d5ce11c6901b3a676f2e2628684722197054d97cd0101ea174ed5cbd"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cw-storage-plus",
|
||||
"schemars",
|
||||
@@ -997,23 +953,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "der"
|
||||
version = "0.6.1"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de"
|
||||
checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1085,9 +1029,9 @@ checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30"
|
||||
|
||||
[[package]]
|
||||
name = "ecdsa"
|
||||
version = "0.14.8"
|
||||
version = "0.13.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c"
|
||||
checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9"
|
||||
dependencies = [
|
||||
"der",
|
||||
"elliptic-curve",
|
||||
@@ -1143,18 +1087,16 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
|
||||
[[package]]
|
||||
name = "elliptic-curve"
|
||||
version = "0.12.3"
|
||||
version = "0.11.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3"
|
||||
checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"crypto-bigint",
|
||||
"der",
|
||||
"digest 0.10.6",
|
||||
"ff 0.12.1",
|
||||
"ff 0.11.1",
|
||||
"generic-array 0.14.7",
|
||||
"group 0.12.1",
|
||||
"pkcs8",
|
||||
"group 0.11.0",
|
||||
"rand_core 0.6.4",
|
||||
"sec1",
|
||||
"subtle 2.4.1",
|
||||
@@ -1269,16 +1211,6 @@ dependencies = [
|
||||
"subtle 2.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ff"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160"
|
||||
dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
"subtle 2.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.26"
|
||||
@@ -1571,17 +1503,6 @@ dependencies = [
|
||||
"subtle 2.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "group"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7"
|
||||
dependencies = [
|
||||
"ff 0.12.1",
|
||||
"rand_core 0.6.4",
|
||||
"subtle 2.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.19"
|
||||
@@ -2036,14 +1957,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "k256"
|
||||
version = "0.11.6"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b"
|
||||
checksum = "19c3a5e0a0b8450278feda242592512e09f61c72e018b8cd5c859482802daf2d"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"ecdsa",
|
||||
"elliptic-curve",
|
||||
"sha2 0.10.6",
|
||||
"sec1",
|
||||
"sha2 0.9.9",
|
||||
"sha3",
|
||||
]
|
||||
|
||||
@@ -2459,7 +2381,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-contracts-common"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"cosmwasm-std",
|
||||
@@ -2494,7 +2416,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-crypto"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
dependencies = [
|
||||
"aes 0.8.2",
|
||||
"blake3",
|
||||
@@ -2594,8 +2516,6 @@ dependencies = [
|
||||
name = "nym-group-contract-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cw-controllers",
|
||||
"cw4",
|
||||
"schemars",
|
||||
"serde",
|
||||
@@ -2603,7 +2523,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-mixnet-contract-common"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"cosmwasm-std",
|
||||
@@ -2612,7 +2532,7 @@ dependencies = [
|
||||
"nym-contracts-common",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde-json-wasm 0.4.1",
|
||||
"serde-json-wasm",
|
||||
"serde_repr",
|
||||
"thiserror",
|
||||
"time",
|
||||
@@ -2622,9 +2542,7 @@ dependencies = [
|
||||
name = "nym-multisig-contract-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cw-storage-plus",
|
||||
"cw-utils",
|
||||
"cw3",
|
||||
"cw4",
|
||||
@@ -2705,7 +2623,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-pemstore"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"pem",
|
||||
]
|
||||
@@ -2715,8 +2633,12 @@ name = "nym-service-provider-directory-common"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cosmwasm-std",
|
||||
"cw-controllers",
|
||||
"cw-utils",
|
||||
"nym-contracts-common",
|
||||
"schemars",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2969,7 +2891,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-vesting-contract-common"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
dependencies = [
|
||||
"cosmwasm-std",
|
||||
"nym-contracts-common",
|
||||
@@ -3115,11 +3037,11 @@ checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
|
||||
|
||||
[[package]]
|
||||
name = "pbkdf2"
|
||||
version = "0.11.0"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
|
||||
checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739"
|
||||
dependencies = [
|
||||
"digest 0.10.6",
|
||||
"crypto-mac 0.11.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3244,12 +3166,13 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkcs8"
|
||||
version = "0.9.0"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba"
|
||||
checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0"
|
||||
dependencies = [
|
||||
"der",
|
||||
"spki",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3578,12 +3501,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rfc6979"
|
||||
version = "0.3.1"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb"
|
||||
checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525"
|
||||
dependencies = [
|
||||
"crypto-bigint",
|
||||
"hmac 0.12.1",
|
||||
"hmac 0.11.0",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
@@ -3602,15 +3525,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ripemd"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f"
|
||||
dependencies = [
|
||||
"digest 0.10.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ripemd160"
|
||||
version = "0.9.1"
|
||||
@@ -3780,11 +3694,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sec1"
|
||||
version = "0.3.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928"
|
||||
checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"der",
|
||||
"generic-array 0.14.7",
|
||||
"pkcs8",
|
||||
@@ -3857,15 +3770,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-json-wasm"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-wasm-bindgen"
|
||||
version = "0.5.0"
|
||||
@@ -3992,12 +3896,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sha3"
|
||||
version = "0.10.8"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
|
||||
checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809"
|
||||
dependencies = [
|
||||
"digest 0.10.6",
|
||||
"block-buffer 0.9.0",
|
||||
"digest 0.9.0",
|
||||
"keccak",
|
||||
"opaque-debug 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4011,11 +3917,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "1.6.4"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
|
||||
checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788"
|
||||
dependencies = [
|
||||
"digest 0.10.6",
|
||||
"digest 0.9.0",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
@@ -4085,9 +3991,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.6.0"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b"
|
||||
checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
"der",
|
||||
@@ -4372,9 +4278,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tendermint"
|
||||
version = "0.23.8"
|
||||
version = "0.23.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a199518e0366ba0aeb0d0e0a59dbd99ea0bdc14280f414ecc758c9228a454ad8"
|
||||
checksum = "3ca881fa4dedd2b46334f13be7fbc8cc1549ba4be5a833fe4e73d1a1baaf7949"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
@@ -4403,9 +4309,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tendermint-config"
|
||||
version = "0.23.8"
|
||||
version = "0.23.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6d8f6a64ae3b59ea3c73efad727271ee085b544b817d7f46901817ca6bb1773"
|
||||
checksum = "f6c56ee93f4e9b7e7daba86d171f44572e91b741084384d0ae00df7991873dfd"
|
||||
dependencies = [
|
||||
"flex-error",
|
||||
"serde",
|
||||
@@ -4417,9 +4323,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tendermint-proto"
|
||||
version = "0.23.8"
|
||||
version = "0.23.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b303d6387aaea38cea7ef924476d1f798573044e7b4f6ddd1166ac5184b2281"
|
||||
checksum = "b71f925d74903f4abbdc4af0110635a307b3cb05b175fdff4a7247c14a4d0874"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"flex-error",
|
||||
@@ -4435,9 +4341,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tendermint-rpc"
|
||||
version = "0.23.8"
|
||||
version = "0.23.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3036f0b65baa11e767dabd22a0663e842b595b0a1903f149b7b8b1e09b2b443d"
|
||||
checksum = "a13e63f57ee05a1e927887191c76d1b139de9fa40c180b9f8727ee44377242a6"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
|
||||
@@ -11,7 +11,7 @@ use nym_client_core::config::{
|
||||
DebugConfig as ConfigDebug, GatewayConnection as ConfigGatewayConnection,
|
||||
ReplySurbs as ConfigReplySurbs, Topology as ConfigTopology, Traffic as ConfigTraffic,
|
||||
};
|
||||
use nym_sphinx::params::PacketSize;
|
||||
use nym_sphinx::params::{PacketSize, PacketType};
|
||||
use nym_validator_client::client::IdentityKey;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
@@ -34,6 +34,8 @@ pub struct Config {
|
||||
pub(crate) gateway: Option<IdentityKey>,
|
||||
|
||||
pub(crate) debug: ConfigDebug,
|
||||
|
||||
pub(crate) packet_type: PacketType,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
@@ -42,9 +44,18 @@ impl Config {
|
||||
pub fn new(
|
||||
id: String,
|
||||
validator_server: String,
|
||||
packet_type: Option<String>,
|
||||
gateway: Option<IdentityKey>,
|
||||
debug: Option<Debug>,
|
||||
) -> Self {
|
||||
let packet_type = if let Some(packet_type) = packet_type {
|
||||
match packet_type.as_str() {
|
||||
"outfox" => PacketType::Outfox,
|
||||
_ => PacketType::Mix,
|
||||
}
|
||||
} else {
|
||||
PacketType::Mix
|
||||
};
|
||||
Config {
|
||||
id,
|
||||
nym_api_url: Some(
|
||||
@@ -55,6 +66,7 @@ impl Config {
|
||||
disabled_credentials_mode: true,
|
||||
gateway,
|
||||
debug: debug.map(Into::into).unwrap_or_default(),
|
||||
packet_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,6 +109,7 @@ impl From<Traffic> for ConfigTraffic {
|
||||
.disable_main_poisson_packet_distribution,
|
||||
primary_packet_size: PacketSize::RegularPacket,
|
||||
secondary_packet_size: use_extended_packet_size,
|
||||
packet_type: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ use nym_client_core::client::inbound_messages::InputMessage;
|
||||
use nym_client_core::client::replies::reply_storage::browser_backend;
|
||||
use nym_client_core::config::{CoverTraffic, DebugConfig, Topology, Traffic};
|
||||
use nym_credential_storage::ephemeral_storage::EphemeralStorage;
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_task::connections::TransmissionLane;
|
||||
use nym_task::TaskManager;
|
||||
use nym_topology::provider_trait::{HardcodedTopologyProvider, TopologyProvider};
|
||||
@@ -52,6 +53,7 @@ pub struct NymClient {
|
||||
// even though we don't use graceful shutdowns, other components rely on existence of this struct
|
||||
// and if it's dropped, everything will start going offline
|
||||
_task_manager: TaskManager,
|
||||
packet_type: Option<PacketType>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
@@ -68,6 +70,7 @@ pub struct NymClientBuilder {
|
||||
bandwidth_controller:
|
||||
Option<BandwidthController<FakeClient<DirectSigningNyxdClient>, EphemeralStorage>>,
|
||||
disabled_credentials: bool,
|
||||
packet_type: Option<PacketType>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
@@ -86,6 +89,7 @@ impl NymClientBuilder {
|
||||
on_message,
|
||||
bandwidth_controller: None,
|
||||
disabled_credentials: true,
|
||||
packet_type: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +128,7 @@ impl NymClientBuilder {
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
packet_type: PacketType::Mix,
|
||||
};
|
||||
|
||||
NymClientBuilder {
|
||||
@@ -136,6 +141,7 @@ impl NymClientBuilder {
|
||||
bandwidth_controller: None,
|
||||
disabled_credentials: true,
|
||||
storage_passphrase: None,
|
||||
packet_type: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +208,8 @@ impl NymClientBuilder {
|
||||
base_builder = base_builder.with_topology_provider(topology_provider);
|
||||
}
|
||||
|
||||
let mut started_client = base_builder.start_base().await?;
|
||||
let packet_type = self.config.packet_type;
|
||||
let mut started_client = base_builder.start_base(packet_type).await?;
|
||||
let self_address = started_client.address.to_string();
|
||||
|
||||
let client_input = started_client.client_input.register_producer();
|
||||
@@ -216,6 +223,7 @@ impl NymClientBuilder {
|
||||
client_state: Arc::new(started_client.client_state),
|
||||
_full_topology: None,
|
||||
_task_manager: started_client.task_manager,
|
||||
packet_type: self.packet_type,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -291,7 +299,7 @@ impl NymClient {
|
||||
let input_msgs = request
|
||||
.test_msgs
|
||||
.into_iter()
|
||||
.map(|p| InputMessage::new_regular(recipient, p, lane))
|
||||
.map(|p| InputMessage::new_regular(recipient, p, lane, None))
|
||||
.collect();
|
||||
|
||||
self.client_input.send_messages(input_msgs)
|
||||
@@ -311,7 +319,7 @@ impl NymClient {
|
||||
|
||||
let lane = TransmissionLane::General;
|
||||
|
||||
let input_msg = InputMessage::new_regular(recipient, message, lane);
|
||||
let input_msg = InputMessage::new_regular(recipient, message, lane, self.packet_type);
|
||||
self.client_input.send_message(input_msg)
|
||||
}
|
||||
|
||||
@@ -338,7 +346,8 @@ impl NymClient {
|
||||
|
||||
let lane = TransmissionLane::General;
|
||||
|
||||
let input_msg = InputMessage::new_anonymous(recipient, message, reply_surbs, lane);
|
||||
let input_msg =
|
||||
InputMessage::new_anonymous(recipient, message, reply_surbs, lane, self.packet_type);
|
||||
self.client_input.send_message(input_msg)
|
||||
}
|
||||
|
||||
@@ -356,7 +365,7 @@ impl NymClient {
|
||||
|
||||
let lane = TransmissionLane::General;
|
||||
|
||||
let input_msg = InputMessage::new_reply(sender_tag, message, lane);
|
||||
let input_msg = InputMessage::new_reply(sender_tag, message, lane, self.packet_type);
|
||||
self.client_input.send_message(input_msg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ impl AsyncFileWatcher {
|
||||
Ok(event) => {
|
||||
let now = Instant::now();
|
||||
if self.should_propagate(&event, now) {
|
||||
self.last_received.insert(event.kind.clone(), now);
|
||||
self.last_received.insert(event.kind, now);
|
||||
if let Err(_err) = self.event_sender.unbounded_send(event) {
|
||||
log::error!("the file watcher receiver has been dropped!");
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ use nym_gateway_client::{
|
||||
use nym_sphinx::acknowledgements::AckKey;
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
use nym_sphinx::addressing::nodes::NodeIdentity;
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_sphinx::receiver::{ReconstructedMessage, SphinxMessageReceiver};
|
||||
use nym_task::connections::{ConnectionCommandReceiver, ConnectionCommandSender, LaneQueueLengths};
|
||||
use nym_task::{TaskClient, TaskManager};
|
||||
@@ -275,6 +276,7 @@ where
|
||||
lane_queue_lengths: LaneQueueLengths,
|
||||
client_connection_rx: ConnectionCommandReceiver,
|
||||
shutdown: TaskClient,
|
||||
packet_type: PacketType,
|
||||
) {
|
||||
info!("Starting real traffic stream...");
|
||||
|
||||
@@ -290,7 +292,7 @@ where
|
||||
lane_queue_lengths,
|
||||
client_connection_rx,
|
||||
)
|
||||
.start_with_shutdown(shutdown);
|
||||
.start_with_shutdown(shutdown, packet_type);
|
||||
}
|
||||
|
||||
// buffer controlling all messages fetched from provider
|
||||
@@ -426,7 +428,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// controller for sending sphinx packets to mixnet (either real traffic or cover traffic)
|
||||
// controller for sending packets to mixnet (either real traffic or cover traffic)
|
||||
// TODO: if we want to send control messages to gateway_client, this CAN'T take the ownership
|
||||
// over it. Perhaps GatewayClient needs to be thread-shareable or have some channel for
|
||||
// requests?
|
||||
@@ -477,7 +479,10 @@ where
|
||||
self.managed_keys = ManagedKeys::load_or_generate(&mut rng, &self.key_store).await;
|
||||
}
|
||||
|
||||
pub async fn start_base(mut self) -> Result<BaseClient, ClientCoreError>
|
||||
pub async fn start_base(
|
||||
mut self,
|
||||
packet_type: PacketType,
|
||||
) -> Result<BaseClient, ClientCoreError>
|
||||
where
|
||||
<S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send,
|
||||
S::ReplyStore: Send + Sync,
|
||||
@@ -548,11 +553,11 @@ where
|
||||
task_manager.subscribe(),
|
||||
);
|
||||
|
||||
// The sphinx_message_sender is the transmitter for any component generating sphinx packets
|
||||
// The message_sender is the transmitter for any component generating sphinx packets
|
||||
// that are to be sent to the mixnet. They are used by cover traffic stream and real
|
||||
// traffic stream.
|
||||
// The MixTrafficController then sends the actual traffic
|
||||
let sphinx_message_sender =
|
||||
let message_sender =
|
||||
Self::start_mix_traffic_controller(gateway_client, task_manager.subscribe());
|
||||
|
||||
// Channels that the websocket listener can use to signal downstream to the real traffic
|
||||
@@ -574,13 +579,14 @@ where
|
||||
shared_topology_accessor.clone(),
|
||||
ack_receiver,
|
||||
input_receiver,
|
||||
sphinx_message_sender.clone(),
|
||||
message_sender.clone(),
|
||||
reply_storage,
|
||||
reply_controller_sender.clone(),
|
||||
reply_controller_receiver,
|
||||
shared_lane_queue_lengths.clone(),
|
||||
client_connection_rx,
|
||||
task_manager.subscribe(),
|
||||
packet_type,
|
||||
);
|
||||
|
||||
if !self
|
||||
@@ -593,7 +599,7 @@ where
|
||||
self.managed_keys.ack_key(),
|
||||
self_address,
|
||||
shared_topology_accessor.clone(),
|
||||
sphinx_message_sender,
|
||||
message_sender,
|
||||
task_manager.subscribe(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,15 +12,15 @@ use nym_credential_storage::ephemeral_storage::{
|
||||
};
|
||||
use nym_credential_storage::storage::Storage as CredentialStorage;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||
use crate::client::base_client::non_wasm_helpers;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||
use crate::client::key_manager::persistence::OnDiskKeys;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||
use crate::config::{persistence::key_pathfinder::ClientKeyPathfinder, Config};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||
use crate::error::ClientCoreError;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||
use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage;
|
||||
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||
@@ -74,14 +74,14 @@ impl MixnetClientStorage for Ephemeral {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||
pub struct OnDiskPersistent {
|
||||
pub(crate) key_store: OnDiskKeys,
|
||||
pub(crate) reply_store: fs_backend::Backend,
|
||||
pub(crate) credential_store: PersistentCredentialStorage,
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||
impl OnDiskPersistent {
|
||||
pub fn new(
|
||||
key_store: OnDiskKeys,
|
||||
@@ -116,7 +116,7 @@ impl OnDiskPersistent {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
|
||||
impl MixnetClientStorage for OnDiskPersistent {
|
||||
type KeyStore = OnDiskKeys;
|
||||
type ReplyStore = fs_backend::Backend;
|
||||
|
||||
@@ -45,7 +45,7 @@ where
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
next_delay: Pin<Box<wasm_timer::Delay>>,
|
||||
|
||||
/// Channel used for sending prepared sphinx packets to `MixTrafficController` that sends them
|
||||
/// Channel used for sending prepared nym packets to `MixTrafficController` that sends them
|
||||
/// out to the network without any further delays.
|
||||
mix_tx: BatchMixMessageSender,
|
||||
|
||||
@@ -194,6 +194,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
||||
self.average_ack_delay,
|
||||
self.cover_traffic.loop_cover_traffic_average_delay,
|
||||
cover_traffic_packet_size,
|
||||
nym_sphinx::params::PacketType::Mix,
|
||||
)
|
||||
.expect("Somehow failed to generate a loop cover message with a valid topology");
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
|
||||
use nym_sphinx::forwarding::packet::MixPacket;
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_task::connections::TransmissionLane;
|
||||
|
||||
pub type InputMessageSender = tokio::sync::mpsc::Sender<InputMessage>;
|
||||
@@ -53,18 +54,49 @@ pub enum InputMessage {
|
||||
data: Vec<u8>,
|
||||
lane: TransmissionLane,
|
||||
},
|
||||
|
||||
MessageWrapper {
|
||||
message: Box<InputMessage>,
|
||||
packet_type: PacketType,
|
||||
},
|
||||
}
|
||||
|
||||
impl InputMessage {
|
||||
pub fn new_premade(msgs: Vec<MixPacket>, lane: TransmissionLane) -> Self {
|
||||
InputMessage::Premade { msgs, lane }
|
||||
pub fn new_premade(
|
||||
msgs: Vec<MixPacket>,
|
||||
lane: TransmissionLane,
|
||||
packet_type: PacketType,
|
||||
) -> Self {
|
||||
let message = InputMessage::Premade { msgs, lane };
|
||||
if packet_type == PacketType::Mix {
|
||||
message
|
||||
} else {
|
||||
InputMessage::new_wrapper(message, packet_type)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_regular(recipient: Recipient, data: Vec<u8>, lane: TransmissionLane) -> Self {
|
||||
InputMessage::Regular {
|
||||
pub fn new_wrapper(message: InputMessage, packet_type: PacketType) -> Self {
|
||||
InputMessage::MessageWrapper {
|
||||
message: Box::new(message),
|
||||
packet_type,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_regular(
|
||||
recipient: Recipient,
|
||||
data: Vec<u8>,
|
||||
lane: TransmissionLane,
|
||||
packet_type: Option<PacketType>,
|
||||
) -> Self {
|
||||
let message = InputMessage::Regular {
|
||||
recipient,
|
||||
data,
|
||||
lane,
|
||||
};
|
||||
if let Some(packet_type) = packet_type {
|
||||
InputMessage::new_wrapper(message, packet_type)
|
||||
} else {
|
||||
message
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,12 +105,18 @@ impl InputMessage {
|
||||
data: Vec<u8>,
|
||||
reply_surbs: u32,
|
||||
lane: TransmissionLane,
|
||||
packet_type: Option<PacketType>,
|
||||
) -> Self {
|
||||
InputMessage::Anonymous {
|
||||
let message = InputMessage::Anonymous {
|
||||
recipient,
|
||||
data,
|
||||
reply_surbs,
|
||||
lane,
|
||||
};
|
||||
if let Some(packet_type) = packet_type {
|
||||
InputMessage::new_wrapper(message, packet_type)
|
||||
} else {
|
||||
message
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,11 +124,17 @@ impl InputMessage {
|
||||
recipient_tag: AnonymousSenderTag,
|
||||
data: Vec<u8>,
|
||||
lane: TransmissionLane,
|
||||
packet_type: Option<PacketType>,
|
||||
) -> Self {
|
||||
InputMessage::Reply {
|
||||
let message = InputMessage::Reply {
|
||||
recipient_tag,
|
||||
data,
|
||||
lane,
|
||||
};
|
||||
if let Some(packet_type) = packet_type {
|
||||
InputMessage::new_wrapper(message, packet_type)
|
||||
} else {
|
||||
message
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,6 +144,7 @@ impl InputMessage {
|
||||
| InputMessage::Anonymous { lane, .. }
|
||||
| InputMessage::Reply { lane, .. }
|
||||
| InputMessage::Premade { lane, .. } => lane,
|
||||
InputMessage::MessageWrapper { message, .. } => message.lane(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,15 +40,15 @@ where
|
||||
pub fn new(
|
||||
gateway_client: GatewayClient<C, St>,
|
||||
) -> (MixTrafficController<C, St>, BatchMixMessageSender) {
|
||||
let (sphinx_message_sender, sphinx_message_receiver) =
|
||||
let (message_sender, message_receiver) =
|
||||
tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE);
|
||||
(
|
||||
MixTrafficController {
|
||||
gateway_client,
|
||||
mix_rx: sphinx_message_receiver,
|
||||
mix_rx: message_receiver,
|
||||
consecutive_gateway_failure_count: 0,
|
||||
},
|
||||
sphinx_message_sender,
|
||||
message_sender,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ impl AcknowledgementListener {
|
||||
while !shutdown.is_shutdown() {
|
||||
tokio::select! {
|
||||
acks = self.ack_receiver.next() => match acks {
|
||||
Some(acks) => self.handle_ack_receiver_item(acks).await,
|
||||
Some(acks) => {self.handle_ack_receiver_item(acks).await}
|
||||
None => {
|
||||
log::trace!("AcknowledgementListener: Stopping since channel closed");
|
||||
break;
|
||||
|
||||
+44
-4
@@ -9,6 +9,7 @@ use log::*;
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
|
||||
use nym_sphinx::forwarding::packet::MixPacket;
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_task::connections::TransmissionLane;
|
||||
use rand::{CryptoRng, Rng};
|
||||
|
||||
@@ -71,10 +72,11 @@ where
|
||||
recipient: Recipient,
|
||||
content: Vec<u8>,
|
||||
lane: TransmissionLane,
|
||||
packet_type: PacketType,
|
||||
) {
|
||||
if let Err(err) = self
|
||||
.message_handler
|
||||
.try_send_plain_message(recipient, content, lane)
|
||||
.try_send_plain_message(recipient, content, lane, packet_type)
|
||||
.await
|
||||
{
|
||||
warn!("failed to send a plain message - {err}")
|
||||
@@ -87,10 +89,11 @@ where
|
||||
content: Vec<u8>,
|
||||
reply_surbs: u32,
|
||||
lane: TransmissionLane,
|
||||
packet_type: PacketType,
|
||||
) {
|
||||
if let Err(err) = self
|
||||
.message_handler
|
||||
.try_send_message_with_reply_surbs(recipient, content, reply_surbs, lane)
|
||||
.try_send_message_with_reply_surbs(recipient, content, reply_surbs, lane, packet_type)
|
||||
.await
|
||||
{
|
||||
warn!("failed to send a repliable message - {err}")
|
||||
@@ -103,14 +106,17 @@ where
|
||||
recipient,
|
||||
data,
|
||||
lane,
|
||||
} => self.handle_plain_message(recipient, data, lane).await,
|
||||
} => {
|
||||
self.handle_plain_message(recipient, data, lane, PacketType::Mix)
|
||||
.await
|
||||
}
|
||||
InputMessage::Anonymous {
|
||||
recipient,
|
||||
data,
|
||||
reply_surbs,
|
||||
lane,
|
||||
} => {
|
||||
self.handle_repliable_message(recipient, data, reply_surbs, lane)
|
||||
self.handle_repliable_message(recipient, data, reply_surbs, lane, PacketType::Mix)
|
||||
.await
|
||||
}
|
||||
InputMessage::Reply {
|
||||
@@ -121,6 +127,40 @@ where
|
||||
self.handle_reply(recipient_tag, data, lane).await;
|
||||
}
|
||||
InputMessage::Premade { msgs, lane } => self.handle_premade_packets(msgs, lane).await,
|
||||
InputMessage::MessageWrapper {
|
||||
message,
|
||||
packet_type,
|
||||
} => match *message {
|
||||
InputMessage::Regular {
|
||||
recipient,
|
||||
data,
|
||||
lane,
|
||||
} => {
|
||||
self.handle_plain_message(recipient, data, lane, packet_type)
|
||||
.await
|
||||
}
|
||||
InputMessage::Anonymous {
|
||||
recipient,
|
||||
data,
|
||||
reply_surbs,
|
||||
lane,
|
||||
} => {
|
||||
self.handle_repliable_message(recipient, data, reply_surbs, lane, packet_type)
|
||||
.await
|
||||
}
|
||||
InputMessage::Reply {
|
||||
recipient_tag,
|
||||
data,
|
||||
lane,
|
||||
} => {
|
||||
self.handle_reply(recipient_tag, data, lane).await;
|
||||
}
|
||||
InputMessage::Premade { msgs, lane } => {
|
||||
self.handle_premade_packets(msgs, lane).await
|
||||
}
|
||||
// MessageWrappers can't be nested
|
||||
InputMessage::MessageWrapper { .. } => unimplemented!(),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ use futures::channel::mpsc;
|
||||
use log::*;
|
||||
use nym_gateway_client::AcknowledgementReceiver;
|
||||
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
|
||||
use nym_sphinx::params::PacketSize;
|
||||
use nym_sphinx::params::{PacketSize, PacketType};
|
||||
use nym_sphinx::{
|
||||
acknowledgements::AckKey,
|
||||
addressing::clients::Recipient,
|
||||
@@ -249,7 +249,11 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn start_with_shutdown(self, shutdown: nym_task::TaskClient) {
|
||||
pub(super) fn start_with_shutdown(
|
||||
self,
|
||||
shutdown: nym_task::TaskClient,
|
||||
packet_type: PacketType,
|
||||
) {
|
||||
let mut acknowledgement_listener = self.acknowledgement_listener;
|
||||
let mut input_message_listener = self.input_message_listener;
|
||||
let mut retransmission_request_listener = self.retransmission_request_listener;
|
||||
@@ -275,7 +279,7 @@ where
|
||||
let shutdown_handle = shutdown.clone();
|
||||
spawn_future(async move {
|
||||
retransmission_request_listener
|
||||
.run_with_shutdown(shutdown_handle)
|
||||
.run_with_shutdown(shutdown_handle, packet_type)
|
||||
.await;
|
||||
debug!("The retransmission request listener has finished execution!");
|
||||
});
|
||||
|
||||
+12
-4
@@ -11,9 +11,9 @@ use crate::client::real_messages_control::real_traffic_stream::RealMessage;
|
||||
use crate::client::replies::reply_controller::ReplyControllerSender;
|
||||
use futures::StreamExt;
|
||||
use log::*;
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
use nym_sphinx::chunking::fragment::Fragment;
|
||||
use nym_sphinx::preparer::PreparedFragment;
|
||||
use nym_sphinx::{addressing::clients::Recipient, params::PacketType};
|
||||
use nym_task::connections::TransmissionLane;
|
||||
use rand::{CryptoRng, Rng};
|
||||
use std::sync::{Arc, Weak};
|
||||
@@ -48,17 +48,20 @@ where
|
||||
&mut self,
|
||||
packet_recipient: Recipient,
|
||||
chunk_data: Fragment,
|
||||
packet_type: PacketType,
|
||||
) -> Result<PreparedFragment, PreparationError> {
|
||||
debug!("retransmitting normal packet...");
|
||||
|
||||
// TODO: Figure out retransmission packet type signaling
|
||||
self.message_handler
|
||||
.try_prepare_single_chunk_for_sending(packet_recipient, chunk_data)
|
||||
.try_prepare_single_chunk_for_sending(packet_recipient, chunk_data, packet_type)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn on_retransmission_request(
|
||||
&mut self,
|
||||
weak_timed_out_ack: Weak<PendingAcknowledgement>,
|
||||
packet_type: PacketType,
|
||||
) {
|
||||
let timed_out_ack = match weak_timed_out_ack.upgrade() {
|
||||
Some(timed_out_ack) => timed_out_ack,
|
||||
@@ -85,6 +88,7 @@ where
|
||||
self.prepare_normal_retransmission_chunk(
|
||||
**recipient,
|
||||
timed_out_ack.message_chunk.clone(),
|
||||
packet_type,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -140,13 +144,17 @@ where
|
||||
.await
|
||||
}
|
||||
|
||||
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) {
|
||||
pub(super) async fn run_with_shutdown(
|
||||
&mut self,
|
||||
mut shutdown: nym_task::TaskClient,
|
||||
packet_type: PacketType,
|
||||
) {
|
||||
debug!("Started RetransmissionRequestListener with graceful shutdown support");
|
||||
|
||||
while !shutdown.is_shutdown() {
|
||||
tokio::select! {
|
||||
timed_out_ack = self.request_receiver.next() => match timed_out_ack {
|
||||
Some(timed_out_ack) => self.on_retransmission_request(timed_out_ack).await,
|
||||
Some(timed_out_ack) => self.on_retransmission_request(timed_out_ack, packet_type).await,
|
||||
None => {
|
||||
log::trace!("RetransmissionRequestListener: Stopping since channel closed");
|
||||
break;
|
||||
|
||||
@@ -15,7 +15,7 @@ use nym_sphinx::anonymous_replies::requests::{AnonymousSenderTag, RepliableMessa
|
||||
use nym_sphinx::anonymous_replies::{ReplySurb, SurbEncryptionKey};
|
||||
use nym_sphinx::chunking::fragment::{Fragment, FragmentIdentifier};
|
||||
use nym_sphinx::message::NymMessage;
|
||||
use nym_sphinx::params::{PacketSize, DEFAULT_NUM_MIX_HOPS};
|
||||
use nym_sphinx::params::{PacketSize, PacketType, DEFAULT_NUM_MIX_HOPS};
|
||||
use nym_sphinx::preparer::{MessagePreparer, PreparedFragment};
|
||||
use nym_sphinx::Delay;
|
||||
use nym_task::connections::TransmissionLane;
|
||||
@@ -27,7 +27,7 @@ use std::time::Duration;
|
||||
use thiserror::Error;
|
||||
|
||||
// TODO: move that error elsewhere since it seems to be contaminating different files
|
||||
#[derive(Debug, Clone, Error)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PreparationError {
|
||||
#[error(transparent)]
|
||||
NymTopologyError(#[from] NymTopologyError),
|
||||
@@ -417,9 +417,10 @@ where
|
||||
recipient: Recipient,
|
||||
message: Vec<u8>,
|
||||
lane: TransmissionLane,
|
||||
packet_type: PacketType,
|
||||
) -> Result<(), PreparationError> {
|
||||
let message = NymMessage::new_plain(message);
|
||||
self.try_split_and_send_non_reply_message(message, recipient, lane)
|
||||
self.try_split_and_send_non_reply_message(message, recipient, lane, packet_type)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -428,7 +429,9 @@ where
|
||||
message: NymMessage,
|
||||
recipient: Recipient,
|
||||
lane: TransmissionLane,
|
||||
packet_type: PacketType,
|
||||
) -> Result<(), PreparationError> {
|
||||
debug!("Sending non-reply message with packet type {packet_type}");
|
||||
// TODO: I really dislike existence of this assertion, it implies code has to be re-organised
|
||||
debug_assert!(!matches!(message, NymMessage::Reply(_)));
|
||||
|
||||
@@ -436,7 +439,11 @@ where
|
||||
let topology_permit = self.topology_access.get_read_permit().await;
|
||||
let topology = self.get_topology(&topology_permit)?;
|
||||
|
||||
let packet_size = self.optimal_packet_size(&message);
|
||||
let packet_size = if packet_type == PacketType::Outfox {
|
||||
PacketSize::OutfoxRegularPacket
|
||||
} else {
|
||||
self.optimal_packet_size(&message)
|
||||
};
|
||||
debug!("Using {packet_size} packets for {message}");
|
||||
let fragments = self
|
||||
.message_preparer
|
||||
@@ -453,6 +460,7 @@ where
|
||||
topology,
|
||||
&self.config.ack_key,
|
||||
&recipient,
|
||||
packet_type,
|
||||
)?;
|
||||
|
||||
let real_message = RealMessage::new(
|
||||
@@ -476,7 +484,9 @@ where
|
||||
&mut self,
|
||||
recipient: Recipient,
|
||||
amount: u32,
|
||||
packet_type: PacketType,
|
||||
) -> Result<(), PreparationError> {
|
||||
debug!("Sending additional reply SURBs with packet type {packet_type}");
|
||||
let sender_tag = self.get_or_create_sender_tag(&recipient);
|
||||
let (reply_surbs, reply_keys) =
|
||||
self.generate_reply_surbs_with_keys(amount as usize).await?;
|
||||
@@ -490,6 +500,7 @@ where
|
||||
message,
|
||||
recipient,
|
||||
TransmissionLane::AdditionalReplySurbs,
|
||||
packet_type,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@@ -505,7 +516,9 @@ where
|
||||
message: Vec<u8>,
|
||||
num_reply_surbs: u32,
|
||||
lane: TransmissionLane,
|
||||
packet_type: PacketType,
|
||||
) -> Result<(), SurbWrappedPreparationError> {
|
||||
debug!("Sending message with reply SURBs with packet type {packet_type}");
|
||||
let sender_tag = self.get_or_create_sender_tag(&recipient);
|
||||
let (reply_surbs, reply_keys) = self
|
||||
.generate_reply_surbs_with_keys(num_reply_surbs as usize)
|
||||
@@ -514,7 +527,7 @@ where
|
||||
let message =
|
||||
NymMessage::new_repliable(RepliableMessage::new_data(message, sender_tag, reply_surbs));
|
||||
|
||||
self.try_split_and_send_non_reply_message(message, recipient, lane)
|
||||
self.try_split_and_send_non_reply_message(message, recipient, lane, packet_type)
|
||||
.await?;
|
||||
|
||||
log::trace!("storing {} reply keys", reply_keys.len());
|
||||
@@ -527,13 +540,21 @@ where
|
||||
&mut self,
|
||||
recipient: Recipient,
|
||||
chunk: Fragment,
|
||||
packet_type: PacketType,
|
||||
) -> Result<PreparedFragment, PreparationError> {
|
||||
debug!("Sending single chunk with packet type {packet_type}");
|
||||
let topology_permit = self.topology_access.get_read_permit().await;
|
||||
let topology = self.get_topology(&topology_permit)?;
|
||||
|
||||
let prepared_fragment = self
|
||||
.message_preparer
|
||||
.prepare_chunk_for_sending(chunk, topology, &self.config.ack_key, &recipient)
|
||||
.prepare_chunk_for_sending(
|
||||
chunk,
|
||||
topology,
|
||||
&self.config.ack_key,
|
||||
&recipient,
|
||||
packet_type,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Ok(prepared_fragment)
|
||||
@@ -544,7 +565,7 @@ where
|
||||
fragments: Vec<Fragment>,
|
||||
reply_surbs: Vec<ReplySurb>,
|
||||
) -> Result<Vec<PreparedFragment>, SurbWrappedPreparationError> {
|
||||
debug_assert_ne!(
|
||||
debug_assert_eq!(
|
||||
fragments.len(),
|
||||
reply_surbs.len(),
|
||||
"attempted to send {} fragments with {} reply surbs",
|
||||
@@ -569,6 +590,7 @@ where
|
||||
topology,
|
||||
&self.config.ack_key,
|
||||
reply_surb,
|
||||
PacketType::Mix,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
@@ -588,7 +610,13 @@ where
|
||||
|
||||
let prepared_fragment = self
|
||||
.message_preparer
|
||||
.prepare_reply_chunk_for_sending(chunk, topology, &self.config.ack_key, reply_surb)
|
||||
.prepare_reply_chunk_for_sending(
|
||||
chunk,
|
||||
topology,
|
||||
&self.config.ack_key,
|
||||
reply_surb,
|
||||
PacketType::Mix,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
Ok(prepared_fragment)
|
||||
|
||||
@@ -26,6 +26,7 @@ use log::*;
|
||||
use nym_gateway_client::AcknowledgementReceiver;
|
||||
use nym_sphinx::acknowledgements::AckKey;
|
||||
use nym_sphinx::addressing::clients::Recipient;
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_task::connections::{ConnectionCommandReceiver, LaneQueueLengths};
|
||||
use rand::{rngs::OsRng, CryptoRng, Rng};
|
||||
use std::sync::Arc;
|
||||
@@ -207,7 +208,7 @@ impl RealMessagesController<OsRng> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_with_shutdown(self, shutdown: nym_task::TaskClient) {
|
||||
pub fn start_with_shutdown(self, shutdown: nym_task::TaskClient, packet_type: PacketType) {
|
||||
let mut out_queue_control = self.out_queue_control;
|
||||
let ack_control = self.ack_control;
|
||||
let mut reply_control = self.reply_control;
|
||||
@@ -223,6 +224,6 @@ impl RealMessagesController<OsRng> {
|
||||
debug!("The reply controller has finished execution!");
|
||||
});
|
||||
|
||||
ack_control.start_with_shutdown(shutdown);
|
||||
ack_control.start_with_shutdown(shutdown, packet_type);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ where
|
||||
// messages.
|
||||
sending_delay_controller: SendingDelayController,
|
||||
|
||||
/// Channel used for sending prepared sphinx packets to `MixTrafficController` that sends them
|
||||
/// Channel used for sending prepared packets to `MixTrafficController` that sends them
|
||||
/// out to the network without any further delays.
|
||||
mix_tx: BatchMixMessageSender,
|
||||
|
||||
@@ -136,7 +136,7 @@ impl From<PreparedFragment> for RealMessage {
|
||||
|
||||
impl RealMessage {
|
||||
pub(crate) fn packet_size(&self) -> usize {
|
||||
self.mix_packet.sphinx_packet().len()
|
||||
self.mix_packet.packet().len()
|
||||
}
|
||||
|
||||
pub(crate) fn new(mix_packet: MixPacket, fragment_id: Option<FragmentIdentifier>) -> Self {
|
||||
@@ -247,6 +247,7 @@ where
|
||||
self.config.average_ack_delay,
|
||||
self.config.traffic.average_packet_delay,
|
||||
cover_traffic_packet_size,
|
||||
self.config.traffic.packet_type.unwrap_or_default(),
|
||||
)
|
||||
.expect(
|
||||
"Somehow failed to generate a loop cover message with a valid topology",
|
||||
@@ -386,7 +387,7 @@ where
|
||||
|
||||
// On every iteration we get new messages from upstream. Given that these come bunched
|
||||
// in `Vec`, this ensures that on average we will fetch messages faster than we can
|
||||
// send, which is a condition for being able to multiplex sphinx packets from multiple
|
||||
// send, which is a condition for being able to multiplex packets from multiple
|
||||
// data streams.
|
||||
match Pin::new(&mut self.real_receiver).poll_recv(cx) {
|
||||
// in the case our real message channel stream was closed, we should also indicate we are closed
|
||||
|
||||
@@ -512,7 +512,11 @@ where
|
||||
let to_send = min(remaining, 100);
|
||||
if let Err(err) = self
|
||||
.message_handler
|
||||
.try_send_additional_reply_surbs(recipient, to_send)
|
||||
.try_send_additional_reply_surbs(
|
||||
recipient,
|
||||
to_send,
|
||||
nym_sphinx::params::PacketType::Mix,
|
||||
)
|
||||
.await
|
||||
{
|
||||
warn!("failed to send additional surbs to {recipient} - {err}");
|
||||
|
||||
@@ -28,7 +28,7 @@ impl SizedData for RealMessage {
|
||||
|
||||
impl SizedData for Fragment {
|
||||
fn data_size(&self) -> usize {
|
||||
// note that raw `Fragment` is smaller than sphinx packet payload
|
||||
// note that raw `Fragment` is smaller than packet payload
|
||||
// as it doesn't include surb-ack or the [shared] key materials
|
||||
self.payload_size()
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
use nym_config::defaults::NymNetworkDetails;
|
||||
use nym_config::{NymConfig, OptionalSet, CRED_DB_FILE_NAME};
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_sphinx::params::PacketSize;
|
||||
use nym_sphinx::params::{PacketSize, PacketType};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::marker::PhantomData;
|
||||
use std::path::{Path, PathBuf};
|
||||
@@ -259,6 +259,11 @@ impl<T> Config<T> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_packet_type(mut self, packet_type: PacketType) -> Self {
|
||||
self.client.packet_type = Some(packet_type);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_high_default_traffic_volume(&mut self) {
|
||||
self.debug.traffic.average_packet_delay = Duration::from_millis(10);
|
||||
// basically don't really send cover messages
|
||||
@@ -446,6 +451,10 @@ impl<T> Config<T> {
|
||||
pub fn get_maximum_reply_key_age(&self) -> Duration {
|
||||
self.debug.reply_surbs.maximum_reply_key_age
|
||||
}
|
||||
|
||||
pub fn get_packet_type(&self) -> PacketType {
|
||||
self.client.packet_type.unwrap_or(PacketType::Mix)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: NymConfig> Default for Config<T> {
|
||||
@@ -568,6 +577,8 @@ pub struct Client<T> {
|
||||
|
||||
#[serde(skip)]
|
||||
pub super_struct: PhantomData<T>,
|
||||
|
||||
pub packet_type: Option<PacketType>,
|
||||
}
|
||||
|
||||
impl<T: NymConfig> Default for Client<T> {
|
||||
@@ -606,6 +617,7 @@ impl<T: NymConfig> Default for Client<T> {
|
||||
reply_surb_database_path: Default::default(),
|
||||
nym_root_directory: T::default_root_directory(),
|
||||
super_struct: Default::default(),
|
||||
packet_type: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -677,6 +689,8 @@ pub struct Traffic {
|
||||
/// Note that its use decreases overall anonymity.
|
||||
/// Do not set it it unless you understand the consequences of that change.
|
||||
pub secondary_packet_size: Option<PacketSize>,
|
||||
|
||||
pub packet_type: Option<PacketType>,
|
||||
}
|
||||
|
||||
impl Traffic {
|
||||
@@ -700,6 +714,7 @@ impl Default for Traffic {
|
||||
disable_main_poisson_packet_distribution: false,
|
||||
primary_packet_size: PacketSize::RegularPacket,
|
||||
secondary_packet_size: None,
|
||||
packet_type: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ impl From<OldDebugConfigV1_1_13> for DebugConfig {
|
||||
.disable_main_poisson_packet_distribution,
|
||||
primary_packet_size: PacketSize::RegularPacket,
|
||||
secondary_packet_size: value.use_extended_packet_size.map(Into::into),
|
||||
packet_type: None,
|
||||
},
|
||||
cover_traffic: CoverTraffic {
|
||||
loop_cover_traffic_average_delay: value.loop_cover_traffic_average_delay,
|
||||
@@ -210,8 +211,8 @@ impl<T, U> From<OldConfigV1_1_13<T>> for Config<U> {
|
||||
database_path: value.client.database_path,
|
||||
reply_surb_database_path: value.client.reply_surb_database_path,
|
||||
nym_root_directory: value.client.nym_root_directory,
|
||||
|
||||
super_struct: PhantomData,
|
||||
packet_type: Some(nym_sphinx::params::PacketType::Mix),
|
||||
},
|
||||
logging: value.logging,
|
||||
debug: value.debug.into(),
|
||||
|
||||
@@ -40,11 +40,17 @@ impl ClientKeyPathfinder {
|
||||
}
|
||||
|
||||
pub fn identity_key_pair_path(&self) -> nym_pemstore::KeyPairPath {
|
||||
nym_pemstore::KeyPairPath::new(self.private_identity_key(), self.public_identity_key())
|
||||
nym_pemstore::KeyPairPath::new(
|
||||
self.private_identity_key().to_path_buf(),
|
||||
self.public_identity_key().to_path_buf(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn encryption_key_pair_path(&self) -> nym_pemstore::KeyPairPath {
|
||||
nym_pemstore::KeyPairPath::new(self.private_encryption_key(), self.public_encryption_key())
|
||||
nym_pemstore::KeyPairPath::new(
|
||||
self.private_encryption_key().to_path_buf(),
|
||||
self.public_encryption_key().to_path_buf(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn any_file_exists(&self) -> bool {
|
||||
|
||||
@@ -155,7 +155,7 @@ pub async fn get_registered_gateway<S>(
|
||||
key_store: &S::KeyStore,
|
||||
setup: GatewaySetup,
|
||||
overwrite_keys: bool,
|
||||
) -> Result<GatewayEndpointConfig, ClientCoreError>
|
||||
) -> Result<(GatewayEndpointConfig, ManagedKeys), ClientCoreError>
|
||||
where
|
||||
S: MixnetClientStorage,
|
||||
<S::KeyStore as KeyStore>::StorageError: Send + Sync + 'static,
|
||||
@@ -164,11 +164,11 @@ where
|
||||
|
||||
// try load keys
|
||||
let mut managed_keys = match ManagedKeys::try_load(key_store).await {
|
||||
Ok(_) => {
|
||||
Ok(loaded_keys) => {
|
||||
// if we loaded something and we don't have full gateway details, check if we can overwrite the data
|
||||
if let GatewaySetup::Predefined { config } = setup {
|
||||
// we already have defined gateway details AND a shared key, so nothing more for us to do
|
||||
return Ok(config);
|
||||
return Ok((config, loaded_keys));
|
||||
} else if overwrite_keys {
|
||||
ManagedKeys::generate_new(&mut rng)
|
||||
} else {
|
||||
@@ -196,7 +196,7 @@ where
|
||||
|
||||
// TODO: here we should be probably persisting gateway details as opposed to returning them
|
||||
|
||||
Ok(gateway_details)
|
||||
Ok((gateway_details, managed_keys))
|
||||
}
|
||||
|
||||
/// Convenience function for setting up the gateway for a client given a `Config`. Depending on the
|
||||
@@ -299,6 +299,15 @@ pub fn get_client_address(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn load_identity_keys(
|
||||
pathfinder: &ClientKeyPathfinder,
|
||||
) -> Result<identity::KeyPair, ClientCoreError> {
|
||||
let identity_keypair: identity::KeyPair =
|
||||
nym_pemstore::load_keypair(&pathfinder.identity_key_pair_path())
|
||||
.tap_err(|_| log::error!("Failed to read stored identity key files"))?;
|
||||
Ok(identity_keypair)
|
||||
}
|
||||
|
||||
/// Get the client address by loading the keys from stored files.
|
||||
// TODO: rethink that sucker
|
||||
pub fn get_client_address_from_stored_ondisk_keys<T>(
|
||||
|
||||
@@ -571,7 +571,7 @@ impl<C, St> GatewayClient<C, St> {
|
||||
fn estimate_required_bandwidth(&self, packets: &[MixPacket]) -> i64 {
|
||||
packets
|
||||
.iter()
|
||||
.map(|packet| packet.sphinx_packet().len())
|
||||
.map(|packet| packet.packet().len())
|
||||
.sum::<usize>() as i64
|
||||
}
|
||||
|
||||
@@ -579,6 +579,8 @@ impl<C, St> GatewayClient<C, St> {
|
||||
&mut self,
|
||||
packets: Vec<MixPacket>,
|
||||
) -> Result<(), GatewayClientError> {
|
||||
debug!("Sending {} mix packets", packets.len());
|
||||
|
||||
if !self.authenticated {
|
||||
return Err(GatewayClientError::NotAuthenticated);
|
||||
}
|
||||
@@ -623,9 +625,10 @@ impl<C, St> GatewayClient<C, St> {
|
||||
) -> Result<(), GatewayClientError> {
|
||||
if let Err(err) = self.send_websocket_message_without_response(msg).await {
|
||||
if err.is_closed_connection() && self.should_reconnect_on_failure {
|
||||
info!("Going to attempt a reconnection");
|
||||
debug!("Going to attempt a reconnection");
|
||||
self.attempt_reconnection().await
|
||||
} else {
|
||||
warn!("{err}");
|
||||
Err(err)
|
||||
}
|
||||
} else {
|
||||
@@ -652,9 +655,9 @@ impl<C, St> GatewayClient<C, St> {
|
||||
if !self.authenticated {
|
||||
return Err(GatewayClientError::NotAuthenticated);
|
||||
}
|
||||
if (mix_packet.sphinx_packet().len() as i64) > self.bandwidth_remaining {
|
||||
if (mix_packet.packet().len() as i64) > self.bandwidth_remaining {
|
||||
return Err(GatewayClientError::NotEnoughBandwidth(
|
||||
mix_packet.sphinx_packet().len() as i64,
|
||||
mix_packet.packet().len() as i64,
|
||||
self.bandwidth_remaining,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -50,10 +50,15 @@ impl PacketRouter {
|
||||
let ack_overhead = PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN;
|
||||
|
||||
for received_packet in unwrapped_packets {
|
||||
if received_packet.len() == PacketSize::AckPacket.plaintext_size() {
|
||||
if received_packet.len() == PacketSize::AckPacket.plaintext_size()
|
||||
|| received_packet.len() == PacketSize::OutfoxAckPacket.plaintext_size()
|
||||
{
|
||||
received_acks.push(received_packet);
|
||||
} else if received_packet.len()
|
||||
== PacketSize::RegularPacket.plaintext_size() - ack_overhead
|
||||
|| received_packet.len()
|
||||
== PacketSize::OutfoxRegularPacket.plaintext_size() - ack_overhead
|
||||
|| received_packet.len() == PacketSize::OutfoxRegularPacket.size() - 6
|
||||
{
|
||||
trace!("routing regular packet");
|
||||
received_messages.push(received_packet);
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
use futures::channel::mpsc;
|
||||
use futures::StreamExt;
|
||||
use log::*;
|
||||
use nym_sphinx::framing::codec::SphinxCodec;
|
||||
use nym_sphinx::framing::packet::FramedSphinxPacket;
|
||||
use nym_sphinx::params::PacketMode;
|
||||
use nym_sphinx::{addressing::nodes::NymNodeRoutingAddress, SphinxPacket};
|
||||
use nym_sphinx::addressing::nodes::NymNodeRoutingAddress;
|
||||
use nym_sphinx::framing::codec::NymCodec;
|
||||
use nym_sphinx::framing::packet::FramedNymPacket;
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_sphinx::NymPacket;
|
||||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
use std::net::SocketAddr;
|
||||
@@ -50,8 +51,8 @@ pub trait SendWithoutResponse {
|
||||
fn send_without_response(
|
||||
&mut self,
|
||||
address: NymNodeRoutingAddress,
|
||||
packet: SphinxPacket,
|
||||
packet_mode: PacketMode,
|
||||
packet: NymPacket,
|
||||
packet_type: PacketType,
|
||||
) -> io::Result<()>;
|
||||
}
|
||||
|
||||
@@ -61,12 +62,12 @@ pub struct Client {
|
||||
}
|
||||
|
||||
struct ConnectionSender {
|
||||
channel: mpsc::Sender<FramedSphinxPacket>,
|
||||
channel: mpsc::Sender<FramedNymPacket>,
|
||||
current_reconnection_attempt: Arc<AtomicU32>,
|
||||
}
|
||||
|
||||
impl ConnectionSender {
|
||||
fn new(channel: mpsc::Sender<FramedSphinxPacket>) -> Self {
|
||||
fn new(channel: mpsc::Sender<FramedNymPacket>) -> Self {
|
||||
ConnectionSender {
|
||||
channel,
|
||||
current_reconnection_attempt: Arc::new(AtomicU32::new(0)),
|
||||
@@ -84,7 +85,7 @@ impl Client {
|
||||
|
||||
async fn manage_connection(
|
||||
address: SocketAddr,
|
||||
receiver: mpsc::Receiver<FramedSphinxPacket>,
|
||||
receiver: mpsc::Receiver<FramedNymPacket>,
|
||||
connection_timeout: Duration,
|
||||
current_reconnection: &AtomicU32,
|
||||
) {
|
||||
@@ -96,7 +97,7 @@ impl Client {
|
||||
debug!("Managed to establish connection to {}", address);
|
||||
// if we managed to connect, reset the reconnection count (whatever it might have been)
|
||||
current_reconnection.store(0, Ordering::Release);
|
||||
Framed::new(stream, SphinxCodec)
|
||||
Framed::new(stream, NymCodec)
|
||||
}
|
||||
Err(err) => {
|
||||
debug!(
|
||||
@@ -148,11 +149,7 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
fn make_connection(
|
||||
&mut self,
|
||||
address: NymNodeRoutingAddress,
|
||||
pending_packet: FramedSphinxPacket,
|
||||
) {
|
||||
fn make_connection(&mut self, address: NymNodeRoutingAddress, pending_packet: FramedNymPacket) {
|
||||
let (mut sender, receiver) = mpsc::channel(self.config.maximum_connection_buffer_size);
|
||||
|
||||
// this CAN'T fail because we just created the channel which has a non-zero capacity
|
||||
@@ -200,12 +197,12 @@ impl SendWithoutResponse for Client {
|
||||
fn send_without_response(
|
||||
&mut self,
|
||||
address: NymNodeRoutingAddress,
|
||||
packet: SphinxPacket,
|
||||
packet_mode: PacketMode,
|
||||
packet: NymPacket,
|
||||
packet_type: PacketType,
|
||||
) -> io::Result<()> {
|
||||
trace!("Sending packet to {:?}", address);
|
||||
let framed_packet =
|
||||
FramedSphinxPacket::new(packet, packet_mode, self.config.use_legacy_version);
|
||||
FramedNymPacket::new(packet, packet_type, self.config.use_legacy_version);
|
||||
|
||||
if let Some(sender) = self.conn_new.get_mut(&address) {
|
||||
if let Err(err) = sender.channel.try_send(framed_packet) {
|
||||
|
||||
@@ -59,14 +59,14 @@ impl PacketForwarder {
|
||||
trace!("Going to forward packet to {:?}", mix_packet.next_hop());
|
||||
|
||||
let next_hop = mix_packet.next_hop();
|
||||
let packet_mode = mix_packet.packet_mode();
|
||||
let sphinx_packet = mix_packet.into_sphinx_packet();
|
||||
let packet_type = mix_packet.packet_type();
|
||||
let packet = mix_packet.into_packet();
|
||||
// we don't care about responses, we just want to fire packets
|
||||
// as quickly as possible
|
||||
|
||||
if let Err(err) =
|
||||
self.mixnet_client
|
||||
.send_without_response(next_hop, sphinx_packet, packet_mode)
|
||||
.send_without_response(next_hop, packet, packet_type)
|
||||
{
|
||||
debug!("failed to forward the packet - {err}")
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ nym-api-requests = { path = "../../../nym-api/nym-api-requests" }
|
||||
async-trait = { workspace = true, optional = true }
|
||||
bip39 = { workspace = true, features = ["rand"], optional = true }
|
||||
nym-config = { path = "../../config", optional = true }
|
||||
cosmrs = { workspace = true, features = ["rpc", "bip32", "cosmwasm"], optional = true }
|
||||
cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support", features = ["rpc", "bip32", "cosmwasm"], optional = true }
|
||||
# note that this has the same version as used by cosmrs
|
||||
eyre = { version = "0.6", optional = true }
|
||||
cw3 = { workspace = true, optional = true }
|
||||
@@ -54,7 +54,7 @@ cosmwasm-std = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
bip39 = { workspace = true }
|
||||
cosmrs = { workspace = true, features = ["rpc", "bip32"] }
|
||||
cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support", features = ["rpc", "bip32"] }
|
||||
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
|
||||
ts-rs = "6.1.2"
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ impl GasAdjustable for Gas {
|
||||
mod sealed {
|
||||
use cosmrs::tx::{self, Gas};
|
||||
use cosmrs::Coin as CosmosCoin;
|
||||
use cosmrs::{AccountId, Denom as CosmosDenom};
|
||||
use cosmrs::{AccountId, Decimal as CosmosDecimal, Denom as CosmosDenom};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
fn cosmos_denom_inner_getter(val: &CosmosDenom) -> String {
|
||||
@@ -144,11 +144,29 @@ mod sealed {
|
||||
}
|
||||
}
|
||||
|
||||
fn cosmos_decimal_inner_getter(val: &CosmosDecimal) -> u64 {
|
||||
// haha, this code is so disgusting. I'll make a PR on cosmrs to slightly alleviate those issues...
|
||||
// note: unwrap here is fine as the to_string is just returning a stringified u64 which, well, is a valid u64
|
||||
val.to_string().parse().unwrap()
|
||||
}
|
||||
|
||||
// at the time of writing it the current cosmrs' Decimal is extremely limited...
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(remote = "CosmosDecimal")]
|
||||
struct Decimal(#[serde(getter = "cosmos_decimal_inner_getter")] u64);
|
||||
|
||||
impl From<Decimal> for CosmosDecimal {
|
||||
fn from(val: Decimal) -> Self {
|
||||
val.0.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
struct Coin {
|
||||
#[serde(with = "Denom")]
|
||||
denom: CosmosDenom,
|
||||
amount: u128,
|
||||
#[serde(with = "Decimal")]
|
||||
amount: CosmosDecimal,
|
||||
}
|
||||
|
||||
impl From<Coin> for CosmosCoin {
|
||||
|
||||
@@ -39,7 +39,7 @@ pub use cosmrs::tendermint::validator::Info as TendermintValidatorInfo;
|
||||
pub use cosmrs::tendermint::Time as TendermintTime;
|
||||
pub use cosmrs::tx::{self, Gas};
|
||||
pub use cosmrs::Coin as CosmosCoin;
|
||||
pub use cosmrs::{bip32, AccountId, Denom};
|
||||
pub use cosmrs::{bip32, AccountId, Decimal, Denom};
|
||||
use cosmwasm_std::Addr;
|
||||
pub use cosmwasm_std::Coin as CosmWasmCoin;
|
||||
pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment};
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use async_trait::async_trait;
|
||||
use cosmrs::AccountId;
|
||||
use nym_contracts_common::ContractBuildInformation;
|
||||
use nym_contracts_common::{signing::Nonce, ContractBuildInformation};
|
||||
use nym_service_provider_directory_common::{
|
||||
msg::QueryMsg as SpQueryMsg,
|
||||
response::{
|
||||
ConfigResponse, PagedServicesListResponse, ServiceInfoResponse, ServicesListResponse,
|
||||
},
|
||||
NymAddress, ServiceId, ServiceInfo,
|
||||
NymAddress, Service, ServiceId,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
@@ -63,17 +63,14 @@ pub trait SpDirectoryQueryClient {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_all_services(&self) -> Result<Vec<ServiceInfo>, NyxdError> {
|
||||
async fn get_all_services(&self) -> Result<Vec<Service>, NyxdError> {
|
||||
let mut services = Vec::new();
|
||||
let mut start_after = None;
|
||||
|
||||
loop {
|
||||
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);
|
||||
|
||||
if let Some(start_after_res) = last_id {
|
||||
if let Some(start_after_res) = paged_response.start_next_after {
|
||||
start_after = Some(start_after_res)
|
||||
} else {
|
||||
break;
|
||||
@@ -82,6 +79,13 @@ pub trait SpDirectoryQueryClient {
|
||||
|
||||
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]
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use async_trait::async_trait;
|
||||
use nym_contracts_common::signing::MessageSignature;
|
||||
use nym_service_provider_directory_common::{
|
||||
msg::ExecuteMsg as SpExecuteMsg, NymAddress, ServiceId, ServiceType,
|
||||
msg::ExecuteMsg as SpExecuteMsg, NymAddress, ServiceDetails, ServiceId,
|
||||
};
|
||||
|
||||
use crate::nyxd::{
|
||||
@@ -22,16 +23,16 @@ pub trait SpDirectorySigningClient {
|
||||
|
||||
async fn announce_service_provider(
|
||||
&self,
|
||||
nym_address: NymAddress,
|
||||
service_type: ServiceType,
|
||||
service: ServiceDetails,
|
||||
owner_signature: MessageSignature,
|
||||
deposit: Coin,
|
||||
fee: Option<Fee>,
|
||||
) -> Result<ExecuteResult, NyxdError> {
|
||||
self.execute_service_provider_directory_contract(
|
||||
fee,
|
||||
SpExecuteMsg::Announce {
|
||||
nym_address,
|
||||
service_type,
|
||||
service,
|
||||
owner_signature,
|
||||
},
|
||||
vec![deposit],
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ clap = { version = "4.0", features = ["derive"] }
|
||||
cw-utils = { workspace = true }
|
||||
handlebars = "3.0.1"
|
||||
humantime-serde = "1.0"
|
||||
k256 = { workspace = true, features = ["ecdsa", "sha256"] }
|
||||
k256 = { version = "0.10", features = ["ecdsa", "sha256"] }
|
||||
log = { workspace = true }
|
||||
rand = {version = "0.6", features = ["std"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
@@ -25,7 +25,7 @@ toml = "0.5.6"
|
||||
url = "2.2"
|
||||
tap = "1"
|
||||
|
||||
cosmrs = { workspace = true }
|
||||
cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" }
|
||||
cosmwasm-std = { workspace = true }
|
||||
|
||||
nym-validator-client = { path = "../client-libs/validator-client", features = ["nyxd-client"] }
|
||||
@@ -40,3 +40,4 @@ nym-coconut-dkg-common = { path = "../cosmwasm-smart-contracts/coconut-dkg" }
|
||||
nym-multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-contract" }
|
||||
nym-service-provider-directory-common = { path = "../cosmwasm-smart-contracts/service-provider-directory" }
|
||||
nym-name-service-common = { path = "../cosmwasm-smart-contracts/name-service" }
|
||||
nym-sphinx = { path = "../../common/nymsphinx" }
|
||||
|
||||
@@ -56,8 +56,6 @@ pub async fn generate(args: Args) {
|
||||
.expect("threshold can't be converted to Decimal"),
|
||||
},
|
||||
max_voting_period: Duration::Time(args.max_voting_period),
|
||||
executor: None,
|
||||
proposal_deposit: None,
|
||||
coconut_bandwidth_contract_address: coconut_bandwidth_contract_address.to_string(),
|
||||
coconut_dkg_contract_address: coconut_dkg_contract_address.to_string(),
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@ pub struct Mixnet {
|
||||
pub command: MixnetCommands,
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum MixnetCommands {
|
||||
/// Query the mixnet directory
|
||||
|
||||
@@ -15,6 +15,7 @@ pub struct MixnetOperators {
|
||||
pub command: MixnetOperatorsCommands,
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum MixnetOperatorsCommands {
|
||||
/// Manage your mixnode
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use clap::Parser;
|
||||
use log::info;
|
||||
use nym_service_provider_directory_common::{Coin, NymAddress, ServiceType};
|
||||
use nym_contracts_common::signing::MessageSignature;
|
||||
use nym_service_provider_directory_common::{Coin, NymAddress, ServiceDetails, ServiceType};
|
||||
use nym_validator_client::nyxd::traits::SpDirectorySigningClient;
|
||||
|
||||
use crate::context::SigningClient;
|
||||
@@ -10,9 +11,15 @@ pub struct Args {
|
||||
#[clap(long)]
|
||||
pub nym_address: String,
|
||||
|
||||
#[clap(long)]
|
||||
pub signature: MessageSignature,
|
||||
|
||||
/// Deposit to be made to the service provider directory, in curent DENOMINATION (e.g. 'unym')
|
||||
#[clap(long)]
|
||||
pub deposit: u128,
|
||||
|
||||
#[clap(long)]
|
||||
pub identity_key: String,
|
||||
}
|
||||
|
||||
pub async fn announce(args: Args, client: SigningClient) {
|
||||
@@ -20,12 +27,17 @@ pub async fn announce(args: Args, client: SigningClient) {
|
||||
|
||||
let nym_address = NymAddress::Address(args.nym_address);
|
||||
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 deposit = Coin::new(args.deposit, denom);
|
||||
|
||||
let res = client
|
||||
.announce_service_provider(nym_address, service_type, deposit.into(), None)
|
||||
.announce_service_provider(service, args.signature, deposit.into(), None)
|
||||
.await
|
||||
.expect("Failed to announce service provider");
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
// 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,6 +1,7 @@
|
||||
use clap::{Args, Subcommand};
|
||||
|
||||
pub mod announce;
|
||||
pub mod announce_sign_payload;
|
||||
pub mod delete;
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
@@ -10,10 +11,13 @@ pub struct MixnetOperatorsService {
|
||||
pub command: MixnetOperatorsServiceCommands,
|
||||
}
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum MixnetOperatorsServiceCommands {
|
||||
/// Announce service provider to the world
|
||||
Announce(announce::Args),
|
||||
/// Delete entry for service provider from the directory
|
||||
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 {
|
||||
table.add_row(vec![
|
||||
service.service_id.to_string(),
|
||||
service.service.announcer.to_string(),
|
||||
service.announcer.to_string(),
|
||||
service.service.service_type.to_string(),
|
||||
service.service.nym_address.to_string(),
|
||||
]);
|
||||
|
||||
@@ -14,7 +14,7 @@ pub struct InstantiateMsg {
|
||||
pub mix_denom: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ExecuteMsg {
|
||||
DepositFunds { data: DepositData },
|
||||
|
||||
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::msg::ExecuteMsg;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct SpendCredentialData {
|
||||
funds: Coin,
|
||||
blinded_serial_number: String,
|
||||
@@ -43,7 +43,7 @@ pub enum SpendCredentialStatus {
|
||||
Spent,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct SpendCredential {
|
||||
funds: Coin,
|
||||
blinded_serial_number: String,
|
||||
@@ -74,7 +74,7 @@ impl SpendCredential {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct PagedSpendCredentialResponse {
|
||||
pub spend_credentials: Vec<SpendCredential>,
|
||||
pub per_page: usize,
|
||||
@@ -95,7 +95,7 @@ impl PagedSpendCredentialResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct SpendCredentialResponse {
|
||||
pub spend_credential: Option<SpendCredential>,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-contracts-common"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
description = "Common library for Nym cosmwasm contracts"
|
||||
edition = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
|
||||
@@ -15,7 +15,7 @@ pub type Nonce = u32;
|
||||
|
||||
// define this type explicitly for [hopefully] better usability
|
||||
// (so you wouldn't need to worry about whether you should use bytes, bs58, etc.)
|
||||
#[derive(Clone, Debug, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct MessageSignature(Vec<u8>);
|
||||
|
||||
impl MessageSignature {
|
||||
|
||||
@@ -11,6 +11,9 @@ use std::ops::Mul;
|
||||
use std::str::FromStr;
|
||||
use thiserror::Error;
|
||||
|
||||
pub type IdentityKey = String;
|
||||
pub type IdentityKeyRef<'a> = &'a str;
|
||||
|
||||
pub fn truncate_decimal(amount: Decimal) -> Uint128 {
|
||||
amount * Uint128::new(1)
|
||||
}
|
||||
|
||||
@@ -6,8 +6,6 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
cosmwasm-schema = { workspace = true }
|
||||
cw4 = { workspace = true }
|
||||
cw-controllers = { workspace = true }
|
||||
schemars = "0.8"
|
||||
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
use cosmwasm_schema::{cw_serde, QueryResponses};
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use cw4::Member;
|
||||
|
||||
#[cw_serde]
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct InstantiateMsg {
|
||||
/// The admin is the only account that can update the group state.
|
||||
/// Omit it to make the group immutable.
|
||||
@@ -9,7 +15,8 @@ pub struct InstantiateMsg {
|
||||
pub members: Vec<Member>,
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ExecuteMsg {
|
||||
/// Change the admin
|
||||
UpdateAdmin { admin: Option<String> },
|
||||
@@ -25,24 +32,23 @@ pub enum ExecuteMsg {
|
||||
RemoveHook { addr: String },
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
#[derive(QueryResponses)]
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum QueryMsg {
|
||||
#[returns(cw_controllers::AdminResponse)]
|
||||
/// Return AdminResponse
|
||||
Admin {},
|
||||
#[returns(cw4::TotalWeightResponse)]
|
||||
TotalWeight { at_height: Option<u64> },
|
||||
#[returns(cw4::MemberListResponse)]
|
||||
/// Return TotalWeightResponse
|
||||
TotalWeight {},
|
||||
/// Returns MembersListResponse
|
||||
ListMembers {
|
||||
start_after: Option<String>,
|
||||
limit: Option<u32>,
|
||||
},
|
||||
#[returns(cw4::MemberResponse)]
|
||||
/// Returns MemberResponse
|
||||
Member {
|
||||
addr: String,
|
||||
at_height: Option<u64>,
|
||||
},
|
||||
/// Shows all registered hooks.
|
||||
#[returns(cw_controllers::HooksResponse)]
|
||||
/// Shows all registered hooks. Returns HooksResponse.
|
||||
Hooks {},
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-mixnet-contract-common"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
description = "Common library for the Nym mixnet contract"
|
||||
rust-version = "1.62"
|
||||
edition = { workspace = true }
|
||||
@@ -15,7 +15,7 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_repr = "0.1"
|
||||
schemars = "0.8"
|
||||
thiserror = "1.0"
|
||||
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.4.0" }
|
||||
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.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)
|
||||
serde-json-wasm = "=0.4.1"
|
||||
|
||||
@@ -37,7 +37,7 @@ pub fn generate_owner_storage_subkey(
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)]
|
||||
pub struct Delegation {
|
||||
/// Address of the owner of this delegation.
|
||||
pub owner: Addr,
|
||||
@@ -114,7 +114,7 @@ impl Delegation {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct PagedMixNodeDelegationsResponse {
|
||||
pub delegations: Vec<Delegation>,
|
||||
pub start_next_after: Option<OwnerProxySubKey>,
|
||||
@@ -129,7 +129,7 @@ impl PagedMixNodeDelegationsResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct PagedDelegatorDelegationsResponse {
|
||||
pub delegations: Vec<Delegation>,
|
||||
pub start_next_after: Option<(MixId, OwnerProxySubKey)>,
|
||||
@@ -147,7 +147,7 @@ impl PagedDelegatorDelegationsResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct MixNodeDelegationResponse {
|
||||
pub delegation: Option<Delegation>,
|
||||
pub mixnode_still_bonded: bool,
|
||||
@@ -162,7 +162,7 @@ impl MixNodeDelegationResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct PagedAllDelegationsResponse {
|
||||
pub delegations: Vec<Delegation>,
|
||||
pub start_next_after: Option<StorageKey>,
|
||||
|
||||
@@ -23,7 +23,7 @@ pub struct Gateway {
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct GatewayBond {
|
||||
pub pledge_amount: Coin,
|
||||
pub owner: Addr,
|
||||
@@ -132,7 +132,7 @@ impl GatewayConfigUpdate {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct PagedGatewayResponse {
|
||||
pub nodes: Vec<GatewayBond>,
|
||||
pub per_page: usize,
|
||||
@@ -153,13 +153,13 @@ impl PagedGatewayResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct GatewayOwnershipResponse {
|
||||
pub address: Addr,
|
||||
pub gateway: Option<GatewayBond>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct GatewayBondResponse {
|
||||
pub identity: IdentityKey,
|
||||
pub gateway: Option<GatewayBond>,
|
||||
|
||||
@@ -489,7 +489,7 @@ impl CurrentIntervalResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
pub struct PendingEpochEventsResponse {
|
||||
pub seconds_until_executable: i64,
|
||||
pub events: Vec<PendingEpochEvent>,
|
||||
@@ -510,7 +510,7 @@ impl PendingEpochEventsResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
|
||||
pub struct PendingIntervalEventsResponse {
|
||||
pub seconds_until_executable: i64,
|
||||
pub events: Vec<PendingIntervalEvent>,
|
||||
|
||||
@@ -33,7 +33,7 @@ impl RewardedSetNodeStatus {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct MixNodeDetails {
|
||||
pub bond_information: MixNodeBond,
|
||||
pub rewarding_details: MixNodeRewarding,
|
||||
@@ -86,7 +86,7 @@ impl MixNodeDetails {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct MixNodeRewarding {
|
||||
/// Information provided by the operator that influence the cost function.
|
||||
pub cost_params: MixNodeCostParams,
|
||||
@@ -465,7 +465,7 @@ impl MixNodeRewarding {
|
||||
}
|
||||
|
||||
// operator information + data assigned by the contract(s)
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct MixNodeBond {
|
||||
/// Unique id assigned to the bonded mixnode.
|
||||
pub mix_id: MixId,
|
||||
@@ -559,7 +559,7 @@ pub struct MixNode {
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct MixNodeCostParams {
|
||||
pub profit_margin_percent: Percent,
|
||||
|
||||
@@ -686,7 +686,7 @@ impl MixNodeConfigUpdate {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct PagedMixnodeBondsResponse {
|
||||
pub nodes: Vec<MixNodeBond>,
|
||||
pub per_page: usize,
|
||||
@@ -703,7 +703,7 @@ impl PagedMixnodeBondsResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct PagedMixnodesDetailsResponse {
|
||||
pub nodes: Vec<MixNodeDetails>,
|
||||
pub per_page: usize,
|
||||
@@ -745,19 +745,19 @@ impl PagedUnbondedMixnodesResponse {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct MixOwnershipResponse {
|
||||
pub address: Addr,
|
||||
pub mixnode_details: Option<MixNodeDetails>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct MixnodeDetailsResponse {
|
||||
pub mix_id: MixId,
|
||||
pub mixnode_details: Option<MixNodeDetails>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct MixnodeRewardingDetailsResponse {
|
||||
pub mix_id: MixId,
|
||||
pub rewarding_details: Option<MixNodeRewarding>,
|
||||
|
||||
@@ -7,19 +7,19 @@ use crate::{BlockHeight, EpochEventId, IntervalEventId, MixId};
|
||||
use cosmwasm_std::{Addr, Coin};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct PendingEpochEvent {
|
||||
pub id: EpochEventId,
|
||||
pub event: PendingEpochEventData,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct PendingEpochEventData {
|
||||
pub created_at: BlockHeight,
|
||||
pub kind: PendingEpochEventKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub enum PendingEpochEventKind {
|
||||
// can't just pass the `Delegation` struct here as it's impossible to determine
|
||||
// `cumulative_reward_ratio` ahead of time
|
||||
@@ -68,19 +68,19 @@ impl From<(EpochEventId, PendingEpochEventData)> for PendingEpochEvent {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct PendingIntervalEvent {
|
||||
pub id: IntervalEventId,
|
||||
pub event: PendingIntervalEventData,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct PendingIntervalEventData {
|
||||
pub created_at: BlockHeight,
|
||||
pub kind: PendingIntervalEventKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub enum PendingIntervalEventKind {
|
||||
ChangeMixCostParams {
|
||||
mix_id: MixId,
|
||||
|
||||
@@ -35,7 +35,7 @@ pub struct RewardDistribution {
|
||||
pub delegates: Decimal,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq)]
|
||||
pub struct PendingRewardResponse {
|
||||
pub amount_staked: Option<Coin>,
|
||||
pub amount_earned: Option<Coin>,
|
||||
@@ -46,7 +46,7 @@ pub struct PendingRewardResponse {
|
||||
pub mixnode_still_fully_bonded: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema, PartialEq)]
|
||||
pub struct EstimatedCurrentEpochRewardResponse {
|
||||
pub original_stake: Option<Coin>,
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use crate::error::MixnetContractError;
|
||||
use crate::families::{Family, FamilyHead};
|
||||
use crate::{Layer, RewardedSetNodeStatus};
|
||||
use contracts_common::IdentityKey;
|
||||
use cosmwasm_std::Addr;
|
||||
use cosmwasm_std::Coin;
|
||||
use schemars::JsonSchema;
|
||||
@@ -11,8 +12,6 @@ use serde::{Deserialize, Serialize};
|
||||
use std::ops::Index;
|
||||
|
||||
// type aliases for better reasoning about available data
|
||||
pub type IdentityKey = String;
|
||||
pub type IdentityKeyRef<'a> = &'a str;
|
||||
pub type SphinxKey = String;
|
||||
pub type SphinxKeyRef<'a> = &'a str;
|
||||
pub type EpochId = u32;
|
||||
@@ -23,7 +22,7 @@ pub type EpochEventId = u32;
|
||||
pub type IntervalEventId = u32;
|
||||
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, PartialEq, Eq)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, JsonSchema, PartialEq)]
|
||||
pub struct LayerAssignment {
|
||||
mix_id: MixId,
|
||||
layer: Layer,
|
||||
@@ -119,7 +118,7 @@ impl Index<Layer> for LayerDistribution {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct ContractState {
|
||||
pub owner: Addr, // only the owner account can update state
|
||||
pub rewarding_validator_address: Addr,
|
||||
@@ -131,7 +130,7 @@ pub struct ContractState {
|
||||
pub params: ContractStateParams,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct ContractStateParams {
|
||||
/// Minimum amount a delegator must stake in orders for his delegation to get accepted.
|
||||
pub minimum_mixnode_delegation: Option<Coin>,
|
||||
|
||||
@@ -9,8 +9,6 @@ edition = "2021"
|
||||
cw-utils = { workspace = true }
|
||||
cw3 = { workspace = true }
|
||||
cw4 = { workspace= true }
|
||||
cw-storage-plus = { workspace = true }
|
||||
cosmwasm-schema = { workspace = true }
|
||||
cosmwasm-std = { workspace = true }
|
||||
schemars = "0.8"
|
||||
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use cosmwasm_std::StdError;
|
||||
use cw3::DepositError;
|
||||
use cw_utils::{PaymentError, ThresholdError};
|
||||
use cw_utils::ThresholdError;
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -18,6 +17,9 @@ pub enum ContractError {
|
||||
#[error("Group contract invalid address '{addr}'")]
|
||||
InvalidGroup { addr: String },
|
||||
|
||||
#[error("Coconut bandwidth contract address not found")]
|
||||
InvalidCoconutBandwidth {},
|
||||
|
||||
#[error("Unauthorized")]
|
||||
Unauthorized {},
|
||||
|
||||
@@ -41,10 +43,4 @@ pub enum ContractError {
|
||||
|
||||
#[error("Cannot close completed or passed proposals")]
|
||||
WrongCloseStatus {},
|
||||
|
||||
#[error("{0}")]
|
||||
Payment(#[from] PaymentError),
|
||||
|
||||
#[error("{0}")]
|
||||
Deposit(#[from] DepositError),
|
||||
}
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
pub mod error;
|
||||
pub mod msg;
|
||||
pub mod state;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use cosmwasm_schema::{cw_serde, QueryResponses};
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use cosmwasm_std::{CosmosMsg, Empty};
|
||||
use cw3::{UncheckedDepositInfo, Vote};
|
||||
use cw3::Vote;
|
||||
use cw4::MemberChangedHookMsg;
|
||||
use cw_utils::{Duration, Expiration, Threshold};
|
||||
|
||||
use crate::state::Executor;
|
||||
|
||||
#[cw_serde]
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, JsonSchema, Debug)]
|
||||
pub struct InstantiateMsg {
|
||||
// this is the group contract that contains the member list
|
||||
pub group_addr: String,
|
||||
@@ -17,15 +17,11 @@ pub struct InstantiateMsg {
|
||||
pub coconut_dkg_contract_address: String,
|
||||
pub threshold: Threshold,
|
||||
pub max_voting_period: Duration,
|
||||
// who is able to execute passed proposals
|
||||
// None means that anyone can execute
|
||||
pub executor: Option<Executor>,
|
||||
/// The cost of creating a proposal (if any).
|
||||
pub proposal_deposit: Option<UncheckedDepositInfo>,
|
||||
}
|
||||
|
||||
// TODO: add some T variants? Maybe good enough as fixed Empty for now
|
||||
#[cw_serde]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ExecuteMsg {
|
||||
Propose {
|
||||
title: String,
|
||||
@@ -49,44 +45,41 @@ pub enum ExecuteMsg {
|
||||
}
|
||||
|
||||
// We can also add this as a cw3 extension
|
||||
#[cw_serde]
|
||||
#[derive(QueryResponses)]
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, JsonSchema, Debug)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum QueryMsg {
|
||||
#[returns(cw_utils::ThresholdResponse)]
|
||||
/// Return ThresholdResponse
|
||||
Threshold {},
|
||||
#[returns(cw3::ProposalResponse)]
|
||||
/// Returns ProposalResponse
|
||||
Proposal { proposal_id: u64 },
|
||||
#[returns(cw3::ProposalListResponse)]
|
||||
/// Returns ProposalListResponse
|
||||
ListProposals {
|
||||
start_after: Option<u64>,
|
||||
limit: Option<u32>,
|
||||
},
|
||||
#[returns(cw3::ProposalListResponse)]
|
||||
/// Returns ProposalListResponse
|
||||
ReverseProposals {
|
||||
start_before: Option<u64>,
|
||||
limit: Option<u32>,
|
||||
},
|
||||
#[returns(cw3::VoteResponse)]
|
||||
/// Returns VoteResponse
|
||||
Vote { proposal_id: u64, voter: String },
|
||||
#[returns(cw3::VoteListResponse)]
|
||||
/// Returns VoteListResponse
|
||||
ListVotes {
|
||||
proposal_id: u64,
|
||||
start_after: Option<String>,
|
||||
limit: Option<u32>,
|
||||
},
|
||||
#[returns(cw3::VoterResponse)]
|
||||
/// Returns VoterInfo
|
||||
Voter { address: String },
|
||||
#[returns(cw3::VoterListResponse)]
|
||||
/// Returns VoterListResponse
|
||||
ListVoters {
|
||||
start_after: Option<String>,
|
||||
limit: Option<u32>,
|
||||
},
|
||||
/// Gets the current configuration.
|
||||
#[returns(crate::state::Config)]
|
||||
Config {},
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct MigrateMsg {
|
||||
pub coconut_bandwidth_address: String,
|
||||
pub coconut_dkg_address: String,
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
use cosmwasm_schema::cw_serde;
|
||||
use cosmwasm_std::{Addr, QuerierWrapper};
|
||||
use cw3::DepositInfo;
|
||||
use cw4::Cw4Contract;
|
||||
use cw_storage_plus::Item;
|
||||
use cw_utils::{Duration, Threshold};
|
||||
|
||||
use crate::error::ContractError;
|
||||
|
||||
/// Defines who is able to execute proposals once passed
|
||||
#[cw_serde]
|
||||
pub enum Executor {
|
||||
/// Any member of the voting group, even with 0 points
|
||||
Member,
|
||||
/// Only the given address
|
||||
Only(Addr),
|
||||
}
|
||||
|
||||
#[cw_serde]
|
||||
pub struct Config {
|
||||
pub threshold: Threshold,
|
||||
pub max_voting_period: Duration,
|
||||
// Total weight and voters are queried from this contract
|
||||
pub group_addr: Cw4Contract,
|
||||
pub coconut_bandwidth_addr: Addr,
|
||||
pub coconut_dkg_addr: Addr,
|
||||
// who is able to execute passed proposals
|
||||
// None means that anyone can execute
|
||||
pub executor: Option<Executor>,
|
||||
/// The price, if any, of creating a new proposal.
|
||||
pub proposal_deposit: Option<DepositInfo>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
// Executor can be set in 3 ways:
|
||||
// - Member: any member of the voting group is authorized
|
||||
// - Only: only passed address is authorized
|
||||
// - None: Everyone are authorized
|
||||
pub fn authorize(&self, querier: &QuerierWrapper, sender: &Addr) -> Result<(), ContractError> {
|
||||
if let Some(executor) = &self.executor {
|
||||
match executor {
|
||||
Executor::Member => {
|
||||
self.group_addr
|
||||
.is_member(querier, sender, None)?
|
||||
.ok_or(ContractError::Unauthorized {})?;
|
||||
}
|
||||
Executor::Only(addr) => {
|
||||
if addr != sender {
|
||||
return Err(ContractError::Unauthorized {});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// unique items
|
||||
pub const CONFIG: Item<Config> = Item::new("config");
|
||||
@@ -7,5 +7,9 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cosmwasm-std = { workspace = true }
|
||||
nym-contracts-common = { path = "../contracts-common", version = "0.5.0" }
|
||||
schemars = "0.8"
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
thiserror = { workspace = true }
|
||||
cw-utils = { workspace = true }
|
||||
cw-controllers = { workspace = true }
|
||||
|
||||
+20
-3
@@ -1,10 +1,12 @@
|
||||
use cosmwasm_std::{Addr, StdError};
|
||||
use cw_controllers::AdminError;
|
||||
use nym_service_provider_directory_common::{NymAddress, ServiceId};
|
||||
use nym_contracts_common::signing::verifier::ApiVerifierError;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::{NymAddress, ServiceId};
|
||||
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
pub enum ContractError {
|
||||
pub enum SpContractError {
|
||||
#[error("{0}")]
|
||||
Std(#[from] StdError),
|
||||
|
||||
@@ -46,6 +48,21 @@ pub enum ContractError {
|
||||
value: String,
|
||||
error_message: String,
|
||||
},
|
||||
|
||||
#[error("Failed to recover ed25519 public key from its base58 representation - {0}")]
|
||||
MalformedEd25519IdentityKey(String),
|
||||
|
||||
#[error("Failed to recover ed25519 signature from its base58 representation - {0}")]
|
||||
MalformedEd25519Signature(String),
|
||||
|
||||
#[error("Provided ed25519 signature did not verify correctly")]
|
||||
InvalidEd25519Signature,
|
||||
|
||||
#[error("failed to verify message signature: {source}")]
|
||||
SignatureVerificationFailure {
|
||||
#[from]
|
||||
source: ApiVerifierError,
|
||||
},
|
||||
}
|
||||
|
||||
pub(crate) type Result<T, E = ContractError> = std::result::Result<T, E>;
|
||||
pub type Result<T, E = SpContractError> = std::result::Result<T, E>;
|
||||
@@ -39,16 +39,16 @@ pub fn new_announce_event(service_id: ServiceId, service: Service) -> Event {
|
||||
Event::new(ServiceProviderEventType::Announce)
|
||||
.add_attribute(ACTION, ServiceProviderEventType::Announce)
|
||||
.add_attribute(SERVICE_ID, service_id.to_string())
|
||||
.add_attribute(SERVICE_TYPE, service.service_type.to_string())
|
||||
.add_attribute(NYM_ADDRESS, service.nym_address.to_string())
|
||||
.add_attribute(SERVICE_TYPE, service.service.service_type.to_string())
|
||||
.add_attribute(NYM_ADDRESS, service.service.nym_address.to_string())
|
||||
.add_attribute(OWNER, service.announcer.to_string())
|
||||
}
|
||||
|
||||
pub fn new_delete_id_event(service_id: ServiceId, service: Service) -> Event {
|
||||
pub fn new_delete_id_event(service: Service) -> Event {
|
||||
Event::new(ServiceProviderEventType::DeleteId)
|
||||
.add_attribute(ACTION, ServiceProviderEventType::DeleteId)
|
||||
.add_attribute(SERVICE_ID, service_id.to_string())
|
||||
.add_attribute(NYM_ADDRESS, service.nym_address.to_string())
|
||||
.add_attribute(SERVICE_ID, service.service_id.to_string())
|
||||
.add_attribute(NYM_ADDRESS, service.service.nym_address.to_string())
|
||||
}
|
||||
|
||||
pub fn new_update_deposit_required_event(deposit_required: Coin) -> Event {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
pub mod error;
|
||||
pub mod events;
|
||||
pub mod msg;
|
||||
pub mod response;
|
||||
pub mod signing_types;
|
||||
pub mod types;
|
||||
|
||||
// Re-export all types at the top-level
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::{NymAddress, ServiceId, ServiceType};
|
||||
use crate::{NymAddress, ServiceDetails, ServiceId};
|
||||
use cosmwasm_std::Coin;
|
||||
use nym_contracts_common::signing::MessageSignature;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||
@@ -22,8 +23,8 @@ pub struct MigrateMsg {}
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ExecuteMsg {
|
||||
Announce {
|
||||
nym_address: NymAddress,
|
||||
service_type: ServiceType,
|
||||
service: ServiceDetails,
|
||||
owner_signature: MessageSignature,
|
||||
},
|
||||
DeleteId {
|
||||
service_id: ServiceId,
|
||||
@@ -44,9 +45,12 @@ impl ExecuteMsg {
|
||||
pub fn default_memo(&self) -> String {
|
||||
match self {
|
||||
ExecuteMsg::Announce {
|
||||
nym_address,
|
||||
service_type,
|
||||
} => format!("announcing {nym_address} as type {service_type}"),
|
||||
service,
|
||||
owner_signature: _,
|
||||
} => format!(
|
||||
"announcing {} as type {}",
|
||||
service.nym_address, service.service_type
|
||||
),
|
||||
ExecuteMsg::DeleteId { service_id } => {
|
||||
format!("deleting service with service id {service_id}")
|
||||
}
|
||||
@@ -76,6 +80,9 @@ pub enum QueryMsg {
|
||||
limit: Option<u32>,
|
||||
start_after: Option<ServiceId>,
|
||||
},
|
||||
SigningNonce {
|
||||
address: String,
|
||||
},
|
||||
Config {},
|
||||
GetContractVersion {},
|
||||
#[serde(rename = "get_cw2_contract_version")]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{msg::ExecuteMsg, Service, ServiceId, ServiceInfo};
|
||||
use crate::{Service, ServiceId};
|
||||
use cosmwasm_std::Coin;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -13,22 +13,17 @@ pub struct ServiceInfoResponse {
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct ServicesListResponse {
|
||||
pub services: Vec<ServiceInfo>,
|
||||
pub services: Vec<Service>,
|
||||
}
|
||||
|
||||
impl ServicesListResponse {
|
||||
pub fn new(services: Vec<(ServiceId, Service)>) -> ServicesListResponse {
|
||||
ServicesListResponse {
|
||||
services: services
|
||||
.into_iter()
|
||||
.map(|(service_id, service)| ServiceInfo::new(service_id, service))
|
||||
.collect(),
|
||||
}
|
||||
pub fn new(services: Vec<Service>) -> ServicesListResponse {
|
||||
ServicesListResponse { services }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&[ServiceInfo]> for ServicesListResponse {
|
||||
fn from(services: &[ServiceInfo]) -> Self {
|
||||
impl From<&[Service]> for ServicesListResponse {
|
||||
fn from(services: &[Service]) -> Self {
|
||||
Self {
|
||||
services: services.to_vec(),
|
||||
}
|
||||
@@ -38,21 +33,17 @@ impl From<&[ServiceInfo]> for ServicesListResponse {
|
||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct PagedServicesListResponse {
|
||||
pub services: Vec<ServiceInfo>,
|
||||
pub services: Vec<Service>,
|
||||
pub per_page: usize,
|
||||
pub start_next_after: Option<ServiceId>,
|
||||
}
|
||||
|
||||
impl PagedServicesListResponse {
|
||||
pub fn new(
|
||||
services: Vec<(ServiceId, Service)>,
|
||||
services: Vec<Service>,
|
||||
per_page: usize,
|
||||
start_next_after: Option<ServiceId>,
|
||||
) -> PagedServicesListResponse {
|
||||
let services = services
|
||||
.into_iter()
|
||||
.map(|(service_id, service)| ServiceInfo::new(service_id, service))
|
||||
.collect();
|
||||
PagedServicesListResponse {
|
||||
services,
|
||||
per_page,
|
||||
@@ -66,12 +57,3 @@ impl PagedServicesListResponse {
|
||||
pub struct ConfigResponse {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
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,6 +1,7 @@
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use cosmwasm_std::{Addr, Coin};
|
||||
use nym_contracts_common::IdentityKey;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@@ -9,11 +10,11 @@ pub type ServiceId = u32;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)]
|
||||
pub struct Service {
|
||||
/// The address of the service.
|
||||
pub nym_address: NymAddress,
|
||||
/// The service type.
|
||||
pub service_type: ServiceType,
|
||||
/// Service owner.
|
||||
/// Unique id assigned to the anounced service.
|
||||
pub service_id: ServiceId,
|
||||
/// The announced service.
|
||||
pub service: ServiceDetails,
|
||||
/// Address of the service owner.
|
||||
pub announcer: Addr,
|
||||
/// Block height at which the service was added.
|
||||
pub block_height: u64,
|
||||
@@ -21,6 +22,16 @@ pub struct Service {
|
||||
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.
|
||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
@@ -28,7 +39,7 @@ pub enum NymAddress {
|
||||
/// String representation of a nym address, which is of the form
|
||||
/// client_id.client_enc@gateway_id.
|
||||
Address(String),
|
||||
// For the future when we have a nym-dns contract
|
||||
// String name that can looked up in the nym-name-service contract (once it exists)
|
||||
//Name(String),
|
||||
}
|
||||
|
||||
@@ -41,6 +52,7 @@ impl NymAddress {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match self {
|
||||
NymAddress::Address(address) => address,
|
||||
//NymAddress::Name(name) => name,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,19 +78,3 @@ impl std::fmt::Display for ServiceType {
|
||||
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]
|
||||
name = "nym-vesting-contract-common"
|
||||
version = "0.6.0"
|
||||
version = "0.7.0"
|
||||
description = "Common library for the Nym vesting contract"
|
||||
edition = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
@@ -9,8 +9,8 @@ repository = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
cosmwasm-std = { workspace = true }
|
||||
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.4.0" }
|
||||
mixnet-contract-common = { path = "../mixnet-contract", package = "nym-mixnet-contract-common", version = "0.6.0" }
|
||||
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
schemars = "0.8"
|
||||
ts-rs = {version = "6.1.2", optional = true}
|
||||
|
||||
@@ -28,7 +28,7 @@ pub enum Period {
|
||||
After,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct PledgeData {
|
||||
pub amount: Coin,
|
||||
pub block_time: Timestamp,
|
||||
@@ -49,7 +49,7 @@ impl PledgeData {
|
||||
}
|
||||
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub enum PledgeCap {
|
||||
Percent(Percent),
|
||||
Absolute(Uint128), // This has to be in unym
|
||||
@@ -77,7 +77,7 @@ impl Default for PledgeCap {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
pub struct OriginalVestingResponse {
|
||||
pub amount: Coin,
|
||||
pub number_of_periods: usize,
|
||||
|
||||
@@ -55,7 +55,7 @@ impl VestingSpecification {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ExecuteMsg {
|
||||
// Families
|
||||
|
||||
@@ -7,7 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bls12_381 = { version = "0.5", default-features = false, features = ["pairings", "alloc", "experimental"] }
|
||||
cosmrs = { workspace = true }
|
||||
cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" }
|
||||
thiserror = "1.0"
|
||||
|
||||
# I guess temporarily until we get serde support in coconut up and running
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-crypto"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
description = "Crypto library for the nym mixnet"
|
||||
edition = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
@@ -28,7 +28,7 @@ zeroize = { workspace = true, optional = true, features = ["zeroize_derive"] }
|
||||
|
||||
# internal
|
||||
nym-sphinx-types = { path = "../nymsphinx/types", version = "0.2.0" }
|
||||
nym-pemstore = { path = "../../common/pemstore", version = "0.2.0" }
|
||||
nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
rand_chacha = "0.2"
|
||||
|
||||
@@ -6,8 +6,8 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bip32 = "0.4.0"
|
||||
k256 = { workspace = true }
|
||||
bip32 = "0.3.0"
|
||||
k256 = "0.10.4"
|
||||
ledger-transport = "0.10.0"
|
||||
ledger-transport-hid = "0.10.0"
|
||||
thiserror = "1"
|
||||
@@ -3,12 +3,15 @@
|
||||
|
||||
use nym_sphinx_acknowledgements::surb_ack::SurbAckRecoveryError;
|
||||
use nym_sphinx_addressing::nodes::NymNodeRoutingAddressError;
|
||||
use nym_sphinx_types::Error as SphinxError;
|
||||
use nym_sphinx_types::{NymPacketError, SphinxError};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum MixProcessingError {
|
||||
#[error("failed to process received packet: {0}")]
|
||||
NymPacketProcessingError(#[from] NymPacketError),
|
||||
|
||||
#[error("failed to process received sphinx packet: {0}")]
|
||||
SphinxProcessingError(#[from] SphinxError),
|
||||
|
||||
#[error("the forward hop address was malformed: {0}")]
|
||||
|
||||
@@ -7,11 +7,11 @@ use log::*;
|
||||
use nym_sphinx_acknowledgements::surb_ack::SurbAck;
|
||||
use nym_sphinx_addressing::nodes::NymNodeRoutingAddress;
|
||||
use nym_sphinx_forwarding::packet::MixPacket;
|
||||
use nym_sphinx_framing::packet::FramedSphinxPacket;
|
||||
use nym_sphinx_params::{PacketMode, PacketSize};
|
||||
use nym_sphinx_framing::packet::FramedNymPacket;
|
||||
use nym_sphinx_params::{PacketSize, PacketType};
|
||||
use nym_sphinx_types::{
|
||||
Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, Payload, PrivateKey,
|
||||
ProcessedPacket, SphinxPacket,
|
||||
Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, NymPacket, NymProcessedPacket,
|
||||
PrivateKey, ProcessedPacket,
|
||||
};
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::Arc;
|
||||
@@ -53,14 +53,14 @@ impl SphinxPacketProcessor {
|
||||
feature = "cpucycles",
|
||||
instrument(skip(self, packet), fields(cpucycles))
|
||||
)]
|
||||
fn perform_initial_sphinx_packet_processing(
|
||||
fn perform_initial_packet_processing(
|
||||
&self,
|
||||
packet: SphinxPacket,
|
||||
) -> Result<ProcessedPacket, MixProcessingError> {
|
||||
packet: NymPacket,
|
||||
) -> Result<NymProcessedPacket, MixProcessingError> {
|
||||
measure!({
|
||||
packet.process(&self.sphinx_key).map_err(|err| {
|
||||
debug!("Failed to unwrap Sphinx packet: {err}");
|
||||
MixProcessingError::SphinxProcessingError(err)
|
||||
debug!("Failed to unwrap NymPacket packet: {err}");
|
||||
MixProcessingError::NymPacketProcessingError(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -72,17 +72,12 @@ impl SphinxPacketProcessor {
|
||||
)]
|
||||
fn perform_initial_unwrapping(
|
||||
&self,
|
||||
received: FramedSphinxPacket,
|
||||
) -> Result<ProcessedPacket, MixProcessingError> {
|
||||
received: FramedNymPacket,
|
||||
) -> Result<NymProcessedPacket, MixProcessingError> {
|
||||
measure!({
|
||||
let packet_mode = received.packet_mode();
|
||||
let sphinx_packet = received.into_inner();
|
||||
let packet = received.into_inner();
|
||||
|
||||
if packet_mode.is_old_vpn() {
|
||||
return Err(MixProcessingError::ReceivedOldTypeVpnPacket);
|
||||
}
|
||||
|
||||
self.perform_initial_sphinx_packet_processing(sphinx_packet)
|
||||
self.perform_initial_packet_processing(packet)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -90,14 +85,14 @@ impl SphinxPacketProcessor {
|
||||
/// and packs all the data in a way that can be easily sent to the next hop.
|
||||
fn process_forward_hop(
|
||||
&self,
|
||||
packet: SphinxPacket,
|
||||
packet: NymPacket,
|
||||
forward_address: NodeAddressBytes,
|
||||
delay: SphinxDelay,
|
||||
packet_mode: PacketMode,
|
||||
packet_type: PacketType,
|
||||
) -> Result<MixProcessingResult, MixProcessingError> {
|
||||
let next_hop_address = NymNodeRoutingAddress::try_from(forward_address)?;
|
||||
|
||||
let mix_packet = MixPacket::new(next_hop_address, packet, packet_mode);
|
||||
let mix_packet = MixPacket::new(next_hop_address, packet, packet_type);
|
||||
Ok(MixProcessingResult::ForwardHop(mix_packet, Some(delay)))
|
||||
}
|
||||
|
||||
@@ -106,14 +101,17 @@ impl SphinxPacketProcessor {
|
||||
fn split_hop_data_into_ack_and_message(
|
||||
&self,
|
||||
mut extracted_data: Vec<u8>,
|
||||
packet_type: PacketType,
|
||||
) -> Result<(Vec<u8>, Vec<u8>), MixProcessingError> {
|
||||
let ack_len = SurbAck::len(Some(packet_type));
|
||||
|
||||
// in theory it's impossible for this to fail since it managed to go into correct `match`
|
||||
// branch at the caller
|
||||
if extracted_data.len() < SurbAck::len() {
|
||||
if extracted_data.len() < ack_len {
|
||||
return Err(MixProcessingError::NoSurbAckInFinalHop);
|
||||
}
|
||||
|
||||
let message = extracted_data.split_off(SurbAck::len());
|
||||
let message = extracted_data.split_off(ack_len);
|
||||
let ack_data = extracted_data;
|
||||
Ok((ack_data, message))
|
||||
}
|
||||
@@ -124,21 +122,30 @@ impl SphinxPacketProcessor {
|
||||
&self,
|
||||
data: Vec<u8>,
|
||||
packet_size: PacketSize,
|
||||
packet_mode: PacketMode,
|
||||
packet_type: PacketType,
|
||||
) -> Result<(Option<MixPacket>, Vec<u8>), MixProcessingError> {
|
||||
match packet_size {
|
||||
PacketSize::AckPacket => {
|
||||
PacketSize::AckPacket | PacketSize::OutfoxAckPacket => {
|
||||
trace!("received an ack packet!");
|
||||
Ok((None, data))
|
||||
}
|
||||
PacketSize::RegularPacket
|
||||
| PacketSize::ExtendedPacket8
|
||||
| PacketSize::ExtendedPacket16
|
||||
| PacketSize::ExtendedPacket32 => {
|
||||
| PacketSize::ExtendedPacket32
|
||||
| PacketSize::OutfoxRegularPacket => {
|
||||
trace!("received a normal packet!");
|
||||
let (ack_data, message) = self.split_hop_data_into_ack_and_message(data)?;
|
||||
let (ack_first_hop, ack_packet) = SurbAck::try_recover_first_hop_packet(&ack_data)?;
|
||||
let forward_ack = MixPacket::new(ack_first_hop, ack_packet, packet_mode);
|
||||
let (ack_data, message) =
|
||||
self.split_hop_data_into_ack_and_message(data, packet_type)?;
|
||||
let (ack_first_hop, ack_packet) =
|
||||
match SurbAck::try_recover_first_hop_packet(&ack_data, packet_type) {
|
||||
Ok((first_hop, packet)) => (first_hop, packet),
|
||||
Err(err) => {
|
||||
debug!("Failed to recover first hop from ack data: {err}");
|
||||
return Err(err.into());
|
||||
}
|
||||
};
|
||||
let forward_ack = MixPacket::new(ack_first_hop, ack_packet, packet_type);
|
||||
Ok((Some(forward_ack), message))
|
||||
}
|
||||
}
|
||||
@@ -150,14 +157,12 @@ impl SphinxPacketProcessor {
|
||||
fn process_final_hop(
|
||||
&self,
|
||||
destination: DestinationAddressBytes,
|
||||
payload: Payload,
|
||||
payload: Vec<u8>,
|
||||
packet_size: PacketSize,
|
||||
packet_mode: PacketMode,
|
||||
packet_type: PacketType,
|
||||
) -> Result<MixProcessingResult, MixProcessingError> {
|
||||
let packet_message = payload.recover_plaintext()?;
|
||||
|
||||
let (forward_ack, message) =
|
||||
self.split_into_ack_and_message(packet_message, packet_size, packet_mode)?;
|
||||
self.split_into_ack_and_message(payload, packet_size, packet_type)?;
|
||||
|
||||
Ok(MixProcessingResult::FinalHop(ProcessedFinalHop {
|
||||
destination,
|
||||
@@ -170,18 +175,48 @@ impl SphinxPacketProcessor {
|
||||
/// or a final hop.
|
||||
fn perform_final_processing(
|
||||
&self,
|
||||
packet: ProcessedPacket,
|
||||
packet: NymProcessedPacket,
|
||||
packet_size: PacketSize,
|
||||
packet_mode: PacketMode,
|
||||
packet_type: PacketType,
|
||||
) -> Result<MixProcessingResult, MixProcessingError> {
|
||||
match packet {
|
||||
ProcessedPacket::ForwardHop(packet, address, delay) => {
|
||||
self.process_forward_hop(*packet, address, delay, packet_mode)
|
||||
NymProcessedPacket::Sphinx(packet) => {
|
||||
match packet {
|
||||
ProcessedPacket::ForwardHop(packet, address, delay) => self
|
||||
.process_forward_hop(
|
||||
NymPacket::Sphinx(*packet),
|
||||
address,
|
||||
delay,
|
||||
packet_type,
|
||||
),
|
||||
// right now there's no use for the surb_id included in the header - probably it should get removed from the
|
||||
// sphinx all together?
|
||||
ProcessedPacket::FinalHop(destination, _, payload) => self.process_final_hop(
|
||||
destination,
|
||||
payload.recover_plaintext()?,
|
||||
packet_size,
|
||||
packet_type,
|
||||
),
|
||||
}
|
||||
}
|
||||
// right now there's no use for the surb_id included in the header - probably it should get removed from the
|
||||
// sphinx all together?
|
||||
ProcessedPacket::FinalHop(destination, _, payload) => {
|
||||
self.process_final_hop(destination, payload, packet_size, packet_mode)
|
||||
NymProcessedPacket::Outfox(packet) => {
|
||||
let next_address = *packet.next_address();
|
||||
let packet = packet.into_packet();
|
||||
if packet.is_final_hop() {
|
||||
self.process_final_hop(
|
||||
DestinationAddressBytes::from_bytes(next_address),
|
||||
packet.recover_plaintext().to_vec(),
|
||||
packet_size,
|
||||
packet_type,
|
||||
)
|
||||
} else {
|
||||
let mix_packet = MixPacket::new(
|
||||
NymNodeRoutingAddress::try_from_bytes(&next_address)?,
|
||||
NymPacket::Outfox(packet),
|
||||
PacketType::Outfox,
|
||||
);
|
||||
Ok(MixProcessingResult::ForwardHop(mix_packet, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,19 +227,19 @@ impl SphinxPacketProcessor {
|
||||
)]
|
||||
pub fn process_received(
|
||||
&self,
|
||||
received: FramedSphinxPacket,
|
||||
received: FramedNymPacket,
|
||||
) -> Result<MixProcessingResult, MixProcessingError> {
|
||||
// explicit packet size will help to correctly parse final hop
|
||||
measure!({
|
||||
let packet_size = received.packet_size();
|
||||
let packet_mode = received.packet_mode();
|
||||
let packet_type = received.packet_type();
|
||||
|
||||
// unwrap the sphinx packet and if possible and appropriate, cache keys
|
||||
let processed_packet = self.perform_initial_unwrapping(received)?;
|
||||
|
||||
// for forward packets, extract next hop and set delay (but do NOT delay here)
|
||||
// for final packets, extract SURBAck
|
||||
self.perform_final_processing(processed_packet, packet_size, packet_mode)
|
||||
self.perform_final_processing(processed_packet, packet_size, packet_type)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -226,31 +261,71 @@ mod tests {
|
||||
|
||||
let short_data = vec![42u8];
|
||||
assert!(processor
|
||||
.split_hop_data_into_ack_and_message(short_data)
|
||||
.split_hop_data_into_ack_and_message(short_data, PacketType::Mix)
|
||||
.is_err());
|
||||
|
||||
let sufficient_data = vec![42u8; SurbAck::len()];
|
||||
let sufficient_data = vec![42u8; SurbAck::len(Some(PacketType::Mix))];
|
||||
let (ack, data) = processor
|
||||
.split_hop_data_into_ack_and_message(sufficient_data.clone())
|
||||
.split_hop_data_into_ack_and_message(sufficient_data.clone(), PacketType::Mix)
|
||||
.unwrap();
|
||||
assert_eq!(sufficient_data, ack);
|
||||
assert!(data.is_empty());
|
||||
|
||||
let long_data = vec![42u8; SurbAck::len() * 5];
|
||||
let long_data = vec![42u8; SurbAck::len(Some(PacketType::Mix)) * 5];
|
||||
let (ack, data) = processor
|
||||
.split_hop_data_into_ack_and_message(long_data)
|
||||
.split_hop_data_into_ack_and_message(long_data, PacketType::Mix)
|
||||
.unwrap();
|
||||
assert_eq!(ack.len(), SurbAck::len());
|
||||
assert_eq!(data.len(), SurbAck::len() * 4)
|
||||
assert_eq!(ack.len(), SurbAck::len(Some(PacketType::Mix)));
|
||||
assert_eq!(data.len(), SurbAck::len(Some(PacketType::Mix)) * 4)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn splitting_hop_data_works_for_sufficiently_long_payload_outfox() {
|
||||
let processor = fixture();
|
||||
|
||||
let short_data = vec![42u8];
|
||||
assert!(processor
|
||||
.split_hop_data_into_ack_and_message(short_data, PacketType::Outfox)
|
||||
.is_err());
|
||||
|
||||
let sufficient_data = vec![42u8; SurbAck::len(Some(PacketType::Outfox))];
|
||||
let (ack, data) = processor
|
||||
.split_hop_data_into_ack_and_message(sufficient_data.clone(), PacketType::Outfox)
|
||||
.unwrap();
|
||||
assert_eq!(sufficient_data, ack);
|
||||
assert!(data.is_empty());
|
||||
|
||||
let long_data = vec![42u8; SurbAck::len(Some(PacketType::Outfox)) * 5];
|
||||
let (ack, data) = processor
|
||||
.split_hop_data_into_ack_and_message(long_data, PacketType::Outfox)
|
||||
.unwrap();
|
||||
assert_eq!(ack.len(), SurbAck::len(Some(PacketType::Outfox)));
|
||||
assert_eq!(data.len(), SurbAck::len(Some(PacketType::Outfox)) * 4)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn splitting_into_ack_and_message_returns_whole_data_for_ack() {
|
||||
let processor = fixture();
|
||||
|
||||
let data = vec![42u8; SurbAck::len() + 10];
|
||||
let data = vec![42u8; SurbAck::len(Some(PacketType::Mix)) + 10];
|
||||
let (ack, message) = processor
|
||||
.split_into_ack_and_message(data.clone(), PacketSize::AckPacket, Default::default())
|
||||
.split_into_ack_and_message(data.clone(), PacketSize::AckPacket, PacketType::Mix)
|
||||
.unwrap();
|
||||
assert!(ack.is_none());
|
||||
assert_eq!(data, message)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn splitting_into_ack_and_message_returns_whole_data_for_ack_outfox() {
|
||||
let processor = fixture();
|
||||
|
||||
let data = vec![42u8; SurbAck::len(Some(PacketType::Outfox)) + 10];
|
||||
let (ack, message) = processor
|
||||
.split_into_ack_and_message(
|
||||
data.clone(),
|
||||
PacketSize::OutfoxAckPacket,
|
||||
PacketType::Outfox,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(ack.is_none());
|
||||
assert_eq!(data, message)
|
||||
|
||||
@@ -17,6 +17,7 @@ tokio = { workspace = true, features = ["macros"]}
|
||||
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
|
||||
nym-task = { path = "../task" }
|
||||
nym-topology = { path = "../topology" }
|
||||
nym-sphinx-params = { path = "../nymsphinx/params" }
|
||||
# TODO: do we need the whole nymsphinx?
|
||||
nym-sphinx = { path = "../nymsphinx" }
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ use nym_sphinx::addressing::clients::Recipient;
|
||||
use nym_sphinx::message::NymMessage;
|
||||
use nym_sphinx::params::{PacketSize, DEFAULT_NUM_MIX_HOPS};
|
||||
use nym_sphinx::preparer::{FragmentPreparer, PreparedFragment};
|
||||
use nym_sphinx_params::PacketType;
|
||||
use nym_topology::{gateway, mix, NymTopology};
|
||||
use rand::{CryptoRng, Rng};
|
||||
use serde::Serialize;
|
||||
@@ -243,7 +244,14 @@ where
|
||||
|
||||
// TODO: can we avoid this arc clone?
|
||||
let ack_key = Arc::clone(&self.ack_key);
|
||||
Ok(self.prepare_chunk_for_sending(fragment, topology, &ack_key, &address, &address)?)
|
||||
Ok(self.prepare_chunk_for_sending(
|
||||
fragment,
|
||||
topology,
|
||||
&ack_key,
|
||||
&address,
|
||||
&address,
|
||||
PacketType::Mix,
|
||||
)?)
|
||||
}
|
||||
|
||||
pub fn create_test_packet<T>(
|
||||
|
||||
@@ -25,15 +25,12 @@ nym-sphinx-types = { path = "types" }
|
||||
|
||||
# those dependencies are due to intriducing preparer and receiver. Perpaphs that indicates they should be moved
|
||||
# to separate crate?
|
||||
nym-crypto = { path = "../crypto", version = "0.3.0" }
|
||||
nym-crypto = { path = "../crypto", version = "0.4.0" }
|
||||
nym-topology = { path = "../topology" }
|
||||
|
||||
# outfox
|
||||
nym-outfox = { path = "../../nym-outfox" }
|
||||
|
||||
[dev-dependencies]
|
||||
nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
|
||||
nym-crypto = { path = "../crypto", version = "0.3.0", features = ["asymmetric"] }
|
||||
nym-crypto = { path = "../crypto", version = "0.4.0", features = ["asymmetric"] }
|
||||
|
||||
# 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
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
|
||||
use crate::AckKey;
|
||||
use nym_crypto::symmetric::stream_cipher::{self, encrypt, iv_from_slice, random_iv, IvSizeUser};
|
||||
use nym_sphinx_params::{
|
||||
packet_sizes::PacketSize, AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN,
|
||||
};
|
||||
use nym_sphinx_params::{AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
// TODO: should those functions even exist in this file?
|
||||
@@ -26,12 +24,6 @@ pub fn recover_identifier(
|
||||
key: &AckKey,
|
||||
iv_id_ciphertext: &[u8],
|
||||
) -> Option<SerializedFragmentIdentifier> {
|
||||
// The content of an 'ACK' packet consists of AckEncryptionAlgorithm::IV followed by
|
||||
// serialized FragmentIdentifier
|
||||
if iv_id_ciphertext.len() != PacketSize::AckPacket.plaintext_size() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let iv_size = AckEncryptionAlgorithm::iv_size();
|
||||
let iv = iv_from_slice::<AckEncryptionAlgorithm>(&iv_id_ciphertext[..iv_size]);
|
||||
|
||||
|
||||
@@ -8,21 +8,18 @@ use nym_sphinx_addressing::nodes::{
|
||||
NymNodeRoutingAddress, NymNodeRoutingAddressError, MAX_NODE_ADDRESS_UNPADDED_LEN,
|
||||
};
|
||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||
use nym_sphinx_params::DEFAULT_NUM_MIX_HOPS;
|
||||
use nym_sphinx_types::builder::SphinxPacketBuilder;
|
||||
use nym_sphinx_types::Error as SphinxError;
|
||||
use nym_sphinx_types::{
|
||||
delays::{self, Delay},
|
||||
SphinxPacket,
|
||||
};
|
||||
use nym_sphinx_params::{PacketType, DEFAULT_NUM_MIX_HOPS};
|
||||
use nym_sphinx_types::delays::{self, Delay};
|
||||
use nym_sphinx_types::{NymPacket, NymPacketError, MIN_PACKET_SIZE};
|
||||
use nym_topology::{NymTopology, NymTopologyError};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use std::convert::TryFrom;
|
||||
use std::time;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SurbAck {
|
||||
surb_ack_packet: SphinxPacket,
|
||||
surb_ack_packet: NymPacket,
|
||||
first_hop_address: NymNodeRoutingAddress,
|
||||
expected_total_delay: Delay,
|
||||
}
|
||||
@@ -35,8 +32,8 @@ pub enum SurbAckRecoveryError {
|
||||
#[error("could not extract first hop address information - {0}")]
|
||||
InvalidAddress(#[from] NymNodeRoutingAddressError),
|
||||
|
||||
#[error("the contained sphinx packet was not correctly formed - {0}")]
|
||||
InvalidSphinxPacket(#[from] SphinxError),
|
||||
#[error("packet: {0}")]
|
||||
NymPacket(#[from] NymPacketError),
|
||||
}
|
||||
|
||||
impl SurbAck {
|
||||
@@ -47,6 +44,7 @@ impl SurbAck {
|
||||
marshaled_fragment_id: [u8; 5],
|
||||
average_delay: time::Duration,
|
||||
topology: &NymTopology,
|
||||
packet_type: PacketType,
|
||||
) -> Result<Self, NymTopologyError>
|
||||
where
|
||||
R: RngCore + CryptoRng,
|
||||
@@ -57,11 +55,34 @@ impl SurbAck {
|
||||
let destination = recipient.as_sphinx_destination();
|
||||
|
||||
let surb_ack_payload = prepare_identifier(rng, ack_key, marshaled_fragment_id);
|
||||
let packet_size = match packet_type {
|
||||
PacketType::Outfox => surb_ack_payload.len().max(MIN_PACKET_SIZE),
|
||||
PacketType::Mix => PacketSize::AckPacket.payload_size(),
|
||||
PacketType::Vpn => PacketSize::AckPacket.payload_size(),
|
||||
};
|
||||
|
||||
let surb_ack_packet = SphinxPacketBuilder::new()
|
||||
.with_payload_size(PacketSize::AckPacket.payload_size())
|
||||
.build_packet(surb_ack_payload, &route, &destination, &delays)
|
||||
.unwrap();
|
||||
let surb_ack_packet = match packet_type {
|
||||
PacketType::Outfox => NymPacket::outfox_build(
|
||||
surb_ack_payload,
|
||||
route.as_slice(),
|
||||
&destination,
|
||||
Some(packet_size),
|
||||
)?,
|
||||
PacketType::Mix => NymPacket::sphinx_build(
|
||||
packet_size,
|
||||
surb_ack_payload,
|
||||
&route,
|
||||
&destination,
|
||||
&delays,
|
||||
)?,
|
||||
PacketType::Vpn => NymPacket::sphinx_build(
|
||||
packet_size,
|
||||
surb_ack_payload,
|
||||
&route,
|
||||
&destination,
|
||||
&delays,
|
||||
)?,
|
||||
};
|
||||
|
||||
// in our case, the last hop is a gateway that does NOT do any delays
|
||||
let expected_total_delay = delays.iter().take(delays.len() - 1).sum();
|
||||
@@ -75,45 +96,50 @@ impl SurbAck {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn len() -> usize {
|
||||
pub fn len(packet_type: Option<PacketType>) -> usize {
|
||||
// TODO: this will be variable once/if we decide to introduce optimization described
|
||||
// in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size()
|
||||
PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN
|
||||
let packet_type = packet_type.unwrap_or(PacketType::Mix);
|
||||
match packet_type {
|
||||
PacketType::Outfox => {
|
||||
PacketSize::OutfoxAckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN
|
||||
}
|
||||
PacketType::Mix => PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN,
|
||||
PacketType::Vpn => PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expected_total_delay(&self) -> Delay {
|
||||
self.expected_total_delay
|
||||
}
|
||||
|
||||
pub fn prepare_for_sending(self) -> (Delay, Vec<u8>) {
|
||||
pub fn prepare_for_sending(self) -> Result<(Delay, Vec<u8>), SurbAckRecoveryError> {
|
||||
// SURB_FIRST_HOP || SURB_ACK
|
||||
let surb_bytes: Vec<_> = self
|
||||
.first_hop_address
|
||||
.as_zero_padded_bytes(MAX_NODE_ADDRESS_UNPADDED_LEN)
|
||||
.into_iter()
|
||||
.chain(self.surb_ack_packet.to_bytes().into_iter())
|
||||
.chain(self.surb_ack_packet.to_bytes()?.into_iter())
|
||||
.collect();
|
||||
(self.expected_total_delay, surb_bytes)
|
||||
Ok((self.expected_total_delay, surb_bytes))
|
||||
}
|
||||
|
||||
// partial reciprocal of `prepare_for_sending` performed by the gateway
|
||||
pub fn try_recover_first_hop_packet(
|
||||
b: &[u8],
|
||||
) -> Result<(NymNodeRoutingAddress, SphinxPacket), SurbAckRecoveryError> {
|
||||
if b.len() != Self::len() {
|
||||
Err(SurbAckRecoveryError::InvalidPacketSize {
|
||||
received: b.len(),
|
||||
expected: Self::len(),
|
||||
})
|
||||
} else {
|
||||
let address = NymNodeRoutingAddress::try_from_bytes(b)?;
|
||||
packet_type: PacketType,
|
||||
) -> Result<(NymNodeRoutingAddress, NymPacket), SurbAckRecoveryError> {
|
||||
let address = NymNodeRoutingAddress::try_from_bytes(b)?;
|
||||
|
||||
// TODO: this will be variable once/if we decide to introduce optimization described
|
||||
// in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size()
|
||||
let address_offset = MAX_NODE_ADDRESS_UNPADDED_LEN;
|
||||
let packet = SphinxPacket::from_bytes(&b[address_offset..])?;
|
||||
// TODO: this will be variable once/if we decide to introduce optimization described
|
||||
// in common/nymsphinx/chunking/src/lib.rs:available_plaintext_size()
|
||||
let address_offset = MAX_NODE_ADDRESS_UNPADDED_LEN;
|
||||
let packet = match packet_type {
|
||||
PacketType::Outfox => NymPacket::outfox_from_bytes(&b[address_offset..])?,
|
||||
PacketType::Mix => NymPacket::sphinx_from_bytes(&b[address_offset..])?,
|
||||
PacketType::Vpn => NymPacket::sphinx_from_bytes(&b[address_offset..])?,
|
||||
};
|
||||
|
||||
Ok((address, packet))
|
||||
}
|
||||
Ok((address, packet))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ use nym_crypto::{generic_array::typenum::Unsigned, Digest};
|
||||
use nym_sphinx_addressing::clients::Recipient;
|
||||
use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN};
|
||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||
use nym_sphinx_params::{ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
||||
use nym_sphinx_types::{delays, Error as SphinxError, SURBMaterial, SphinxPacket, SURB};
|
||||
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
||||
use nym_sphinx_types::{delays, NymPacket, SURBMaterial, SphinxError, SURB};
|
||||
use nym_topology::{NymTopology, NymTopologyError};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use serde::de::{Error as SerdeError, Visitor};
|
||||
@@ -173,7 +173,8 @@ impl ReplySurb {
|
||||
self,
|
||||
message: M,
|
||||
packet_size: PacketSize,
|
||||
) -> Result<(SphinxPacket, NymNodeRoutingAddress), ReplySurbError> {
|
||||
_packet_type: PacketType,
|
||||
) -> Result<(NymPacket, NymNodeRoutingAddress), ReplySurbError> {
|
||||
let message_bytes = message.as_ref();
|
||||
if message_bytes.len() != packet_size.plaintext_size() {
|
||||
return Err(ReplySurbError::UnpaddedMessageError);
|
||||
@@ -187,6 +188,6 @@ impl ReplySurb {
|
||||
|
||||
let first_hop_address = NymNodeRoutingAddress::try_from(first_hop).unwrap();
|
||||
|
||||
Ok((packet, first_hop_address))
|
||||
Ok((NymPacket::Sphinx(packet), first_hop_address))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
use nym_crypto::shared_key::new_ephemeral_shared_key;
|
||||
use nym_crypto::symmetric::stream_cipher;
|
||||
use nym_sphinx_acknowledgements::surb_ack::SurbAck;
|
||||
use nym_sphinx_acknowledgements::surb_ack::{SurbAck, SurbAckRecoveryError};
|
||||
use nym_sphinx_acknowledgements::AckKey;
|
||||
use nym_sphinx_addressing::clients::Recipient;
|
||||
use nym_sphinx_addressing::nodes::NymNodeRoutingAddress;
|
||||
@@ -11,10 +11,9 @@ use nym_sphinx_chunking::fragment::COVER_FRAG_ID;
|
||||
use nym_sphinx_forwarding::packet::MixPacket;
|
||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||
use nym_sphinx_params::{
|
||||
PacketEncryptionAlgorithm, PacketHkdfAlgorithm, PacketMode, DEFAULT_NUM_MIX_HOPS,
|
||||
PacketEncryptionAlgorithm, PacketHkdfAlgorithm, PacketType, DEFAULT_NUM_MIX_HOPS,
|
||||
};
|
||||
use nym_sphinx_types::builder::SphinxPacketBuilder;
|
||||
use nym_sphinx_types::{delays, Error as SphinxError};
|
||||
use nym_sphinx_types::{delays, NymPacket};
|
||||
use nym_topology::{NymTopology, NymTopologyError};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use std::convert::TryFrom;
|
||||
@@ -28,8 +27,11 @@ pub enum CoverMessageError {
|
||||
#[error("Could not construct cover message due to invalid topology - {0}")]
|
||||
InvalidTopologyError(#[from] NymTopologyError),
|
||||
|
||||
#[error("Could not construct a valid sphinx packet - {0}")]
|
||||
SphinxError(#[from] SphinxError),
|
||||
#[error("SurbAck: {0}")]
|
||||
SurbAck(#[from] SurbAckRecoveryError),
|
||||
|
||||
#[error("NymPacket: {0}")]
|
||||
NymPacket(#[from] nym_sphinx_types::NymPacketError),
|
||||
}
|
||||
|
||||
pub fn generate_loop_cover_surb_ack<R>(
|
||||
@@ -38,6 +40,7 @@ pub fn generate_loop_cover_surb_ack<R>(
|
||||
ack_key: &AckKey,
|
||||
full_address: &Recipient,
|
||||
average_ack_delay: time::Duration,
|
||||
packet_type: PacketType,
|
||||
) -> Result<SurbAck, CoverMessageError>
|
||||
where
|
||||
R: RngCore + CryptoRng,
|
||||
@@ -49,9 +52,11 @@ where
|
||||
COVER_FRAG_ID.to_bytes(),
|
||||
average_ack_delay,
|
||||
topology,
|
||||
packet_type,
|
||||
)?)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn generate_loop_cover_packet<R>(
|
||||
rng: &mut R,
|
||||
topology: &NymTopology,
|
||||
@@ -60,14 +65,21 @@ pub fn generate_loop_cover_packet<R>(
|
||||
average_ack_delay: time::Duration,
|
||||
average_packet_delay: time::Duration,
|
||||
packet_size: PacketSize,
|
||||
packet_type: PacketType,
|
||||
) -> Result<MixPacket, CoverMessageError>
|
||||
where
|
||||
R: RngCore + CryptoRng,
|
||||
{
|
||||
// we don't care about total ack delay - we will not be retransmitting it anyway
|
||||
let (_, ack_bytes) =
|
||||
generate_loop_cover_surb_ack(rng, topology, ack_key, full_address, average_ack_delay)?
|
||||
.prepare_for_sending();
|
||||
let (_, ack_bytes) = generate_loop_cover_surb_ack(
|
||||
rng,
|
||||
topology,
|
||||
ack_key,
|
||||
full_address,
|
||||
average_ack_delay,
|
||||
packet_type,
|
||||
)?
|
||||
.prepare_for_sending()?;
|
||||
|
||||
// cover message can't be distinguishable from a normal traffic so we have to go through
|
||||
// all the effort of key generation, encryption, etc. Note here we are generating shared key
|
||||
@@ -111,15 +123,18 @@ where
|
||||
let destination = full_address.as_sphinx_destination();
|
||||
|
||||
// once merged, that's an easy rng injection point for sphinx packets : )
|
||||
let packet = SphinxPacketBuilder::new()
|
||||
.with_payload_size(packet_size.payload_size())
|
||||
.build_packet(packet_payload, &route, &destination, &delays)
|
||||
.unwrap();
|
||||
let packet = NymPacket::sphinx_build(
|
||||
packet_size.payload_size(),
|
||||
packet_payload,
|
||||
&route,
|
||||
&destination,
|
||||
&delays,
|
||||
)?;
|
||||
|
||||
let first_hop_address =
|
||||
NymNodeRoutingAddress::try_from(route.first().unwrap().address).unwrap();
|
||||
|
||||
Ok(MixPacket::new(first_hop_address, packet, PacketMode::Mix))
|
||||
Ok(MixPacket::new(first_hop_address, packet, PacketType::Mix))
|
||||
}
|
||||
|
||||
/// Helper function used to determine if given message represents a loop cover message.
|
||||
|
||||
@@ -12,3 +12,4 @@ nym-sphinx-addressing = { path = "../addressing" }
|
||||
nym-sphinx-params = { path = "../params" }
|
||||
nym-sphinx-types = { path = "../types" }
|
||||
nym-outfox = { path = "../../../nym-outfox" }
|
||||
thiserror = "1"
|
||||
|
||||
@@ -2,42 +2,28 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, NymNodeRoutingAddressError};
|
||||
use nym_sphinx_params::{PacketMode, PacketSize};
|
||||
use nym_sphinx_types::SphinxPacket;
|
||||
use nym_sphinx_params::{PacketSize, PacketType};
|
||||
use nym_sphinx_types::{NymPacket, NymPacketError};
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt::{self, Debug, Display, Formatter};
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Error)]
|
||||
pub enum MixPacketFormattingError {
|
||||
#[error("too few bytes provided to recover from bytes")]
|
||||
TooFewBytesProvided,
|
||||
InvalidPacketMode,
|
||||
#[error("provided packet mode is invalid")]
|
||||
InvalidPacketType,
|
||||
#[error("received request had invalid size - received {0}")]
|
||||
InvalidPacketSize(usize),
|
||||
#[error("address field was incorrectly encoded")]
|
||||
InvalidAddress,
|
||||
#[error("received sphinx packet was malformed")]
|
||||
MalformedSphinxPacket,
|
||||
#[error("Packet: {0}")]
|
||||
Packet(#[from] NymPacketError),
|
||||
}
|
||||
|
||||
impl Display for MixPacketFormattingError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
use MixPacketFormattingError::*;
|
||||
match self {
|
||||
TooFewBytesProvided => write!(f, "Too few bytes provided to recover from bytes"),
|
||||
InvalidAddress => write!(f, "address field was incorrectly encoded"),
|
||||
InvalidPacketSize(actual) =>
|
||||
write!(
|
||||
f,
|
||||
"received request had invalid size. (actual: {}, but expected one of: {} (ACK), {} (REGULAR), {}, {}, {} (EXTENDED))",
|
||||
actual, PacketSize::AckPacket.size(), PacketSize::RegularPacket.size(),
|
||||
PacketSize::ExtendedPacket8.size(), PacketSize::ExtendedPacket16.size(),
|
||||
PacketSize::ExtendedPacket32.size()
|
||||
),
|
||||
MalformedSphinxPacket => write!(f, "received sphinx packet was malformed"),
|
||||
InvalidPacketMode => write!(f, "provided packet mode is invalid")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for MixPacketFormattingError {}
|
||||
|
||||
impl From<NymNodeRoutingAddressError> for MixPacketFormattingError {
|
||||
fn from(_: NymNodeRoutingAddressError) -> Self {
|
||||
MixPacketFormattingError::InvalidAddress
|
||||
@@ -46,19 +32,16 @@ impl From<NymNodeRoutingAddressError> for MixPacketFormattingError {
|
||||
|
||||
pub struct MixPacket {
|
||||
next_hop: NymNodeRoutingAddress,
|
||||
sphinx_packet: SphinxPacket,
|
||||
packet_mode: PacketMode,
|
||||
packet: NymPacket,
|
||||
packet_type: PacketType,
|
||||
}
|
||||
|
||||
impl Debug for MixPacket {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"MixPacket to {:?} with packet_mode {:?}. Sphinx header: {:?}, payload length: {}",
|
||||
self.next_hop,
|
||||
self.packet_mode,
|
||||
self.sphinx_packet.header,
|
||||
self.sphinx_packet.payload.len()
|
||||
"MixPacket to {:?} with packet_type {:?}. Packet {:?}",
|
||||
self.next_hop, self.packet_type, self.packet
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -66,13 +49,13 @@ impl Debug for MixPacket {
|
||||
impl MixPacket {
|
||||
pub fn new(
|
||||
next_hop: NymNodeRoutingAddress,
|
||||
sphinx_packet: SphinxPacket,
|
||||
packet_mode: PacketMode,
|
||||
packet: NymPacket,
|
||||
packet_type: PacketType,
|
||||
) -> Self {
|
||||
MixPacket {
|
||||
next_hop,
|
||||
sphinx_packet,
|
||||
packet_mode,
|
||||
packet,
|
||||
packet_type,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,52 +63,52 @@ impl MixPacket {
|
||||
self.next_hop
|
||||
}
|
||||
|
||||
pub fn sphinx_packet(&self) -> &SphinxPacket {
|
||||
&self.sphinx_packet
|
||||
pub fn packet(&self) -> &NymPacket {
|
||||
&self.packet
|
||||
}
|
||||
|
||||
pub fn into_sphinx_packet(self) -> SphinxPacket {
|
||||
self.sphinx_packet
|
||||
pub fn into_packet(self) -> NymPacket {
|
||||
self.packet
|
||||
}
|
||||
|
||||
pub fn packet_mode(&self) -> PacketMode {
|
||||
self.packet_mode
|
||||
pub fn packet_type(&self) -> PacketType {
|
||||
self.packet_type
|
||||
}
|
||||
|
||||
// the message is formatted as follows:
|
||||
// PACKET_MODE || FIRST_HOP || SPHINX_PACKET
|
||||
// packet_type || FIRST_HOP || packet
|
||||
pub fn try_from_bytes(b: &[u8]) -> Result<Self, MixPacketFormattingError> {
|
||||
let packet_mode = match PacketMode::try_from(b[0]) {
|
||||
let packet_type = match PacketType::try_from(b[0]) {
|
||||
Ok(mode) => mode,
|
||||
Err(_) => return Err(MixPacketFormattingError::InvalidPacketMode),
|
||||
Err(_) => return Err(MixPacketFormattingError::InvalidPacketType),
|
||||
};
|
||||
|
||||
let next_hop = NymNodeRoutingAddress::try_from_bytes(&b[1..])?;
|
||||
let addr_offset = next_hop.bytes_min_len();
|
||||
|
||||
let sphinx_packet_data = &b[addr_offset + 1..];
|
||||
let packet_size = sphinx_packet_data.len();
|
||||
let packet_data = &b[addr_offset + 1..];
|
||||
let packet_size = packet_data.len();
|
||||
if PacketSize::get_type(packet_size).is_err() {
|
||||
Err(MixPacketFormattingError::InvalidPacketSize(packet_size))
|
||||
} else {
|
||||
let sphinx_packet = match SphinxPacket::from_bytes(sphinx_packet_data) {
|
||||
Ok(packet) => packet,
|
||||
Err(_) => return Err(MixPacketFormattingError::MalformedSphinxPacket),
|
||||
let packet = match packet_type {
|
||||
PacketType::Outfox => NymPacket::outfox_from_bytes(packet_data)?,
|
||||
_ => NymPacket::sphinx_from_bytes(packet_data)?,
|
||||
};
|
||||
|
||||
Ok(MixPacket {
|
||||
next_hop,
|
||||
sphinx_packet,
|
||||
packet_mode,
|
||||
packet,
|
||||
packet_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_bytes(self) -> Vec<u8> {
|
||||
std::iter::once(self.packet_mode as u8)
|
||||
pub fn into_bytes(self) -> Result<Vec<u8>, MixPacketFormattingError> {
|
||||
Ok(std::iter::once(self.packet_type as u8)
|
||||
.chain(self.next_hop.as_bytes().into_iter())
|
||||
.chain(self.sphinx_packet.to_bytes().into_iter())
|
||||
.collect()
|
||||
.chain(self.packet.to_bytes()?.into_iter())
|
||||
.collect())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user