Compare commits

..

22 Commits

Author SHA1 Message Date
Dave Hrycyszyn 1b5cc1bb54 Changelog tweaks 2023-02-08 08:43:20 +01:00
joeiacono2021 e980441e5f Merge branch 'release/v1.1.9' of https://github.com/nymtech/nym into release/v1.1.9 2023-02-08 08:43:20 +01:00
joeiacono2021 f1214e29f9 changelog changes for release 1.1.9 2023-02-08 08:43:20 +01:00
Jon Häggblad 604742bddb changelog: add note about fix for unexpected shutdown 2023-02-08 08:43:20 +01:00
Fouad e935b2c60f Feature/nym connect health status frontend (#2969)
* filter services on rust side by gateway performance

* format rust code

* create events hook

* use events hook

* remove unused component

remove unused component

update prop names in svg

* display errors in connected screen when needed

update failed health check message
2023-02-08 08:43:20 +01:00
Fouad 4cb04e9192 link owner field to ng explorer (#2970)
* link owner field to ng explorer
2023-02-08 08:43:20 +01:00
Fouad 4fa5c7f2d3 filter services on rust side by gateway performance (#2966)
* filter services on rust side by gateway performance

* update changelog for NC
2023-02-08 08:43:20 +01:00
Mark Sinclair 3321331cb0 GitHub Actions: fix up build-and-upload-binaries-ci.yml 2023-02-08 08:43:20 +01:00
Jędrzej Stuczyński 1e031391fa introduced '/circulating-supply/total-supply-value' and '/circulating-supply/circulating-supply-value' endpoints (#2965) 2023-02-08 08:43:20 +01:00
Mark Sinclair e9f5f0223f Update build-and-upload-binaries-ci.yml 2023-02-08 08:43:20 +01:00
Mark Sinclair 8e8adc45f3 Update build-and-upload-binaries-ci.yml 2023-02-08 08:43:20 +01:00
Mark Sinclair 158ad15d37 Update build-and-upload-binaries-ci.yml 2023-02-08 08:43:20 +01:00
Mark Sinclair 9954334b30 GitHub Actions: add action to build and upload binaries to CI server 2023-02-08 08:43:20 +01:00
Jon Häggblad 8ddd9e37e0 Don't drop in mixnet connection handlers (#2963) 2023-02-08 08:43:20 +01:00
Fouad d7deb9819b NymConnect - Add button animations (#2950)
* add button animations

* pulse and disable button on connecting/disconnecting status

* update button component story

* disabled hover on connecting/disconnecting

* add transition delay

fix up overflow
2023-02-08 08:43:20 +01:00
Jędrzej Stuczyński 3ec0fcb0a4 Added an option to set custom 'host' for the native client (#2939)
* Added an option to set custom 'host' for the native client

* Changelog entry
2023-02-08 08:43:20 +01:00
Pierre Dommerc ba6584e4b6 build(nc-android): prepare for apk release (#2943)
* chore(nc-android): prepare for production build

* refactor(nc-android): remove dead code

* feat(nc-android): update native color theme

* feat(nc-android): update native color theme

* build(nc-android): fix rfd version issue

* build(nc-android): fix dist dir no such file error

* fix(nc-android): post rebase changes
2023-02-08 08:43:20 +01:00
Bogdan-Ștefan Neacşu 44bec774c3 Fix typo during merge back to develop (#2956) 2023-02-08 08:43:20 +01:00
cgi-bin/ a1f15cda16 typo: electrum (#2954) 2023-02-08 08:43:20 +01:00
farbanas 2a42090eb7 fix: formatting 2023-02-08 08:43:20 +01:00
farbanas d31d4630b7 fix: wrong parameter type for addresses in generator commands (should be AccountId instead of String) 2023-02-08 08:43:20 +01:00
Fran Arbanas a1890e49cf Update CHANGELOG.md 2023-02-08 08:43:20 +01:00
531 changed files with 5936 additions and 18626 deletions
+6 -2
View File
@@ -39,14 +39,18 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: 16
- name: Matrix - Node Install
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: security
NYM_PROJECT_NAME: "Daily security report"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "security"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
+6 -2
View File
@@ -43,10 +43,10 @@ jobs:
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/ts-${{ env.GITHUB_REF_SLUG }}-example
EXCLUDE: "/dist/, /node_modules/"
- name: Matrix - Node Install
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: ts-packages
NYM_PROJECT_NAME: "ts-packages"
@@ -54,6 +54,10 @@ jobs:
NYM_CI_WWW_LOCATION: "ts-${{ env.GITHUB_REF_SLUG }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-ts-packages"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
@@ -1,61 +0,0 @@
name: check-merge-conflicts
# Check that the latest release branch merges into master and develop without
# any conflicts that git is not able to resolve
on:
workflow_dispatch:
schedule:
- cron: '5 6 * * *'
jobs:
get_release:
runs-on: ubuntu-latest
outputs:
output1: ${{ steps.step2.outputs.latest_release }}
steps:
- name: Check out repository code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set output variable to latest release branch
id: step2
run: echo "latest_release=$(git branch -r | grep -E 'release/v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n 1)" >> $GITHUB_OUTPUT
check-merge-release-into-master:
name: Check that the release branch merges into master
needs: get_release
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup git user
run: |
git config --global user.name "ci"
git config --global user.email "ci@localhost"
- name: Check merge release branch into master
run: |
./.github/workflows/support-files/git-merge-check.sh origin/master $branch1
env:
branch1: ${{needs.get_release.outputs.output1}}
check-merge-release-into-develop:
name: Check that the release branch merges into develop
needs: get_release
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup git user
run: |
git config --global user.name "ci"
git config --global user.email "ci@localhost"
- name: Check merge release branch into develop
run: |
./.github/workflows/support-files/git-merge-check.sh origin/develop $branch1
env:
branch1: ${{needs.get_release.outputs.output1}}
-134
View File
@@ -1,134 +0,0 @@
name: NC Android APK Release
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 \
libwebkit2gtk-4.0-dev \
build-essential \
unzip \
curl \
wget \
libssl-dev \
libgtk-3-dev \
squashfs-tools \
libayatana-appindicator3-dev \
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
- 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-android webpack:prod
- name: Build APK
working-directory: nym-connect-android
env:
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
WRY_ANDROID_PACKAGE: net.nymtech.nym_connect_android
WRY_ANDROID_LIBRARY: nym_connect_android
# TODO build with release profile (--release), it will requires
# to sign the APK. For now build with debug profile to avoid that
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-android/src-tauri/gen/android/nym_connect_android/app/build/outputs/apk/arm64/debug/app-arm64-debug.apk \
apk/nym-connect-arm64-debug.apk
mv nym-connect-android/src-tauri/gen/android/nym_connect_android/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: ???
+6 -2
View File
@@ -57,10 +57,10 @@ jobs:
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/ne-sb-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/"
- name: Matrix - Node Install
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: network-explorer
NYM_PROJECT_NAME: "Network Explorer"
@@ -69,6 +69,10 @@ jobs:
NYM_CI_WWW_LOCATION_STORYBOOK: "ne-sb-${{ env.GITHUB_REF_SLUG }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-network-explorer"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
+9 -5
View File
@@ -10,7 +10,7 @@ jobs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
# creates the matrix strategy from nightly_build_matrix_includes.json
- uses: actions/checkout@v3
- uses: actions/checkout@v2
- id: set-matrix
uses: JoshuaTheMiller/conditional-build-matrix@main
with:
@@ -29,7 +29,7 @@ jobs:
if: matrix.os == 'ubuntu-20.04'
- name: Check out repository code
uses: actions/checkout@v3
uses: actions/checkout@v2
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
@@ -147,17 +147,17 @@ jobs:
- name: Collect jobs status
uses: technote-space/workflow-conclusion-action@v2
- name: Check out repository code
uses: actions/checkout@v3
uses: actions/checkout@v2
- name: install npm
uses: actions/setup-node@v3
if: env.WORKFLOW_CONCLUSION == 'failure'
with:
node-version: 16
- name: Matrix - Node Install
- name: Keybase - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
- name: Keybase - Send Notification
if: env.WORKFLOW_CONCLUSION == 'failure'
env:
NYM_NOTIFICATION_KIND: nightly
@@ -165,6 +165,10 @@ jobs:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-nightly"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
+16 -24
View File
@@ -28,7 +28,7 @@ jobs:
run: git fetch --all
- name: Set output variable to latest release branch
id: step2
run: echo "latest_release=$(git branch -r | grep -E 'release/v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n 1 | sed 's/ origin\///')" >> $GITHUB_OUTPUT
run: echo "latest_release=$(git branch -r | grep -E 'release/v[0-9]+\.[0-9]+\.[0-9]+' | tail -n 1 | sed 's/ origin\///')" >> $GITHUB_OUTPUT
build:
needs: [get_release,matrix_prep]
strategy:
@@ -54,12 +54,6 @@ jobs:
override: true
components: rustfmt, clippy
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
@@ -72,18 +66,6 @@ jobs:
with:
command: clean
- name: Build all examples
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --examples
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run all tests
uses: actions-rs/cargo@v1
with:
@@ -92,7 +74,7 @@ jobs:
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
@@ -101,7 +83,13 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace -- --ignored
args: --workspace --all-features -- --ignored
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
@@ -114,7 +102,7 @@ jobs:
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --workspace
args: --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
@@ -168,11 +156,11 @@ jobs:
if: env.WORKFLOW_CONCLUSION == 'failure'
with:
node-version: 16
- name: Matrix - Node Install
- name: Keybase - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
- name: Keybase - Send Notification
if: env.WORKFLOW_CONCLUSION == 'failure'
env:
NYM_NOTIFICATION_KIND: nightly
@@ -180,6 +168,10 @@ jobs:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH_NAME: "${{needs.get_release.outputs.output1}}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-nightly-release"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
+16 -24
View File
@@ -28,7 +28,7 @@ jobs:
run: git fetch --all
- name: Set output variable to latest release branch
id: step2
run: echo "latest_release=$(git branch -r | grep -E 'release/v[0-9]+\.[0-9]+\.[0-9]+$' | sort -V | tail -n 2 | head -n 1 | sed 's/ origin\///')" >> $GITHUB_OUTPUT
run: echo "latest_release=$(git branch -r | grep -E 'release/v[0-9]+\.[0-9]+\.[0-9]+' | tail -n 2 | head -n 1 | sed 's/ origin\///')" >> $GITHUB_OUTPUT
build:
needs: [get_release,matrix_prep]
strategy:
@@ -54,12 +54,6 @@ jobs:
override: true
components: rustfmt, clippy
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
@@ -72,18 +66,6 @@ jobs:
with:
command: clean
- name: Build all examples
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --examples
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run all tests
uses: actions-rs/cargo@v1
with:
@@ -92,7 +74,7 @@ jobs:
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
@@ -101,7 +83,13 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace -- --ignored
args: --workspace --all-features -- --ignored
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
@@ -114,7 +102,7 @@ jobs:
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --workspace
args: --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
@@ -168,11 +156,11 @@ jobs:
if: env.WORKFLOW_CONCLUSION == 'failure'
with:
node-version: 16
- name: Matrix - Node Install
- name: Keybase - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
- name: Keybase - Send Notification
if: env.WORKFLOW_CONCLUSION == 'failure'
env:
NYM_NOTIFICATION_KIND: nightly
@@ -180,6 +168,10 @@ jobs:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH_NAME: "${{needs.get_release.outputs.output1}}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-nightly-release"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
+1 -1
View File
@@ -10,7 +10,7 @@ env:
jobs:
publish-nym-cli:
if: ${{ startsWith(github.ref, 'refs/tags/nym-cli-') && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') }}
if: ${{ startsWith(github.ref, 'refs/tags/nym-cli-') && (github.event_name == 'release' || github.event_name = 'workflow_dispatch') }}
strategy:
fail-fast: false
matrix:
+6 -2
View File
@@ -39,10 +39,10 @@ jobs:
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/nym-connect-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/"
- name: Matrix - Node Install
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: nym-connect
NYM_PROJECT_NAME: "nym-connect"
@@ -50,6 +50,10 @@ jobs:
NYM_CI_WWW_LOCATION: "nym-connect-${{ env.GITHUB_REF_SLUG }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-nym-connect"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
+6 -2
View File
@@ -35,10 +35,10 @@ jobs:
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/wallet-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/"
- name: Matrix - Node Install
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: nym-wallet
NYM_PROJECT_NAME: "nym-wallet"
@@ -46,6 +46,10 @@ jobs:
NYM_CI_WWW_LOCATION: "wallet-${{ env.GITHUB_REF_SLUG }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-nym-wallet"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
+5 -1
View File
@@ -1,3 +1,7 @@
KEYBASE_NYM_CHANNEL=
KEYBASE_NYMBOT_USERNAME=
KEYBASE_NYMBOT_PAPERKEY=
MATRIX_SERVER=
MATRIX_ROOM=
MATRIX_ROOM_OF_SHAME=
@@ -35,4 +39,4 @@ NYM_CI_WWW_BASE=example.com
# Nightly builds
WORKFLOW_CONCLUSION=success
SHOW_DEBUG=true
SHOW_DEBUG=true
+9 -10
View File
@@ -4,7 +4,7 @@ This is a collection of scripts and files to support GitHub Actions.
## Sending Notifications
These scripts send CI notifications to Matrix by creating messages from templates and env vars passed from GitHub Actions.
These scripts send CI notifications to Keybase by creating messages from templates and env vars passed from GitHub Actions.
### Adding notifications to a GitHub Action
@@ -19,11 +19,10 @@ jobs:
env:
NYM_NOTIFICATION_KIND: "my-component"
GIT_BRANCH: "${GITHUB_REF##*/}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-network-explorer"
IS_SUCCESS: "${{ job.status == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
@@ -35,8 +34,8 @@ Notifications are run by adding the snippet above to a GitHub Action, and:
1. Installing node packages needed at run time
2. Set the env vars as required:
- `NYM_NOTIFICATION_KIND` matches the directory in `.github/workflows/support-files/${NYM_NOTIFICATION_KIND}` to provide the templates and extra scripting in `index.js`
- Matrix credentials, room and other env vars for the status of the build and repo
3. Replacing the default entry point shell script on the `keybaseio/client:stable-node` docker image to run `.github/workflows/support-files/notifications/entry_point.sh`
- Keybase credentials, channel and other env vars for the status of the build and repo
3. Replacing the default entry point shell script on the `keybaseio/client:stable-node` docker image to run `.github/workflows/support-files/notifications/entry_point.sh`
### Running locally
@@ -44,7 +43,7 @@ You will need:
- Node 16 LTS
- npm
Copy `.github/workflows/support-files/.env.example` to `.github/workflows/support-files/.env` and valid Matrix credentials.
Copy `.github/workflows/support-files/.env.example` to `.github/workflows/support-files/.env` and valid Keybase credentials.
Then run `npm install` to get dependencies.
@@ -56,4 +55,4 @@ npm install
cp .env.example .env
vi .env
npm run dev
```
```
@@ -1,62 +0,0 @@
#!/usr/bin/env bash
#
# Basic usage:
# ./git-merge-check origin/develop origin/release/v1.1.9
#
set -x
set -o nounset
set -o pipefail
# Start from branch ...
branch1=$1
# ... and try to merge in
branch2=$2
echo "Checking if $branch2 merges without conflicts into $branch1..."
git checkout -q $branch1 || exit 1
# There are two options here as far as I see on what we should check for. Either
#
# (A) check for CONFLICT in any file except whitelist (such as .lock files)
# (B) check for "Automatic merge failed"
#
# Both of these options have drawbacks.
#
# The first (A) has the problem in that maybe we don't want to fail if the
# changes can be automatically merged (duh), but at least we are not pestered
# about constant lock file changes.
# The second (B) has the problem that it's difficult to filter out automatic
# merge fails for files we don't care about (.lock files).
#
# The ideal solution would be to check for automatic merge fails for files
# except those on a whitelist (e.g. lock files).
# For now I choose to use (B) here, because I hope it might be less noisy
# Alternative A
#output=$(git merge --no-commit --no-ff $branch2 | grep -v .lock)
#merge_failed=$(echo $output | grep -v "CONFLICT")
#return_code=$?
# Alternative B
output=$(git merge --no-commit --no-ff $branch2)
merge_failed=$(echo $output | grep -v "Automatic merge failed")
return_code=$?
# Restore
git merge --abort
git checkout -q -
if [ $return_code -eq 0 ]; then
echo "Merge check success"
else
echo "Merge check failed"
fi
exit $return_code
@@ -1,5 +1,6 @@
require('dotenv').config();
const Bot = require('keybase-bot');
const { sendMatrixMessage } = require('./send_message_to_matrix');
let context = {
@@ -23,6 +24,21 @@ function validateContext() {
'Please set env var NYM_PROJECT_NAME with the project name for displaying in notification messages',
);
}
if (!context.env.KEYBASE_NYM_CHANNEL) {
throw new Error(
'Please set env var KEYBASE_NYM_CHANNEL with the channel name for the notification message',
);
}
if (!context.env.KEYBASE_NYMBOT_USERNAME) {
throw new Error(
'Username is not defined. Please set env var KEYBASE_NYMBOT_USERNAME',
);
}
if (!context.env.KEYBASE_NYMBOT_PAPERKEY) {
throw new Error(
'Paperkey is not defined. Please set env var KEYBASE_NYMBOT_PAPERKEY',
);
}
if (context.env.MATRIX_ROOM) {
if (!context.env.MATRIX_SERVER) {
throw new Error(
@@ -68,6 +84,12 @@ function createTemplateContext() {
context.kind = context.env.NYM_NOTIFICATION_KIND;
context.keybase = {
channel: context.env.KEYBASE_NYM_CHANNEL,
username: context.env.KEYBASE_NYMBOT_USERNAME,
paperkey: context.env.KEYBASE_NYMBOT_PAPERKEY,
};
if (!context.env.GIT_BRANCH_NAME) {
context.env.GIT_BRANCH_NAME = context.env.GITHUB_REF.split('/')
.slice(2)
@@ -77,6 +99,40 @@ function createTemplateContext() {
context.status = process.env.IS_SUCCESS === 'true' ? 'success' : 'failure';
}
async function sendKeybaseMessage(messageBody) {
const bot = new Bot();
try {
console.log(
`Initialising keybase with user "${
context.keybase.username
}" and key: "${'*'.repeat(context.keybase.paperkey.length)}"...`,
);
await bot.init(context.keybase.username, context.keybase.paperkey, {
verbose: false,
});
const channel = {
name: context.env.KEYBASE_NYMBOT_TEAM || 'nymtech_bot',
membersType: 'team',
topicName: context.keybase.channel,
topic_type: 'CHAT',
};
const message = {
body: messageBody,
};
console.log(`Sending to ${channel.name}#${channel.topicName}...`);
await bot.chat.send(channel, message);
console.log('Message sent!');
} catch (error) {
console.error(error);
process.exitCode = -1;
} finally {
await bot.deinit();
}
}
/**
* Uses the `kind` set in the context to process the context and generate a notification message
* @returns {Promise<string>} A string notification message body
@@ -113,6 +169,7 @@ async function main() {
console.log(messageBody);
console.log('-----------------------------------------');
}
await sendKeybaseMessage(messageBody);
if(context.env.MATRIX_ROOM) {
await sendMatrixMessage(context, messageBody, context.env.MATRIX_ROOM)
}
+3 -2
View File
@@ -1,6 +1,6 @@
{
"name": "send-matrix-message",
"description": "Sends a notification message with the matrix sdk",
"name": "send-keybase-message",
"description": "Sends a notification message with the keybase package that fails when piped into the keybase CLI",
"version": "1.0.0",
"private": true,
"scripts": {
@@ -10,6 +10,7 @@
"dependencies": {
"dotenv": "^16.0.0",
"handlebars": "^4.7.7",
"keybase-bot": "^3.6.1",
"matrix-js-sdk": "^9.3.0",
"node-localstorage": "^2.1.6",
"octokit": "^1.7.1",
+7 -3
View File
@@ -24,11 +24,11 @@ jobs:
- name: Setup yarn
run: npm install -g yarn
- name: Lint
run: yarn && yarn build && yarn lint && yarn tsc
- name: Matrix - Node Install
run: yarn && yarn lint && yarn tsc
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: ts-packages
NYM_PROJECT_NAME: "ts-packages"
@@ -36,6 +36,10 @@ jobs:
NYM_CI_WWW_LOCATION: "ts-${{ env.GITHUB_REF_SLUG }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-ts-packages"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
+1 -1
View File
@@ -42,4 +42,4 @@ envs/qwerty.env
Cargo.lock
nym-connect/Cargo.lock
.parcel-cache
**/.DS_Store
.DS_Store
+17 -37
View File
@@ -2,52 +2,26 @@
Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
# [Unreleased]
## [v1.1.10] (2023-02-21)
- Verloc listener causing mixnode unexpected shutdown ([#3038])
- rust-sdk - update API following implementation experience with the network-requester ([#3001])
- Prevent coconut deposits in incompatible states ([#2991])
- Support unavailable signer within threshold ([#2987])
- Implement DKG re-sharing ([#2935])
- contracts: add nym prefix to mixnet and vesting contract packages ([#2855])
- Introduce common interface for all service providers to allow obtaining information such as whether they're online, what binary version they're running, etc. ([#2758])
- Add client functionality to nym-network-requester ([#1900])
- nym-api: uptime rework ([#3053])
- ci: update typescript-lint.yml ([#3035])
- contracts: add nym prefix to mixnet and vesting contract packages ([#2855])
[#3038]: https://github.com/nymtech/nym/issues/3038
[#3001]: https://github.com/nymtech/nym/issues/3001
[#2991]: https://github.com/nymtech/nym/issues/2991
[#2987]: https://github.com/nymtech/nym/issues/2987
[#2935]: https://github.com/nymtech/nym/issues/2935
[#2855]: https://github.com/nymtech/nym/pull/2855
[#2758]: https://github.com/nymtech/nym/issues/2758
[#1900]: https://github.com/nymtech/nym/issues/1900
[#3053]: https://github.com/nymtech/nym/pull/3053
[#3035]: https://github.com/nymtech/nym/pull/3035
[#2855]: https://github.com/nymtech/nym/pull/2855
## [v1.1.9] (2023-02-07)
# [v1.1.9] (2023-02-07)
### Added
- Remove Coconut feature flag ([#2793])
- Separate `nym-api` endpoints with values of "total-supply" and "circulating-supply" in `nym` ([#2964])
- Add `host` option to client init ([#2912])
- Remove Coconut feature flag ([#2793])
- Don't drop in mixnet connection handler ([#2963])
### Changed
- native-client: is now capable of listening for requests on sockets different than `127.0.0.1` ([#2912]). This can be specified via `--host` flag during `init` or `run`. Alternatively a custom `host` can be set in `config.toml` file under `socket` section.
- native-client: is now capable of listening for requests on sockets different than `127.0.0.1` ([#2939]). This can be specified via `--host` flag during `init` or `run`. Alternatively a custom `host` can be set in `config.toml` file under `socket` section.
- mixnode, gateway: fix unexpected shutdown on corrupted connection ([#2963])
[#2793]: https://github.com/nymtech/nym/issues/2793
[#2912]: https://github.com/nymtech/nym/issues/2912
[#2964]: https://github.com/nymtech/nym/issues/2964
[#2963]: https://github.com/nymtech/nym/issues/3017
[#2939]: https://github.com/nymtech/nym/pull/2939
[#2963]: https://github.com/nymtech/nym/pull/2963
## [v1.1.8] (2023-01-31)
# [v1.1.8] (2023-01-31)
### Added
@@ -67,7 +41,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
[#2873]: https://github.com/nymtech/nym/issues/2873
## [v1.1.7] (2023-01-24)
# [v1.1.7] (2023-01-24)
### Added
@@ -123,6 +97,12 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
### Added
### Changed
## [v1.1.5] (2023-01-10)
### Added
- socks5: send status message for service ready, and network-requester error response in https://github.com/nymtech/nym/pull/2715
### Changed
Generated
+300 -340
View File
File diff suppressed because it is too large Load Diff
-9
View File
@@ -76,7 +76,6 @@ members = [
"integrations/bity",
"mixnode",
"sdk/rust/nym-sdk",
"service-providers/common",
"service-providers/network-requester",
"service-providers/network-statistics",
"nym-api",
@@ -106,12 +105,4 @@ homepage = "https://nymtech.net"
edition = "2021"
[workspace.dependencies]
async-trait = "0.1.63"
lazy_static = "1.4.0"
log = "0.4"
serde = "1.0.152"
serde_json = "1.0.91"
tap = "1.0.1"
thiserror = "1.0.38"
tokio = "1.24.1"
url = "2.2"
BIN
View File
Binary file not shown.
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "client-core"
version = "1.1.10"
version = "1.1.8"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
edition = "2021"
rust-version = "1.66"
@@ -26,13 +26,13 @@ time = "0.3.17"
# internal
config = { path = "../../common/config" }
client-connections = { path = "../../common/client-connections" }
nym-crypto = { path = "../../common/crypto" }
crypto = { path = "../../common/crypto" }
gateway-client = { path = "../../common/client-libs/gateway-client" }
#gateway-client = { path = "../../common/client-libs/gateway-client", default-features = false, features = ["wasm", "coconut"] }
gateway-requests = { path = "../../gateway/gateway-requests" }
nonexhaustive-delayqueue = { path = "../../common/nonexhaustive-delayqueue" }
nymsphinx = { path = "../../common/nymsphinx" }
nym-pemstore = { path = "../../common/pemstore" }
pemstore = { path = "../../common/pemstore" }
topology = { path = "../../common/topology" }
validator-client = { path = "../../common/client-libs/validator-client", default-features = false }
task = { path = "../../common/task" }
@@ -22,6 +22,7 @@ use crate::config::{Config, DebugConfig, GatewayEndpointConfig};
use crate::error::ClientCoreError;
use crate::spawn_future;
use client_connections::{ConnectionCommandReceiver, ConnectionCommandSender, LaneQueueLengths};
use crypto::asymmetric::{encryption, identity};
use futures::channel::mpsc;
use gateway_client::bandwidth::BandwidthController;
#[cfg(target_arch = "wasm32")]
@@ -31,7 +32,6 @@ use gateway_client::{
MixnetMessageSender,
};
use log::{debug, info};
use nym_crypto::asymmetric::{encryption, identity};
use nymsphinx::acknowledgements::AckKey;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::addressing::nodes::NodeIdentity;
@@ -51,22 +51,11 @@ pub mod non_wasm_helpers;
pub mod helpers;
#[derive(Clone)]
pub struct ClientInput {
pub connection_command_sender: ConnectionCommandSender,
pub input_sender: InputMessageSender,
}
impl ClientInput {
pub async fn send(
&self,
message: InputMessage,
) -> Result<(), tokio::sync::mpsc::error::SendError<InputMessage>> {
self.input_sender.send(message).await
}
}
#[derive(Clone)]
pub struct ClientOutput {
pub received_buffer_request_sender: ReceivedBufferRequestSender,
}
@@ -314,7 +303,6 @@ where
let shared_key = if self.key_manager.is_gateway_key_set() {
Some(self.key_manager.gateway_shared_key())
} else {
log::info!("Gateway key not set! Will proceed anyway.");
None
};
@@ -77,12 +77,4 @@ impl InputMessage {
lane,
}
}
pub fn lane(&self) -> &TransmissionLane {
match self {
InputMessage::Regular { lane, .. }
| InputMessage::Anonymous { lane, .. }
| InputMessage::Reply { lane, .. } => lane,
}
}
}
+13 -13
View File
@@ -2,9 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
use crate::config::persistence::key_pathfinder::ClientKeyPathfinder;
use crypto::asymmetric::{encryption, identity};
use gateway_requests::registration::handshake::SharedKeys;
use log::*;
use nym_crypto::asymmetric::{encryption, identity};
use nymsphinx::acknowledgements::AckKey;
use rand::{CryptoRng, RngCore};
use std::io;
@@ -72,17 +72,17 @@ impl KeyManager {
/// Loads previously stored client keys from the disk.
fn load_client_keys(client_pathfinder: &ClientKeyPathfinder) -> io::Result<Self> {
let identity_keypair: identity::KeyPair =
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
pemstore::load_keypair(&pemstore::KeyPairPath::new(
client_pathfinder.private_identity_key().to_owned(),
client_pathfinder.public_identity_key().to_owned(),
))?;
let encryption_keypair: encryption::KeyPair =
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
pemstore::load_keypair(&pemstore::KeyPairPath::new(
client_pathfinder.private_encryption_key().to_owned(),
client_pathfinder.public_encryption_key().to_owned(),
))?;
let ack_key: AckKey = nym_pemstore::load_key(client_pathfinder.ack_key())?;
let ack_key: AckKey = pemstore::load_key(client_pathfinder.ack_key())?;
Ok(KeyManager {
identity_keypair: Arc::new(identity_keypair),
@@ -98,7 +98,7 @@ impl KeyManager {
let mut key_manager = Self::load_client_keys(client_pathfinder)?;
let gateway_shared_key: SharedKeys =
nym_pemstore::load_key(client_pathfinder.gateway_shared_key())?;
pemstore::load_key(client_pathfinder.gateway_shared_key())?;
key_manager.gateway_shared_key = Some(Arc::new(gateway_shared_key));
@@ -113,7 +113,7 @@ impl KeyManager {
let mut key_manager = Self::load_client_keys(client_pathfinder)?;
let gateway_shared_key: Result<SharedKeys, io::Error> =
nym_pemstore::load_key(client_pathfinder.gateway_shared_key());
pemstore::load_key(client_pathfinder.gateway_shared_key());
// It's ok if the gateway key was not found
let gateway_shared_key = match gateway_shared_key {
@@ -132,27 +132,27 @@ impl KeyManager {
// it is done so for the consistency sake so that you wouldn't require an rng instance
// during `load_keys` to generate the said key.
pub fn store_keys(&self, client_pathfinder: &ClientKeyPathfinder) -> io::Result<()> {
nym_pemstore::store_keypair(
pemstore::store_keypair(
self.identity_keypair.as_ref(),
&nym_pemstore::KeyPairPath::new(
&pemstore::KeyPairPath::new(
client_pathfinder.private_identity_key().to_owned(),
client_pathfinder.public_identity_key().to_owned(),
),
)?;
nym_pemstore::store_keypair(
pemstore::store_keypair(
self.encryption_keypair.as_ref(),
&nym_pemstore::KeyPairPath::new(
&pemstore::KeyPairPath::new(
client_pathfinder.private_encryption_key().to_owned(),
client_pathfinder.public_encryption_key().to_owned(),
),
)?;
nym_pemstore::store_key(self.ack_key.as_ref(), client_pathfinder.ack_key())?;
pemstore::store_key(self.ack_key.as_ref(), client_pathfinder.ack_key())?;
match self.gateway_shared_key.as_ref() {
None => debug!("No gateway shared key available to store!"),
Some(gate_key) => {
nym_pemstore::store_key(gate_key.as_ref(), client_pathfinder.gateway_shared_key())?
pemstore::store_key(gate_key.as_ref(), client_pathfinder.gateway_shared_key())?
}
}
@@ -168,7 +168,7 @@ impl KeyManager {
))
}
Some(gate_key) => {
nym_pemstore::store_key(gate_key.as_ref(), client_pathfinder.gateway_shared_key())?
pemstore::store_key(gate_key.as_ref(), client_pathfinder.gateway_shared_key())?
}
}
@@ -342,6 +342,7 @@ where
if let Poll::Ready(Some(id)) = Pin::new(&mut self.client_connection_rx).poll_next(cx) {
match id {
ConnectionCommand::Close(id) => self.on_close_connection(id),
ConnectionCommand::ActiveConnections(_) => panic!(),
}
}
@@ -420,6 +421,7 @@ where
if let Poll::Ready(Some(id)) = Pin::new(&mut self.client_connection_rx).poll_next(cx) {
match id {
ConnectionCommand::Close(id) => self.on_close_connection(id),
ConnectionCommand::ActiveConnections(_) => panic!(),
}
}
@@ -4,13 +4,13 @@
use crate::client::replies::reply_controller::ReplyControllerSender;
use crate::client::replies::reply_storage::SentReplyKeys;
use crate::spawn_future;
use crypto::asymmetric::encryption;
use crypto::Digest;
use futures::channel::mpsc;
use futures::lock::Mutex;
use futures::StreamExt;
use gateway_client::MixnetMessageReceiver;
use log::*;
use nym_crypto::asymmetric::encryption;
use nym_crypto::Digest;
use nymsphinx::anonymous_replies::requests::{
RepliableMessage, RepliableMessageContent, ReplyMessage, ReplyMessageContent,
};
@@ -5,8 +5,6 @@ use crate::client::replies::reply_storage::backend::Empty;
use crate::client::replies::reply_storage::{CombinedReplyStorage, ReplyStorageBackend};
use async_trait::async_trait;
use std::path::PathBuf;
// well, right now we don't have the browser storage : (
// so we keep everything in memory
#[derive(Debug)]
@@ -29,18 +27,6 @@ impl Backend {
impl ReplyStorageBackend for Backend {
type StorageError = <Empty as ReplyStorageBackend>::StorageError;
async fn new(
debug_config: &crate::config::DebugConfig,
_db_path: Option<PathBuf>,
) -> Result<Self, Self::StorageError> {
Ok(Backend {
empty: Empty {
min_surb_threshold: debug_config.minimum_reply_surb_storage_threshold,
max_surb_threshold: debug_config.maximum_reply_surb_storage_threshold,
},
})
}
async fn flush_surb_storage(
&mut self,
storage: &CombinedReplyStorage,
@@ -56,9 +56,4 @@ pub enum StorageError {
details: String,
// err: Option<Box<dyn std::error::Error>>
},
#[error("failed to create storage")]
FailedToCreateStorage {
source: Box<dyn std::error::Error + Send + Sync>,
},
}
@@ -1,7 +1,6 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::base_client::non_wasm_helpers;
use crate::client::replies::reply_storage::backend::fs_backend::manager::StorageManager;
use crate::client::replies::reply_storage::backend::fs_backend::models::{
ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender,
@@ -368,20 +367,6 @@ impl Backend {
impl ReplyStorageBackend for Backend {
type StorageError = error::StorageError;
async fn new(
debug_config: &crate::config::DebugConfig,
db_path: Option<PathBuf>,
) -> Result<Self, Self::StorageError> {
non_wasm_helpers::setup_fs_reply_surb_backend(db_path, debug_config)
.await
.map_err(|err| {
log::error!("Failed to create storage: {err}");
Self::StorageError::FailedToCreateStorage {
source: Box::new(err),
}
})
}
fn is_active(&self) -> bool {
self.manager.is_active()
}
@@ -3,8 +3,8 @@
use crate::client::replies::reply_storage::backend::fs_backend::error::StorageError;
use crate::client::replies::reply_storage::key_storage::UsedReplyKey;
use nym_crypto::generic_array::typenum::Unsigned;
use nym_crypto::Digest;
use crypto::generic_array::typenum::Unsigned;
use crypto::Digest;
use nymsphinx::addressing::clients::{Recipient, RecipientBytes};
use nymsphinx::anonymous_replies::encryption_key::EncryptionKeyDigest;
use nymsphinx::anonymous_replies::requests::{AnonymousSenderTag, SENDER_TAG_SIZE};
@@ -3,7 +3,7 @@
use crate::client::replies::reply_storage::CombinedReplyStorage;
use async_trait::async_trait;
use std::{error::Error, path::PathBuf};
use std::error::Error;
use thiserror::Error;
#[cfg(target_arch = "wasm32")]
@@ -30,16 +30,6 @@ pub struct Empty {
impl ReplyStorageBackend for Empty {
type StorageError = UndefinedError;
async fn new(
debug_config: &crate::config::DebugConfig,
_db_path: Option<PathBuf>,
) -> Result<Self, Self::StorageError> {
Ok(Self {
min_surb_threshold: debug_config.minimum_reply_surb_storage_threshold,
max_surb_threshold: debug_config.maximum_reply_surb_storage_threshold,
})
}
async fn flush_surb_storage(
&mut self,
_storage: &CombinedReplyStorage,
@@ -73,11 +63,6 @@ impl ReplyStorageBackend for Empty {
pub trait ReplyStorageBackend: Sized {
type StorageError: Error + 'static;
async fn new(
debug_config: &crate::config::DebugConfig,
db_path: Option<PathBuf>,
) -> Result<Self, Self::StorageError>;
fn is_active(&self) -> bool {
true
}
+1 -6
View File
@@ -171,15 +171,10 @@ impl<T> Config<T> {
self
}
pub fn set_gateway_endpoint(&mut self, gateway_endpoint: GatewayEndpointConfig) {
pub fn with_gateway_endpoint(&mut self, gateway_endpoint: GatewayEndpointConfig) {
self.client.gateway_endpoint = gateway_endpoint;
}
pub fn with_gateway_endpoint(mut self, gateway_endpoint: GatewayEndpointConfig) -> Self {
self.client.gateway_endpoint = gateway_endpoint;
self
}
pub fn with_gateway_id<S: Into<String>>(&mut self, id: S) {
self.client.gateway_endpoint.gateway_id = id.into();
}
+1 -1
View File
@@ -1,8 +1,8 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crypto::asymmetric::identity::Ed25519RecoveryError;
use gateway_client::error::GatewayClientError;
use nym_crypto::asymmetric::identity::Ed25519RecoveryError;
use topology::NymTopologyError;
use validator_client::ValidatorClientError;
+1 -1
View File
@@ -7,11 +7,11 @@ use crate::{
error::ClientCoreError,
};
use config::NymConfig;
use crypto::asymmetric::identity;
#[cfg(target_arch = "wasm32")]
use gateway_client::wasm_mockups::SigningNyxdClient;
use gateway_client::GatewayClient;
use gateway_requests::registration::handshake::SharedKeys;
use nym_crypto::asymmetric::identity;
use rand::{seq::SliceRandom, thread_rng};
use std::{sync::Arc, time::Duration};
use tap::TapFallible;
+3 -3
View File
@@ -11,7 +11,7 @@ use serde::Serialize;
use tap::TapFallible;
use config::NymConfig;
use nym_crypto::asymmetric::{encryption, identity};
use crypto::asymmetric::{encryption, identity};
use url::Url;
use crate::client::key_manager::KeyManager;
@@ -188,7 +188,7 @@ where
pathfinder: &ClientKeyPathfinder,
) -> Result<identity::KeyPair, ClientCoreError> {
let identity_keypair: identity::KeyPair =
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
pemstore::load_keypair(&pemstore::KeyPairPath::new(
pathfinder.private_identity_key().to_owned(),
pathfinder.public_identity_key().to_owned(),
))
@@ -200,7 +200,7 @@ where
pathfinder: &ClientKeyPathfinder,
) -> Result<encryption::KeyPair, ClientCoreError> {
let sphinx_keypair: encryption::KeyPair =
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
pemstore::load_keypair(&pemstore::KeyPairPath::new(
pathfinder.private_encryption_key().to_owned(),
pathfinder.public_encryption_key().to_owned(),
))
+2 -4
View File
@@ -8,7 +8,6 @@ edition = "2021"
[dependencies]
bip39 = "1.0.1"
clap = { version = "4.0", features = ["cargo", "derive"] }
log = "0.4"
rand = "0.7.3"
serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0"
@@ -20,9 +19,8 @@ config = { path = "../../common/config" }
completions = { path = "../../common/completions" }
credentials = { path = "../../common/credentials" }
credential-storage = { path = "../../common/credential-storage" }
nym-crypto = { path = "../../common/crypto", features = ["rand", "asymmetric", "symmetric", "aes", "hashing"] }
logging = { path = "../../common/logging"}
crypto = { path = "../../common/crypto", features = ["rand", "asymmetric", "symmetric", "aes", "hashing"] }
network-defaults = { path = "../../common/network-defaults" }
nym-pemstore = { path = "../../common/pemstore" }
pemstore = { path = "../../common/pemstore" }
validator-client = { path = "../../common/client-libs/validator-client", features = ["nyxd-client"] }
+33 -82
View File
@@ -1,9 +1,8 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use clap::{ArgGroup, Args, Subcommand};
use clap::{Args, Subcommand};
use completions::ArgShell;
use log::*;
use rand::rngs::OsRng;
use std::str::FromStr;
@@ -12,21 +11,19 @@ use credential_storage::storage::Storage;
use credential_storage::PersistentStorage;
use credentials::coconut::bandwidth::{BandwidthVoucher, TOTAL_ATTRIBUTES};
use credentials::coconut::utils::obtain_aggregate_signature;
use network_defaults::VOUCHER_INFO;
use nym_crypto::asymmetric::{encryption, identity};
use crypto::asymmetric::{encryption, identity};
use network_defaults::{NymNetworkDetails, VOUCHER_INFO};
use validator_client::nyxd::traits::DkgQueryClient;
use validator_client::nyxd::tx::Hash;
use validator_client::nyxd::CosmWasmClient;
use validator_client::CoconutApiClient;
use validator_client::{CoconutApiClient, Config};
use crate::client::Client;
use crate::error::{CredentialClientError, Result};
use crate::recovery_storage::RecoveryStorage;
use crate::state::{KeyPair, State};
#[derive(Subcommand)]
pub(crate) enum Command {
/// Run the binary to obtain a credential
/// Run the binary
Run(Run),
/// Generate shell completions
@@ -37,11 +34,6 @@ pub(crate) enum Command {
}
#[derive(Args)]
#[clap(group(
ArgGroup::new("recov")
.required(true)
.args(&["amount", "recovery_mode"]),
))]
pub(crate) struct Run {
/// Home directory of the client that is supposed to use the credential.
#[clap(long)]
@@ -55,25 +47,15 @@ pub(crate) struct Run {
#[clap(long)]
pub(crate) mnemonic: String,
/// The amount of utokens the credential will hold. If recovery mode is enabled, this value
/// is not needed
#[clap(long, default_value = "0")]
/// The amount of utokens the credential will hold
#[clap(long)]
pub(crate) amount: u64,
/// Path to a directory used to store recovery files for unconsumed deposits
#[clap(long)]
pub(crate) recovery_dir: std::path::PathBuf,
/// Recovery mode, when enabled, tries to recover any deposit data dumped in recovery_dir
#[clap(long)]
pub(crate) recovery_mode: bool,
}
pub(crate) async fn deposit(nyxd_url: &str, mnemonic: &str, amount: u64) -> Result<State> {
let mut rng = OsRng;
let signing_keypair = KeyPair::from(identity::KeyPair::new(&mut rng));
let encryption_keypair = KeyPair::from(encryption::KeyPair::new(&mut rng));
let params = Parameters::new(TOTAL_ATTRIBUTES).unwrap();
let client = Client::new(nyxd_url, mnemonic);
let tx_hash = client
@@ -85,47 +67,46 @@ pub(crate) async fn deposit(nyxd_url: &str, mnemonic: &str, amount: u64) -> Resu
)
.await?;
let voucher = BandwidthVoucher::new(
&params,
amount.to_string(),
VOUCHER_INFO.to_string(),
Hash::from_str(&tx_hash).map_err(|_| CredentialClientError::InvalidTxHash)?,
identity::PrivateKey::from_base58_string(&signing_keypair.private_key)?,
encryption::PrivateKey::from_base58_string(&encryption_keypair.private_key)?,
);
let state = State { voucher, params };
let state = State {
amount,
tx_hash,
signing_keypair,
encryption_keypair,
};
Ok(state)
}
pub(crate) async fn get_credential<C: Clone + CosmWasmClient + Send + Sync>(
state: &State,
client: validator_client::Client<C>,
shared_storage: PersistentStorage,
) -> Result<()> {
pub(crate) async fn get_credential(state: &State, shared_storage: PersistentStorage) -> Result<()> {
let network_details = NymNetworkDetails::new_from_env();
let config = Config::try_from_nym_network_details(&network_details)?;
let client = validator_client::Client::new_query(config)?;
let epoch_id = client.nyxd.get_current_epoch().await?.epoch_id;
let threshold = client
.nyxd
.get_current_epoch_threshold()
.await?
.ok_or(CredentialClientError::NoThreshold)?;
let coconut_api_clients = CoconutApiClient::all_coconut_api_clients(&client, epoch_id).await?;
let params = Parameters::new(TOTAL_ATTRIBUTES).unwrap();
let bandwidth_credential_attributes = BandwidthVoucher::new(
&params,
state.amount.to_string(),
VOUCHER_INFO.to_string(),
Hash::from_str(&state.tx_hash).map_err(|_| CredentialClientError::InvalidTxHash)?,
identity::PrivateKey::from_base58_string(&state.signing_keypair.private_key)?,
encryption::PrivateKey::from_base58_string(&state.encryption_keypair.private_key)?,
);
let signature = obtain_aggregate_signature(
&state.params,
&state.voucher,
&params,
&bandwidth_credential_attributes,
&coconut_api_clients,
threshold,
)
.await?;
info!("Signature: {:?}", signature.to_bs58());
println!("Signature: {:?}", signature.to_bs58());
shared_storage
.insert_coconut_credential(
state.voucher.get_voucher_value(),
state.amount.to_string(),
VOUCHER_INFO.to_string(),
state.voucher.get_private_attributes()[0].to_bs58(),
state.voucher.get_private_attributes()[1].to_bs58(),
bandwidth_credential_attributes.get_private_attributes()[0].to_bs58(),
bandwidth_credential_attributes.get_private_attributes()[1].to_bs58(),
signature.to_bs58(),
epoch_id.to_string(),
)
@@ -133,33 +114,3 @@ pub(crate) async fn get_credential<C: Clone + CosmWasmClient + Send + Sync>(
Ok(())
}
pub(crate) async fn recover_credentials<C: Clone + CosmWasmClient + Send + Sync>(
client: validator_client::Client<C>,
recovery_storage: &RecoveryStorage,
shared_storage: PersistentStorage,
) -> Result<()> {
for voucher in recovery_storage.unconsumed_vouchers()? {
let state = State {
voucher,
params: Parameters::new(TOTAL_ATTRIBUTES).unwrap(),
};
if let Err(e) = get_credential(&state, client.clone(), shared_storage.clone()).await {
error!(
"Could not recover deposit {} due to {:?}, try again later",
state.voucher.tx_hash(),
e
)
} else {
info!(
"Converted deposit {} to a credential, removing recovery data for it",
state.voucher.tx_hash()
);
if let Err(e) = recovery_storage.remove_voucher(state.voucher.tx_hash().to_string()) {
warn!("Could not remove recovery data - {:?}", e);
}
}
}
Ok(())
}
+2 -12
View File
@@ -1,13 +1,12 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::time::SystemTimeError;
use thiserror::Error;
use credential_storage::error::StorageError;
use credentials::error::Error as CredentialError;
use nym_crypto::asymmetric::encryption::KeyRecoveryError;
use nym_crypto::asymmetric::identity::Ed25519RecoveryError;
use crypto::asymmetric::encryption::KeyRecoveryError;
use crypto::asymmetric::identity::Ed25519RecoveryError;
use validator_client::nyxd::error::NyxdError;
use validator_client::ValidatorClientError;
@@ -15,9 +14,6 @@ pub type Result<T> = std::result::Result<T, CredentialClientError>;
#[derive(Error, Debug)]
pub enum CredentialClientError {
#[error("IO error: {0}")]
IOError(#[from] std::io::Error),
#[error("Nyxd error: {0}")]
Nyxd(#[from] NyxdError),
@@ -38,10 +34,4 @@ pub enum CredentialClientError {
#[error("Could not use shared storage")]
SharedStorageError(#[from] StorageError),
#[error("Could not get system time")]
SysTimeError(#[from] SystemTimeError),
#[error("Threshold not set yet")]
NoThreshold,
}
+3 -65
View File
@@ -4,25 +4,15 @@
mod client;
mod commands;
mod error;
mod recovery_storage;
mod state;
use commands::*;
use completions::fig_generate;
use config::{DATA_DIR, DB_FILE_NAME};
use error::Result;
use log::*;
use network_defaults::{setup_env, NymNetworkDetails};
use std::process::exit;
use std::time::{Duration, SystemTime};
use network_defaults::setup_env;
use clap::{CommandFactory, Parser};
use logging::setup_logging;
use validator_client::nyxd::traits::DkgQueryClient;
use validator_client::nyxd::CosmWasmClient;
use validator_client::Config;
const SAFETY_BUFFER_SECS: u64 = 60; // 1 minute
#[derive(Parser)]
#[clap(author = "Nymtech", version, about)]
@@ -35,36 +25,9 @@ struct Cli {
pub(crate) command: Command,
}
async fn block_until_coconut_is_available<C: Clone + CosmWasmClient + Send + Sync>(
client: &validator_client::Client<C>,
) -> Result<()> {
loop {
let epoch = client.nyxd.get_current_epoch().await?;
let current_timestamp_secs = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)?
.as_secs();
if epoch.state.is_final() {
if current_timestamp_secs + SAFETY_BUFFER_SECS >= epoch.finish_timestamp.seconds() {
info!("In the next {} minute(s), a transition will take place in the coconut system. Deposits should be halted in this time for safety reasons.", SAFETY_BUFFER_SECS / 60);
exit(0);
}
break;
} else {
// Use 20 additional seconds to avoid the exact moment of going into the final epoch state
let secs_until_final = epoch.final_timestamp_secs() + 20 - current_timestamp_secs;
info!("Approximately {} seconds until coconut is available. Sleeping until then. You can safely kill the process at any moment.", secs_until_final);
std::thread::sleep(Duration::from_secs(secs_until_final));
}
}
Ok(())
}
#[tokio::main]
async fn main() -> Result<()> {
let args = Cli::parse();
setup_logging();
setup_env(args.config_env_file.as_ref());
let bin_name = "nym-credential-client";
@@ -72,34 +35,9 @@ async fn main() -> Result<()> {
Command::Run(r) => {
let db_path = r.client_home_directory.join(DATA_DIR).join(DB_FILE_NAME);
let shared_storage = credential_storage::initialise_storage(db_path).await;
let recovery_storage = recovery_storage::RecoveryStorage::new(r.recovery_dir)?;
let network_details = NymNetworkDetails::new_from_env();
let config = Config::try_from_nym_network_details(&network_details)?;
let client = validator_client::Client::new_query(config)?;
block_until_coconut_is_available(&client).await?;
info!("Starting depositing funds, don't kill the process");
if !r.recovery_mode {
let state = deposit(&r.nyxd_url, &r.mnemonic, r.amount).await?;
if get_credential(&state, client, shared_storage)
.await
.is_err()
{
warn!("Failed to obtain credential. Dumping recovery data.",);
match recovery_storage.insert_voucher(&state.voucher) {
Ok(file_path) => {
warn!("Dumped recovery data to {:?}. Try using recovery mode to convert it to a credential", file_path);
}
Err(e) => {
error!("Could not dump recovery data to file system due to {:?}, the deposit will be lost!", e)
}
}
}
} else {
recover_credentials(client, &recovery_storage, shared_storage).await?;
}
let state = deposit(&r.nyxd_url, &r.mnemonic, r.amount).await?;
get_credential(&state, shared_storage).await?;
}
Command::Completions(c) => c.generate(&mut crate::Cli::command(), bin_name),
Command::GenerateFigSpec => fig_generate(&mut crate::Cli::command(), bin_name),
@@ -1,56 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use credentials::coconut::bandwidth::BandwidthVoucher;
use std::fs::{create_dir_all, read_dir, File};
use std::io::{Read, Write};
use std::path::PathBuf;
pub struct RecoveryStorage {
recovery_dir: PathBuf,
}
impl RecoveryStorage {
pub fn new(recovery_dir: PathBuf) -> std::io::Result<Self> {
create_dir_all(&recovery_dir)?;
Ok(Self { recovery_dir })
}
pub fn unconsumed_vouchers(&self) -> std::io::Result<impl Iterator<Item = BandwidthVoucher>> {
Ok(read_dir(&self.recovery_dir)?
.filter_map(|entry| entry.ok())
.filter_map(|entry| {
let path = entry.path();
if path.is_file() {
Some(path)
} else {
None
}
})
.filter_map(|path| File::open(path).ok())
.filter_map(|mut f| {
let mut buff = Vec::new();
if f.read_to_end(&mut buff).is_ok() {
Some(buff)
} else {
None
}
})
.filter_map(|buff| BandwidthVoucher::try_from_bytes(&buff).ok()))
}
pub fn insert_voucher(&self, voucher: &BandwidthVoucher) -> std::io::Result<PathBuf> {
let file_name = voucher.tx_hash().to_string();
let file_path = self.recovery_dir.join(file_name);
let mut file = File::create(&file_path)?;
let buff = voucher.to_bytes();
file.write_all(&buff)?;
Ok(file_path)
}
pub fn remove_voucher(&self, file_name: String) -> std::io::Result<()> {
let file_path = self.recovery_dir.join(file_name);
std::fs::remove_file(file_path)
}
}
+8 -5
View File
@@ -1,11 +1,11 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use coconut_interface::Parameters;
use credentials::coconut::bandwidth::BandwidthVoucher;
use serde::{Deserialize, Serialize};
use nym_crypto::asymmetric::{encryption, identity};
use crypto::asymmetric::{encryption, identity};
#[derive(Clone, Debug, Deserialize, Serialize)]
pub(crate) struct KeyPair {
pub public_key: String,
pub private_key: String,
@@ -29,7 +29,10 @@ impl From<encryption::KeyPair> for KeyPair {
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub(crate) struct State {
pub voucher: BandwidthVoucher,
pub params: Parameters,
pub amount: u64,
pub tx_hash: String,
pub signing_keypair: KeyPair,
pub encryption_keypair: KeyPair,
}
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.1.10"
version = "1.1.8"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
@@ -42,13 +42,13 @@ config = { path = "../../common/config" }
completions = { path = "../../common/completions" }
credential-storage = { path = "../../common/credential-storage" }
credentials = { path = "../../common/credentials" }
nym-crypto = { path = "../../common/crypto" }
crypto = { path = "../../common/crypto" }
logging = { path = "../../common/logging"}
gateway-client = { path = "../../common/client-libs/gateway-client" }
gateway-requests = { path = "../../gateway/gateway-requests" }
network-defaults = { path = "../../common/network-defaults" }
nymsphinx = { path = "../../common/nymsphinx" }
nym-pemstore = { path = "../../common/pemstore" }
pemstore = { path = "../../common/pemstore" }
task = { path = "../../common/task" }
topology = { path = "../../common/topology" }
validator-client = { path = "../../common/client-libs/validator-client", features = ["nyxd-client"] }
+3 -5
View File
@@ -2,7 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
use crate::client::config::template::config_template;
use client_core::config::ClientCoreConfigTrait;
pub use client_core::config::Config as BaseConfig;
pub use client_core::config::MISSING_VALUE;
use client_core::config::{ClientCoreConfigTrait, DebugConfig};
use config::defaults::DEFAULT_WEBSOCKET_LISTENING_PORT;
use config::{NymConfig, OptionalSet};
use serde::{Deserialize, Serialize};
@@ -11,10 +13,6 @@ use std::net::{IpAddr, Ipv4Addr};
use std::path::PathBuf;
use std::str::FromStr;
pub use client_core::config::Config as BaseConfig;
pub use client_core::config::MISSING_VALUE;
pub use client_core::config::{DebugConfig, GatewayEndpointConfig};
mod template;
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone, Copy)]
+9 -52
View File
@@ -11,22 +11,19 @@ use client_core::client::base_client::{
non_wasm_helpers, BaseClientBuilder, ClientInput, ClientOutput, ClientState,
};
use client_core::client::inbound_messages::InputMessage;
use client_core::client::received_buffer::{
ReceivedBufferMessage, ReceivedBufferRequestSender, ReconstructedMessagesReceiver,
};
use client_core::client::key_manager::KeyManager;
use client_core::client::received_buffer::{ReceivedBufferMessage, ReconstructedMessagesReceiver};
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use futures::channel::mpsc;
use gateway_client::bandwidth::BandwidthController;
use log::*;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::anonymous_replies::requests::AnonymousSenderTag;
use nymsphinx::receiver::ReconstructedMessage;
use task::TaskManager;
use tokio::sync::watch::error::SendError;
use validator_client::nyxd::QueryNyxdClient;
pub use client_core::client::key_manager::KeyManager;
pub use nymsphinx::addressing::clients::Recipient;
pub use nymsphinx::receiver::ReconstructedMessage;
pub mod config;
pub(crate) mod config;
pub struct SocketClient {
/// Client configuration options, including, among other things, packet sending rates,
@@ -48,13 +45,6 @@ impl SocketClient {
}
}
pub fn new_with_keys(config: Config, key_manager: KeyManager) -> Self {
SocketClient {
config,
key_manager,
}
}
async fn create_bandwidth_controller(config: &Config) -> BandwidthController<QueryNyxdClient> {
let details = network_defaults::NymNetworkDetails::new_from_env();
let mut client_config = validator_client::Config::try_from_nym_network_details(&details)
@@ -130,17 +120,10 @@ impl SocketClient {
return Err(ClientError::InvalidSocketMode);
}
// don't create bandwidth controller if credentials are disabled
let bandwidth_controller = if self.config.get_base().get_disabled_credentials_mode() {
None
} else {
Some(Self::create_bandwidth_controller(&self.config).await)
};
let base_builder = BaseClientBuilder::new_from_base_config(
self.config.get_base(),
self.key_manager,
bandwidth_controller,
Some(Self::create_bandwidth_controller(&self.config).await),
non_wasm_helpers::setup_fs_reply_surb_backend(
Some(self.config.get_base().get_reply_surb_database_path()),
self.config.get_debug_settings(),
@@ -174,17 +157,10 @@ impl SocketClient {
return Err(ClientError::InvalidSocketMode);
}
// don't create bandwidth controller if credentials are disabled
let bandwidth_controller = if self.config.get_base().get_disabled_credentials_mode() {
None
} else {
Some(Self::create_bandwidth_controller(&self.config).await)
};
let base_client = BaseClientBuilder::new_from_base_config(
self.config.get_base(),
self.key_manager,
bandwidth_controller,
Some(Self::create_bandwidth_controller(&self.config).await),
non_wasm_helpers::setup_fs_reply_surb_backend(
Some(self.config.get_base().get_reply_surb_database_path()),
self.config.get_debug_settings(),
@@ -192,8 +168,6 @@ impl SocketClient {
.await?,
);
let address = base_client.as_mix_recipient();
let mut started_client = base_client.start_base().await?;
let client_input = started_client.client_input.register_producer();
let client_output = started_client.client_output.register_consumer();
@@ -211,38 +185,21 @@ impl SocketClient {
Ok(DirectClient {
client_input,
_received_buffer_request_sender: client_output.received_buffer_request_sender,
reconstructed_receiver,
address,
shutdown_notifier: started_client.task_manager,
_shutdown_notifier: started_client.task_manager,
})
}
}
pub struct DirectClient {
client_input: ClientInput,
// make sure to not drop the channel
_received_buffer_request_sender: ReceivedBufferRequestSender,
reconstructed_receiver: ReconstructedMessagesReceiver,
address: Recipient,
// we need to keep reference to this guy otherwise things will start dropping
shutdown_notifier: TaskManager,
_shutdown_notifier: TaskManager,
}
impl DirectClient {
pub fn address(&self) -> &Recipient {
&self.address
}
pub fn signal_shutdown(&self) -> Result<(), SendError<()>> {
self.shutdown_notifier.signal_shutdown()
}
pub async fn wait_for_shutdown(&mut self) {
self.shutdown_notifier.wait_for_shutdown().await
}
/// EXPERIMENTAL DIRECT RUST API
/// It's untested and there are absolutely no guarantees about it (but seems to have worked
/// well enough in local tests)
+4 -4
View File
@@ -8,7 +8,7 @@ use crate::{
};
use clap::Args;
use config::NymConfig;
use nym_crypto::asymmetric::identity;
use crypto::asymmetric::identity;
use nymsphinx::addressing::clients::Recipient;
use serde::Serialize;
use std::fmt::Display;
@@ -31,7 +31,7 @@ pub(crate) struct Init {
force_register_gateway: bool,
/// Comma separated list of rest endpoints of the nyxd validators
#[clap(long, alias = "nyxd_validators", value_delimiter = ',', hide = true)]
#[clap(long, alias = "nymd_validators", value_delimiter = ',')]
nyxd_urls: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the API validators
@@ -62,7 +62,7 @@ pub(crate) struct Init {
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[clap(long, hide = true)]
#[clap(long)]
enabled_credentials_mode: Option<bool>,
/// Save a summary of the initialization to a json file
@@ -147,7 +147,7 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> {
.await
.tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?;
config.get_base_mut().set_gateway_endpoint(gateway);
config.get_base_mut().with_gateway_endpoint(gateway);
config.save_to_file(None).tap_err(|_| {
log::error!("Failed to save the config file");
+3 -3
View File
@@ -12,8 +12,8 @@ use crate::{
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::identity;
use log::*;
use nym_crypto::asymmetric::identity;
use version_checker::is_minor_version_compatible;
#[derive(Args, Clone)]
@@ -23,7 +23,7 @@ pub(crate) struct Run {
id: String,
/// Comma separated list of rest endpoints of the nyxd validators
#[clap(long, alias = "nyxd_validators", value_delimiter = ',', hide = true)]
#[clap(long, alias = "nymd_validators", value_delimiter = ',')]
nyxd_urls: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the API validators
@@ -59,7 +59,7 @@ pub(crate) struct Run {
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[clap(long, hide = true)]
#[clap(long)]
enabled_credentials_mode: Option<bool>,
}
+5 -6
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-socks5-client"
version = "1.1.10"
version = "1.1.8"
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"
@@ -19,8 +19,8 @@ log = { workspace = true }
pin-project = "1.0"
pretty_env_logger = "0.4"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
serde_json = { workspace = true }
serde = { version = "1.0", features = ["derive"] } # for config serialization/deserialization
serde_json = "1.0.89"
tap = "1.0.1"
thiserror = "1.0.34"
tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] }
@@ -36,16 +36,15 @@ completions = { path = "../../common/completions" }
credential-storage = { path = "../../common/credential-storage", optional = true }
mobile-storage = { path = "../../common/mobile-storage", optional = true }
credentials = { path = "../../common/credentials" }
nym-crypto = { path = "../../common/crypto" }
crypto = { path = "../../common/crypto" }
logging = { path = "../../common/logging"}
gateway-client = { path = "../../common/client-libs/gateway-client" }
gateway-requests = { path = "../../gateway/gateway-requests" }
network-defaults = { path = "../../common/network-defaults" }
nymsphinx = { path = "../../common/nymsphinx" }
ordered-buffer = { path = "../../common/socks5/ordered-buffer" }
nym-pemstore = { path = "../../common/pemstore" }
pemstore = { path = "../../common/pemstore" }
proxy-helpers = { path = "../../common/socks5/proxy-helpers" }
service-providers-common = { path = "../../service-providers/common" }
socks5-requests = { path = "../../common/socks5/requests" }
task = { path = "../../common/task" }
topology = { path = "../../common/topology" }
+1 -34
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::config::template::config_template;
@@ -9,8 +9,6 @@ use config::defaults::DEFAULT_SOCKS5_LISTENING_PORT;
use config::{NymConfig, OptionalSet};
use nymsphinx::addressing::clients::Recipient;
use serde::{Deserialize, Serialize};
use service_providers_common::interface::ProviderInterfaceVersion;
use socks5_requests::Socks5ProtocolVersion;
use std::fmt::Debug;
use std::path::PathBuf;
use std::str::FromStr;
@@ -92,16 +90,6 @@ impl Config {
self
}
pub fn with_provider_interface_version(mut self, version: ProviderInterfaceVersion) -> Self {
self.socks5.provider_interface_version = version;
self
}
pub fn with_socks5_protocol_version(mut self, version: Socks5ProtocolVersion) -> Self {
self.socks5.socks5_protocol_version = version;
self
}
pub fn with_anonymous_replies(mut self, anonymous_replies: bool) -> Self {
self.socks5.send_anonymously = anonymous_replies;
self
@@ -129,14 +117,6 @@ impl Config {
.expect("malformed provider address")
}
pub fn get_provider_interface_version(&self) -> ProviderInterfaceVersion {
self.socks5.provider_interface_version
}
pub fn get_socks5_protocol_version(&self) -> Socks5ProtocolVersion {
self.socks5.socks5_protocol_version
}
pub fn get_send_anonymously(&self) -> bool {
self.socks5.send_anonymously
}
@@ -207,15 +187,6 @@ pub struct Socks5 {
/// The mix address of the provider to which all requests are going to be sent.
provider_mix_address: String,
/// The version of the 'service provider' this client is going to use in its communication with the
/// specified socks5 provider.
// if in doubt, use the legacy version as initially nobody will be using the updated binaries
#[serde(default = "ProviderInterfaceVersion::new_legacy")]
provider_interface_version: ProviderInterfaceVersion,
#[serde(default = "Socks5ProtocolVersion::new_legacy")]
socks5_protocol_version: Socks5ProtocolVersion,
/// Specifies whether this client is going to use an anonymous sender tag for communication with the service provider.
/// While this is going to hide its actual address information, it will make the actual communication
/// slower and consume nearly double the bandwidth as it will require sending reply SURBs.
@@ -230,8 +201,6 @@ impl Socks5 {
Socks5 {
listening_port: DEFAULT_SOCKS5_LISTENING_PORT,
provider_mix_address: provider_mix_address.into(),
provider_interface_version: ProviderInterfaceVersion::Legacy,
socks5_protocol_version: Socks5ProtocolVersion::Legacy,
send_anonymously: false,
}
}
@@ -242,8 +211,6 @@ impl Default for Socks5 {
Socks5 {
listening_port: DEFAULT_SOCKS5_LISTENING_PORT,
provider_mix_address: "".into(),
provider_interface_version: ProviderInterfaceVersion::Legacy,
socks5_protocol_version: Socks5ProtocolVersion::Legacy,
send_anonymously: false,
}
}
-4
View File
@@ -18,7 +18,6 @@ use client_core::client::key_manager::KeyManager;
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use futures::channel::mpsc;
use futures::StreamExt;
#[cfg(not(feature = "mobile"))]
use gateway_client::bandwidth::BandwidthController;
use log::*;
use nymsphinx::addressing::clients::Recipient;
@@ -70,7 +69,6 @@ impl NymClient {
}
}
#[cfg(not(feature = "mobile"))]
async fn create_bandwidth_controller(config: &Config) -> BandwidthController<QueryNyxdClient> {
let details = network_defaults::NymNetworkDetails::new_from_env();
let mut client_config = validator_client::Config::try_from_nym_network_details(&details)
@@ -134,8 +132,6 @@ impl NymClient {
self_address,
shared_lane_queue_lengths,
socks::client::Config::new(
config.get_provider_interface_version(),
config.get_socks5_protocol_version(),
config.get_send_anonymously(),
config.get_connection_start_surbs(),
config.get_per_request_surbs(),
+4 -6
View File
@@ -8,7 +8,7 @@ use crate::{
};
use clap::Args;
use config::NymConfig;
use nym_crypto::asymmetric::identity;
use crypto::asymmetric::identity;
use nymsphinx::addressing::clients::Recipient;
use serde::Serialize;
use std::fmt::Display;
@@ -43,7 +43,7 @@ pub(crate) struct Init {
force_register_gateway: bool,
/// Comma separated list of rest endpoints of the nyxd validators
#[clap(long, alias = "nyxd_validators", value_delimiter = ',', hide = true)]
#[clap(long, alias = "nymd_validators", value_delimiter = ',')]
nyxd_urls: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the API validators
@@ -66,7 +66,7 @@ pub(crate) struct Init {
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[clap(long, hide = true)]
#[clap(long)]
enabled_credentials_mode: Option<bool>,
/// Save a summary of the initialization to a json file
@@ -153,9 +153,7 @@ pub(crate) async fn execute(args: &Init) -> Result<(), Socks5ClientError> {
.await
.tap_err(|err| eprintln!("Failed to setup gateway\nError: {err}"))?;
config.get_base_mut().set_gateway_endpoint(gateway);
// TODO: ask the service provider we specified for its interface version and set it in the config
config.get_base_mut().with_gateway_endpoint(gateway);
config.save_to_file(None).tap_err(|_| {
log::error!("Failed to save the config file");
+3 -3
View File
@@ -9,8 +9,8 @@ use crate::{
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::identity;
use log::*;
use nym_crypto::asymmetric::identity;
use nymsphinx::addressing::clients::Recipient;
use version_checker::is_minor_version_compatible;
@@ -43,7 +43,7 @@ pub(crate) struct Run {
gateway: Option<identity::PublicKey>,
/// Comma separated list of rest endpoints of the nyxd validators
#[clap(long, alias = "nyxd_validators", value_delimiter = ',', hide = true)]
#[clap(long, alias = "nymd_validators", value_delimiter = ',')]
nyxd_urls: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the Nym APIs
@@ -65,7 +65,7 @@ pub(crate) struct Run {
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
/// with bandwidth credential requirement.
#[clap(long, hide = true)]
#[clap(long)]
enabled_credentials_mode: Option<bool>,
}
+1 -10
View File
@@ -1,6 +1,6 @@
use crate::socks::types::SocksProxyError;
use client_core::error::ClientCoreError;
use socks5_requests::{ConnectionError, ConnectionId};
use socks5_requests::ConnectionId;
#[derive(thiserror::Error, Debug)]
pub enum Socks5ClientError {
@@ -28,12 +28,3 @@ pub enum Socks5ClientError {
error: String,
},
}
impl From<ConnectionError> for Socks5ClientError {
fn from(value: ConnectionError) -> Self {
Socks5ClientError::NetworkRequesterError {
connection_id: value.connection_id,
error: value.network_requester_error,
}
}
}
+30 -132
View File
@@ -16,10 +16,7 @@ use proxy_helpers::connection_controller::{
};
use proxy_helpers::proxy_runner::ProxyRunner;
use rand::RngCore;
use service_providers_common::interface::{ProviderInterfaceVersion, RequestVersion};
use socks5_requests::{
ConnectionId, RemoteAddress, Socks5ProtocolVersion, Socks5ProviderRequest, Socks5Request,
};
use socks5_requests::{ConnectionId, Message, RemoteAddress, Request};
use std::io;
use std::net::SocketAddr;
use std::pin::Pin;
@@ -131,8 +128,6 @@ impl AsyncWrite for StreamState {
#[derive(Debug, Copy, Clone)]
pub(crate) struct Config {
provider_interface_version: ProviderInterfaceVersion,
socks5_protocol_version: Socks5ProtocolVersion,
use_surbs_for_responses: bool,
connection_start_surbs: u32,
per_request_surbs: u32,
@@ -140,27 +135,16 @@ pub(crate) struct Config {
impl Config {
pub(crate) fn new(
provider_interface_version: ProviderInterfaceVersion,
socks5_protocol_version: Socks5ProtocolVersion,
use_surbs_for_responses: bool,
connection_start_surbs: u32,
per_request_surbs: u32,
) -> Self {
Self {
provider_interface_version,
socks5_protocol_version,
use_surbs_for_responses,
connection_start_surbs,
per_request_surbs,
}
}
fn request_version(&self) -> RequestVersion<Socks5Request> {
RequestVersion {
provider_interface: self.provider_interface_version,
provider_protocol: self.socks5_protocol_version,
}
}
}
/// A client connecting to the Socks proxy server, because
@@ -189,9 +173,7 @@ impl Drop for SocksClient {
// if we never managed to start a proxy, the entry will not exist in the controller
if self.started_proxy {
self.controller_sender
.unbounded_send(ControllerCommand::Remove {
connection_id: self.connection_id,
})
.unbounded_send(ControllerCommand::Remove(self.connection_id))
.unwrap();
}
}
@@ -266,26 +248,19 @@ impl SocksClient {
// Send an error back to the client
pub async fn send_error_v4(&mut self, r: ResponseCodeV4) -> Result<(), SocksProxyError> {
self.stream
.write_all(&[SOCKS4_VERSION, r as u8])
.await
.map_err(|source| SocksProxyError::SocketWriteError { source })
self.stream.write_all(&[SOCKS4_VERSION, r as u8]).await?;
Ok(())
}
pub async fn send_error_v5(&mut self, r: ResponseCodeV5) -> Result<(), SocksProxyError> {
self.stream
.write_all(&[SOCKS5_VERSION, r as u8])
.await
.map_err(|source| SocksProxyError::SocketWriteError { source })
self.stream.write_all(&[SOCKS5_VERSION, r as u8]).await?;
Ok(())
}
/// Shutdown the `TcpStream` to the client and end the session
pub async fn shutdown(&mut self) -> Result<(), SocksProxyError> {
info!("client is shutting down its TCP stream");
self.stream
.shutdown()
.await
.map_err(|source| SocksProxyError::SocketShutdownFailure { source })?;
self.stream.shutdown().await?;
self.shutdown_listener.mark_as_success();
Ok(())
}
@@ -293,20 +268,11 @@ impl SocksClient {
/// Initializes the new client, checking that the correct Socks version (5)
/// is in use and that the client is authenticated, then runs the request.
pub async fn run(&mut self) -> Result<(), SocksProxyError> {
debug!(
"New connection from: {}",
self.stream
.peer_addr()
.map_err(|source| SocksProxyError::PeerAddrExtractionFailure { source })?
.ip()
);
debug!("New connection from: {}", self.stream.peer_addr()?.ip());
// Read a byte from the stream and determine the version being requested
let mut header = [0u8];
self.stream
.read_exact(&mut header)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
self.stream.read_exact(&mut header).await?;
self.socks_version = match SocksVersion::try_from(header[0]) {
Ok(version) => Some(version),
@@ -318,10 +284,7 @@ impl SocksClient {
if self.socks_version == Some(SocksVersion::V5) {
let mut auth = [0u8];
self.stream
.read_exact(&mut auth)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
self.stream.read_exact(&mut auth).await?;
self.auth_nmethods = auth[0];
self.authenticate_socks5().await?;
}
@@ -330,15 +293,8 @@ impl SocksClient {
}
async fn send_anonymous_connect_to_mixnet(&mut self, remote_address: RemoteAddress) {
// TODO: simplify by using `request_version`
let req = Socks5Request::new_connect(
self.config.socks5_protocol_version,
self.connection_id,
remote_address,
None,
);
let msg =
Socks5ProviderRequest::new_provider_data(self.config.provider_interface_version, req);
let req = Request::new_connect(self.connection_id, remote_address, None);
let msg = Message::Request(req);
let input_message = InputMessage::new_anonymous(
self.service_provider,
@@ -353,15 +309,8 @@ impl SocksClient {
}
async fn send_connect_to_mixnet_with_return_address(&mut self, remote_address: RemoteAddress) {
// TODO: simplify by using `request_version`
let req = Socks5Request::new_connect(
self.config.socks5_protocol_version,
self.connection_id,
remote_address,
Some(self.self_address),
);
let msg =
Socks5ProviderRequest::new_provider_data(self.config.provider_interface_version, req);
let req = Request::new_connect(self.connection_id, remote_address, Some(self.self_address));
let msg = Message::Request(req);
let input_message = InputMessage::new_regular(
self.service_provider,
@@ -401,7 +350,6 @@ impl SocksClient {
let input_sender = self.input_sender.clone();
let anonymous = self.config.use_surbs_for_responses;
let per_request_surbs = self.config.per_request_surbs;
let request_version = self.config.request_version();
let recipient = self.service_provider;
let (stream, _) = ProxyRunner::new(
@@ -415,16 +363,8 @@ impl SocksClient {
self.shutdown_listener.clone(),
)
.run(move |conn_id, read_data, socket_closed| {
let provider_request = Socks5Request::new_send(
request_version.provider_protocol,
conn_id,
read_data,
socket_closed,
);
let provider_message = Socks5ProviderRequest::new_provider_data(
request_version.provider_interface,
provider_request,
);
let provider_request = Request::new_send(conn_id, read_data, socket_closed);
let provider_message = Message::Request(provider_request);
let lane = TransmissionLane::ConnectionId(conn_id);
if anonymous {
InputMessage::new_anonymous(
@@ -473,10 +413,7 @@ impl SocksClient {
self.started_proxy = true;
self.controller_sender
.unbounded_send(ControllerCommand::Insert {
connection_id: self.connection_id,
connection_sender: mix_sender,
})
.unbounded_send(ControllerCommand::Insert(self.connection_id, mix_sender))
.unwrap();
info!(
@@ -554,13 +491,7 @@ impl SocksClient {
/// into the Authenticator (where it'll be more easily testable)
/// would be a good next step.
async fn authenticate_socks5(&mut self) -> Result<(), SocksProxyError> {
debug!(
"Authenticating w/ {}",
self.stream
.peer_addr()
.map_err(|source| SocksProxyError::PeerAddrExtractionFailure { source })?
.ip()
);
debug!("Authenticating w/ {}", self.stream.peer_addr()?.ip());
// Get valid auth methods
let methods = self.get_available_methods().await?;
trace!("methods: {:?}", methods);
@@ -574,45 +505,27 @@ impl SocksClient {
response[1] = AuthenticationMethods::UserPass as u8;
debug!("Sending USER/PASS packet");
self.stream
.write_all(&response)
.await
.map_err(|source| SocksProxyError::SocketWriteError { source })?;
self.stream.write_all(&response).await?;
let mut header = [0u8; 2];
// Read a byte from the stream and determine the version being requested
self.stream
.read_exact(&mut header)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
self.stream.read_exact(&mut header).await?;
// debug!("Auth Header: [{}, {}]", header[0], header[1]);
// Username parsing
let ulen = header[1];
let mut username = vec![0; ulen as usize];
self.stream
.read_exact(&mut username)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
self.stream.read_exact(&mut username).await?;
// Password Parsing
let plen = self
.stream
.read_u8()
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
let plen = self.stream.read_u8().await?;
let mut password = vec![0; plen as usize];
self.stream
.read_exact(&mut password)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
self.stream.read_exact(&mut password).await?;
let username_str = String::from_utf8(username)
.map_err(|source| SocksProxyError::MalformedAuthUsername { source })?;
let password_str = String::from_utf8(password)
.map_err(|source| SocksProxyError::MalformedAuthPassword { source })?;
let username_str = String::from_utf8(username)?;
let password_str = String::from_utf8(password)?;
let user = User {
username: username_str,
@@ -623,17 +536,11 @@ impl SocksClient {
if self.authenticator.is_allowed(&user) {
debug!("Access Granted. User: {}", user.username);
let response = [1, ResponseCodeV5::Success as u8];
self.stream
.write_all(&response)
.await
.map_err(|source| SocksProxyError::SocketWriteError { source })?;
self.stream.write_all(&response).await?;
} else {
debug!("Access Denied. User: {}", user.username);
let response = [1, ResponseCodeV5::Failure as u8];
self.stream
.write_all(&response)
.await
.map_err(|source| SocksProxyError::SocketWriteError { source })?;
self.stream.write_all(&response).await?;
// Shutdown
self.shutdown().await?;
@@ -644,18 +551,12 @@ impl SocksClient {
// set the default auth method (no auth)
response[1] = AuthenticationMethods::NoAuth as u8;
debug!("Sending NOAUTH packet");
self.stream
.write_all(&response)
.await
.map_err(|source| SocksProxyError::SocketWriteError { source })?;
self.stream.write_all(&response).await?;
Ok(())
} else {
warn!("Client has no suitable authentication methods!");
response[1] = AuthenticationMethods::NoMethods as u8;
self.stream
.write_all(&response)
.await
.map_err(|source| SocksProxyError::SocketWriteError { source })?;
self.stream.write_all(&response).await?;
self.shutdown().await?;
Err(ResponseCodeV5::Failure.into())
}
@@ -666,10 +567,7 @@ impl SocksClient {
let mut methods: Vec<u8> = Vec::with_capacity(self.auth_nmethods as usize);
for _ in 0..self.auth_nmethods {
let mut method = [0u8; 1];
self.stream
.read_exact(&mut method)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
self.stream.read_exact(&mut method).await?;
if self.authenticator.auth_methods.contains(&method[0]) {
methods.append(&mut method.to_vec());
}
+30 -54
View File
@@ -5,9 +5,8 @@ use log::*;
use client_core::client::received_buffer::ReconstructedMessagesReceiver;
use client_core::client::received_buffer::{ReceivedBufferMessage, ReceivedBufferRequestSender};
use nymsphinx::receiver::ReconstructedMessage;
use proxy_helpers::connection_controller::ControllerSender;
use service_providers_common::interface::{ControlResponse, ResponseContent};
use socks5_requests::{Socks5ProviderResponse, Socks5Response, Socks5ResponseContent};
use proxy_helpers::connection_controller::{ControllerCommand, ControllerSender};
use socks5_requests::Message;
use task::TaskClient;
use crate::error::Socks5ClientError;
@@ -53,39 +52,6 @@ impl MixnetResponseListener {
}
}
fn on_control_response(
&self,
control_response: ControlResponse,
) -> Result<(), Socks5ClientError> {
error!("received a control response which we don't know how to handle yet!");
error!("got: {:?}", control_response);
// I guess we'd need another channel here to forward those to where they need to go
Ok(())
}
fn on_provider_data_response(
&self,
provider_response: Socks5Response,
) -> Result<(), Socks5ClientError> {
match provider_response.content {
Socks5ResponseContent::ConnectionError(err_response) => {
error!(
"Network requester failed on connection id {} with error: {}",
err_response.connection_id, err_response.network_requester_error
);
Err(err_response.into())
}
Socks5ResponseContent::NetworkData(response) => {
self.controller_sender
.unbounded_send(response.into())
.unwrap();
Ok(())
}
}
}
fn on_message(
&self,
reconstructed_message: ReconstructedMessage,
@@ -94,28 +60,38 @@ impl MixnetResponseListener {
if reconstructed_message.sender_tag.is_some() {
warn!("this message was sent anonymously - it couldn't have come from the service provider");
}
match Socks5ProviderResponse::try_from_bytes(&raw_message) {
let response = match Message::try_from_bytes(&raw_message) {
Err(err) => {
warn!("failed to parse received response: {err}");
Ok(())
warn!("failed to parse received response - {err}");
return Ok(());
}
Ok(response) => {
// as long as the client used the same (or older) interface than the service provider,
// the response should have used exactly the same version
trace!(
"the received response was sent with {:?} interface version",
response.interface_version
Ok(Message::Request(_)) => {
warn!("unexpected request");
return Ok(());
}
Ok(Message::Response(data)) => data,
Ok(Message::NetworkRequesterResponse(r)) => {
error!(
"Network requester failed on connection id {} with error: {}",
r.connection_id, r.network_requester_error
);
match response.content {
ResponseContent::Control(control_response) => {
self.on_control_response(control_response)
}
ResponseContent::ProviderData(provider_response) => {
self.on_provider_data_response(provider_response)
}
}
return Err(Socks5ClientError::NetworkRequesterError {
connection_id: r.connection_id,
error: r.network_requester_error,
});
}
}
};
self.controller_sender
.unbounded_send(ControllerCommand::Send(
response.connection_id,
response.data,
response.is_closed,
))
.unwrap();
Ok(())
}
pub(crate) async fn run(&mut self) {
+1 -1
View File
@@ -33,7 +33,7 @@ impl TryFrom<u8> for SocksVersion {
match version {
SOCKS4_VERSION => Ok(Self::V4),
SOCKS5_VERSION => Ok(Self::V5),
_ => Err(SocksProxyError::UnsupportedProxyVersion { version }),
_ => Err(SocksProxyError::UnsupportedProxyVersion(version)),
}
}
}
+10 -39
View File
@@ -28,10 +28,7 @@ impl SocksRequest {
log::trace!("read from stream socks4");
let mut packet = [0u8; 3];
stream
.read_exact(&mut packet)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
stream.read_exact(&mut packet).await?;
// CD (command)
let Some(command) = SocksCommand::from(packet[0] as usize) else {
@@ -46,10 +43,7 @@ impl SocksRequest {
// DSTIP
let mut ip = [0u8; 4];
stream
.read_exact(&mut ip)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
stream.read_exact(&mut ip).await?;
// USERID
let _userid = read_until_zero(stream).await;
@@ -82,17 +76,12 @@ impl SocksRequest {
let mut packet = [0u8; 4];
// Read a byte from the stream and determine the version being requested
stream
.read_exact(&mut packet)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
stream.read_exact(&mut packet).await?;
// VER
if packet[0] != SOCKS5_VERSION {
warn!("Unsupported version: SOCKS{}", packet[0]);
return Err(SocksProxyError::UnsupportedProxyVersion {
version: (packet[0]),
});
return Err(SocksProxyError::UnsupportedProxyVersion(packet[0]));
}
// CMD
@@ -114,41 +103,26 @@ impl SocksRequest {
let addr = match addr_type {
AddrType::Domain => {
let mut domain_length = [0u8];
stream
.read_exact(&mut domain_length)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
stream.read_exact(&mut domain_length).await?;
let mut domain = vec![0u8; domain_length[0] as usize];
stream
.read_exact(&mut domain)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
stream.read_exact(&mut domain).await?;
domain
}
AddrType::V4 => {
let mut addr = [0u8; 4];
stream
.read_exact(&mut addr)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
stream.read_exact(&mut addr).await?;
addr.to_vec()
}
AddrType::V6 => {
let mut addr = [0u8; 16];
stream
.read_exact(&mut addr)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
stream.read_exact(&mut addr).await?;
addr.to_vec()
}
};
// DST.PORT
let mut port = [0u8; 2];
stream
.read_exact(&mut port)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
stream.read_exact(&mut port).await?;
let port = merge_u8_into_u16(port[0], port[1]);
Ok(SocksRequest {
@@ -205,10 +179,7 @@ where
let mut result = Vec::new();
let mut char = [0u8];
loop {
stream
.read_exact(&mut char)
.await
.map_err(|source| SocksProxyError::SocketReadError { source })?;
stream.read_exact(&mut char).await?;
if char[0] == 0 {
break;
}
+2 -7
View File
@@ -10,7 +10,7 @@ use client_core::client::{
};
use log::*;
use nymsphinx::addressing::clients::Recipient;
use proxy_helpers::connection_controller::Controller;
use proxy_helpers::connection_controller::{BroadcastActiveConnections, Controller};
use std::net::SocketAddr;
use tap::TapFallible;
use task::TaskClient;
@@ -69,7 +69,7 @@ impl SphinxSocksServer {
// controller for managing all active connections
let (mut active_streams_controller, controller_sender) = Controller::new(
client_connection_tx,
//BroadcastActiveConnections::Off,
BroadcastActiveConnections::Off,
self.shutdown.clone(),
);
tokio::spawn(async move {
@@ -86,11 +86,6 @@ impl SphinxSocksServer {
mixnet_response_listener.run().await;
});
// TODO:, if required, there should be another task here responsible for control requests.
// it should get `input_sender` to send actual requests into the mixnet
// and some channel that connects it from `MixnetResponseListener` to receive
// any control responses
loop {
tokio::select! {
Ok((stream, _remote)) = listener.accept() => {
+24 -52
View File
@@ -1,7 +1,3 @@
use socks5_requests::Socks5RequestError;
use std::string::FromUtf8Error;
use thiserror::Error;
/// SOCKS4 Response codes
#[allow(dead_code)]
pub(crate) enum ResponseCodeV4 {
@@ -12,8 +8,9 @@ pub(crate) enum ResponseCodeV4 {
}
/// Possible SOCKS5 Response Codes
#[derive(Debug, Error)]
pub enum ResponseCodeV5 {
#[allow(dead_code)]
#[derive(Debug, thiserror::Error)]
pub(crate) enum ResponseCodeV5 {
#[error("SOCKS5 Server Success")]
Success = 0x00,
#[error("SOCKS5 Server Failure")]
@@ -34,55 +31,30 @@ pub enum ResponseCodeV5 {
AddrTypeNotSupported = 0x08,
}
#[derive(Error, Debug)]
#[derive(Debug)]
pub enum SocksProxyError {
#[error("{version} of the socks protocol is not supported by this client")]
UnsupportedProxyVersion { version: u8 },
GenericError(Box<dyn std::error::Error + Send + Sync>),
UnsupportedProxyVersion(u8),
}
#[error("failed to write to the socket: {source}")]
SocketWriteError {
#[source]
source: std::io::Error,
},
impl std::fmt::Display for SocksProxyError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SocksProxyError::GenericError(err) => write!(f, "GenericError - {err}"),
SocksProxyError::UnsupportedProxyVersion(version) => {
write!(f, "Unsupported proxy version {}", version)
}
}
}
}
#[error("failed to read from the socket: {source}")]
SocketReadError {
#[source]
source: std::io::Error,
},
#[error("failed to shutdown underlying socket stream: {source}")]
SocketShutdownFailure {
#[source]
source: std::io::Error,
},
#[error("failed to extract ip address of the connected peer: {source}")]
PeerAddrExtractionFailure {
#[source]
source: std::io::Error,
},
#[error("failed to authenticate user due to malformed username: {source}")]
MalformedAuthUsername {
#[source]
source: FromUtf8Error,
},
#[error("failed to authenticate user due to malformed password: {source}")]
MalformedAuthPassword {
#[source]
source: FromUtf8Error,
},
#[error(transparent)]
Socks5ResponseFailure(#[from] ResponseCodeV5),
#[error("could not complete the provider request: {source}")]
ProviderRequestFailure {
#[from]
source: Socks5RequestError,
},
impl<E> From<E> for SocksProxyError
where
E: std::error::Error + Send + Sync + 'static,
{
fn from(err: E) -> Self {
SocksProxyError::GenericError(Box::new(err))
}
}
/// DST.addr variant types
+1 -1
View File
@@ -34,7 +34,7 @@ client-core = { path = "../client-core", default-features = false, features = ["
client-connections = { path = "../../common/client-connections" }
coconut-interface = { path = "../../common/coconut-interface" }
credentials = { path = "../../common/credentials" }
nym-crypto = { path = "../../common/crypto" }
crypto = { path = "../../common/crypto" }
nymsphinx = { path = "../../common/nymsphinx" }
topology = { path = "../../common/topology" }
gateway-client = { path = "../../common/client-libs/gateway-client", default-features = false, features = ["wasm"] }
-4
View File
@@ -6,10 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { workspace = true, features = ["derive"], optional = true }
[build-dependencies]
vergen = { version = "7", default-features = false, features = ["build", "git", "rustc", "cargo"] }
[features]
default = []
-50
View File
@@ -4,7 +4,6 @@
// TODO: at a later date this crate should probably also expose `ContractBuildInformation`
// and be used by our smart contracts
#[derive(Debug)]
pub struct BinaryBuildInformation {
// VERGEN_BUILD_TIMESTAMP
/// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.
@@ -54,19 +53,6 @@ impl BinaryBuildInformation {
}
}
pub fn to_owned(&self) -> BinaryBuildInformationOwned {
BinaryBuildInformationOwned {
build_timestamp: self.build_timestamp.to_owned(),
build_version: self.build_version.to_owned(),
commit_sha: self.commit_sha.to_owned(),
commit_timestamp: self.commit_timestamp.to_owned(),
commit_branch: self.commit_branch.to_owned(),
rustc_version: self.rustc_version.to_owned(),
rustc_channel: self.rustc_channel.to_owned(),
cargo_profile: self.cargo_profile.to_owned(),
}
}
pub fn pretty_print(&self) -> String {
format!(
r#"
@@ -98,39 +84,3 @@ impl BinaryBuildInformation {
)
}
}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BinaryBuildInformationOwned {
// VERGEN_BUILD_TIMESTAMP
/// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.
pub build_timestamp: String,
// VERGEN_BUILD_SEMVER
/// Provides the build version, for example `0.1.0-9-g46f83e1`.
pub build_version: String,
// VERGEN_GIT_SHA
/// Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.
pub commit_sha: String,
// VERGEN_GIT_COMMIT_TIMESTAMP
/// Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.
pub commit_timestamp: String,
// VERGEN_GIT_BRANCH
/// Provides the name of the git branch that was used for the build, for example `master`.
pub commit_branch: String,
// VERGEN_RUSTC_SEMVER
/// Provides the rustc version that was used for the build, for example `1.52.0-nightly`.
pub rustc_version: String,
// VERGEN_RUSTC_CHANNEL
/// Provides the rustc channel that was used for the build, for example `nightly`.
pub rustc_channel: String,
// VERGEN_CARGO_PROFILE
/// Provides the cargo profile that was used for the build, for example `debug`.
pub cargo_profile: String,
}
+6
View File
@@ -25,6 +25,12 @@ pub enum ConnectionCommand {
// Announce that at a connection was closed. E.g the `OutQueueControl` uses this to discard
// transmission lanes.
Close(ConnectionId),
// In the network requester for example, we usually want to broadcast active connections
// regularly, so we know what connections we need to request lane queue lengths for from the
// client.
// In the socks5-client, this is not needed since have direct access to the lane queue lengths.
ActiveConnections(Vec<ConnectionId>),
}
// The `OutQueueControl` publishes the backlog per lane, primarily so that upstream can slow down
+2 -2
View File
@@ -20,11 +20,11 @@ tokio = { version = "1.24.1", features = ["macros"] }
# internal
coconut-interface = { path = "../../coconut-interface" }
credentials = { path = "../../credentials" }
nym-crypto = { path = "../../crypto" }
crypto = { path = "../../crypto" }
gateway-requests = { path = "../../../gateway/gateway-requests" }
network-defaults = { path = "../../network-defaults" }
nymsphinx = { path = "../../nymsphinx" }
nym-pemstore = { path = "../../pemstore" }
pemstore = { path = "../../pemstore" }
validator-client = { path = "../validator-client" }
task = { path = "../../task" }
serde = { version = "1.0", features = ["derive"]}
@@ -10,6 +10,7 @@ pub use crate::packet_router::{
use crate::socket_state::{PartiallyDelegated, SocketState};
use crate::{cleanup_socket_message, try_decrypt_binary_message};
use coconut_interface::Credential;
use crypto::asymmetric::identity;
use futures::{SinkExt, StreamExt};
use gateway_requests::authentication::encrypted_address::EncryptedAddressBytes;
use gateway_requests::iv::IV;
@@ -17,7 +18,6 @@ use gateway_requests::registration::handshake::{client_handshake, SharedKeys};
use gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse, PROTOCOL_VERSION};
use log::*;
use network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN};
use nym_crypto::asymmetric::identity;
use nymsphinx::forwarding::packet::MixPacket;
use rand::rngs::OsRng;
use std::convert::TryFrom;
@@ -441,7 +441,6 @@ where
}
debug_assert!(self.connection.is_available());
log::trace!("Registering gateway");
// it's fine to instantiate it here as it's only used once (during authentication or registration)
// and putting it into the GatewayClient struct would be a hassle
@@ -12,13 +12,13 @@ base64 = "0.13"
colored = "2.0"
coconut-dkg-common = { path = "../../cosmwasm-smart-contracts/coconut-dkg" }
nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" }
nym-mixnet-contract-common = { path= "../../cosmwasm-smart-contracts/mixnet-contract" }
nym-vesting-contract-common = { path= "../../cosmwasm-smart-contracts/vesting-contract" }
contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" }
mixnet-contract-common = { path= "../../cosmwasm-smart-contracts/mixnet-contract" }
vesting-contract-common = { path= "../../cosmwasm-smart-contracts/vesting-contract" }
coconut-bandwidth-contract-common = { path= "../../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" }
group-contract-common = { path = "../../cosmwasm-smart-contracts/group-contract" }
nym-vesting-contract = { path = "../../../contracts/vesting" }
vesting-contract = { path = "../../../contracts/vesting" }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
reqwest = { version = "0.11", features = ["json"] }
@@ -4,6 +4,9 @@
use crate::{nym_api, ValidatorClientError};
use coconut_dkg_common::types::NodeIndex;
use coconut_interface::VerificationKey;
use mixnet_contract_common::mixnode::MixNodeDetails;
use mixnet_contract_common::MixId;
use mixnet_contract_common::{GatewayBond, IdentityKeyRef};
use nym_api_requests::coconut::{
BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse,
};
@@ -11,9 +14,6 @@ use nym_api_requests::models::{
GatewayCoreStatusResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse,
RewardEstimationResponse, StakeSaturationResponse,
};
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
use nym_mixnet_contract_common::MixId;
use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef};
#[cfg(feature = "nyxd-client")]
use crate::nyxd::traits::{DkgQueryClient, MixnetQueryClient, MultisigQueryClient};
@@ -30,17 +30,17 @@ use coconut_interface::Base58;
#[cfg(feature = "nyxd-client")]
use cw3::ProposalResponse;
#[cfg(feature = "nyxd-client")]
use network_defaults::NymNetworkDetails;
#[cfg(feature = "nyxd-client")]
use nym_api_requests::models::MixNodeBondAnnotated;
#[cfg(feature = "nyxd-client")]
use nym_mixnet_contract_common::{
use mixnet_contract_common::{
families::{Family, FamilyHead},
mixnode::MixNodeBond,
pending_events::{PendingEpochEvent, PendingIntervalEvent},
Delegation, IdentityKey, RewardedSetNodeStatus, UnbondedMixnode,
};
#[cfg(feature = "nyxd-client")]
use network_defaults::NymNetworkDetails;
#[cfg(feature = "nyxd-client")]
use nym_api_requests::models::MixNodeBondAnnotated;
#[cfg(feature = "nyxd-client")]
use std::str::FromStr;
use url::Url;
@@ -934,6 +934,16 @@ impl NymApiClient {
Ok(self.nym_api_client.blind_sign(request_body).await?)
}
pub async fn partial_bandwidth_credential(
&self,
request_body: &str,
) -> Result<BlindedSignatureResponse, ValidatorClientError> {
Ok(self
.nym_api_client
.partial_bandwidth_credential(request_body)
.await?)
}
pub async fn verify_bandwidth_credential(
&self,
request_body: &VerifyCredentialBody,
@@ -3,6 +3,8 @@
use crate::nym_api::error::NymAPIError;
use crate::nym_api::routes::{CORE_STATUS_COUNT, SINCE_ARG};
use mixnet_contract_common::mixnode::MixNodeDetails;
use mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId};
use nym_api_requests::coconut::{
BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse,
};
@@ -13,8 +15,6 @@ use nym_api_requests::models::{
MixnodeUptimeHistoryResponse, RequestError, RewardEstimationResponse, StakeSaturationResponse,
UptimeResponse,
};
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId};
use reqwest::Response;
use serde::{Deserialize, Serialize};
use url::Url;
@@ -449,6 +449,23 @@ impl Client {
.await
}
pub async fn partial_bandwidth_credential(
&self,
request_body: &str,
) -> Result<BlindedSignatureResponse, NymAPIError> {
self.post_nym_api(
&[
routes::API_VERSION,
routes::COCONUT_ROUTES,
routes::BANDWIDTH,
routes::COCONUT_PARTIAL_BANDWIDTH_CREDENTIAL,
],
NO_PARAMS,
request_body,
)
.await
}
pub async fn verify_bandwidth_credential(
&self,
request_body: &VerifyCredentialBody,
@@ -14,6 +14,7 @@ pub const COCONUT_ROUTES: &str = "coconut";
pub const BANDWIDTH: &str = "bandwidth";
pub const COCONUT_BLIND_SIGN: &str = "blind-sign";
pub const COCONUT_PARTIAL_BANDWIDTH_CREDENTIAL: &str = "partial-bandwidth-credential";
pub const COCONUT_VERIFY_BANDWIDTH_CREDENTIAL: &str = "verify-bandwidth-credential";
pub const STATUS_ROUTES: &str = "status";
@@ -17,13 +17,13 @@ use cosmrs::rpc::HttpClientUrl;
use cosmrs::tx::Msg;
use execute::execute;
use log::debug;
use mixnet_contract_common::MixId;
use network_defaults::{ChainDetails, NymNetworkDetails};
use nym_mixnet_contract_common::MixId;
use nym_vesting_contract_common::ExecuteMsg as VestingExecuteMsg;
use nym_vesting_contract_common::PledgeCap;
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
use std::time::SystemTime;
use vesting_contract_common::ExecuteMsg as VestingExecuteMsg;
use vesting_contract_common::PledgeCap;
pub use crate::nyxd::cosmwasm_client::client::CosmWasmClient;
pub use crate::nyxd::cosmwasm_client::signing_client::SigningCosmWasmClient;
@@ -8,7 +8,7 @@ use coconut_dkg_common::dealer::{
DealerDetailsResponse, PagedDealerResponse, PagedDealingsResponse,
};
use coconut_dkg_common::msg::QueryMsg as DkgQueryMsg;
use coconut_dkg_common::types::{Epoch, EpochId, InitialReplacementData};
use coconut_dkg_common::types::{Epoch, EpochId};
use coconut_dkg_common::verification_key::PagedVKSharesResponse;
use cosmrs::AccountId;
@@ -16,7 +16,6 @@ use cosmrs::AccountId;
pub trait DkgQueryClient {
async fn get_current_epoch(&self) -> Result<Epoch, NyxdError>;
async fn get_current_epoch_threshold(&self) -> Result<Option<u64>, NyxdError>;
async fn get_initial_dealers(&self) -> Result<Option<InitialReplacementData>, NyxdError>;
async fn get_dealer_details(
&self,
address: &AccountId,
@@ -63,14 +62,6 @@ where
.query_contract_smart(self.coconut_dkg_contract_address(), &request)
.await
}
async fn get_initial_dealers(&self) -> Result<Option<InitialReplacementData>, NyxdError> {
let request = DkgQueryMsg::GetInitialDealers {};
self.client
.query_contract_smart(self.coconut_dkg_contract_address(), &request)
.await
}
async fn get_dealer_details(
&self,
address: &AccountId,
@@ -8,7 +8,7 @@ use async_trait::async_trait;
use coconut_dkg_common::msg::ExecuteMsg as DkgExecuteMsg;
use coconut_dkg_common::types::EncodedBTEPublicKeyWithProof;
use coconut_dkg_common::verification_key::VerificationKeyShare;
use nym_contracts_common::dealings::ContractSafeBytes;
use contracts_common::dealings::ContractSafeBytes;
#[async_trait]
pub trait DkgSigningClient {
@@ -17,21 +17,18 @@ pub trait DkgSigningClient {
&self,
bte_key: EncodedBTEPublicKeyWithProof,
announce_address: String,
resharing: bool,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError>;
async fn submit_dealing_bytes(
&self,
commitment: ContractSafeBytes,
resharing: bool,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError>;
async fn submit_verification_key_share(
&self,
share: VerificationKeyShare,
resharing: bool,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError>;
}
@@ -60,13 +57,11 @@ where
&self,
bte_key: EncodedBTEPublicKeyWithProof,
announce_address: String,
resharing: bool,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = DkgExecuteMsg::RegisterDealer {
bte_key_with_proof: bte_key,
announce_address,
resharing,
};
self.client
@@ -84,13 +79,9 @@ where
async fn submit_dealing_bytes(
&self,
dealing_bytes: ContractSafeBytes,
resharing: bool,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = DkgExecuteMsg::CommitDealing {
dealing_bytes,
resharing,
};
let req = DkgExecuteMsg::CommitDealing { dealing_bytes };
self.client
.execute(
@@ -107,10 +98,9 @@ where
async fn submit_verification_key_share(
&self,
share: VerificationKeyShare,
resharing: bool,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
let req = DkgExecuteMsg::CommitVerificationKeyShare { share, resharing };
let req = DkgExecuteMsg::CommitVerificationKeyShare { share };
self.client
.execute(
@@ -6,17 +6,17 @@ use crate::nyxd::error::NyxdError;
use crate::nyxd::NyxdClient;
use async_trait::async_trait;
use cosmrs::AccountId;
use nym_mixnet_contract_common::delegation::{MixNodeDelegationResponse, OwnerProxySubKey};
use nym_mixnet_contract_common::families::Family;
use nym_mixnet_contract_common::mixnode::{
use mixnet_contract_common::delegation::{MixNodeDelegationResponse, OwnerProxySubKey};
use mixnet_contract_common::families::Family;
use mixnet_contract_common::mixnode::{
MixNodeDetails, MixnodeRewardingDetailsResponse, PagedMixnodesDetailsResponse,
PagedUnbondedMixnodesResponse, StakeSaturationResponse, UnbondedMixnodeResponse,
};
use nym_mixnet_contract_common::reward_params::{Performance, RewardingParams};
use nym_mixnet_contract_common::rewarding::{
use mixnet_contract_common::reward_params::{Performance, RewardingParams};
use mixnet_contract_common::rewarding::{
EstimatedCurrentEpochRewardResponse, PendingRewardResponse,
};
use nym_mixnet_contract_common::{
use mixnet_contract_common::{
delegation, ContractBuildInformation, ContractState, ContractStateParams,
CurrentIntervalResponse, EpochEventId, GatewayBondResponse, GatewayOwnershipResponse,
IdentityKey, IntervalEventId, LayerDistribution, MixId, MixOwnershipResponse,
@@ -8,9 +8,9 @@ use crate::nyxd::error::NyxdError;
use crate::nyxd::{Fee, NyxdClient, SigningCosmWasmClient};
use async_trait::async_trait;
use cosmrs::AccountId;
use nym_mixnet_contract_common::mixnode::{MixNodeConfigUpdate, MixNodeCostParams};
use nym_mixnet_contract_common::reward_params::{IntervalRewardingParamsUpdate, Performance};
use nym_mixnet_contract_common::{
use mixnet_contract_common::mixnode::{MixNodeConfigUpdate, MixNodeCostParams};
use mixnet_contract_common::reward_params::{IntervalRewardingParamsUpdate, Performance};
use mixnet_contract_common::{
ContractStateParams, ExecuteMsg as MixnetExecuteMsg, Gateway, LayerAssignment, MixId, MixNode,
};
@@ -6,16 +6,16 @@ pub use crate::nyxd::cosmwasm_client::client::CosmWasmClient;
use crate::nyxd::error::NyxdError;
use crate::nyxd::NyxdClient;
use async_trait::async_trait;
use contracts_common::ContractBuildInformation;
use cosmwasm_std::{Coin as CosmWasmCoin, Timestamp};
use nym_contracts_common::ContractBuildInformation;
use nym_mixnet_contract_common::MixId;
use nym_vesting_contract_common::{
use mixnet_contract_common::MixId;
use serde::Deserialize;
use vesting_contract::vesting::Account;
use vesting_contract_common::{
messages::QueryMsg as VestingQueryMsg, AccountVestingCoins, AccountsResponse,
AllDelegationsResponse, BaseVestingAccountInfo, DelegationTimesResponse,
OriginalVestingResponse, Period, PledgeData, VestingCoinsResponse, VestingDelegation,
};
use serde::Deserialize;
use vesting_contract::vesting::Account;
#[async_trait]
pub trait VestingQueryClient {
@@ -134,68 +134,28 @@ pub trait VestingQueryClient {
.await
}
async fn get_historical_vesting_staking_reward(
async fn delegated_free(
&self,
vesting_account_address: &str,
block_time: Option<Timestamp>,
) -> Result<Coin, NyxdError> {
self.query_vesting_contract::<CosmWasmCoin>(
VestingQueryMsg::GetHistoricalVestingStakingReward {
vesting_account_address: vesting_account_address.to_string(),
},
)
self.query_vesting_contract::<CosmWasmCoin>(VestingQueryMsg::GetDelegatedFree {
vesting_account_address: vesting_account_address.to_string(),
block_time,
})
.await
.map(Into::into)
}
async fn get_spendable_vested_coins(
/// Returns the total amount of delegated tokens that have vested
async fn delegated_vesting(
&self,
vesting_account_address: &str,
block_time: Option<Timestamp>,
) -> Result<Coin, NyxdError> {
self.query_vesting_contract::<CosmWasmCoin>(VestingQueryMsg::GetSpendableVestedCoins {
vesting_account_address: vesting_account_address.to_string(),
})
.await
.map(Into::into)
}
async fn get_spendable_reward_coins(
&self,
vesting_account_address: &str,
) -> Result<Coin, NyxdError> {
self.query_vesting_contract::<CosmWasmCoin>(VestingQueryMsg::GetSpendableRewardCoins {
vesting_account_address: vesting_account_address.to_string(),
})
.await
.map(Into::into)
}
async fn get_delegated_coins(&self, vesting_account_address: &str) -> Result<Coin, NyxdError> {
self.query_vesting_contract::<CosmWasmCoin>(VestingQueryMsg::GetDelegatedCoins {
vesting_account_address: vesting_account_address.to_string(),
})
.await
.map(Into::into)
}
async fn get_pledged_coins(&self, vesting_account_address: &str) -> Result<Coin, NyxdError> {
self.query_vesting_contract::<CosmWasmCoin>(VestingQueryMsg::GetPledgedCoins {
vesting_account_address: vesting_account_address.to_string(),
})
.await
.map(Into::into)
}
async fn get_staked_coins(&self, vesting_account_address: &str) -> Result<Coin, NyxdError> {
self.query_vesting_contract::<CosmWasmCoin>(VestingQueryMsg::GetStakedCoins {
vesting_account_address: vesting_account_address.to_string(),
})
.await
.map(Into::into)
}
async fn get_withdrawn_coins(&self, vesting_account_address: &str) -> Result<Coin, NyxdError> {
self.query_vesting_contract::<CosmWasmCoin>(VestingQueryMsg::GetWithdrawnCoins {
self.query_vesting_contract::<CosmWasmCoin>(VestingQueryMsg::GetDelegatedVesting {
vesting_account_address: vesting_account_address.to_string(),
block_time,
})
.await
.map(Into::into)
@@ -6,12 +6,10 @@ use crate::nyxd::cosmwasm_client::types::ExecuteResult;
use crate::nyxd::error::NyxdError;
use crate::nyxd::{Coin, Fee, NyxdClient};
use async_trait::async_trait;
use nym_mixnet_contract_common::mixnode::{MixNodeConfigUpdate, MixNodeCostParams};
use nym_mixnet_contract_common::{Gateway, MixId, MixNode};
use nym_vesting_contract_common::messages::{
ExecuteMsg as VestingExecuteMsg, VestingSpecification,
};
use nym_vesting_contract_common::PledgeCap;
use mixnet_contract_common::mixnode::{MixNodeConfigUpdate, MixNodeCostParams};
use mixnet_contract_common::{Gateway, MixId, MixNode};
use vesting_contract_common::messages::{ExecuteMsg as VestingExecuteMsg, VestingSpecification};
use vesting_contract_common::PledgeCap;
#[async_trait]
pub trait VestingSigningClient {
+2 -2
View File
@@ -30,8 +30,8 @@ cosmwasm-std = { version = "1.0.0" }
validator-client = { path = "../client-libs/validator-client", features = ["nyxd-client"] }
network-defaults = { path = "../network-defaults" }
nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
nym-vesting-contract-common = { path = "../cosmwasm-smart-contracts/vesting-contract" }
mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
vesting-contract-common = { path = "../cosmwasm-smart-contracts/vesting-contract" }
coconut-bandwidth-contract-common = { path = "../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
coconut-dkg-common = { path = "../cosmwasm-smart-contracts/coconut-dkg" }
multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-contract" }
@@ -5,7 +5,7 @@ use clap::Parser;
use log::{debug, info};
use cosmwasm_std::Decimal;
use nym_mixnet_contract_common::{InitialRewardingParams, InstantiateMsg, Percent};
use mixnet_contract_common::{InitialRewardingParams, InstantiateMsg, Percent};
use std::str::FromStr;
use std::time::Duration;
use validator_client::nyxd::AccountId;
@@ -6,8 +6,8 @@ use std::str::FromStr;
use clap::Parser;
use log::{debug, info};
use nym_vesting_contract_common::InitMsg;
use validator_client::nyxd::AccountId;
use vesting_contract_common::InitMsg;
#[derive(Debug, Parser)]
pub struct Args {
@@ -4,7 +4,7 @@
use crate::context::SigningClient;
use clap::Parser;
use log::info;
use nym_mixnet_contract_common::{Coin, MixId};
use mixnet_contract_common::{Coin, MixId};
use validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient};
#[derive(Debug, Parser)]
@@ -9,7 +9,7 @@ use crate::utils::{pretty_cosmwasm_coin, show_error_passthrough};
use comfy_table::Table;
use cosmwasm_std::Addr;
use nym_mixnet_contract_common::{Delegation, PendingEpochEvent, PendingEpochEventKind};
use mixnet_contract_common::{Delegation, PendingEpochEvent, PendingEpochEventKind};
#[derive(Debug, Parser)]
pub struct Args {}
@@ -4,7 +4,7 @@
use crate::context::SigningClient;
use clap::Parser;
use log::info;
use nym_mixnet_contract_common::MixId;
use mixnet_contract_common::MixId;
use validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient};
#[derive(Debug, Parser)]
@@ -4,7 +4,7 @@
use crate::context::SigningClient;
use clap::Parser;
use log::info;
use nym_mixnet_contract_common::MixId;
use mixnet_contract_common::MixId;
use validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient};
#[derive(Debug, Parser)]
@@ -4,7 +4,7 @@
use crate::context::SigningClient;
use clap::Parser;
use log::info;
use nym_mixnet_contract_common::MixId;
use mixnet_contract_common::MixId;
use validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient};
#[derive(Debug, Parser)]
@@ -4,7 +4,7 @@
use clap::Parser;
use log::info;
use nym_mixnet_contract_common::{Coin, MixId};
use mixnet_contract_common::{Coin, MixId};
use validator_client::nyxd::traits::MixnetQueryClient;
use validator_client::nyxd::VestingSigningClient;
@@ -3,7 +3,7 @@
use clap::Parser;
use log::info;
use nym_mixnet_contract_common::MixId;
use mixnet_contract_common::MixId;
use validator_client::nyxd::traits::MixnetQueryClient;
use validator_client::nyxd::VestingSigningClient;
@@ -4,8 +4,8 @@
use crate::context::SigningClient;
use clap::Parser;
use log::{info, warn};
use mixnet_contract_common::Coin;
use network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
use nym_mixnet_contract_common::Coin;
use validator_client::nyxd::traits::MixnetSigningClient;
#[derive(Debug, Parser)]
@@ -55,7 +55,7 @@ pub async fn bond_gateway(args: Args, client: SigningClient) {
return;
}
let gateway = nym_mixnet_contract_common::Gateway {
let gateway = mixnet_contract_common::Gateway {
host: args.host,
mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT),
clients_port: args.clients_port.unwrap_or(DEFAULT_CLIENT_LISTENING_PORT),
@@ -4,8 +4,8 @@
use crate::context::SigningClient;
use clap::Parser;
use log::{info, warn};
use mixnet_contract_common::{Coin, Gateway};
use network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
use nym_mixnet_contract_common::{Coin, Gateway};
use validator_client::nyxd::VestingSigningClient;
#[derive(Debug, Parser)]
@@ -5,10 +5,10 @@ use clap::Parser;
use cosmwasm_std::Uint128;
use log::{info, warn};
use mixnet_contract_common::{Coin, MixNodeCostParams, Percent};
use network_defaults::{
DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT,
};
use nym_mixnet_contract_common::{Coin, MixNodeCostParams, Percent};
use validator_client::nyxd::traits::MixnetSigningClient;
use validator_client::nyxd::CosmWasmCoin;
@@ -70,7 +70,7 @@ pub async fn bond_mixnode(args: Args, client: SigningClient) {
return;
}
let mixnode = nym_mixnet_contract_common::MixNode {
let mixnode = mixnet_contract_common::MixNode {
host: args.host,
mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT),
verloc_port: args.verloc_port.unwrap_or(DEFAULT_VERLOC_LISTENING_PORT),
@@ -4,7 +4,7 @@
use crate::context::SigningClient;
use clap::Parser;
use log::info;
use nym_mixnet_contract_common::MixNodeConfigUpdate;
use mixnet_contract_common::MixNodeConfigUpdate;
use validator_client::nyxd::traits::{MixnetQueryClient, MixnetSigningClient};
#[derive(Debug, Parser)]
@@ -4,7 +4,7 @@
use crate::context::SigningClient;
use clap::Parser;
use log::info;
use nym_mixnet_contract_common::MixNodeConfigUpdate;
use mixnet_contract_common::MixNodeConfigUpdate;
use validator_client::nyxd::traits::MixnetQueryClient;
use validator_client::nyxd::VestingSigningClient;
@@ -5,11 +5,11 @@ use crate::context::SigningClient;
use clap::Parser;
use cosmwasm_std::Uint128;
use log::{info, warn};
use mixnet_contract_common::{Coin, MixNodeCostParams};
use mixnet_contract_common::{MixNode, Percent};
use network_defaults::{
DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT,
};
use nym_mixnet_contract_common::{Coin, MixNodeCostParams};
use nym_mixnet_contract_common::{MixNode, Percent};
use validator_client::nyxd::{CosmWasmCoin, VestingSigningClient};
#[derive(Debug, Parser)]
@@ -6,13 +6,13 @@ use std::str::FromStr;
use clap::Parser;
use log::info;
use mixnet_contract_common::Coin;
use network_defaults::NymNetworkDetails;
use nym_mixnet_contract_common::Coin;
use nym_vesting_contract_common::messages::VestingSpecification;
use nym_vesting_contract_common::PledgeCap;
use validator_client::nyxd::AccountId;
use validator_client::nyxd::VestingSigningClient;
use validator_client::nyxd::{CosmosCoin, Denom};
use vesting_contract_common::messages::VestingSpecification;
use vesting_contract_common::PledgeCap;
use crate::context::SigningClient;
@@ -53,10 +53,8 @@ pub async fn query(args: Args, client: QueryClient, address_from_mnemonic: Optio
// TODO: get better copy text for what these are
let vesting_coins = client.vesting_coins(&vesting_address, None).await;
let delegated = client.get_delegated_coins(&vesting_address).await;
let pledged = client.get_pledged_coins(&vesting_address).await;
let withdrawn = client.get_withdrawn_coins(&vesting_address).await;
let staked = client.get_staked_coins(&vesting_address).await;
let delegated_vesting = client.delegated_vesting(&vesting_address, None).await;
let delegated_free = client.delegated_free(&vesting_address, None).await;
original_vesting.as_ref().map_or_else(show_error, |res| {
println!(
@@ -141,17 +139,11 @@ pub async fn query(args: Args, client: QueryClient, address_from_mnemonic: Optio
vesting_coins.map_or_else(show_error, |res| {
println!("Vesting coins: {} ({})", pretty_coin(&res), res);
});
withdrawn.map_or_else(show_error, |res| {
println!("Withdrawn: {} ({})", pretty_coin(&res), res);
delegated_vesting.map_or_else(show_error, |res| {
println!("Delegated vesting: {} ({})", pretty_coin(&res), res);
});
delegated.map_or_else(show_error, |res| {
println!("Delegated: {} ({})", pretty_coin(&res), res);
});
pledged.map_or_else(show_error, |res| {
println!("Pledged: {} ({})", pretty_coin(&res), res);
});
staked.map_or_else(show_error, |res| {
println!("Staked: {} ({})", pretty_coin(&res), res);
delegated_free.map_or_else(show_error, |res| {
println!("Delegation free: {} ({})", pretty_coin(&res), res);
});
println!();
@@ -11,5 +11,5 @@ cw-utils = "0.13.4"
schemars = "0.8"
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common" }
multisig-contract-common = { path = "../multisig-contract" }
contracts-common = { path = "../contracts-common" }
multisig-contract-common = { path = "../multisig-contract" }
@@ -21,22 +21,18 @@ pub enum ExecuteMsg {
RegisterDealer {
bte_key_with_proof: EncodedBTEPublicKeyWithProof,
announce_address: String,
resharing: bool,
},
CommitDealing {
dealing_bytes: ContractSafeBytes,
resharing: bool,
},
CommitVerificationKeyShare {
share: VerificationKeyShare,
resharing: bool,
},
VerifyVerificationKeyShare {
owner: Addr,
resharing: bool,
},
SurpassedThreshold {},
@@ -49,7 +45,6 @@ pub enum ExecuteMsg {
pub enum QueryMsg {
GetCurrentEpochState {},
GetCurrentEpochThreshold {},
GetInitialDealers {},
GetDealerDetails {
dealer_address: String,
},
@@ -18,12 +18,6 @@ pub type EpochId = u64;
// 2 public attributes, 2 private attributes, 1 fixed for coconut credential
pub const TOTAL_DEALINGS: usize = 2 + 2 + 1;
#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
pub struct InitialReplacementData {
pub initial_dealers: Vec<Addr>,
pub initial_height: Option<u64>,
}
#[derive(
Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd, JsonSchema,
)]
@@ -92,17 +86,15 @@ impl Epoch {
current_timestamp: Timestamp,
) -> Self {
let duration = match state {
EpochState::PublicKeySubmission { .. } => {
time_configuration.public_key_submission_time_secs
}
EpochState::DealingExchange { .. } => time_configuration.dealing_exchange_time_secs,
EpochState::VerificationKeySubmission { .. } => {
EpochState::PublicKeySubmission => time_configuration.public_key_submission_time_secs,
EpochState::DealingExchange => time_configuration.dealing_exchange_time_secs,
EpochState::VerificationKeySubmission => {
time_configuration.verification_key_submission_time_secs
}
EpochState::VerificationKeyValidation { .. } => {
EpochState::VerificationKeyValidation => {
time_configuration.verification_key_validation_time_secs
}
EpochState::VerificationKeyFinalization { .. } => {
EpochState::VerificationKeyFinalization => {
time_configuration.verification_key_finalization_time_secs
}
EpochState::InProgress => time_configuration.in_progress_time_secs,
@@ -114,33 +106,6 @@ impl Epoch {
finish_timestamp: current_timestamp.plus_seconds(duration),
}
}
pub fn final_timestamp_secs(&self) -> u64 {
let mut finish = self.finish_timestamp.seconds();
let time_configuration = self.time_configuration;
let mut curr_epoch_state = self.state;
while let Some(state) = curr_epoch_state.next() {
curr_epoch_state = state;
let adding = match curr_epoch_state {
EpochState::PublicKeySubmission { .. } => {
time_configuration.public_key_submission_time_secs
}
EpochState::DealingExchange { .. } => time_configuration.dealing_exchange_time_secs,
EpochState::VerificationKeySubmission { .. } => {
time_configuration.verification_key_submission_time_secs
}
EpochState::VerificationKeyValidation { .. } => {
time_configuration.verification_key_validation_time_secs
}
EpochState::VerificationKeyFinalization { .. } => {
time_configuration.verification_key_finalization_time_secs
}
EpochState::InProgress { .. } => 0,
};
finish += adding;
}
finish
}
}
// currently (it is still extremely likely to change, we might be able to get rid of verification key-related complaints),
@@ -158,36 +123,28 @@ impl Epoch {
#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, Ord, PartialOrd)]
#[serde(rename_all = "snake_case")]
pub enum EpochState {
PublicKeySubmission { resharing: bool },
DealingExchange { resharing: bool },
VerificationKeySubmission { resharing: bool },
VerificationKeyValidation { resharing: bool },
VerificationKeyFinalization { resharing: bool },
PublicKeySubmission,
DealingExchange,
VerificationKeySubmission,
VerificationKeyValidation,
VerificationKeyFinalization,
InProgress,
}
impl Default for EpochState {
fn default() -> Self {
Self::PublicKeySubmission { resharing: false }
Self::PublicKeySubmission
}
}
impl Display for EpochState {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
EpochState::PublicKeySubmission { resharing } => {
write!(f, "PublicKeySubmission with resharing {resharing}")
}
EpochState::DealingExchange { resharing } => write!(f, "DealingExchange {resharing}"),
EpochState::VerificationKeySubmission { resharing } => {
write!(f, "VerificationKeySubmission with resharing {resharing}")
}
EpochState::VerificationKeyValidation { resharing } => {
write!(f, "VerificationKeyValidation with resharing {resharing}")
}
EpochState::VerificationKeyFinalization { resharing } => {
write!(f, "VerificationKeyFinalization with resharing {resharing}")
}
EpochState::PublicKeySubmission => write!(f, "PublicKeySubmission"),
EpochState::DealingExchange => write!(f, "DealingExchange"),
EpochState::VerificationKeySubmission => write!(f, "VerificationKeySubmission"),
EpochState::VerificationKeyValidation => write!(f, "VerificationKeyValidation"),
EpochState::VerificationKeyFinalization => write!(f, "VerificationKeyFinalization"),
EpochState::InProgress => write!(f, "InProgress"),
}
}
@@ -196,19 +153,11 @@ impl Display for EpochState {
impl EpochState {
pub fn next(self) -> Option<Self> {
match self {
EpochState::PublicKeySubmission { resharing } => {
Some(EpochState::DealingExchange { resharing })
}
EpochState::DealingExchange { resharing } => {
Some(EpochState::VerificationKeySubmission { resharing })
}
EpochState::VerificationKeySubmission { resharing } => {
Some(EpochState::VerificationKeyValidation { resharing })
}
EpochState::VerificationKeyValidation { resharing } => {
Some(EpochState::VerificationKeyFinalization { resharing })
}
EpochState::VerificationKeyFinalization { .. } => Some(EpochState::InProgress),
EpochState::PublicKeySubmission => Some(EpochState::DealingExchange),
EpochState::DealingExchange => Some(EpochState::VerificationKeySubmission),
EpochState::VerificationKeySubmission => Some(EpochState::VerificationKeyValidation),
EpochState::VerificationKeyValidation => Some(EpochState::VerificationKeyFinalization),
EpochState::VerificationKeyFinalization => Some(EpochState::InProgress),
EpochState::InProgress => None,
}
}
@@ -222,8 +171,4 @@ impl EpochState {
states
}
pub fn is_final(&self) -> bool {
*self == EpochState::InProgress
}
}
@@ -30,12 +30,11 @@ pub struct PagedVKSharesResponse {
pub fn to_cosmos_msg(
owner: Addr,
resharing: bool,
coconut_dkg_addr: String,
multisig_addr: String,
expiration_time: Timestamp,
) -> StdResult<CosmosMsg> {
let verify_vk_share_req = ExecuteMsg::VerifyVerificationKeyShare { owner, resharing };
let verify_vk_share_req = ExecuteMsg::VerifyVerificationKeyShare { owner };
let verify_vk_share_msg = CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: coconut_dkg_addr,
msg: to_binary(&verify_vk_share_req)?,
@@ -63,8 +62,7 @@ pub fn owner_from_cosmos_msgs(msgs: &[CosmosMsg]) -> Option<Addr> {
funds: _,
})) = msgs.get(0)
{
if let Ok(ExecuteMsg::VerifyVerificationKeyShare { owner, .. }) =
from_binary::<ExecuteMsg>(msg)
if let Ok(ExecuteMsg::VerifyVerificationKeyShare { owner }) = from_binary::<ExecuteMsg>(msg)
{
return Some(owner);
}
@@ -1,5 +1,5 @@
[package]
name = "nym-contracts-common"
name = "contracts-common"
version = "0.1.0"
authors = ["Jędrzej Stuczyński <andrew@nymtech.net>"]
edition = "2021"
@@ -15,4 +15,4 @@ serde = { version = "1.0", features = ["derive"] }
thiserror = "1"
[dev-dependencies]
serde_json = "1.0.0"
serde_json = "1.0.0"

Some files were not shown because too many files have changed in this diff Show More