Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dfee78e6c0 | |||
| e17ae9dce0 | |||
| 997faeb1e6 | |||
| 565e7768e3 | |||
| 271a5fbab6 | |||
| 90a97b398e | |||
| fc2236c3c8 | |||
| c3d3164533 | |||
| fa2e0a9010 | |||
| fcc5398aab | |||
| 6403d0055b | |||
| ed48a2ddd4 | |||
| 7a1a7c003e | |||
| ef36c29b91 | |||
| 4025fed882 | |||
| 9aaa74204b | |||
| 9d7a6b2aec | |||
| c9489fb48e | |||
| 6c3653c128 | |||
| 31568b544c | |||
| 2953837f25 | |||
| ee98820bb4 | |||
| ed76000dd0 | |||
| 0dfe1460e4 | |||
| e06087ad3f | |||
| 0a6a015987 | |||
| efd8ba5978 | |||
| 0c7181a211 | |||
| f47a111640 | |||
| ae5a9ccc50 | |||
| 40465665f0 | |||
| 8c437ac964 | |||
| f3b17ad2f8 | |||
| 9121078576 | |||
| c505a00fac | |||
| 09bad9c6b4 | |||
| 597f5e9545 | |||
| 54cb7be1e1 | |||
| 431c98e591 | |||
| 35f2e71202 | |||
| 0134030341 | |||
| 97c775bc68 | |||
| 62ba6b30ae | |||
| 24354275d3 | |||
| 76335e9adc | |||
| bab8eb746e | |||
| f298f5d4fa | |||
| 85b078a3e8 | |||
| 0115b02be3 | |||
| a4ffd135e7 | |||
| bbce67902b | |||
| e6930046c4 | |||
| 0c9402503a | |||
| 81e133b789 | |||
| 7be07c29c1 | |||
| 31bc439f65 | |||
| 6479480cf7 | |||
| 4af70ef255 | |||
| eba58f6451 | |||
| 35206655e0 | |||
| e14db00fc2 | |||
| 72b92784cc | |||
| 38b95c2673 | |||
| f0f9899f82 | |||
| 09c46e3403 | |||
| 8f57919571 | |||
| 3cdca0ad8d | |||
| 4c13d91bfb | |||
| 8355e6ce5e | |||
| 4caa9390cf | |||
| bbb1e5e15a | |||
| 6d30e7ea8e | |||
| 92e902c81e | |||
| c47bc174bc | |||
| 3515e4e1c3 | |||
| 5ec20e5599 | |||
| 9f408d4c79 | |||
| 31233b3b68 | |||
| c4ea887319 | |||
| 6a69449e43 | |||
| 7aac01cca1 |
@@ -38,7 +38,7 @@ jobs:
|
|||||||
- name: install npm
|
- name: install npm
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Matrix - Node Install
|
- name: Matrix - Node Install
|
||||||
run: npm install
|
run: npm install
|
||||||
working-directory: .github/workflows/support-files
|
working-directory: .github/workflows/support-files
|
||||||
|
|||||||
@@ -16,9 +16,15 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Setup yarn
|
- name: Setup yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Install wasm-pack
|
||||||
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
- name: Build
|
- name: Build
|
||||||
run: yarn && yarn build && yarn build:ci
|
run: yarn && yarn build && yarn build:ci
|
||||||
- name: Deploy branch to CI www (storybook)
|
- name: Deploy branch to CI www (storybook)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: "16"
|
node-version: 18
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: "16"
|
node-version: 18
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: "16"
|
node-version: 18
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: "16"
|
node-version: 18
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Install Yarn
|
- name: Install Yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
- run: yarn
|
- run: yarn
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
name: Linting for Network Explorer (eslint/prettier)
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
paths:
|
|
||||||
- 'explorer/**'
|
|
||||||
|
|
||||||
defaults:
|
|
||||||
run:
|
|
||||||
working-directory: explorer
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: custom-runner-linux
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
- name: Setup yarn
|
|
||||||
run: npm install -g yarn
|
|
||||||
- name: Run ESLint
|
|
||||||
# GitHub should automatically annotate the PR
|
|
||||||
run: yarn && yarn lint
|
|
||||||
@@ -21,7 +21,7 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Setup yarn
|
- name: Setup yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Matrix - Node Install
|
- name: Matrix - Node Install
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Matrix - Node Install
|
- name: Matrix - Node Install
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ jobs:
|
|||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Matrix - Node Install
|
- name: Matrix - Node Install
|
||||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||||
run: npm install
|
run: npm install
|
||||||
|
|||||||
@@ -15,15 +15,22 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [macos-latest]
|
platform: [macos-latest]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Node v16
|
- name: Node v16
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
@@ -81,10 +88,38 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-connect/desktop/target/release/bundle/dmg/*.dmg
|
nym-connect/desktop/target/release/bundle/dmg/*.dmg
|
||||||
nym-connect/desktop/target/release/bundle/macos/*.app.tar.gz*
|
nym-connect/desktop/target/release/bundle/macos/*.app.tar.gz*
|
||||||
|
- id: release-info
|
||||||
|
name: Prepare release info
|
||||||
|
run: |
|
||||||
|
semver="${${{ github.ref_name }}##nym-connect-}" && semver="${semver##v}"
|
||||||
|
echo "version=$semver" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "filename=nym-connect_$version_x64.dmg" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/dmg/nym-connect_*_x64.dmg') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-connect/desktop/CHANGELOG.md
|
||||||
|
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect.app.tar.gz
|
||||||
|
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect.app.tar.gz.sig
|
||||||
|
version: ${{ needs.publish-tauri.outputs.version }}
|
||||||
|
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||||
|
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||||
|
name: NymConnect
|
||||||
|
category: connect
|
||||||
|
platform: MacOS
|
||||||
|
secrets: inherit
|
||||||
|
|||||||
@@ -15,8 +15,15 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [custom-runner-linux]
|
platform: [custom-runner-linux]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
@@ -29,7 +36,7 @@ jobs:
|
|||||||
- name: Node v16
|
- name: Node v16
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -56,10 +63,38 @@ jobs:
|
|||||||
path: nym-connect/desktop/target/release/bundle/appimage/nym-connect_1.0.0_amd64.AppImage
|
path: nym-connect/desktop/target/release/bundle/appimage/nym-connect_1.0.0_amd64.AppImage
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-connect/desktop/target/release/bundle/appimage/*.AppImage
|
nym-connect/desktop/target/release/bundle/appimage/*.AppImage
|
||||||
nym-connect/desktop/target/release/bundle/appimage/*.AppImage.tar.gz*
|
nym-connect/desktop/target/release/bundle/appimage/*.AppImage.tar.gz*
|
||||||
|
- id: release-info
|
||||||
|
name: Prepare release info
|
||||||
|
run: |
|
||||||
|
semver="${${{ github.ref_name }}##nym-connect-}" && semver="${semver##v}"
|
||||||
|
echo "version=$semver" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "filename=nym-connect_$version_amd64.AppImage" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/appimage/nym-connect_*_amd64.AppImage') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-connect/desktop/CHANGELOG.md
|
||||||
|
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect_${{ needs.publish-tauri.outputs.version }}_amd64.AppImage.tar.gz
|
||||||
|
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect_${{ needs.publish-tauri.outputs.version }}_amd64.AppImage.tar.gz.sig
|
||||||
|
version: ${{ needs.publish-tauri.outputs.version }}
|
||||||
|
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||||
|
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||||
|
name: NymConnect
|
||||||
|
category: connect
|
||||||
|
platform: Ubuntu
|
||||||
|
secrets: inherit
|
||||||
|
|||||||
@@ -15,8 +15,15 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [windows10]
|
platform: [windows10]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clean up first
|
- name: Clean up first
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
@@ -42,7 +49,7 @@ jobs:
|
|||||||
- name: Node v16
|
- name: Node v16
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -75,10 +82,38 @@ jobs:
|
|||||||
path: nym-connect/desktop/target/release/bundle/msi/nym-connect_1.0.0_x64_en-US.msi
|
path: nym-connect/desktop/target/release/bundle/msi/nym-connect_1.0.0_x64_en-US.msi
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-connect/desktop/target/release/bundle/msi/*.msi
|
nym-connect/desktop/target/release/bundle/msi/*.msi
|
||||||
nym-connect/desktop/target/release/bundle/msi/*.msi.zip*
|
nym-connect/desktop/target/release/bundle/msi/*.msi.zip*
|
||||||
|
- id: release-info
|
||||||
|
name: Prepare release info
|
||||||
|
run: |
|
||||||
|
semver="${${{ github.ref_name }}##nym-connect-}" && semver="${semver##v}"
|
||||||
|
echo "version=$semver" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "filename=nym-connect_$version_x64_en-US.msi" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "file_hash=${{ hashFiles('nym-connect/desktop/target/release/bundle/msi/nym-connect_*_x64_en-US.msi') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-connect/desktop/CHANGELOG.md
|
||||||
|
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect_${{ needs.publish-tauri.outputs.version }}_x64_en-US.msi.zip
|
||||||
|
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-connect_${{ needs.publish-tauri.outputs.version }}_x64_en-US.msi.zip.sig
|
||||||
|
version: ${{ needs.publish-tauri.outputs.version }}
|
||||||
|
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||||
|
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||||
|
name: NymConnect
|
||||||
|
category: connect
|
||||||
|
platform: Windows
|
||||||
|
secrets: inherit
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ name: Publish Nym binaries
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
add_tokio_unstable:
|
add_tokio_unstable:
|
||||||
description: 'True to add RUSTFLAGS="--cfg tokio_unstable"'
|
description: 'True to add RUSTFLAGS="--cfg tokio_unstable"'
|
||||||
required: true
|
required: true
|
||||||
default: false
|
default: false
|
||||||
type: boolean
|
type: boolean
|
||||||
release:
|
release:
|
||||||
types: [created]
|
types: [created]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
NETWORK: mainnet
|
NETWORK: mainnet
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-nym:
|
publish-nym:
|
||||||
@@ -21,15 +21,33 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [custom-runner-linux]
|
platform: [custom-runner-linux]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }}
|
||||||
|
client_hash: ${{ steps.binary-hashes.outputs.client_hash }}
|
||||||
|
mixnode_hash: ${{ steps.binary-hashes.outputs.mixnode_hash }}
|
||||||
|
gateway_hash: ${{ steps.binary-hashes.outputs.gateway_hash }}
|
||||||
|
socks5_hash: ${{ steps.binary-hashes.outputs.socks5_hash }}
|
||||||
|
netreq_hash: ${{ steps.binary-hashes.outputs.netreq_hash }}
|
||||||
|
cli_hash: ${{ steps.binary-hashes.outputs.cli_hash }}
|
||||||
|
netstat_hash: ${{ steps.binary-hashes.outputs.netstat_hash }}
|
||||||
|
client_version: ${{ steps.binary-versions.outputs.client_version }}
|
||||||
|
mixnode_version: ${{ steps.binary-versions.outputs.mixnode_version }}
|
||||||
|
gateway_version: ${{ steps.binary-versions.outputs.gateway_version }}
|
||||||
|
socks5_version: ${{ steps.binary-versions.outputs.socks5_version }}
|
||||||
|
netreq_version: ${{ steps.binary-versions.outputs.netreq_version }}
|
||||||
|
cli_version: ${{ steps.binary-versions.outputs.cli_version }}
|
||||||
|
netstat_version: ${{ steps.binary-versions.outputs.netstat_version }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install Dependencies (Linux)
|
- name: Install Dependencies (Linux)
|
||||||
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
|
run: sudo apt-get update && sudo apt-get -y install ripgrep libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- name: Sets env vars for tokio if set in manual dispatch inputs
|
- name: Sets env vars for tokio if set in manual dispatch inputs
|
||||||
run: |
|
run: |
|
||||||
echo 'RUSTFLAGS="--cfg tokio_unstable"' >> $GITHUB_ENV
|
echo 'RUSTFLAGS="--cfg tokio_unstable"' >> $GITHUB_ENV
|
||||||
@@ -62,7 +80,8 @@ jobs:
|
|||||||
target/release/nym-cli
|
target/release/nym-cli
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
@@ -76,3 +95,150 @@ jobs:
|
|||||||
target/release/nym-network-requester
|
target/release/nym-network-requester
|
||||||
target/release/nym-network-statistics
|
target/release/nym-network-statistics
|
||||||
target/release/nym-cli
|
target/release/nym-cli
|
||||||
|
|
||||||
|
- id: release-info
|
||||||
|
name: Prepare release info
|
||||||
|
run: |
|
||||||
|
semver="${${{ github.ref_name }}##nym-binaries-}" && semver="${semver##v}"
|
||||||
|
echo "version=$semver" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- id: binary-hashes
|
||||||
|
name: Generate binary hashes
|
||||||
|
run: |
|
||||||
|
echo "client_hash=${{ hashFiles('target/release/nym-client') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "mixnode_hash=${{ hashFiles('target/release/nym-mixnode') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "gateway_hash=${{ hashFiles('target/release/nym-gateway') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "socks5_hash=${{ hashFiles('target/release/nym-socks5-client') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "netreq_hash=${{ hashFiles('target/release/nym-network-requester') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "cli_hash=${{ hashFiles('target/release/nym-cli') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "netstat_hash=${{ hashFiles('target/release/nym-network-statistics') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- id: binary-versions
|
||||||
|
name: Get binary versions
|
||||||
|
run: |
|
||||||
|
v=$(rg '^version = "(.*)"' -or '$1' clients/native/Cargo.toml) && echo "client_version=$v" >> "$GITHUB_OUTPUT"
|
||||||
|
v=$(rg '^version = "(.*)"' -or '$1' mixnode/Cargo.toml) && echo "mixnode_version=$v" >> "$GITHUB_OUTPUT"
|
||||||
|
v=$(rg '^version = "(.*)"' -or '$1' gateway/Cargo.toml) && echo "gateway_version=$v" >> "$GITHUB_OUTPUT"
|
||||||
|
v=$(rg '^version = "(.*)"' -or '$1' clients/socks5/Cargo.toml) && echo "socks5_version=$v" >> "$GITHUB_OUTPUT"
|
||||||
|
v=$(rg '^version = "(.*)"' -or '$1' service-providers/network-requester/Cargo.toml) && echo "netreq_version=$v" >> "$GITHUB_OUTPUT"
|
||||||
|
v=$(rg '^version = "(.*)"' -or '$1' tools/nym-cli/Cargo.toml) && echo "cli_version=$v" >> "$GITHUB_OUTPUT"
|
||||||
|
v=$(rg '^version = "(.*)"' -or '$1' service-providers/network-statistics/Cargo.toml) && echo "netstat_version=$v" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
push-release-data-client:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-nym
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||||
|
version: ${{ needs.publish-nym.outputs.client_version }}
|
||||||
|
filename: nym-client
|
||||||
|
file_hash: ${{ needs.publish-nym.outputs.client_hash }}
|
||||||
|
name: Client
|
||||||
|
category: binaries
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
push-release-data-mixnode:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-nym
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||||
|
version: ${{ needs.publish-nym.outputs.mixnode_version }}
|
||||||
|
filename: nym-mixnode
|
||||||
|
file_hash: ${{ needs.publish-nym.outputs.mixnode_hash }}
|
||||||
|
name: Mixnode
|
||||||
|
category: binaries
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
push-release-data-gateway:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-nym
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||||
|
version: ${{ needs.publish-nym.outputs.gateway_version }}
|
||||||
|
filename: nym-gateway
|
||||||
|
file_hash: ${{ needs.publish-nym.outputs.gateway_hash }}
|
||||||
|
name: Gateway
|
||||||
|
category: binaries
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
push-release-data-socks5:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-nym
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||||
|
version: ${{ needs.publish-nym.outputs.socks5_version }}
|
||||||
|
filename: nym-socks5-client
|
||||||
|
file_hash: ${{ needs.publish-nym.outputs.socks5_hash }}
|
||||||
|
name: Socks5 Client
|
||||||
|
category: binaries
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
push-release-data-network-requester:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-nym
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||||
|
version: ${{ needs.publish-nym.outputs.netreq_version }}
|
||||||
|
filename: nym-network-requester
|
||||||
|
file_hash: ${{ needs.publish-nym.outputs.netreq_hash }}
|
||||||
|
name: Network Requester
|
||||||
|
category: binaries
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
push-release-data-cli:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-nym
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||||
|
version: ${{ needs.publish-nym.outputs.cli_version }}
|
||||||
|
filename: nym-cli
|
||||||
|
file_hash: ${{ needs.publish-nym.outputs.cli_hash }}
|
||||||
|
name: Cli
|
||||||
|
category: binaries
|
||||||
|
secrets: inherit
|
||||||
|
|
||||||
|
push-release-data-network-stat:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-nym
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-nym.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-nym.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/CHANGELOG.md
|
||||||
|
version: ${{ needs.publish-nym.outputs.netstat_version }}
|
||||||
|
filename: nym-network-statistics
|
||||||
|
file_hash: ${{ needs.publish-nym.outputs.netstat_hash }}
|
||||||
|
name: Network Statistics
|
||||||
|
category: binaries
|
||||||
|
secrets: inherit
|
||||||
|
|||||||
@@ -15,15 +15,22 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [macos-latest]
|
platform: [macos-latest]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Node v16
|
- name: Node v16
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
@@ -80,11 +87,38 @@ jobs:
|
|||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
run: |
|
run: |
|
||||||
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
|
||||||
|
- id: create-release
|
||||||
- name: Upload to release based on tag name
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-wallet/target/release/bundle/dmg/*.dmg
|
nym-wallet/target/release/bundle/dmg/*.dmg
|
||||||
nym-wallet/target/release/bundle/macos/*.app.tar.gz*
|
nym-wallet/target/release/bundle/macos/*.app.tar.gz*
|
||||||
|
- id: release-info
|
||||||
|
name: Prepare release info
|
||||||
|
run: |
|
||||||
|
semver="${${{ github.ref_name }}##nym-wallet-}" && semver="${semver##v}"
|
||||||
|
echo "version=$semver" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "filename=nym-wallet_$version_x64.dmg" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/dmg/nym-wallet_*_x64.dmg') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-wallet/CHANGELOG.md
|
||||||
|
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet.app.tar.gz
|
||||||
|
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet.app.tar.gz.sig
|
||||||
|
version: ${{ needs.publish-tauri.outputs.version }}
|
||||||
|
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||||
|
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||||
|
name: Wallet
|
||||||
|
category: wallet
|
||||||
|
platform: MacOS
|
||||||
|
secrets: inherit
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
name: Publish Nym Wallet (Ubuntu)
|
name: Publish Nym Wallet (Ubuntu)
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
release:
|
release:
|
||||||
types: [created]
|
types: [created]
|
||||||
|
|
||||||
@@ -14,8 +15,15 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [custom-runner-linux]
|
platform: [custom-runner-linux]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
@@ -28,7 +36,7 @@ jobs:
|
|||||||
- name: Node v16
|
- name: Node v16
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -47,9 +55,37 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
- name: Upload to release based on tag name
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-wallet/target/release/bundle/appimage/*.AppImage
|
nym-wallet/target/release/bundle/appimage/*.AppImage
|
||||||
nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz*
|
nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz*
|
||||||
|
- id: release-info
|
||||||
|
name: Prepare release info
|
||||||
|
run: |
|
||||||
|
semver="${${{ github.ref_name }}##nym-wallet-}" && semver="${semver##v}"
|
||||||
|
echo "version=$semver" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "filename=nym-wallet_$version_amd64.AppImage" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/appimage/nym-wallet_*_amd64.AppImage') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-wallet/CHANGELOG.md
|
||||||
|
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet_${{ needs.publish-tauri.outputs.version }}_amd64.AppImage.tar.gz
|
||||||
|
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet_${{ needs.publish-tauri.outputs.version }}_amd64.AppImage.tar.gz.sig
|
||||||
|
version: ${{ needs.publish-tauri.outputs.version }}
|
||||||
|
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||||
|
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||||
|
name: Wallet
|
||||||
|
category: wallet
|
||||||
|
platform: Ubuntu
|
||||||
|
secrets: inherit
|
||||||
|
|||||||
@@ -15,8 +15,15 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [windows10]
|
platform: [windows10]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }}
|
||||||
|
version: ${{ steps.release-info.outputs.version }}
|
||||||
|
filename: ${{ steps.release-info.outputs.filename }}
|
||||||
|
file_hash: ${{ steps.release-info.outputs.file_hash }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clean up first
|
- name: Clean up first
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
@@ -42,7 +49,7 @@ jobs:
|
|||||||
- name: Node v16
|
- name: Node v16
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
|
|
||||||
- name: Install Rust stable
|
- name: Install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
@@ -75,10 +82,38 @@ jobs:
|
|||||||
path: nym-wallet/target/release/bundle/msi/nym-wallet_1.*.msi
|
path: nym-wallet/target/release/bundle/msi/nym-wallet_1.*.msi
|
||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
- name: Upload to release based on tag name
|
- id: create-release
|
||||||
|
name: Upload to release based on tag name
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
with:
|
with:
|
||||||
files: |
|
files: |
|
||||||
nym-wallet/target/release/bundle/msi/*.msi
|
nym-wallet/target/release/bundle/msi/*.msi
|
||||||
nym-wallet/target/release/bundle/msi/*.msi.zip*
|
nym-wallet/target/release/bundle/msi/*.msi.zip*
|
||||||
|
- id: release-info
|
||||||
|
name: Prepare release info
|
||||||
|
run: |
|
||||||
|
semver="${${{ github.ref_name }}##nym-wallet-}" && semver="${semver##v}"
|
||||||
|
echo "version=$semver" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "filename=nym-wallet_$version_x64_en-US.msi" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "file_hash=${{ hashFiles('nym-wallet/target/release/bundle/msi/nym-wallet_*_x64_en-US.msi') }}" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
push-release-data:
|
||||||
|
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
|
||||||
|
uses: ./.github/workflows/push-release-data.yml
|
||||||
|
needs: publish-tauri
|
||||||
|
with:
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
release_id: ${{ needs.publish-tauri.outputs.release_id }}
|
||||||
|
release_date: ${{ needs.publish-tauri.outputs.release_date }}
|
||||||
|
download_base_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}
|
||||||
|
changelog_url: https://github.com/nymtech/nym/blob/${{ github.ref_name }}/nym-wallet/CHANGELOG.md
|
||||||
|
archive_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet_${{ needs.publish-tauri.outputs.version }}_x64_en-US.msi.zip
|
||||||
|
sig_url: https://github.com/nymtech/nym/releases/download/${{ github.ref_name }}/nym-wallet_${{ needs.publish-tauri.outputs.version }}_x64_en-US.msi.zip.sig
|
||||||
|
version: ${{ needs.publish-tauri.outputs.version }}
|
||||||
|
filename: ${{ needs.publish-tauri.outputs.filename }}
|
||||||
|
file_hash: ${{ needs.publish-tauri.outputs.file_hash }}
|
||||||
|
name: Wallet
|
||||||
|
category: wallet
|
||||||
|
platform: Windows
|
||||||
|
secrets: inherit
|
||||||
|
|||||||
@@ -16,9 +16,15 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Setup yarn
|
- name: Setup yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Install wasm-pack
|
||||||
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
- name: Build dependencies
|
- name: Build dependencies
|
||||||
run: yarn && yarn build
|
run: yarn && yarn build
|
||||||
- name: Build storybook
|
- name: Build storybook
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ jobs:
|
|||||||
- name: Node v16
|
- name: Node v16
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
|
|
||||||
- name: Install yarn for building application
|
- name: Install yarn for building application
|
||||||
run: yarn install
|
run: yarn install
|
||||||
|
|||||||
@@ -68,8 +68,10 @@ jobs:
|
|||||||
working-directory: nym-connect/native/android
|
working-directory: nym-connect/native/android
|
||||||
env:
|
env:
|
||||||
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
|
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
|
||||||
|
SENTRY_AUTH_TOKEN: ${{ secrets.NYMS5_ANDROID_SENTRY_AUTH_TOKEN }}
|
||||||
# build for arm64 and x86_64
|
# build for arm64 and x86_64
|
||||||
run: |
|
run: |
|
||||||
|
echo "auth.token=$SENTRY_AUTH_TOKEN" | tee -a sentry.properties
|
||||||
./gradlew :app:assembleArch64Debug
|
./gradlew :app:assembleArch64Debug
|
||||||
./gradlew :app:assembleArch64Release
|
./gradlew :app:assembleArch64Release
|
||||||
|
|
||||||
@@ -107,4 +109,3 @@ jobs:
|
|||||||
files: |
|
files: |
|
||||||
apk/nyms5-arch64-debug.apk
|
apk/nyms5-arch64-debug.apk
|
||||||
apk/nyms5-arch64-release.apk
|
apk/nyms5-arch64-release.apk
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,211 @@
|
|||||||
|
name: Push release data
|
||||||
|
|
||||||
|
env:
|
||||||
|
strapi_download_url: 'https://strapi.feat-nym-update-nym-web.websites.dev.nymte.ch/api/downloaders'
|
||||||
|
strapi_updater_url: 'https://strapi.feat-nym-update-nym-web.websites.dev.nymte.ch/api/updaters'
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
release_tag:
|
||||||
|
required: true
|
||||||
|
description: Release tag
|
||||||
|
type: string
|
||||||
|
release_id:
|
||||||
|
required: true
|
||||||
|
description: Release ID
|
||||||
|
type: string
|
||||||
|
release_date:
|
||||||
|
required: true
|
||||||
|
description: Release date
|
||||||
|
type: string
|
||||||
|
download_base_url:
|
||||||
|
required: true
|
||||||
|
description: Download base URL
|
||||||
|
type: string
|
||||||
|
changelog_url:
|
||||||
|
required: true
|
||||||
|
description: Changelog URL
|
||||||
|
type: string
|
||||||
|
archive_url:
|
||||||
|
required: false
|
||||||
|
description: Binary archive URL
|
||||||
|
type: string
|
||||||
|
sig_url:
|
||||||
|
required: false
|
||||||
|
description: Archive signature URL
|
||||||
|
type: string
|
||||||
|
version:
|
||||||
|
required: true
|
||||||
|
description: Release version (semver)
|
||||||
|
type: string
|
||||||
|
filename:
|
||||||
|
required: true
|
||||||
|
description: Binary file name
|
||||||
|
type: string
|
||||||
|
file_hash:
|
||||||
|
required: true
|
||||||
|
description: Binary hash (sha256)
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
required: true
|
||||||
|
description: Name
|
||||||
|
type: string
|
||||||
|
category:
|
||||||
|
required: true
|
||||||
|
description: Category
|
||||||
|
type: string
|
||||||
|
platform:
|
||||||
|
required: false
|
||||||
|
description: Platform
|
||||||
|
type: string
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
# ⚠ since inputs are limited to 10 max for workflow_dispatch
|
||||||
|
# some properties were omitted
|
||||||
|
version:
|
||||||
|
required: true
|
||||||
|
description: Release version (semver)
|
||||||
|
type: string
|
||||||
|
default: '1.0.0'
|
||||||
|
release_id:
|
||||||
|
required: true
|
||||||
|
description: Release ID
|
||||||
|
type: string
|
||||||
|
default: '1234'
|
||||||
|
release_date:
|
||||||
|
required: true
|
||||||
|
description: Release date
|
||||||
|
type: string
|
||||||
|
default: '2023-06-26T10:09:16Z'
|
||||||
|
download_base_url:
|
||||||
|
required: true
|
||||||
|
description: Download base URL
|
||||||
|
type: string
|
||||||
|
default: 'https://github.com/nymtech/nym/releases/download/nym-wallet-v1.0.0'
|
||||||
|
changelog_url:
|
||||||
|
required: true
|
||||||
|
description: Changelog URL
|
||||||
|
type: string
|
||||||
|
default: 'https://github.com/nymtech/nym/blob/nym-wallet-v1.0.0/nym-wallet/CHANGELOG.md'
|
||||||
|
filename:
|
||||||
|
required: true
|
||||||
|
description: Binary file name
|
||||||
|
type: string
|
||||||
|
default: 'nym-wallet_1.0.0_amd64.AppImage'
|
||||||
|
file_hash:
|
||||||
|
required: true
|
||||||
|
description: Binary hash (sha256)
|
||||||
|
type: string
|
||||||
|
default: 'xxx'
|
||||||
|
name:
|
||||||
|
required: true
|
||||||
|
description: Name
|
||||||
|
type: string
|
||||||
|
default: 'Wallet'
|
||||||
|
category:
|
||||||
|
required: true
|
||||||
|
description: Category
|
||||||
|
default: 'wallet'
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- wallet
|
||||||
|
- connect
|
||||||
|
- binaries
|
||||||
|
platform:
|
||||||
|
required: false
|
||||||
|
description: Platform
|
||||||
|
default: 'Ubuntu'
|
||||||
|
type: choice
|
||||||
|
options:
|
||||||
|
- Ubuntu
|
||||||
|
- Windows
|
||||||
|
- MacOS
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
push-download-data:
|
||||||
|
name: Push download data to Strapi
|
||||||
|
runs-on: custom-runner-linux
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Release info
|
||||||
|
run: |
|
||||||
|
echo "version: ${{ inputs.version }}"
|
||||||
|
echo "tag: ${{ inputs.release_tag }}"
|
||||||
|
- id: get_sig
|
||||||
|
name: Get sig
|
||||||
|
if: ${{ inputs.sig_url != null }}
|
||||||
|
run: |
|
||||||
|
output=$(curl -LsSf ${{ inputs.sig_url }})
|
||||||
|
echo "sig=$output" >> "$GITHUB_OUTPUT"
|
||||||
|
- id: strapi-request
|
||||||
|
name: Strapi request
|
||||||
|
uses: fjogeleit/http-request-action@v1
|
||||||
|
with:
|
||||||
|
url: ${{ env.strapi_download_url }}
|
||||||
|
method: 'POST'
|
||||||
|
bearerToken: ${{ secrets.STRAPI_API_TOKEN_RELEASES }}
|
||||||
|
customHeaders: '{"Content-Type": "application/json"}'
|
||||||
|
data: |
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"releaseId": "${{ inputs.release_id }}",
|
||||||
|
"releaseDate": "${{ inputs.release_date }}",
|
||||||
|
"downloadBaseUrl": "${{ inputs.download_base_url }}",
|
||||||
|
"changelogUrl": "${{ inputs.changelog_url }}",
|
||||||
|
"version": "${{ inputs.version }}",
|
||||||
|
"filename": "${{ inputs.filename }}",
|
||||||
|
"name": "${{ inputs.name }}",
|
||||||
|
"category": "${{ inputs.category }}",
|
||||||
|
"platform": "${{ inputs.platform }}",
|
||||||
|
"sha256": "${{ inputs.file_hash }}",
|
||||||
|
"sig": "${{ steps.get_sig.outputs.sig }}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- name: Strapi Response
|
||||||
|
run: |
|
||||||
|
echo ${{ steps.strapi-request.outputs.response }}
|
||||||
|
|
||||||
|
push-update-data:
|
||||||
|
name: Push update data to Strapi
|
||||||
|
runs-on: custom-runner-linux
|
||||||
|
# only push update data for tauri apps (desktop wallet and NC)
|
||||||
|
if: ${{ inputs.category == 'wallet' || inputs.category == 'connect' }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Release info
|
||||||
|
run: |
|
||||||
|
echo "version: ${{ inputs.version }}"
|
||||||
|
echo "tag: ${{ inputs.release_tag }}"
|
||||||
|
- id: get_sig
|
||||||
|
name: Get sig
|
||||||
|
if: ${{ inputs.sig_url != null }}
|
||||||
|
run: |
|
||||||
|
output=$(curl -LsSf ${{ inputs.sig_url }})
|
||||||
|
echo "sig=$output" >> "$GITHUB_OUTPUT"
|
||||||
|
- id: strapi-request
|
||||||
|
name: Strapi request
|
||||||
|
uses: fjogeleit/http-request-action@v1
|
||||||
|
with:
|
||||||
|
url: ${{ env.strapi_updater_url }}
|
||||||
|
method: 'POST'
|
||||||
|
bearerToken: ${{ secrets.STRAPI_API_TOKEN_RELEASES }}
|
||||||
|
customHeaders: '{"Content-Type": "application/json"}'
|
||||||
|
data: |
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"releaseId": "${{ inputs.release_id }}",
|
||||||
|
"releaseDate": "${{ inputs.release_date }}",
|
||||||
|
"downloadUrl": "${{ inputs.archive_url }}",
|
||||||
|
"changelog": "See ${{ inputs.changelog_url }} for the changelog",
|
||||||
|
"version": "${{ inputs.version }}",
|
||||||
|
"filename": "${{ inputs.filename }}",
|
||||||
|
"category": "${{ inputs.category }}",
|
||||||
|
"platform": "${{ inputs.platform }}",
|
||||||
|
"sha256": "${{ inputs.file_hash }}",
|
||||||
|
"sig": "${{ steps.get_sig.outputs.sig }}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- name: Strapi Response
|
||||||
|
run: |
|
||||||
|
echo ${{ steps.strapi-request.outputs.response }}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
name: Publish SDK to NPM
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: sdk/typescript/packages/sdk
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: [custom-runner-linux]
|
||||||
|
steps:
|
||||||
|
- name: Install Node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
|
||||||
|
- name: Setup yarn
|
||||||
|
run: npm install -g yarn
|
||||||
@@ -1 +1 @@
|
|||||||
16
|
18
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ on:
|
|||||||
- 'nym-connect/mobile/package.json'
|
- 'nym-connect/mobile/package.json'
|
||||||
- 'nym-wallet/src/**'
|
- 'nym-wallet/src/**'
|
||||||
- 'nym-wallet/package.json'
|
- 'nym-wallet/package.json'
|
||||||
|
- 'explorer/**'
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'ts-packages/**'
|
- 'ts-packages/**'
|
||||||
@@ -21,6 +22,7 @@ on:
|
|||||||
- 'nym-connect/mobile/package.json'
|
- 'nym-connect/mobile/package.json'
|
||||||
- 'nym-wallet/src/**'
|
- 'nym-wallet/src/**'
|
||||||
- 'nym-wallet/package.json'
|
- 'nym-wallet/package.json'
|
||||||
|
- 'explorer/**'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -33,9 +35,15 @@ jobs:
|
|||||||
- uses: rlespinasse/github-slug-action@v3.x
|
- uses: rlespinasse/github-slug-action@v3.x
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 18
|
||||||
- name: Setup yarn
|
- name: Setup yarn
|
||||||
run: npm install -g yarn
|
run: npm install -g yarn
|
||||||
|
- name: Install Rust stable
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
toolchain: stable
|
||||||
|
- name: Install wasm-pack
|
||||||
|
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||||
- name: Install
|
- name: Install
|
||||||
run: yarn
|
run: yarn
|
||||||
- name: Build packages
|
- name: Build packages
|
||||||
|
|||||||
@@ -4,6 +4,14 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [1.1.23] (2023-06-27)
|
||||||
|
|
||||||
|
- nym-cli: add client identity key signing support ([#3576])
|
||||||
|
- Don't fully turn off background task when cover traffic is disabled ([#3596])
|
||||||
|
|
||||||
|
[#3576]: https://github.com/nymtech/nym/issues/3576
|
||||||
|
[#3596]: https://github.com/nymtech/nym/pull/3596
|
||||||
|
|
||||||
## [v1.1.22] (2023-06-20)
|
## [v1.1.22] (2023-06-20)
|
||||||
|
|
||||||
- CLI tool for querying network-requesters ([#3539])
|
- CLI tool for querying network-requesters ([#3539])
|
||||||
|
|||||||
Generated
+24
-14
@@ -1732,7 +1732,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "explorer-api"
|
name = "explorer-api"
|
||||||
version = "1.1.22"
|
version = "1.1.23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 4.2.7",
|
"clap 4.2.7",
|
||||||
@@ -3322,7 +3322,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-api"
|
name = "nym-api"
|
||||||
version = "1.1.23"
|
version = "1.1.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -3459,7 +3459,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-cli"
|
name = "nym-cli"
|
||||||
version = "1.1.22"
|
version = "1.1.23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
@@ -3507,8 +3507,10 @@ dependencies = [
|
|||||||
"nym-multisig-contract-common",
|
"nym-multisig-contract-common",
|
||||||
"nym-name-service-common",
|
"nym-name-service-common",
|
||||||
"nym-network-defaults",
|
"nym-network-defaults",
|
||||||
|
"nym-pemstore",
|
||||||
"nym-service-provider-directory-common",
|
"nym-service-provider-directory-common",
|
||||||
"nym-sphinx",
|
"nym-sphinx",
|
||||||
|
"nym-types",
|
||||||
"nym-validator-client",
|
"nym-validator-client",
|
||||||
"nym-vesting-contract-common",
|
"nym-vesting-contract-common",
|
||||||
"rand 0.6.5",
|
"rand 0.6.5",
|
||||||
@@ -3523,7 +3525,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-client"
|
name = "nym-client"
|
||||||
version = "1.1.22"
|
version = "1.1.23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 4.2.7",
|
"clap 4.2.7",
|
||||||
"dirs 4.0.0",
|
"dirs 4.0.0",
|
||||||
@@ -3797,7 +3799,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-gateway"
|
name = "nym-gateway"
|
||||||
version = "1.1.22"
|
version = "1.1.23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -3948,7 +3950,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-mixnode"
|
name = "nym-mixnode"
|
||||||
version = "1.1.23"
|
version = "1.1.24"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bs58",
|
"bs58",
|
||||||
@@ -4039,8 +4041,12 @@ name = "nym-name-service-common"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
|
"cw-controllers",
|
||||||
|
"cw-utils",
|
||||||
|
"nym-contracts-common",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -4058,7 +4064,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-network-requester"
|
name = "nym-network-requester"
|
||||||
version = "1.1.22"
|
version = "1.1.23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-file-watcher",
|
"async-file-watcher",
|
||||||
@@ -4090,6 +4096,7 @@ dependencies = [
|
|||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"publicsuffix",
|
"publicsuffix",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@@ -4104,7 +4111,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-network-statistics"
|
name = "nym-network-statistics"
|
||||||
version = "1.1.22"
|
version = "1.1.23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs 4.0.0",
|
"dirs 4.0.0",
|
||||||
"log",
|
"log",
|
||||||
@@ -4263,7 +4270,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-socks5-client"
|
name = "nym-socks5-client"
|
||||||
version = "1.1.22"
|
version = "1.1.23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 4.2.7",
|
"clap 4.2.7",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@@ -4402,6 +4409,7 @@ dependencies = [
|
|||||||
"nym-pemstore",
|
"nym-pemstore",
|
||||||
"nym-sphinx-addressing",
|
"nym-sphinx-addressing",
|
||||||
"nym-sphinx-params",
|
"nym-sphinx-params",
|
||||||
|
"nym-sphinx-routing",
|
||||||
"nym-sphinx-types",
|
"nym-sphinx-types",
|
||||||
"nym-topology",
|
"nym-topology",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
@@ -4429,6 +4437,7 @@ dependencies = [
|
|||||||
"nym-crypto",
|
"nym-crypto",
|
||||||
"nym-sphinx-addressing",
|
"nym-sphinx-addressing",
|
||||||
"nym-sphinx-params",
|
"nym-sphinx-params",
|
||||||
|
"nym-sphinx-routing",
|
||||||
"nym-sphinx-types",
|
"nym-sphinx-types",
|
||||||
"nym-topology",
|
"nym-topology",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
@@ -4460,6 +4469,7 @@ dependencies = [
|
|||||||
"nym-sphinx-chunking",
|
"nym-sphinx-chunking",
|
||||||
"nym-sphinx-forwarding",
|
"nym-sphinx-forwarding",
|
||||||
"nym-sphinx-params",
|
"nym-sphinx-params",
|
||||||
|
"nym-sphinx-routing",
|
||||||
"nym-sphinx-types",
|
"nym-sphinx-types",
|
||||||
"nym-topology",
|
"nym-topology",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
@@ -5701,13 +5711,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.8.1"
|
version = "1.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
|
checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
"regex-syntax 0.7.1",
|
"regex-syntax 0.7.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -5727,9 +5737,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.7.1"
|
version = "0.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c"
|
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ The credential binary is still experimental software. The infrastructure for usi
|
|||||||
|
|
||||||
From the project's root directory, run:
|
From the project's root directory, run:
|
||||||
```
|
```
|
||||||
cargo build -p credential
|
cargo build -p nym-credential-client
|
||||||
```
|
```
|
||||||
which generates the `credential` binary in `target/debug/credential`.
|
which generates the `nym-credential-client` binary in `target/debug/nym-credential-client`.
|
||||||
|
|
||||||
|
|
||||||
### Running
|
### Running
|
||||||
@@ -25,7 +25,7 @@ which generates the `credential` binary in `target/debug/credential`.
|
|||||||
For example, you can get a credential worth 3 nym (3000000 unym) in a socks5 client that was already initialized like so:
|
For example, you can get a credential worth 3 nym (3000000 unym) in a socks5 client that was already initialized like so:
|
||||||
|
|
||||||
```
|
```
|
||||||
./target/debug/credential --config-env-file envs/sandbox.env --client-home-directory ~/.nym/socks5-clients/cred_client --nyxd-url https://sandbox-validator1.nymtech.net --mnemonic $MNEMONIC --recovery-dir /tmp/recovery --amount 3000000
|
./target/debug/nym-credential-client --config-env-file envs/sandbox.env --client-home-directory ~/.nym/socks5-clients/cred_client --nyxd-url https://sandbox-validator1.nymtech.net --mnemonic $MNEMONIC --recovery-dir /tmp/recovery --amount 3000000
|
||||||
```
|
```
|
||||||
|
|
||||||
More information regarding how to run the binary can be found by running it with the `--help` argument.
|
More information regarding how to run the binary can be found by running it with the `--help` argument.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-client"
|
name = "nym-client"
|
||||||
version = "1.1.22"
|
version = "1.1.23"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||||
description = "Implementation of the Nym Client"
|
description = "Implementation of the Nym Client"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ use std::net::IpAddr;
|
|||||||
|
|
||||||
pub(crate) mod init;
|
pub(crate) mod init;
|
||||||
pub(crate) mod run;
|
pub(crate) mod run;
|
||||||
pub(crate) mod upgrade;
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref PRETTY_BUILD_INFORMATION: String =
|
pub static ref PRETTY_BUILD_INFORMATION: String =
|
||||||
@@ -51,10 +50,9 @@ pub(crate) struct Cli {
|
|||||||
pub(crate) enum Commands {
|
pub(crate) enum Commands {
|
||||||
/// Initialise a Nym client. Do this first!
|
/// Initialise a Nym client. Do this first!
|
||||||
Init(init::Init),
|
Init(init::Init),
|
||||||
|
|
||||||
/// Run the Nym client with provided configuration client optionally overriding set parameters
|
/// Run the Nym client with provided configuration client optionally overriding set parameters
|
||||||
Run(run::Run),
|
Run(run::Run),
|
||||||
/// Try to upgrade the client
|
|
||||||
Upgrade(upgrade::Upgrade),
|
|
||||||
|
|
||||||
/// Generate shell completions
|
/// Generate shell completions
|
||||||
Completions(ArgShell),
|
Completions(ArgShell),
|
||||||
@@ -81,7 +79,6 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Syn
|
|||||||
match &args.command {
|
match &args.command {
|
||||||
Commands::Init(m) => init::execute(m).await?,
|
Commands::Init(m) => init::execute(m).await?,
|
||||||
Commands::Run(m) => run::execute(m).await?,
|
Commands::Run(m) => run::execute(m).await?,
|
||||||
Commands::Upgrade(m) => upgrade::execute(m),
|
|
||||||
Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name),
|
Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name),
|
||||||
Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name),
|
Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::client::config::Config;
|
|
||||||
use crate::commands::try_load_current_config;
|
|
||||||
use clap::Args;
|
|
||||||
use nym_bin_common::version_checker::Version;
|
|
||||||
use std::process;
|
|
||||||
|
|
||||||
fn unimplemented_upgrade(current_version: &Version, config_version: &Version) -> ! {
|
|
||||||
eprintln!("Cannot perform upgrade from {config_version} to {current_version} as it hasn't been implemented yet");
|
|
||||||
process::exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Args, Clone)]
|
|
||||||
pub(crate) struct Upgrade {
|
|
||||||
/// Id of the nym-client we want to upgrade
|
|
||||||
#[clap(long)]
|
|
||||||
id: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_config_version(config: &Config) -> Version {
|
|
||||||
let version = Version::parse(&config.base.client.version).unwrap_or_else(|err| {
|
|
||||||
eprintln!("failed to parse client version! - {err}");
|
|
||||||
process::exit(1)
|
|
||||||
});
|
|
||||||
|
|
||||||
if version.is_prerelease() || !version.build.is_empty() {
|
|
||||||
eprintln!(
|
|
||||||
"Trying to upgrade from a non-released version {version}. This is not supported!"
|
|
||||||
);
|
|
||||||
process::exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
version
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_package_version() -> Version {
|
|
||||||
let version = Version::parse(env!("CARGO_PKG_VERSION")).unwrap();
|
|
||||||
|
|
||||||
// technically this is not a correct way of checking it as a released version might contain valid build identifiers
|
|
||||||
// however, we are not using them ourselves at the moment and hence it should be fine.
|
|
||||||
// if we change our mind, we could easily tweak this code
|
|
||||||
if version.is_prerelease() || !version.build.is_empty() {
|
|
||||||
eprintln!("Trying to upgrade to a non-released version {version}. This is not supported!");
|
|
||||||
process::exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
version
|
|
||||||
}
|
|
||||||
|
|
||||||
fn do_upgrade(config: Config, _args: &Upgrade, package_version: &Version) {
|
|
||||||
let config_version = parse_config_version(&config);
|
|
||||||
if &config_version == package_version {
|
|
||||||
println!("You're using the most recent version!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unimplemented_upgrade(package_version, &config_version)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn execute(args: &Upgrade) {
|
|
||||||
let package_version = parse_package_version();
|
|
||||||
|
|
||||||
let id = &args.id;
|
|
||||||
|
|
||||||
let existing_config = try_load_current_config(id).unwrap_or_else(|err| {
|
|
||||||
eprintln!("failed to load existing config file! - {err}");
|
|
||||||
process::exit(1)
|
|
||||||
});
|
|
||||||
|
|
||||||
if existing_config.base.client.version.is_empty() {
|
|
||||||
eprintln!("the existing configuration file does not seem to contain version number.");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
do_upgrade(existing_config, args, &package_version)
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// all variable size data is always prefixed with u64 length
|
// all variable size data is always prefixed with u64 length
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// all variable size data is always prefixed with u64 length
|
// all variable size data is always prefixed with u64 length
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::error::ErrorKind;
|
use crate::error::ErrorKind;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-socks5-client"
|
name = "nym-socks5-client"
|
||||||
version = "1.1.22"
|
version = "1.1.23"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ impl From<Init> for OverrideConfig {
|
|||||||
use_anonymous_replies: init_config.use_reply_surbs,
|
use_anonymous_replies: init_config.use_reply_surbs,
|
||||||
fastmode: init_config.fastmode,
|
fastmode: init_config.fastmode,
|
||||||
no_cover: init_config.no_cover,
|
no_cover: init_config.no_cover,
|
||||||
|
medium_toggle: false,
|
||||||
nyxd_urls: init_config.nyxd_urls,
|
nyxd_urls: init_config.nyxd_urls,
|
||||||
enabled_credentials_mode: init_config.enabled_credentials_mode,
|
enabled_credentials_mode: init_config.enabled_credentials_mode,
|
||||||
outfox: false,
|
outfox: false,
|
||||||
|
|||||||
@@ -19,12 +19,11 @@ use nym_client_core::client::key_manager::persistence::OnDiskKeys;
|
|||||||
use nym_client_core::config::GatewayEndpointConfig;
|
use nym_client_core::config::GatewayEndpointConfig;
|
||||||
use nym_client_core::error::ClientCoreError;
|
use nym_client_core::error::ClientCoreError;
|
||||||
use nym_config::OptionalSet;
|
use nym_config::OptionalSet;
|
||||||
use nym_sphinx::params::PacketType;
|
use nym_sphinx::params::{PacketSize, PacketType};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
pub mod init;
|
pub mod init;
|
||||||
pub(crate) mod run;
|
pub(crate) mod run;
|
||||||
pub(crate) mod upgrade;
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref PRETTY_BUILD_INFORMATION: String =
|
pub static ref PRETTY_BUILD_INFORMATION: String =
|
||||||
@@ -55,9 +54,6 @@ pub(crate) enum Commands {
|
|||||||
/// Run the Nym client with provided configuration client optionally overriding set parameters
|
/// Run the Nym client with provided configuration client optionally overriding set parameters
|
||||||
Run(run::Run),
|
Run(run::Run),
|
||||||
|
|
||||||
/// Try to upgrade the client
|
|
||||||
Upgrade(upgrade::Upgrade),
|
|
||||||
|
|
||||||
/// Generate shell completions
|
/// Generate shell completions
|
||||||
Completions(ArgShell),
|
Completions(ArgShell),
|
||||||
|
|
||||||
@@ -72,6 +68,7 @@ pub(crate) struct OverrideConfig {
|
|||||||
use_anonymous_replies: Option<bool>,
|
use_anonymous_replies: Option<bool>,
|
||||||
fastmode: bool,
|
fastmode: bool,
|
||||||
no_cover: bool,
|
no_cover: bool,
|
||||||
|
medium_toggle: bool,
|
||||||
nyxd_urls: Option<Vec<url::Url>>,
|
nyxd_urls: Option<Vec<url::Url>>,
|
||||||
enabled_credentials_mode: Option<bool>,
|
enabled_credentials_mode: Option<bool>,
|
||||||
outfox: bool,
|
outfox: bool,
|
||||||
@@ -83,7 +80,6 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Syn
|
|||||||
match &args.command {
|
match &args.command {
|
||||||
Commands::Init(m) => init::execute(m).await?,
|
Commands::Init(m) => init::execute(m).await?,
|
||||||
Commands::Run(m) => run::execute(m).await?,
|
Commands::Run(m) => run::execute(m).await?,
|
||||||
Commands::Upgrade(m) => upgrade::execute(m),
|
|
||||||
Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name),
|
Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name),
|
||||||
Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name),
|
Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name),
|
||||||
}
|
}
|
||||||
@@ -91,6 +87,10 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Syn
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
||||||
|
let disable_cover_traffic_with_keepalive = args.medium_toggle;
|
||||||
|
let secondary_packet_size = args.medium_toggle.then_some(PacketSize::ExtendedPacket16);
|
||||||
|
let no_per_hop_delays = args.medium_toggle;
|
||||||
|
|
||||||
let packet_type = if args.outfox {
|
let packet_type = if args.outfox {
|
||||||
PacketType::Outfox
|
PacketType::Outfox
|
||||||
} else {
|
} else {
|
||||||
@@ -101,6 +101,17 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
|||||||
BaseClientConfig::with_high_default_traffic_volume,
|
BaseClientConfig::with_high_default_traffic_volume,
|
||||||
args.fastmode,
|
args.fastmode,
|
||||||
)
|
)
|
||||||
|
.with_base(
|
||||||
|
// NOTE: This interacts with disabling cover traffic fully, so we want to this to be set before
|
||||||
|
BaseClientConfig::with_disabled_cover_traffic_with_keepalive,
|
||||||
|
disable_cover_traffic_with_keepalive,
|
||||||
|
)
|
||||||
|
.with_base(
|
||||||
|
BaseClientConfig::with_secondary_packet_size,
|
||||||
|
secondary_packet_size,
|
||||||
|
)
|
||||||
|
.with_base(BaseClientConfig::with_no_per_hop_delays, no_per_hop_delays)
|
||||||
|
// NOTE: see comment above about the order of the other disble cover traffic config
|
||||||
.with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover)
|
.with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover)
|
||||||
.with_base(BaseClientConfig::with_packet_type, packet_type)
|
.with_base(BaseClientConfig::with_packet_type, packet_type)
|
||||||
.with_optional(Config::with_anonymous_replies, args.use_anonymous_replies)
|
.with_optional(Config::with_anonymous_replies, args.use_anonymous_replies)
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ pub(crate) struct Run {
|
|||||||
#[clap(long, hide = true)]
|
#[clap(long, hide = true)]
|
||||||
no_cover: bool,
|
no_cover: bool,
|
||||||
|
|
||||||
|
/// Enable medium mixnet traffic, for experiments only.
|
||||||
|
/// This includes things like disabling cover traffic, no per hop delays, etc.
|
||||||
|
#[clap(long, hide = true)]
|
||||||
|
medium_toggle: bool,
|
||||||
|
|
||||||
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
|
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
|
||||||
/// with bandwidth credential requirement.
|
/// with bandwidth credential requirement.
|
||||||
#[clap(long, hide = true)]
|
#[clap(long, hide = true)]
|
||||||
@@ -77,6 +82,7 @@ impl From<Run> for OverrideConfig {
|
|||||||
use_anonymous_replies: run_config.use_anonymous_replies,
|
use_anonymous_replies: run_config.use_anonymous_replies,
|
||||||
fastmode: run_config.fastmode,
|
fastmode: run_config.fastmode,
|
||||||
no_cover: run_config.no_cover,
|
no_cover: run_config.no_cover,
|
||||||
|
medium_toggle: run_config.medium_toggle,
|
||||||
nyxd_urls: run_config.nyxd_urls,
|
nyxd_urls: run_config.nyxd_urls,
|
||||||
enabled_credentials_mode: run_config.enabled_credentials_mode,
|
enabled_credentials_mode: run_config.enabled_credentials_mode,
|
||||||
outfox: run_config.outfox,
|
outfox: run_config.outfox,
|
||||||
|
|||||||
@@ -1,78 +0,0 @@
|
|||||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use crate::commands::try_load_current_config;
|
|
||||||
use crate::config::Config;
|
|
||||||
use clap::Args;
|
|
||||||
use nym_bin_common::version_checker::Version;
|
|
||||||
use std::process;
|
|
||||||
|
|
||||||
fn unimplemented_upgrade(current_version: &Version, config_version: &Version) -> ! {
|
|
||||||
eprintln!("Cannot perform upgrade from {config_version} to {current_version} as it hasn't been implemented yet");
|
|
||||||
process::exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Args, Clone)]
|
|
||||||
pub(crate) struct Upgrade {
|
|
||||||
/// Id of the nym-client we want to upgrade
|
|
||||||
#[clap(long)]
|
|
||||||
id: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_config_version(config: &Config) -> Version {
|
|
||||||
let version = Version::parse(&config.core.base.client.version).unwrap_or_else(|err| {
|
|
||||||
eprintln!("failed to parse client version! - {err}");
|
|
||||||
process::exit(1)
|
|
||||||
});
|
|
||||||
|
|
||||||
if version.is_prerelease() || !version.build.is_empty() {
|
|
||||||
eprintln!(
|
|
||||||
"Trying to upgrade from a non-released version {version}. This is not supported!"
|
|
||||||
);
|
|
||||||
process::exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
version
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_package_version() -> Version {
|
|
||||||
let version = Version::parse(env!("CARGO_PKG_VERSION")).unwrap();
|
|
||||||
|
|
||||||
// technically this is not a correct way of checking it as a released version might contain valid build identifiers
|
|
||||||
// however, we are not using them ourselves at the moment and hence it should be fine.
|
|
||||||
// if we change our mind, we could easily tweak this code
|
|
||||||
if version.is_prerelease() || !version.build.is_empty() {
|
|
||||||
eprintln!("Trying to upgrade to a non-released version {version}. This is not supported!");
|
|
||||||
process::exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
version
|
|
||||||
}
|
|
||||||
|
|
||||||
fn do_upgrade(config: Config, _args: &Upgrade, package_version: &Version) {
|
|
||||||
let config_version = parse_config_version(&config);
|
|
||||||
if &config_version == package_version {
|
|
||||||
println!("You're using the most recent version!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unimplemented_upgrade(package_version, &config_version)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn execute(args: &Upgrade) {
|
|
||||||
let package_version = parse_package_version();
|
|
||||||
|
|
||||||
let id = &args.id;
|
|
||||||
|
|
||||||
let existing_config = try_load_current_config(id).unwrap_or_else(|err| {
|
|
||||||
eprintln!("failed to load existing config file! - {err}");
|
|
||||||
process::exit(1)
|
|
||||||
});
|
|
||||||
|
|
||||||
if existing_config.core.base.client.version.is_empty() {
|
|
||||||
eprintln!("the existing configuration file does not seem to contain version number.");
|
|
||||||
process::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
do_upgrade(existing_config, args, &package_version)
|
|
||||||
}
|
|
||||||
@@ -1 +1 @@
|
|||||||
16
|
18
|
||||||
Generated
+21
-3
@@ -2240,7 +2240,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-bin-common"
|
name = "nym-bin-common"
|
||||||
version = "0.5.0"
|
version = "0.6.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"clap",
|
"clap",
|
||||||
@@ -2255,7 +2255,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-client-core"
|
name = "nym-client-core"
|
||||||
version = "1.1.14"
|
version = "1.1.15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.21.2",
|
"base64 0.21.2",
|
||||||
@@ -2300,7 +2300,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-client-wasm"
|
name = "nym-client-wasm"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -2580,8 +2580,12 @@ name = "nym-name-service-common"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
|
"cw-controllers",
|
||||||
|
"cw-utils",
|
||||||
|
"nym-contracts-common",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2697,6 +2701,7 @@ dependencies = [
|
|||||||
"nym-pemstore",
|
"nym-pemstore",
|
||||||
"nym-sphinx-addressing",
|
"nym-sphinx-addressing",
|
||||||
"nym-sphinx-params",
|
"nym-sphinx-params",
|
||||||
|
"nym-sphinx-routing",
|
||||||
"nym-sphinx-types",
|
"nym-sphinx-types",
|
||||||
"nym-topology",
|
"nym-topology",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
@@ -2723,6 +2728,7 @@ dependencies = [
|
|||||||
"nym-crypto",
|
"nym-crypto",
|
||||||
"nym-sphinx-addressing",
|
"nym-sphinx-addressing",
|
||||||
"nym-sphinx-params",
|
"nym-sphinx-params",
|
||||||
|
"nym-sphinx-routing",
|
||||||
"nym-sphinx-types",
|
"nym-sphinx-types",
|
||||||
"nym-topology",
|
"nym-topology",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
@@ -2753,6 +2759,7 @@ dependencies = [
|
|||||||
"nym-sphinx-chunking",
|
"nym-sphinx-chunking",
|
||||||
"nym-sphinx-forwarding",
|
"nym-sphinx-forwarding",
|
||||||
"nym-sphinx-params",
|
"nym-sphinx-params",
|
||||||
|
"nym-sphinx-routing",
|
||||||
"nym-sphinx-types",
|
"nym-sphinx-types",
|
||||||
"nym-topology",
|
"nym-topology",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
@@ -2884,6 +2891,7 @@ dependencies = [
|
|||||||
"nym-service-provider-directory-common",
|
"nym-service-provider-directory-common",
|
||||||
"nym-vesting-contract",
|
"nym-vesting-contract",
|
||||||
"nym-vesting-contract-common",
|
"nym-vesting-contract-common",
|
||||||
|
"openssl",
|
||||||
"prost",
|
"prost",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -2974,6 +2982,15 @@ version = "0.1.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openssl-src"
|
||||||
|
version = "111.26.0+1.1.1u"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.87"
|
version = "0.9.87"
|
||||||
@@ -2982,6 +2999,7 @@ checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
|
"openssl-src",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -3,3 +3,6 @@ clippy:
|
|||||||
|
|
||||||
test:
|
test:
|
||||||
wasm-pack test --node
|
wasm-pack test --node
|
||||||
|
|
||||||
|
wasm-build:
|
||||||
|
wasm-pack build
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack --config webpack.config.js",
|
"build": "webpack --config webpack.config.js",
|
||||||
|
"build:wasm": "cd ../ && make wasm-build",
|
||||||
"start": "webpack-dev-server --port 8001"
|
"start": "webpack-dev-server --port 8001"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -36,4 +37,4 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nymproject/nym-client-wasm": "file:../pkg"
|
"@nymproject/nym-client-wasm": "file:../pkg"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,333 +12,371 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
importScripts('nym_client_wasm.js');
|
importScripts("nym_client_wasm.js");
|
||||||
|
|
||||||
console.log('Initializing worker');
|
console.log("Initializing worker");
|
||||||
|
|
||||||
// wasm_bindgen creates a global variable (with the exports attached) that is in scope after `importScripts`
|
// wasm_bindgen creates a global variable (with the exports attached) that is in scope after `importScripts`
|
||||||
const {
|
const {
|
||||||
NymNodeTester,
|
NymNodeTester,
|
||||||
WasmGateway,
|
WasmGateway,
|
||||||
WasmMixNode,
|
WasmMixNode,
|
||||||
WasmNymTopology,
|
WasmNymTopology,
|
||||||
default_debug,
|
default_debug,
|
||||||
NymClientBuilder,
|
NymClientBuilder,
|
||||||
NymClient,
|
NymClient,
|
||||||
set_panic_hook,
|
set_panic_hook,
|
||||||
Config,
|
Config,
|
||||||
GatewayEndpointConfig,
|
GatewayEndpointConfig,
|
||||||
ClientStorage,
|
ClientStorage,
|
||||||
current_network_topology,
|
current_network_topology,
|
||||||
make_key,
|
make_key,
|
||||||
make_key2
|
make_key2,
|
||||||
} = wasm_bindgen;
|
} = wasm_bindgen;
|
||||||
|
|
||||||
let client = null;
|
let client = null;
|
||||||
let tester = null;
|
let tester = null;
|
||||||
|
|
||||||
|
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
|
||||||
|
|
||||||
function dummyTopology() {
|
function dummyTopology() {
|
||||||
const l1Mixnode = new WasmMixNode(
|
const l1Mixnode = new WasmMixNode(
|
||||||
1,
|
1,
|
||||||
'n1fzv4jc7fanl9s0qj02ge2ezk3kts545kjtek47',
|
"n1fzv4jc7fanl9s0qj02ge2ezk3kts545kjtek47",
|
||||||
'178.79.143.65',
|
"178.79.143.65",
|
||||||
1789,
|
1789,
|
||||||
'4Yr4qmEHd9sgsuQ83191FR2hD88RfsbMmB4tzhhZWriz',
|
"4Yr4qmEHd9sgsuQ83191FR2hD88RfsbMmB4tzhhZWriz",
|
||||||
'8ndjk5oZ6HxUZNScLJJ7hk39XtUqGexdKgW7hSX6kpWG',
|
"8ndjk5oZ6HxUZNScLJJ7hk39XtUqGexdKgW7hSX6kpWG",
|
||||||
1,
|
1,
|
||||||
'1.10.0',
|
"1.10.0"
|
||||||
);
|
);
|
||||||
const l2Mixnode = new WasmMixNode(
|
const l2Mixnode = new WasmMixNode(
|
||||||
2,
|
2,
|
||||||
'n1z93z44vf8ssvdhujjvxcj4rd5e3lz0l60wdk70',
|
"n1z93z44vf8ssvdhujjvxcj4rd5e3lz0l60wdk70",
|
||||||
'109.74.197.180',
|
"109.74.197.180",
|
||||||
1789,
|
1789,
|
||||||
'7sVjiMrPYZrDWRujku9QLxgE8noT7NTgBAqizCsu7AoK',
|
"7sVjiMrPYZrDWRujku9QLxgE8noT7NTgBAqizCsu7AoK",
|
||||||
'GepXwRnKZDd8x2nBWAajGGBVvF3mrpVMQBkgfrGuqRCN',
|
"GepXwRnKZDd8x2nBWAajGGBVvF3mrpVMQBkgfrGuqRCN",
|
||||||
2,
|
2,
|
||||||
'1.10.0',
|
"1.10.0"
|
||||||
);
|
);
|
||||||
const l3Mixnode = new WasmMixNode(
|
const l3Mixnode = new WasmMixNode(
|
||||||
3,
|
3,
|
||||||
'n1ptg680vnmef2cd8l0s9uyc4f0hgf3x8sed6w77',
|
"n1ptg680vnmef2cd8l0s9uyc4f0hgf3x8sed6w77",
|
||||||
'176.58.101.80',
|
"176.58.101.80",
|
||||||
1789,
|
1789,
|
||||||
'FoM5Mx9Pxk1g3zEqkS3APgtBeTtTo3M8k7Yu4bV6kK1R',
|
"FoM5Mx9Pxk1g3zEqkS3APgtBeTtTo3M8k7Yu4bV6kK1R",
|
||||||
'DeYjrDC2AcQRVFshiKnbUo6bRvPyZ33QGYR2DLeFJ9qD',
|
"DeYjrDC2AcQRVFshiKnbUo6bRvPyZ33QGYR2DLeFJ9qD",
|
||||||
3,
|
3,
|
||||||
'1.10.0',
|
"1.10.0"
|
||||||
);
|
);
|
||||||
|
|
||||||
const gateway = new WasmGateway(
|
const gateway = new WasmGateway(
|
||||||
'n16evnn8glr0sham3matj8rg2s24m6x56ayk87ts',
|
"n16evnn8glr0sham3matj8rg2s24m6x56ayk87ts",
|
||||||
'85.159.212.96',
|
"85.159.212.96",
|
||||||
1789,
|
1789,
|
||||||
9000,
|
9000,
|
||||||
'336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9',
|
"336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9",
|
||||||
'BtYjoWihiuFihGKQypmpSspbhmWDPxzqeTVSd8ciCpWL',
|
"BtYjoWihiuFihGKQypmpSspbhmWDPxzqeTVSd8ciCpWL",
|
||||||
'1.10.1',
|
"1.10.1"
|
||||||
);
|
);
|
||||||
|
|
||||||
const mixnodes = new Map();
|
const mixnodes = new Map();
|
||||||
mixnodes.set(1, [l1Mixnode]);
|
mixnodes.set(1, [l1Mixnode]);
|
||||||
mixnodes.set(2, [l2Mixnode]);
|
mixnodes.set(2, [l2Mixnode]);
|
||||||
mixnodes.set(3, [l3Mixnode]);
|
mixnodes.set(3, [l3Mixnode]);
|
||||||
|
|
||||||
|
const gateways = [gateway];
|
||||||
|
|
||||||
const gateways = [gateway];
|
return new WasmNymTopology(mixnodes, gateways);
|
||||||
|
|
||||||
return new WasmNymTopology(mixnodes, gateways)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function printAndDisplayTestResult(result) {
|
function printAndDisplayTestResult(result) {
|
||||||
result.log_details();
|
result.log_details();
|
||||||
|
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
kind: 'DisplayTesterResults',
|
kind: "DisplayTesterResults",
|
||||||
args: {
|
args: {
|
||||||
score: result.score(),
|
score: result.score(),
|
||||||
sentPackets: result.sent_packets,
|
sentPackets: result.sent_packets,
|
||||||
receivedPackets: result.received_packets,
|
receivedPackets: result.received_packets,
|
||||||
receivedAcks: result.received_acks,
|
receivedAcks: result.received_acks,
|
||||||
duplicatePackets: result.duplicate_packets,
|
duplicatePackets: result.duplicate_packets,
|
||||||
duplicateAcks: result.duplicate_acks,
|
duplicateAcks: result.duplicate_acks,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testWithTester() {
|
async function testWithTester() {
|
||||||
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
|
// A) construct with hardcoded topology
|
||||||
|
const topology = dummyTopology();
|
||||||
|
const nodeTester = await new NymNodeTester(topology, preferredGateway);
|
||||||
|
|
||||||
// A) construct with hardcoded topology
|
// B) first get topology directly from nym-api
|
||||||
const topology = dummyTopology()
|
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||||
const nodeTester = await new NymNodeTester(topology, preferredGateway);
|
// const topology = await current_network_topology(validator)
|
||||||
|
// const nodeTester = await new NymNodeTester(topology, preferredGateway);
|
||||||
|
//
|
||||||
|
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
|
||||||
|
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||||
|
// const nodeTester = await NymNodeTester.new_with_api(validator, preferredGateway)
|
||||||
|
|
||||||
// B) first get topology directly from nym-api
|
// B) first get topology directly from nym-api
|
||||||
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||||
// const topology = await current_network_topology(validator)
|
// const topology = await current_network_topology(validator)
|
||||||
// const nodeTester = await new NymNodeTester(topology, preferredGateway);
|
// const nodeTester = await new NymNodeTester(topology, undefined, preferredGateway);
|
||||||
//
|
//
|
||||||
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
|
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
|
||||||
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||||
// const nodeTester = await NymNodeTester.new_with_api(validator, preferredGateway)
|
// const nodeTester = await NymNodeTester.new_with_api(validator, undefined, preferredGateway)
|
||||||
|
// D, E, F) you also don't have to specify the gateway. if you don't, a random one (from your topology) will be used
|
||||||
|
// const topology = dummyTopology()
|
||||||
|
// const nodeTester = await new NymNodeTester(topology);
|
||||||
|
|
||||||
// D, E, F) you also don't have to specify the gateway. if you don't, a random one (from your topology) will be used
|
self.onmessage = async (event) => {
|
||||||
// const topology = dummyTopology()
|
if (event.data && event.data.kind) {
|
||||||
// const nodeTester = await new NymNodeTester(topology);
|
switch (event.data.kind) {
|
||||||
|
case "TestPacket": {
|
||||||
|
const { mixnodeIdentity } = event.data.args;
|
||||||
|
console.log("starting node test...");
|
||||||
|
|
||||||
self.onmessage = async event => {
|
let result = await nodeTester.test_node(mixnodeIdentity);
|
||||||
if (event.data && event.data.kind) {
|
printAndDisplayTestResult(result);
|
||||||
switch (event.data.kind) {
|
|
||||||
case 'TestPacket': {
|
|
||||||
const {mixnodeIdentity} = event.data.args;
|
|
||||||
console.log("starting node test...");
|
|
||||||
|
|
||||||
let result = await nodeTester.test_node(mixnodeIdentity);
|
|
||||||
printAndDisplayTestResult(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function testerReconnection() {
|
||||||
|
const validator = "https://qwerty-validator-api.qa.nymte.ch/api";
|
||||||
|
const nodeTester = await NymNodeTester.new_with_api(validator);
|
||||||
|
|
||||||
|
self.onmessage = async (event) => {
|
||||||
|
if (event.data && event.data.kind) {
|
||||||
|
switch (event.data.kind) {
|
||||||
|
case "TestPacket": {
|
||||||
|
const { mixnodeIdentity } = event.data.args;
|
||||||
|
console.log("starting node test...");
|
||||||
|
|
||||||
|
let result1 = await nodeTester.test_node(mixnodeIdentity);
|
||||||
|
console.log("sleeping for 5s");
|
||||||
|
await new Promise((r) => setTimeout(r, 5000));
|
||||||
|
await nodeTester.disconnect_from_gateway();
|
||||||
|
|
||||||
|
console.log("sleeping for 5s");
|
||||||
|
await new Promise((r) => setTimeout(r, 5000));
|
||||||
|
|
||||||
|
await nodeTester.reconnect_to_gateway();
|
||||||
|
let result2 = await nodeTester.test_node(mixnodeIdentity);
|
||||||
|
|
||||||
|
printAndDisplayTestResult(result1);
|
||||||
|
printAndDisplayTestResult(result2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testWithNymClient() {
|
async function testWithNymClient() {
|
||||||
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
|
const topology = dummyTopology();
|
||||||
const topology = dummyTopology()
|
|
||||||
|
|
||||||
let received = 0
|
let received = 0;
|
||||||
|
|
||||||
const onMessageHandler = (message) => {
|
const onMessageHandler = (message) => {
|
||||||
received += 1;
|
received += 1;
|
||||||
self.postMessage({
|
|
||||||
kind: 'ReceiveMessage',
|
|
||||||
args: {
|
|
||||||
message,
|
|
||||||
senderTag: undefined,
|
|
||||||
isTestPacket: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// it's really up to the user to create proper callback here...
|
|
||||||
console.log(`received ${received} packets so far`)
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('Instantiating WASM client...');
|
|
||||||
|
|
||||||
let clientBuilder = NymClientBuilder.new_tester(topology, onMessageHandler, preferredGateway)
|
|
||||||
console.log('Web worker creating WASM client...');
|
|
||||||
let local_client = await clientBuilder.start_client();
|
|
||||||
console.log('WASM client running!');
|
|
||||||
|
|
||||||
const selfAddress = local_client.self_address();
|
|
||||||
|
|
||||||
// set the global (I guess we don't have to anymore?)
|
|
||||||
client = local_client;
|
|
||||||
|
|
||||||
console.log(`Client address is ${selfAddress}`);
|
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
kind: 'Ready',
|
kind: "ReceiveMessage",
|
||||||
args: {
|
args: {
|
||||||
selfAddress,
|
message,
|
||||||
},
|
senderTag: undefined,
|
||||||
|
isTestPacket: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set callback to handle messages passed to the worker.
|
// it's really up to the user to create proper callback here...
|
||||||
self.onmessage = async event => {
|
console.log(`received ${received} packets so far`);
|
||||||
console.log(event)
|
};
|
||||||
if (event.data && event.data.kind) {
|
|
||||||
switch (event.data.kind) {
|
console.log("Instantiating WASM client...");
|
||||||
case 'SendMessage': {
|
|
||||||
const {message, recipient} = event.data.args;
|
let clientBuilder = NymClientBuilder.new_tester(
|
||||||
let uint8Array = new TextEncoder().encode(message);
|
topology,
|
||||||
await client.send_regular_message(uint8Array, recipient);
|
onMessageHandler,
|
||||||
break;
|
preferredGateway
|
||||||
}
|
);
|
||||||
case 'TestPacket': {
|
|
||||||
const {mixnodeIdentity} = event.data.args;
|
console.log("Web worker creating WASM client...");
|
||||||
const req = await client.try_construct_test_packet_request(mixnodeIdentity);
|
let local_client = await clientBuilder.start_client();
|
||||||
await client.change_hardcoded_topology(req.injectable_topology());
|
console.log("WASM client running!");
|
||||||
await client.try_send_test_packets(req);
|
|
||||||
break;
|
const selfAddress = local_client.self_address();
|
||||||
}
|
|
||||||
}
|
// set the global (I guess we don't have to anymore?)
|
||||||
|
client = local_client;
|
||||||
|
|
||||||
|
console.log(`Client address is ${selfAddress}`);
|
||||||
|
self.postMessage({
|
||||||
|
kind: "Ready",
|
||||||
|
args: {
|
||||||
|
selfAddress,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set callback to handle messages passed to the worker.
|
||||||
|
self.onmessage = async (event) => {
|
||||||
|
console.log(event);
|
||||||
|
if (event.data && event.data.kind) {
|
||||||
|
switch (event.data.kind) {
|
||||||
|
case "SendMessage": {
|
||||||
|
const { message, recipient } = event.data.args;
|
||||||
|
let uint8Array = new TextEncoder().encode(message);
|
||||||
|
await client.send_regular_message(uint8Array, recipient);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
case "TestPacket": {
|
||||||
|
const { mixnodeIdentity } = event.data.args;
|
||||||
|
const req = await client.try_construct_test_packet_request(
|
||||||
|
mixnodeIdentity
|
||||||
|
);
|
||||||
|
await client.change_hardcoded_topology(req.injectable_topology());
|
||||||
|
await client.try_send_test_packets(req);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function normalNymClientUsage() {
|
async function normalNymClientUsage() {
|
||||||
self.postMessage({kind: 'DisableMagicTestButton'});
|
self.postMessage({ kind: "DisableMagicTestButton" });
|
||||||
|
|
||||||
// only really useful if you want to adjust some settings like traffic rate
|
// only really useful if you want to adjust some settings like traffic rate
|
||||||
// (if not needed you can just pass a null)
|
// (if not needed you can just pass a null)
|
||||||
const debug = default_debug();
|
const debug = default_debug();
|
||||||
|
|
||||||
debug.disable_main_poisson_packet_distribution = true;
|
debug.disable_main_poisson_packet_distribution = true;
|
||||||
debug.disable_loop_cover_traffic_stream = true;
|
debug.disable_loop_cover_traffic_stream = true;
|
||||||
debug.use_extended_packet_size = false;
|
debug.use_extended_packet_size = false;
|
||||||
// debug.average_packet_delay_ms = BigInt(10);
|
// debug.average_packet_delay_ms = BigInt(10);
|
||||||
// debug.average_ack_delay_ms = BigInt(10);
|
// debug.average_ack_delay_ms = BigInt(10);
|
||||||
// debug.ack_wait_addition_ms = BigInt(3000);
|
// debug.ack_wait_addition_ms = BigInt(3000);
|
||||||
// debug.ack_wait_multiplier = 10;
|
// debug.ack_wait_multiplier = 10;
|
||||||
|
|
||||||
debug.topology_refresh_rate_ms = BigInt(60000)
|
debug.topology_refresh_rate_ms = BigInt(60000);
|
||||||
|
|
||||||
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
|
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
|
||||||
const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
const validator = "https://qwerty-validator-api.qa.nymte.ch/api";
|
||||||
|
|
||||||
const config = new Config('my-awesome-wasm-client', validator, debug);
|
const config = new Config("my-awesome-wasm-client", validator, debug);
|
||||||
|
|
||||||
const onMessageHandler = (message) => {
|
const onMessageHandler = (message) => {
|
||||||
console.log(message);
|
console.log(message);
|
||||||
self.postMessage({
|
|
||||||
kind: 'ReceiveMessage',
|
|
||||||
args: {
|
|
||||||
message,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log('Instantiating WASM client...');
|
|
||||||
|
|
||||||
let localClient = await new NymClient(config, onMessageHandler)
|
|
||||||
console.log('WASM client running!');
|
|
||||||
|
|
||||||
const selfAddress = localClient.self_address();
|
|
||||||
|
|
||||||
// set the global (I guess we don't have to anymore?)
|
|
||||||
client = localClient;
|
|
||||||
|
|
||||||
console.log(`Client address is ${selfAddress}`);
|
|
||||||
self.postMessage({
|
self.postMessage({
|
||||||
kind: 'Ready',
|
kind: "ReceiveMessage",
|
||||||
args: {
|
args: {
|
||||||
selfAddress,
|
message,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Set callback to handle messages passed to the worker.
|
console.log("Instantiating WASM client...");
|
||||||
self.onmessage = async event => {
|
|
||||||
console.log(event)
|
let localClient = await new NymClient(config, onMessageHandler);
|
||||||
if (event.data && event.data.kind) {
|
console.log("WASM client running!");
|
||||||
switch (event.data.kind) {
|
|
||||||
case 'SendMessage': {
|
const selfAddress = localClient.self_address();
|
||||||
const {message, recipient} = event.data.args;
|
|
||||||
let uint8Array = new TextEncoder().encode(message);
|
// set the global (I guess we don't have to anymore?)
|
||||||
await client.send_regular_message(uint8Array, recipient);
|
client = localClient;
|
||||||
break;
|
|
||||||
}
|
console.log(`Client address is ${selfAddress}`);
|
||||||
}
|
self.postMessage({
|
||||||
|
kind: "Ready",
|
||||||
|
args: {
|
||||||
|
selfAddress,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set callback to handle messages passed to the worker.
|
||||||
|
self.onmessage = async (event) => {
|
||||||
|
console.log(event);
|
||||||
|
if (event.data && event.data.kind) {
|
||||||
|
switch (event.data.kind) {
|
||||||
|
case "SendMessage": {
|
||||||
|
const { message, recipient } = event.data.args;
|
||||||
|
let uint8Array = new TextEncoder().encode(message);
|
||||||
|
await client.send_regular_message(uint8Array, recipient);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function messWithStorage() {
|
async function messWithStorage() {
|
||||||
self.onmessage = async event => {
|
self.onmessage = async (event) => {
|
||||||
if (event.data && event.data.kind) {
|
if (event.data && event.data.kind) {
|
||||||
switch (event.data.kind) {
|
switch (event.data.kind) {
|
||||||
case 'TestPacket': {
|
case "TestPacket": {
|
||||||
const { mixnodeIdentity } = event.data.args;
|
const { mixnodeIdentity } = event.data.args;
|
||||||
console.log("button clicked...", mixnodeIdentity);
|
console.log("button clicked...", mixnodeIdentity);
|
||||||
|
|
||||||
let id1 = "one";
|
let id1 = "one";
|
||||||
let id2 = "two";
|
let id2 = "two";
|
||||||
|
|
||||||
console.log("making store1 NO-ENC");
|
console.log("making store1 NO-ENC");
|
||||||
let _storage1 = await ClientStorage.new_unencrypted(id1);
|
let _storage1 = await ClientStorage.new_unencrypted(id1);
|
||||||
|
|
||||||
console.log("making store2 ENC")
|
console.log("making store2 ENC");
|
||||||
let _storage2 = await new ClientStorage(id2, "my-secret-password");
|
let _storage2 = await new ClientStorage(id2, "my-secret-password");
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// console.log("attempting to use store1 WITH PASSWORD")
|
// console.log("attempting to use store1 WITH PASSWORD")
|
||||||
// let _storage1_alt = await new ClientStorage(id1, "password");
|
// let _storage1_alt = await new ClientStorage(id1, "password");
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// console.log("attempting to use store2 WITHOUT PASSWORD")
|
// console.log("attempting to use store2 WITHOUT PASSWORD")
|
||||||
// let _storage2_alt = await ClientStorage.new_unencrypted(id2);
|
// let _storage2_alt = await ClientStorage.new_unencrypted(id2);
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// console.log("attempting to use store2 with WRONG PASSWORD")
|
// console.log("attempting to use store2 with WRONG PASSWORD")
|
||||||
// let _storage2_bad = await new ClientStorage(id2, "bad-password")
|
// let _storage2_bad = await new ClientStorage(id2, "bad-password")
|
||||||
|
|
||||||
|
//
|
||||||
//
|
// console.log("read1: ", await storage1.read());
|
||||||
// console.log("read1: ", await storage1.read());
|
// console.log("read2: ", await storage2.read());
|
||||||
// console.log("read2: ", await storage2.read());
|
//
|
||||||
//
|
// console.log("store1: ", await storage1.store("FOOMP"));
|
||||||
// console.log("store1: ", await storage1.store("FOOMP"));
|
//
|
||||||
//
|
// console.log("read1: ", await storage1.read());
|
||||||
// console.log("read1: ", await storage1.read());
|
// console.log("read2: ", await storage2.read());
|
||||||
// console.log("read2: ", await storage2.read());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
// load WASM package
|
// load WASM package
|
||||||
await wasm_bindgen('nym_client_wasm_bg.wasm');
|
await wasm_bindgen("nym_client_wasm_bg.wasm");
|
||||||
console.log('Loaded WASM');
|
console.log("Loaded WASM");
|
||||||
|
|
||||||
// sets up better stack traces in case of in-rust panics
|
// sets up better stack traces in case of in-rust panics
|
||||||
set_panic_hook();
|
set_panic_hook();
|
||||||
|
|
||||||
// run test on simplified and dedicated tester:
|
// show reconnection capabilities
|
||||||
// await testWithTester()
|
// await testerReconnection()
|
||||||
|
|
||||||
// hook-up the whole client for testing
|
// run test on simplified and dedicated tester:
|
||||||
// await testWithNymClient()
|
await testWithTester();
|
||||||
|
|
||||||
// 'Normal' client setup (to send 'normal' messages)
|
// 'Normal' client setup (to send 'normal' messages)
|
||||||
await normalNymClientUsage()
|
// await normalNymClientUsage()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's get started!
|
// Let's get started!
|
||||||
main();
|
main();
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
// due to expansion of #[wasm_bindgen] macro on NodeTestResult
|
// due to expansion of #[wasm_bindgen] macro on NodeTestResult
|
||||||
#![allow(clippy::drop_non_drop)]
|
#![allow(clippy::drop_non_drop)]
|
||||||
|
|
||||||
|
use crate::error::WasmClientError;
|
||||||
|
use crate::tester::LockedGatewayClient;
|
||||||
|
use js_sys::Promise;
|
||||||
use nym_node_tester_utils::processor::Received;
|
use nym_node_tester_utils::processor::Received;
|
||||||
use nym_node_tester_utils::receiver::ReceivedReceiver;
|
use nym_node_tester_utils::receiver::ReceivedReceiver;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -12,6 +15,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard};
|
use tokio::sync::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
use wasm_bindgen_futures::future_to_promise;
|
||||||
use wasm_utils::{console_log, console_warn};
|
use wasm_utils::{console_log, console_warn};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -107,3 +111,37 @@ impl Drop for TestMarker {
|
|||||||
self.value.store(false, Ordering::SeqCst)
|
self.value.store(false, Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) trait GatewayReconnection {
|
||||||
|
fn disconnect_from_gateway(&self) -> Promise;
|
||||||
|
|
||||||
|
fn reconnect_to_gateway(&self) -> Promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GatewayReconnection for LockedGatewayClient {
|
||||||
|
fn disconnect_from_gateway(&self) -> Promise {
|
||||||
|
let this = self.clone();
|
||||||
|
|
||||||
|
future_to_promise(async move {
|
||||||
|
let mut guard = this.lock().await;
|
||||||
|
guard
|
||||||
|
.disconnect()
|
||||||
|
.await
|
||||||
|
.map_err(|err| JsValue::from(WasmClientError::from(err)))?;
|
||||||
|
Ok(JsValue::undefined())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reconnect_to_gateway(&self) -> Promise {
|
||||||
|
let this = self.clone();
|
||||||
|
|
||||||
|
future_to_promise(async move {
|
||||||
|
let mut guard = this.lock().await;
|
||||||
|
guard
|
||||||
|
.try_reconnect()
|
||||||
|
.await
|
||||||
|
.map_err(|err| JsValue::from(WasmClientError::from(err)))?;
|
||||||
|
Ok(JsValue::undefined())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::helpers::{current_network_topology_async, setup_from_topology};
|
|||||||
use crate::storage::ClientStorage;
|
use crate::storage::ClientStorage;
|
||||||
use crate::tester::ephemeral_receiver::EphemeralTestReceiver;
|
use crate::tester::ephemeral_receiver::EphemeralTestReceiver;
|
||||||
use crate::tester::helpers::{
|
use crate::tester::helpers::{
|
||||||
NodeTestResult, ReceivedReceiverWrapper, TestMarker, WasmTestMessageExt,
|
GatewayReconnection, NodeTestResult, ReceivedReceiverWrapper, TestMarker, WasmTestMessageExt,
|
||||||
};
|
};
|
||||||
use crate::topology::WasmNymTopology;
|
use crate::topology::WasmNymTopology;
|
||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
@@ -73,6 +73,7 @@ pub struct NymNodeTester {
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct NymNodeTesterBuilder {
|
pub struct NymNodeTesterBuilder {
|
||||||
gateway: Option<IdentityKey>,
|
gateway: Option<IdentityKey>,
|
||||||
|
id: Option<String>,
|
||||||
|
|
||||||
base_topology: NymTopology,
|
base_topology: NymTopology,
|
||||||
|
|
||||||
@@ -94,9 +95,11 @@ impl NymNodeTesterBuilder {
|
|||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
base_topology: WasmNymTopology,
|
base_topology: WasmNymTopology,
|
||||||
|
id: Option<String>,
|
||||||
gateway: Option<IdentityKey>,
|
gateway: Option<IdentityKey>,
|
||||||
) -> NymNodeTesterBuilder {
|
) -> NymNodeTesterBuilder {
|
||||||
NymNodeTesterBuilder {
|
NymNodeTesterBuilder {
|
||||||
|
id,
|
||||||
gateway,
|
gateway,
|
||||||
base_topology: base_topology.into(),
|
base_topology: base_topology.into(),
|
||||||
bandwidth_controller: None,
|
bandwidth_controller: None,
|
||||||
@@ -105,15 +108,20 @@ impl NymNodeTesterBuilder {
|
|||||||
|
|
||||||
async fn _new_with_api(
|
async fn _new_with_api(
|
||||||
api_url: String,
|
api_url: String,
|
||||||
|
id: Option<String>,
|
||||||
gateway: Option<IdentityKey>,
|
gateway: Option<IdentityKey>,
|
||||||
) -> Result<Self, WasmClientError> {
|
) -> Result<Self, WasmClientError> {
|
||||||
let topology = current_network_topology_async(api_url).await?;
|
let topology = current_network_topology_async(api_url).await?;
|
||||||
Ok(NymNodeTesterBuilder::new(topology, gateway))
|
Ok(NymNodeTesterBuilder::new(topology, id, gateway))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_api(gateway: Option<IdentityKey>, api_url: String) -> Promise {
|
pub fn new_with_api(
|
||||||
|
api_url: String,
|
||||||
|
id: Option<String>,
|
||||||
|
gateway: Option<IdentityKey>,
|
||||||
|
) -> Promise {
|
||||||
future_to_promise(async move {
|
future_to_promise(async move {
|
||||||
Self::_new_with_api(api_url, gateway)
|
Self::_new_with_api(api_url, id, gateway)
|
||||||
.await
|
.await
|
||||||
.into_promise_result()
|
.into_promise_result()
|
||||||
})
|
})
|
||||||
@@ -133,7 +141,13 @@ impl NymNodeTesterBuilder {
|
|||||||
async fn _setup_client(mut self) -> Result<NymNodeTester, WasmClientError> {
|
async fn _setup_client(mut self) -> Result<NymNodeTester, WasmClientError> {
|
||||||
let task_manager = TaskManager::default();
|
let task_manager = TaskManager::default();
|
||||||
|
|
||||||
let client_store = ClientStorage::new_async(NODE_TESTER_ID, None).await?;
|
let storage_id = if let Some(client_id) = &self.id {
|
||||||
|
format!("{NODE_TESTER_ID}-{client_id}")
|
||||||
|
} else {
|
||||||
|
NODE_TESTER_ID.to_owned()
|
||||||
|
};
|
||||||
|
|
||||||
|
let client_store = ClientStorage::new_async(&storage_id, None).await?;
|
||||||
|
|
||||||
let init_details = self.gateway_info(&client_store).await?;
|
let init_details = self.gateway_info(&client_store).await?;
|
||||||
let gateway_endpoint = init_details.gateway_details;
|
let gateway_endpoint = init_details.gateway_details;
|
||||||
@@ -234,29 +248,46 @@ async fn test_mixnode(
|
|||||||
impl NymNodeTester {
|
impl NymNodeTester {
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
pub fn new(topology: WasmNymTopology, gateway: Option<IdentityKey>) -> Promise {
|
pub fn new(
|
||||||
|
topology: WasmNymTopology,
|
||||||
|
id: Option<String>,
|
||||||
|
gateway: Option<IdentityKey>,
|
||||||
|
) -> Promise {
|
||||||
console_log!("constructing node tester!");
|
console_log!("constructing node tester!");
|
||||||
NymNodeTesterBuilder::new(topology, gateway).setup_client()
|
NymNodeTesterBuilder::new(topology, id, gateway).setup_client()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn _new_with_api(
|
async fn _new_with_api(
|
||||||
api_url: String,
|
api_url: String,
|
||||||
|
id: Option<String>,
|
||||||
gateway: Option<IdentityKey>,
|
gateway: Option<IdentityKey>,
|
||||||
) -> Result<Self, WasmClientError> {
|
) -> Result<Self, WasmClientError> {
|
||||||
NymNodeTesterBuilder::_new_with_api(api_url, gateway)
|
NymNodeTesterBuilder::_new_with_api(api_url, id, gateway)
|
||||||
.await?
|
.await?
|
||||||
._setup_client()
|
._setup_client()
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_api(api_url: String, gateway: Option<IdentityKey>) -> Promise {
|
pub fn new_with_api(
|
||||||
|
api_url: String,
|
||||||
|
id: Option<String>,
|
||||||
|
gateway: Option<IdentityKey>,
|
||||||
|
) -> Promise {
|
||||||
future_to_promise(async move {
|
future_to_promise(async move {
|
||||||
Self::_new_with_api(api_url, gateway)
|
Self::_new_with_api(api_url, id, gateway)
|
||||||
.await
|
.await
|
||||||
.into_promise_result()
|
.into_promise_result()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn disconnect_from_gateway(&self) -> Promise {
|
||||||
|
self.gateway_client.disconnect_from_gateway()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reconnect_to_gateway(&self) -> Promise {
|
||||||
|
self.gateway_client.reconnect_to_gateway()
|
||||||
|
}
|
||||||
|
|
||||||
fn prepare_test_packets(
|
fn prepare_test_packets(
|
||||||
&self,
|
&self,
|
||||||
mixnode_identity: String,
|
mixnode_identity: String,
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use log::*;
|
|||||||
use nym_sphinx::acknowledgements::AckKey;
|
use nym_sphinx::acknowledgements::AckKey;
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
use nym_sphinx::addressing::clients::Recipient;
|
||||||
use nym_sphinx::cover::generate_loop_cover_packet;
|
use nym_sphinx::cover::generate_loop_cover_packet;
|
||||||
use nym_sphinx::params::PacketSize;
|
use nym_sphinx::params::{PacketSize, PacketType};
|
||||||
use nym_sphinx::utils::sample_poisson_duration;
|
use nym_sphinx::utils::sample_poisson_duration;
|
||||||
use rand::{rngs::OsRng, CryptoRng, Rng};
|
use rand::{rngs::OsRng, CryptoRng, Rng};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
@@ -63,6 +63,8 @@ where
|
|||||||
|
|
||||||
/// Optional secondary predefined packet size used for the loop cover messages.
|
/// Optional secondary predefined packet size used for the loop cover messages.
|
||||||
secondary_packet_size: Option<PacketSize>,
|
secondary_packet_size: Option<PacketSize>,
|
||||||
|
|
||||||
|
packet_type: PacketType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R> Stream for LoopCoverTrafficStream<R>
|
impl<R> Stream for LoopCoverTrafficStream<R>
|
||||||
@@ -135,6 +137,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
|||||||
topology_access,
|
topology_access,
|
||||||
primary_packet_size: traffic_config.primary_packet_size,
|
primary_packet_size: traffic_config.primary_packet_size,
|
||||||
secondary_packet_size: traffic_config.secondary_packet_size,
|
secondary_packet_size: traffic_config.secondary_packet_size,
|
||||||
|
packet_type: traffic_config.packet_type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,7 +197,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
|||||||
self.average_ack_delay,
|
self.average_ack_delay,
|
||||||
self.cover_traffic.loop_cover_traffic_average_delay,
|
self.cover_traffic.loop_cover_traffic_average_delay,
|
||||||
cover_traffic_packet_size,
|
cover_traffic_packet_size,
|
||||||
nym_sphinx::params::PacketType::Mix,
|
self.packet_type,
|
||||||
)
|
)
|
||||||
.expect("Somehow failed to generate a loop cover message with a valid topology");
|
.expect("Somehow failed to generate a loop cover message with a valid topology");
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::client::inbound_messages::{InputMessage, InputMessageReceiver};
|
use crate::client::inbound_messages::{InputMessage, InputMessageReceiver};
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
|||||||
@@ -137,14 +137,46 @@ impl Config {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_no_cover_traffic(&mut self) {
|
||||||
|
self.debug.cover_traffic.disable_loop_cover_traffic_stream = true;
|
||||||
|
self.debug.traffic.disable_main_poisson_packet_distribution = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_disabled_cover_traffic_with_keepalive(mut self, disabled: bool) -> Self {
|
||||||
|
if disabled {
|
||||||
|
self.set_no_cover_traffic_with_keepalive()
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn set_no_cover_traffic_with_keepalive(&mut self) {
|
||||||
|
self.debug.traffic.disable_main_poisson_packet_distribution = true;
|
||||||
|
self.debug.cover_traffic.loop_cover_traffic_average_delay = Duration::from_secs(5);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn with_disabled_topology_refresh(mut self, disable_topology_refresh: bool) -> Self {
|
pub fn with_disabled_topology_refresh(mut self, disable_topology_refresh: bool) -> Self {
|
||||||
self.debug.topology.disable_refreshing = disable_topology_refresh;
|
self.debug.topology.disable_refreshing = disable_topology_refresh;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_no_cover_traffic(&mut self) {
|
pub fn with_no_per_hop_delays(mut self, no_per_hop_delays: bool) -> Self {
|
||||||
self.debug.cover_traffic.disable_loop_cover_traffic_stream = true;
|
if no_per_hop_delays {
|
||||||
self.debug.traffic.disable_main_poisson_packet_distribution = true;
|
self.set_no_per_hop_delays()
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_no_per_hop_delays(&mut self) {
|
||||||
|
self.debug.traffic.average_packet_delay = Duration::ZERO;
|
||||||
|
self.debug.acknowledgements.average_ack_delay = Duration::ZERO;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_secondary_packet_size(mut self, secondary_packet_size: Option<PacketSize>) -> Self {
|
||||||
|
self.set_secondary_packet_size(secondary_packet_size);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_secondary_packet_size(&mut self, secondary_packet_size: Option<PacketSize>) {
|
||||||
|
self.debug.traffic.secondary_packet_size = secondary_packet_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_custom_version(&mut self, version: &str) {
|
pub fn set_custom_version(&mut self, version: &str) {
|
||||||
@@ -282,7 +314,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
||||||
#[serde(default)]
|
#[serde(default, deny_unknown_fields)]
|
||||||
pub struct Traffic {
|
pub struct Traffic {
|
||||||
/// The parameter of Poisson distribution determining how long, on average,
|
/// The parameter of Poisson distribution determining how long, on average,
|
||||||
/// sent packet is going to be delayed at any given mix node.
|
/// sent packet is going to be delayed at any given mix node.
|
||||||
|
|||||||
@@ -724,7 +724,7 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn try_reconnect(&mut self) -> Result<(), GatewayClientError> {
|
pub async fn try_reconnect(&mut self) -> Result<(), GatewayClientError> {
|
||||||
if !self.connection.is_established() {
|
if !self.connection.is_established() {
|
||||||
self.establish_connection().await?;
|
self.establish_connection().await?;
|
||||||
}
|
}
|
||||||
@@ -738,6 +738,12 @@ impl<C, St> GatewayClient<C, St> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn disconnect(&mut self) -> Result<(), GatewayClientError> {
|
||||||
|
self.recover_socket_connection().await?;
|
||||||
|
self.connection = SocketState::NotConnected;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn authenticate_and_start(&mut self) -> Result<Arc<SharedKeys>, GatewayClientError>
|
pub async fn authenticate_and_start(&mut self) -> Result<Arc<SharedKeys>, GatewayClientError>
|
||||||
where
|
where
|
||||||
C: DkgQueryClient + Send + Sync,
|
C: DkgQueryClient + Send + Sync,
|
||||||
|
|||||||
@@ -48,17 +48,21 @@ impl PacketRouter {
|
|||||||
// data he takes the SURB-ACK and first hop address.
|
// data he takes the SURB-ACK and first hop address.
|
||||||
// currently SURB-ACKs are attached in EVERY packet, even cover, so this is always true
|
// currently SURB-ACKs are attached in EVERY packet, even cover, so this is always true
|
||||||
let ack_overhead = PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN;
|
let ack_overhead = PacketSize::AckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN;
|
||||||
|
let outfox_ack_overhead =
|
||||||
|
PacketSize::OutfoxAckPacket.size() + MAX_NODE_ADDRESS_UNPADDED_LEN;
|
||||||
|
|
||||||
for received_packet in unwrapped_packets {
|
for received_packet in unwrapped_packets {
|
||||||
if received_packet.len() == PacketSize::AckPacket.plaintext_size()
|
if received_packet.len() == PacketSize::AckPacket.plaintext_size()
|
||||||
|| received_packet.len() == PacketSize::OutfoxAckPacket.plaintext_size()
|
// we don't know the real size of the payload, it could be anything <= 48 bytes
|
||||||
|
|| received_packet.len() <= PacketSize::OutfoxAckPacket.plaintext_size()
|
||||||
{
|
{
|
||||||
received_acks.push(received_packet);
|
received_acks.push(received_packet);
|
||||||
} else if received_packet.len()
|
} else if received_packet.len()
|
||||||
== PacketSize::RegularPacket.plaintext_size() - ack_overhead
|
== PacketSize::RegularPacket.plaintext_size() - ack_overhead
|
||||||
|| received_packet.len()
|
|| received_packet.len()
|
||||||
== PacketSize::OutfoxRegularPacket.plaintext_size() - ack_overhead
|
== PacketSize::OutfoxRegularPacket.plaintext_size() - outfox_ack_overhead
|
||||||
|| received_packet.len() == PacketSize::OutfoxRegularPacket.size() - 6
|
|| received_packet.len()
|
||||||
|
== PacketSize::OutfoxRegularPacket.size() - outfox_ack_overhead
|
||||||
{
|
{
|
||||||
trace!("routing regular packet");
|
trace!("routing regular packet");
|
||||||
received_messages.push(received_packet);
|
received_messages.push(received_packet);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::error::GatewayClientError;
|
use crate::error::GatewayClientError;
|
||||||
|
|||||||
@@ -15,10 +15,9 @@ use std::net::SocketAddr;
|
|||||||
use std::sync::atomic::{AtomicU32, Ordering};
|
use std::sync::atomic::{AtomicU32, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::net::{TcpStream, UdpSocket};
|
use tokio::net::TcpStream;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use tokio_util::codec::Framed;
|
use tokio_util::codec::Framed;
|
||||||
use tokio_util::udp::UdpFramed;
|
|
||||||
|
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
initial_reconnection_backoff: Duration,
|
initial_reconnection_backoff: Duration,
|
||||||
@@ -58,98 +57,136 @@ pub trait SendWithoutResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
conn_new: Option<mpsc::Sender<(FramedNymPacket, SocketAddr)>>,
|
conn_new: HashMap<NymNodeRoutingAddress, ConnectionSender>,
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ConnectionSender {
|
||||||
|
channel: mpsc::Sender<FramedNymPacket>,
|
||||||
|
current_reconnection_attempt: Arc<AtomicU32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConnectionSender {
|
||||||
|
fn new(channel: mpsc::Sender<FramedNymPacket>) -> Self {
|
||||||
|
ConnectionSender {
|
||||||
|
channel,
|
||||||
|
current_reconnection_attempt: Arc::new(AtomicU32::new(0)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
pub fn new(config: Config) -> Client {
|
pub fn new(config: Config) -> Client {
|
||||||
Client {
|
Client {
|
||||||
conn_new: None,
|
conn_new: HashMap::new(),
|
||||||
config,
|
config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn manage_connection(
|
async fn manage_connection(
|
||||||
address: SocketAddr,
|
address: SocketAddr,
|
||||||
receiver: mpsc::Receiver<(FramedNymPacket, SocketAddr)>,
|
receiver: mpsc::Receiver<FramedNymPacket>,
|
||||||
|
connection_timeout: Duration,
|
||||||
|
current_reconnection: &AtomicU32,
|
||||||
) {
|
) {
|
||||||
let socket = match UdpSocket::bind("0.0.0.0:0").await {
|
let connection_fut = TcpStream::connect(address);
|
||||||
Ok(socket) => socket,
|
|
||||||
Err(err) => {
|
let conn = match tokio::time::timeout(connection_timeout, connection_fut).await {
|
||||||
error!("Failed to bind to - {err}. Are you sure nothing else is running on the specified port and your user has sufficient permission to bind to the requested address?");
|
Ok(stream_res) => match stream_res {
|
||||||
|
Ok(stream) => {
|
||||||
|
debug!("Managed to establish connection to {}", address);
|
||||||
|
// if we managed to connect, reset the reconnection count (whatever it might have been)
|
||||||
|
current_reconnection.store(0, Ordering::Release);
|
||||||
|
Framed::new(stream, NymCodec)
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
debug!(
|
||||||
|
"failed to establish connection to {} (err: {})",
|
||||||
|
address, err
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
debug!(
|
||||||
|
"failed to connect to {} within {:?}",
|
||||||
|
address, connection_timeout
|
||||||
|
);
|
||||||
|
|
||||||
|
// we failed to connect - increase reconnection attempt
|
||||||
|
current_reconnection.fetch_add(1, Ordering::SeqCst);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let framed_conn = UdpFramed::new(socket, NymCodec);
|
|
||||||
// Take whatever the receiver channel produces and put it on the connection.
|
// Take whatever the receiver channel produces and put it on the connection.
|
||||||
// We could have as well used conn.send_all(receiver.map(Ok)), but considering we don't care
|
// We could have as well used conn.send_all(receiver.map(Ok)), but considering we don't care
|
||||||
// about neither receiver nor the connection, it doesn't matter which one gets consumed
|
// about neither receiver nor the connection, it doesn't matter which one gets consumed
|
||||||
if let Err(err) = receiver.map(Ok).forward(framed_conn).await {
|
if let Err(err) = receiver.map(Ok).forward(conn).await {
|
||||||
warn!("Failed to forward packets to {} - {err}", address);
|
warn!("Failed to forward packets to {} - {err}", address);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"connection manager is finished. Either the connection failed or mixnet client got dropped"
|
"connection manager to {} is finished. Either the connection failed or mixnet client got dropped",
|
||||||
|
address
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If we're trying to reconnect, determine how long we should wait.
|
/// If we're trying to reconnect, determine how long we should wait.
|
||||||
// fn determine_backoff(&self, current_attempt: u32) -> Option<Duration> {
|
fn determine_backoff(&self, current_attempt: u32) -> Option<Duration> {
|
||||||
// if current_attempt == 0 {
|
if current_attempt == 0 {
|
||||||
// None
|
None
|
||||||
// } else {
|
} else {
|
||||||
// let exp = 2_u32.checked_pow(current_attempt);
|
let exp = 2_u32.checked_pow(current_attempt);
|
||||||
// let backoff = exp
|
let backoff = exp
|
||||||
// .and_then(|exp| self.config.initial_reconnection_backoff.checked_mul(exp))
|
.and_then(|exp| self.config.initial_reconnection_backoff.checked_mul(exp))
|
||||||
// .unwrap_or(self.config.maximum_reconnection_backoff);
|
.unwrap_or(self.config.maximum_reconnection_backoff);
|
||||||
|
|
||||||
// Some(std::cmp::min(
|
Some(std::cmp::min(
|
||||||
// backoff,
|
backoff,
|
||||||
// self.config.maximum_reconnection_backoff,
|
self.config.maximum_reconnection_backoff,
|
||||||
// ))
|
))
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
fn make_connection(&mut self, address: NymNodeRoutingAddress, pending_packet: FramedNymPacket) {
|
fn make_connection(&mut self, address: NymNodeRoutingAddress, pending_packet: FramedNymPacket) {
|
||||||
let (mut sender, receiver) = mpsc::channel(self.config.maximum_connection_buffer_size);
|
let (mut sender, receiver) = mpsc::channel(self.config.maximum_connection_buffer_size);
|
||||||
|
|
||||||
// this CAN'T fail because we just created the channel which has a non-zero capacity
|
// this CAN'T fail because we just created the channel which has a non-zero capacity
|
||||||
if self.config.maximum_connection_buffer_size > 0 {
|
if self.config.maximum_connection_buffer_size > 0 {
|
||||||
sender.try_send((pending_packet, address.into())).unwrap();
|
sender.try_send(pending_packet).unwrap();
|
||||||
}
|
}
|
||||||
self.conn_new = Some(sender);
|
|
||||||
|
|
||||||
// if we already tried to connect to `address` before, grab the current attempt count
|
// if we already tried to connect to `address` before, grab the current attempt count
|
||||||
// let current_reconnection_attempt = if let Some(existing) = self.conn_new.get_mut(&address) {
|
let current_reconnection_attempt = if let Some(existing) = self.conn_new.get_mut(&address) {
|
||||||
// existing.channel = sender;
|
existing.channel = sender;
|
||||||
// Arc::clone(&existing.current_reconnection_attempt)
|
Arc::clone(&existing.current_reconnection_attempt)
|
||||||
// } else {
|
} else {
|
||||||
// let new_entry = ConnectionSender::new(sender);
|
let new_entry = ConnectionSender::new(sender);
|
||||||
// let current_attempt = Arc::clone(&new_entry.current_reconnection_attempt);
|
let current_attempt = Arc::clone(&new_entry.current_reconnection_attempt);
|
||||||
// self.conn_new.insert(address, new_entry);
|
self.conn_new.insert(address, new_entry);
|
||||||
// current_attempt
|
current_attempt
|
||||||
// };
|
};
|
||||||
|
|
||||||
// load the actual value.
|
// load the actual value.
|
||||||
// let reconnection_attempt = current_reconnection_attempt.load(Ordering::Acquire);
|
let reconnection_attempt = current_reconnection_attempt.load(Ordering::Acquire);
|
||||||
// let backoff = self.determine_backoff(reconnection_attempt);
|
let backoff = self.determine_backoff(reconnection_attempt);
|
||||||
|
|
||||||
// copy the value before moving into another task
|
// copy the value before moving into another task
|
||||||
// let initial_connection_timeout = self.config.initial_connection_timeout;
|
let initial_connection_timeout = self.config.initial_connection_timeout;
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
// before executing the manager, wait for what was specified, if anything
|
// before executing the manager, wait for what was specified, if anything
|
||||||
// if let Some(backoff) = backoff {
|
if let Some(backoff) = backoff {
|
||||||
// trace!("waiting for {:?} before attempting connection", backoff);
|
trace!("waiting for {:?} before attempting connection", backoff);
|
||||||
// sleep(backoff).await;
|
sleep(backoff).await;
|
||||||
// }
|
}
|
||||||
|
|
||||||
Self::manage_connection(
|
Self::manage_connection(
|
||||||
address.into(),
|
address.into(),
|
||||||
receiver,
|
receiver,
|
||||||
//initial_connection_timeout,
|
initial_connection_timeout,
|
||||||
//¤t_reconnection_attempt,
|
¤t_reconnection_attempt,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
});
|
});
|
||||||
@@ -167,53 +204,48 @@ impl SendWithoutResponse for Client {
|
|||||||
let framed_packet =
|
let framed_packet =
|
||||||
FramedNymPacket::new(packet, packet_type, self.config.use_legacy_version);
|
FramedNymPacket::new(packet, packet_type, self.config.use_legacy_version);
|
||||||
|
|
||||||
match &self.conn_new {
|
if let Some(sender) = self.conn_new.get_mut(&address) {
|
||||||
Some(sender) => {
|
if let Err(err) = sender.channel.try_send(framed_packet) {
|
||||||
if let Err(err) = sender.clone().try_send((framed_packet, address.into())) {
|
if err.is_full() {
|
||||||
if err.is_full() {
|
debug!("Connection to {} seems to not be able to handle all the traffic - dropping the current packet", address);
|
||||||
debug!("Connection to {} seems to not be able to handle all the traffic - dropping the current packet", address);
|
// it's not a 'big' error, but we did not manage to send the packet
|
||||||
// it's not a 'big' error, but we did not manage to send the packet
|
// if the queue is full, we can't really do anything but to drop the packet
|
||||||
// if the queue is full, we can't really do anything but to drop the packet
|
Err(io::Error::new(
|
||||||
Err(io::Error::new(
|
io::ErrorKind::WouldBlock,
|
||||||
io::ErrorKind::WouldBlock,
|
"connection queue is full",
|
||||||
"connection queue is full",
|
))
|
||||||
))
|
} else if err.is_disconnected() {
|
||||||
} else if err.is_disconnected() {
|
debug!(
|
||||||
debug!(
|
"Connection to {} seems to be dead. attempting to re-establish it...",
|
||||||
"Connection to {} seems to be dead. attempting to re-establish it...",
|
address
|
||||||
address
|
);
|
||||||
);
|
// it's not a 'big' error, but we did not manage to send the packet, but queue
|
||||||
// it's not a 'big' error, but we did not manage to send the packet, but queue
|
// it up to send it as soon as the connection is re-established
|
||||||
// it up to send it as soon as the connection is re-established
|
self.make_connection(address, err.into_inner());
|
||||||
self.make_connection(address, err.into_inner().0);
|
Err(io::Error::new(
|
||||||
Err(io::Error::new(
|
io::ErrorKind::ConnectionAborted,
|
||||||
io::ErrorKind::ConnectionAborted,
|
"reconnection attempt is in progress",
|
||||||
"reconnection attempt is in progress",
|
))
|
||||||
))
|
|
||||||
} else {
|
|
||||||
// this can't really happen, but let's safe-guard against it in case something changes in futures library
|
|
||||||
Err(io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
"unknown connection buffer error",
|
|
||||||
))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
debug!("Sending packet to {:?}", address);
|
// this can't really happen, but let's safe-guard against it in case something changes in futures library
|
||||||
Ok(())
|
Err(io::Error::new(
|
||||||
|
io::ErrorKind::Other,
|
||||||
|
"unknown connection buffer error",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
None => {
|
// there was never a connection to begin with
|
||||||
// there was never a connection to begin with
|
debug!("establishing initial connection to {}", address);
|
||||||
debug!("establishing initial connection");
|
// it's not a 'big' error, but we did not manage to send the packet, but queue the packet
|
||||||
// it's not a 'big' error, but we did not manage to send the packet, but queue the packet
|
// for sending for as soon as the connection is created
|
||||||
// for sending for as soon as the connection is created
|
self.make_connection(address, framed_packet);
|
||||||
self.make_connection(address, framed_packet);
|
Err(io::Error::new(
|
||||||
Err(io::Error::new(
|
io::ErrorKind::NotConnected,
|
||||||
io::ErrorKind::NotConnected,
|
"connection is in progress",
|
||||||
"connection is in progress",
|
))
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::{nym_api, ValidatorClientError};
|
use crate::{nym_api, ValidatorClientError};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::nym_api::error::NymAPIError;
|
use crate::nym_api::error::NymAPIError;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// TODO: There's a significant argument to pull those out of the package and make a PR on https://github.com/cosmos/cosmos-rust/
|
// TODO: There's a significant argument to pull those out of the package and make a PR on https://github.com/cosmos/cosmos-rust/
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// TODO: expose query-related capabilities to wasm client...
|
// TODO: expose query-related capabilities to wasm client...
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use nym_contracts_common::ContractBuildInformation;
|
|||||||
use nym_name_service_common::{
|
use nym_name_service_common::{
|
||||||
msg::QueryMsg as NameQueryMsg,
|
msg::QueryMsg as NameQueryMsg,
|
||||||
response::{ConfigResponse, NamesListResponse, PagedNamesListResponse},
|
response::{ConfigResponse, NamesListResponse, PagedNamesListResponse},
|
||||||
Address, NameEntry, NameId,
|
Address, NameId, RegisteredName,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ pub trait NameServiceQueryClient {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_name_entry(&self, name_id: NameId) -> Result<NameEntry, NyxdError> {
|
async fn get_name_entry(&self, name_id: NameId) -> Result<RegisteredName, NyxdError> {
|
||||||
self.query_name_service_contract(NameQueryMsg::NameId { name_id })
|
self.query_name_service_contract(NameQueryMsg::NameId { name_id })
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
@@ -54,14 +54,14 @@ pub trait NameServiceQueryClient {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_all_names(&self) -> Result<Vec<NameEntry>, NyxdError> {
|
async fn get_all_names(&self) -> Result<Vec<RegisteredName>, NyxdError> {
|
||||||
let mut services = Vec::new();
|
let mut services = Vec::new();
|
||||||
let mut start_after = None;
|
let mut start_after = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut paged_response = self.get_names_paged(start_after.take(), None).await?;
|
let mut paged_response = self.get_names_paged(start_after.take(), None).await?;
|
||||||
|
|
||||||
let last_id = paged_response.names.last().map(|serv| serv.name_id);
|
let last_id = paged_response.names.last().map(|serv| serv.id);
|
||||||
services.append(&mut paged_response.names);
|
services.append(&mut paged_response.names);
|
||||||
|
|
||||||
if let Some(start_after_res) = last_id {
|
if let Some(start_after_res) = last_id {
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use nym_name_service_common::{msg::ExecuteMsg as NameExecuteMsg, Address, NameId, NymName};
|
use nym_contracts_common::signing::MessageSignature;
|
||||||
|
use nym_name_service_common::{msg::ExecuteMsg as NameExecuteMsg, NameDetails, NameId, NymName};
|
||||||
|
|
||||||
use crate::nyxd::{
|
use crate::nyxd::{
|
||||||
coin::Coin, cosmwasm_client::types::ExecuteResult, error::NyxdError, Fee, NyxdClient,
|
coin::Coin, cosmwasm_client::types::ExecuteResult, error::NyxdError, Fee, NyxdClient,
|
||||||
@@ -20,14 +21,17 @@ pub trait NameServiceSigningClient {
|
|||||||
|
|
||||||
async fn register_name(
|
async fn register_name(
|
||||||
&self,
|
&self,
|
||||||
name: NymName,
|
name: NameDetails,
|
||||||
address: Address,
|
owner_signature: MessageSignature,
|
||||||
deposit: Coin,
|
deposit: Coin,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError> {
|
) -> Result<ExecuteResult, NyxdError> {
|
||||||
self.execute_name_service_contract(
|
self.execute_name_service_contract(
|
||||||
fee,
|
fee,
|
||||||
NameExecuteMsg::Register { name, address },
|
NameExecuteMsg::Register {
|
||||||
|
name,
|
||||||
|
owner_signature,
|
||||||
|
},
|
||||||
vec![deposit],
|
vec![deposit],
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -41,3 +41,6 @@ nym-multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-co
|
|||||||
nym-service-provider-directory-common = { path = "../cosmwasm-smart-contracts/service-provider-directory" }
|
nym-service-provider-directory-common = { path = "../cosmwasm-smart-contracts/service-provider-directory" }
|
||||||
nym-name-service-common = { path = "../cosmwasm-smart-contracts/name-service" }
|
nym-name-service-common = { path = "../cosmwasm-smart-contracts/name-service" }
|
||||||
nym-sphinx = { path = "../../common/nymsphinx" }
|
nym-sphinx = { path = "../../common/nymsphinx" }
|
||||||
|
|
||||||
|
nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
|
||||||
|
nym-types = { path = "../../common/types" }
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
use clap::{Args, Parser, Subcommand};
|
||||||
|
use nym_bin_common::output_format::OutputFormat;
|
||||||
|
use nym_crypto::asymmetric::identity;
|
||||||
|
use nym_types::helpers::ConsoleSigningOutput;
|
||||||
|
use nym_validator_client::nyxd::error::NyxdError;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[derive(Debug, Args)]
|
||||||
|
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
|
||||||
|
pub struct MixnetOperatorsIdentityKey {
|
||||||
|
#[clap(subcommand)]
|
||||||
|
pub command: MixnetOperatorsIdentityKeyCommands,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Subcommand)]
|
||||||
|
pub enum MixnetOperatorsIdentityKeyCommands {
|
||||||
|
/// Register a name alias for a nym address
|
||||||
|
Sign(SignArgs),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
pub struct SignArgs {
|
||||||
|
/// Path to private identity key (example: private_identity_key.pem)
|
||||||
|
#[clap(long)]
|
||||||
|
private_key: PathBuf,
|
||||||
|
|
||||||
|
/// Base58 encoded message to sign
|
||||||
|
#[clap(long)]
|
||||||
|
base58_msg: String,
|
||||||
|
|
||||||
|
#[clap(short, long, default_value_t = OutputFormat::default())]
|
||||||
|
output: OutputFormat,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn sign(args: SignArgs) -> Result<(), NyxdError> {
|
||||||
|
eprintln!(">>> loading: {}", args.private_key.display());
|
||||||
|
let private_identity_key: identity::PrivateKey =
|
||||||
|
nym_pemstore::load_key(args.private_key).expect("failed to load key");
|
||||||
|
|
||||||
|
print_signed_msg(&private_identity_key, &args.base58_msg, args.output);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_signed_msg(private_key: &identity::PrivateKey, raw_msg: &str, output: OutputFormat) {
|
||||||
|
let trimmed = raw_msg.trim();
|
||||||
|
eprintln!(">>> attempting to sign: {trimmed}");
|
||||||
|
|
||||||
|
let Ok(decoded) = bs58::decode(trimmed).into_vec() else {
|
||||||
|
println!("failed to base58 decode the message, did you copy it correctly?");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
eprintln!(">>> decoding the message...");
|
||||||
|
|
||||||
|
// we don't really care about what particular information is embedded inside of it,
|
||||||
|
// we just want to know if user correctly copied the string, i.e. whether it's a valid bs58 encoded json
|
||||||
|
if serde_json::from_slice::<serde_json::Value>(&decoded).is_err() {
|
||||||
|
println!("failed to parse the message after decoding, did you copy it correctly?");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// if this is a valid json, it MUST be a valid string
|
||||||
|
let decoded_string = String::from_utf8(decoded.clone()).unwrap();
|
||||||
|
let signature = private_key.sign(&decoded).to_base58_string();
|
||||||
|
|
||||||
|
let sign_output = ConsoleSigningOutput::new(decoded_string, signature);
|
||||||
|
println!("{}", output.format(&sign_output));
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
use clap::{Args, Subcommand};
|
use clap::{Args, Subcommand};
|
||||||
|
|
||||||
pub mod gateway;
|
pub mod gateway;
|
||||||
|
pub mod identity_key;
|
||||||
pub mod mixnode;
|
pub mod mixnode;
|
||||||
pub mod name;
|
pub mod name;
|
||||||
pub mod service;
|
pub mod service;
|
||||||
@@ -26,4 +27,6 @@ pub enum MixnetOperatorsCommands {
|
|||||||
ServiceProvider(service::MixnetOperatorsService),
|
ServiceProvider(service::MixnetOperatorsService),
|
||||||
/// Manage your registered name
|
/// Manage your registered name
|
||||||
Name(name::MixnetOperatorsName),
|
Name(name::MixnetOperatorsName),
|
||||||
|
/// Sign messages using your private identity key
|
||||||
|
IdentityKey(identity_key::MixnetOperatorsIdentityKey),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use log::{error, info};
|
use log::{error, info};
|
||||||
use nym_name_service_common::{Address, Coin, NymName};
|
use nym_contracts_common::signing::MessageSignature;
|
||||||
|
use nym_name_service_common::{Address, Coin, NameDetails, NymName};
|
||||||
use nym_validator_client::nyxd::{error::NyxdError, traits::NameServiceSigningClient};
|
use nym_validator_client::nyxd::{error::NyxdError, traits::NameServiceSigningClient};
|
||||||
use tap::TapFallible;
|
use tap::TapFallible;
|
||||||
|
|
||||||
@@ -16,9 +17,15 @@ pub struct Args {
|
|||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub nym_address: String,
|
pub nym_address: String,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub signature: MessageSignature,
|
||||||
|
|
||||||
/// Deposit to be made to the service provider directory, in curent DENOMINATION (e.g. 'unym')
|
/// Deposit to be made to the service provider directory, in curent DENOMINATION (e.g. 'unym')
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub deposit: u128,
|
pub deposit: u128,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub identity_key: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn register(args: Args, client: SigningClient) -> Result<(), NyxdError> {
|
pub async fn register(args: Args, client: SigningClient) -> Result<(), NyxdError> {
|
||||||
@@ -29,12 +36,17 @@ pub async fn register(args: Args, client: SigningClient) -> Result<(), NyxdError
|
|||||||
|
|
||||||
let name = NymName::new(&args.name).expect("invalid name");
|
let name = NymName::new(&args.name).expect("invalid name");
|
||||||
let address = Address::new(&args.nym_address);
|
let address = Address::new(&args.nym_address);
|
||||||
|
let name = NameDetails {
|
||||||
|
name,
|
||||||
|
address,
|
||||||
|
identity_key: args.identity_key,
|
||||||
|
};
|
||||||
|
|
||||||
let denom = client.current_chain_details().mix_denom.base.as_str();
|
let denom = client.current_chain_details().mix_denom.base.as_str();
|
||||||
let deposit = Coin::new(args.deposit, denom);
|
let deposit = Coin::new(args.deposit, denom);
|
||||||
|
|
||||||
let res = client
|
let res = client
|
||||||
.register_name(name, address, deposit.into(), None)
|
.register_name(name, args.signature, deposit.into(), None)
|
||||||
.await
|
.await
|
||||||
.tap_err(|err| error!("Failed to register name: {err:#?}"))?;
|
.tap_err(|err| error!("Failed to register name: {err:#?}"))?;
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ pub async fn query(args: Args, client: &QueryClientWithNyxd) {
|
|||||||
table.set_header(vec!["Name Id", "Owner", "Nym Address", "Name"]);
|
table.set_header(vec!["Name Id", "Owner", "Nym Address", "Name"]);
|
||||||
for name_entry in res.names {
|
for name_entry in res.names {
|
||||||
table.add_row(vec![
|
table.add_row(vec![
|
||||||
name_entry.name_id.to_string(),
|
name_entry.id.to_string(),
|
||||||
name_entry.name.owner.to_string(),
|
name_entry.owner.to_string(),
|
||||||
name_entry.name.address.to_string(),
|
name_entry.name.address.to_string(),
|
||||||
name_entry.name.name.to_string(),
|
name_entry.name.name.to_string(),
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// due to code generated by JsonSchema
|
// due to code generated by JsonSchema
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// due to code generated by JsonSchema
|
// due to code generated by JsonSchema
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// due to code generated by JsonSchema
|
// due to code generated by JsonSchema
|
||||||
@@ -88,7 +88,7 @@ impl MixNodeDetails {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||||
pub struct MixNodeRewarding {
|
pub struct MixNodeRewarding {
|
||||||
/// Information provided by the operator that influence the cost function.
|
/// Information provided by the operator that influence the cost function.
|
||||||
pub cost_params: MixNodeCostParams,
|
pub cost_params: MixNodeCostParams,
|
||||||
|
|
||||||
/// Total pledge and compounded reward earned by the node operator.
|
/// Total pledge and compounded reward earned by the node operator.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::delegation::OwnerProxySubKey;
|
use crate::delegation::OwnerProxySubKey;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::error::MixnetContractError;
|
use crate::error::MixnetContractError;
|
||||||
|
|||||||
@@ -7,5 +7,9 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cosmwasm-std = { workspace = true }
|
cosmwasm-std = { workspace = true }
|
||||||
|
cw-controllers = { workspace = true }
|
||||||
|
cw-utils = { workspace = true }
|
||||||
|
nym-contracts-common = { path = "../contracts-common", version = "0.5.0" }
|
||||||
schemars = "0.8"
|
schemars = "0.8"
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
|
thiserror = { workspace = true }
|
||||||
|
|||||||
+19
-2
@@ -1,8 +1,10 @@
|
|||||||
use cosmwasm_std::{Addr, StdError};
|
use cosmwasm_std::{Addr, StdError};
|
||||||
use cw_controllers::AdminError;
|
use cw_controllers::AdminError;
|
||||||
use nym_name_service_common::{Address, NameId, NymName};
|
use nym_contracts_common::signing::verifier::ApiVerifierError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
use crate::{Address, NameId, NymName};
|
||||||
|
|
||||||
#[derive(Error, Debug, PartialEq)]
|
#[derive(Error, Debug, PartialEq)]
|
||||||
pub enum NameServiceError {
|
pub enum NameServiceError {
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
@@ -47,6 +49,21 @@ pub enum NameServiceError {
|
|||||||
error_message: String,
|
error_message: String,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
#[error("Failed to recover ed25519 public key from its base58 representation - {0}")]
|
||||||
|
MalformedEd25519IdentityKey(String),
|
||||||
|
|
||||||
|
#[error("Failed to recover ed25519 signature from its base58 representation - {0}")]
|
||||||
|
MalformedEd25519Signature(String),
|
||||||
|
|
||||||
|
#[error("Provided ed25519 signature did not verify correctly")]
|
||||||
|
InvalidEd25519Signature,
|
||||||
|
|
||||||
|
#[error("failed to verify message signature: {source}")]
|
||||||
|
SignatureVerificationFailure {
|
||||||
|
#[from]
|
||||||
|
source: ApiVerifierError,
|
||||||
|
},
|
||||||
|
|
||||||
#[error("duplicate entries detected for name: {name}")]
|
#[error("duplicate entries detected for name: {name}")]
|
||||||
DuplicateNames { name: NymName },
|
DuplicateNames { name: NymName },
|
||||||
|
|
||||||
@@ -54,4 +71,4 @@ pub enum NameServiceError {
|
|||||||
NameAlreadyRegistered { name: NymName },
|
NameAlreadyRegistered { name: NymName },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type Result<T, E = NameServiceError> = std::result::Result<T, E>;
|
pub type Result<T, E = NameServiceError> = std::result::Result<T, E>;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
use cosmwasm_std::{Coin, Event};
|
use cosmwasm_std::{Coin, Event};
|
||||||
|
|
||||||
use crate::{NameId, RegisteredName};
|
use crate::RegisteredName;
|
||||||
|
|
||||||
pub enum NameEventType {
|
pub enum NameEventType {
|
||||||
Register,
|
Register,
|
||||||
@@ -34,29 +34,29 @@ pub const OWNER: &str = "owner";
|
|||||||
|
|
||||||
pub const DEPOSIT_REQUIRED: &str = "deposit_required";
|
pub const DEPOSIT_REQUIRED: &str = "deposit_required";
|
||||||
|
|
||||||
pub fn new_register_event(name_id: NameId, name: RegisteredName) -> Event {
|
pub fn new_register_event(name: RegisteredName) -> Event {
|
||||||
Event::new(NameEventType::Register)
|
Event::new(NameEventType::Register)
|
||||||
.add_attribute(ACTION, NameEventType::Register)
|
.add_attribute(ACTION, NameEventType::Register)
|
||||||
.add_attribute(NAME_ID, name_id.to_string())
|
.add_attribute(NAME_ID, name.id.to_string())
|
||||||
.add_attribute(NAME, name.name.to_string())
|
.add_attribute(NAME, name.name.name.to_string())
|
||||||
.add_attribute(name.address.event_tag(), name.address.to_string())
|
.add_attribute(name.name.address.event_tag(), name.name.address.to_string())
|
||||||
.add_attribute(OWNER, name.owner.to_string())
|
.add_attribute(OWNER, name.owner.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_delete_id_event(name_id: NameId, name: RegisteredName) -> Event {
|
pub fn new_delete_id_event(name: RegisteredName) -> Event {
|
||||||
Event::new(NameEventType::DeleteId)
|
Event::new(NameEventType::DeleteId)
|
||||||
.add_attribute(ACTION, NameEventType::DeleteId)
|
.add_attribute(ACTION, NameEventType::DeleteId)
|
||||||
.add_attribute(NAME_ID, name_id.to_string())
|
.add_attribute(NAME_ID, name.id.to_string())
|
||||||
.add_attribute(NAME, name.name.to_string())
|
.add_attribute(NAME, name.name.name.to_string())
|
||||||
.add_attribute(name.address.event_tag(), name.address.to_string())
|
.add_attribute(name.name.address.event_tag(), name.name.address.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_delete_name_event(name_id: NameId, name: RegisteredName) -> Event {
|
pub fn new_delete_name_event(name: RegisteredName) -> Event {
|
||||||
Event::new(NameEventType::DeleteId)
|
Event::new(NameEventType::DeleteId)
|
||||||
.add_attribute(ACTION, NameEventType::DeleteName)
|
.add_attribute(ACTION, NameEventType::DeleteName)
|
||||||
.add_attribute(NAME_ID, name_id.to_string())
|
.add_attribute(NAME_ID, name.id.to_string())
|
||||||
.add_attribute(NAME, name.name.to_string())
|
.add_attribute(NAME, name.name.name.to_string())
|
||||||
.add_attribute(name.address.event_tag(), name.address.to_string())
|
.add_attribute(name.name.address.event_tag(), name.name.address.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_update_deposit_required_event(deposit_required: Coin) -> Event {
|
pub fn new_update_deposit_required_event(deposit_required: Coin) -> Event {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
pub mod error;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
pub mod msg;
|
pub mod msg;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
|
pub mod signing_types;
|
||||||
pub mod types;
|
pub mod types;
|
||||||
|
|
||||||
// Re-export all types at the top-level
|
// Re-export all types at the top-level
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::{Address, NameId, NymName};
|
use crate::{Address, NameDetails, NameId, NymName};
|
||||||
use cosmwasm_std::Coin;
|
use cosmwasm_std::Coin;
|
||||||
|
use nym_contracts_common::signing::MessageSignature;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||||
@@ -22,7 +23,10 @@ pub struct MigrateMsg {}
|
|||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum ExecuteMsg {
|
pub enum ExecuteMsg {
|
||||||
/// Announcing a name pointing to a nym-address
|
/// Announcing a name pointing to a nym-address
|
||||||
Register { name: NymName, address: Address },
|
Register {
|
||||||
|
name: NameDetails,
|
||||||
|
owner_signature: MessageSignature,
|
||||||
|
},
|
||||||
/// Delete a name entry by id
|
/// Delete a name entry by id
|
||||||
DeleteId { name_id: NameId },
|
DeleteId { name_id: NameId },
|
||||||
/// Delete a name entry by name
|
/// Delete a name entry by name
|
||||||
@@ -38,8 +42,11 @@ impl ExecuteMsg {
|
|||||||
|
|
||||||
pub fn default_memo(&self) -> String {
|
pub fn default_memo(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
ExecuteMsg::Register { name, address } => {
|
ExecuteMsg::Register {
|
||||||
format!("registering {address} as name: {name}")
|
name,
|
||||||
|
owner_signature: _,
|
||||||
|
} => {
|
||||||
|
format!("registering {} as name: {}", name.address, name.name)
|
||||||
}
|
}
|
||||||
ExecuteMsg::DeleteId { name_id } => {
|
ExecuteMsg::DeleteId { name_id } => {
|
||||||
format!("deleting name with id {name_id}")
|
format!("deleting name with id {name_id}")
|
||||||
@@ -75,6 +82,9 @@ pub enum QueryMsg {
|
|||||||
limit: Option<u32>,
|
limit: Option<u32>,
|
||||||
start_after: Option<NameId>,
|
start_after: Option<NameId>,
|
||||||
},
|
},
|
||||||
|
SigningNonce {
|
||||||
|
address: String,
|
||||||
|
},
|
||||||
Config {},
|
Config {},
|
||||||
GetContractVersion {},
|
GetContractVersion {},
|
||||||
#[serde(rename = "get_cw2_contract_version")]
|
#[serde(rename = "get_cw2_contract_version")]
|
||||||
|
|||||||
@@ -1,36 +1,22 @@
|
|||||||
use crate::{msg::ExecuteMsg, NameEntry, NameId, RegisteredName};
|
use crate::{NameId, RegisteredName};
|
||||||
use cosmwasm_std::Coin;
|
use cosmwasm_std::Coin;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// Like [`NameEntry`] but since it's a response type the name is an option depending on if
|
|
||||||
/// the name exists or not.
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub struct NameEntryResponse {
|
|
||||||
pub name_id: NameId,
|
|
||||||
pub name: Option<RegisteredName>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct NamesListResponse {
|
pub struct NamesListResponse {
|
||||||
pub names: Vec<NameEntry>,
|
pub names: Vec<RegisteredName>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NamesListResponse {
|
impl NamesListResponse {
|
||||||
pub fn new(names: Vec<(NameId, RegisteredName)>) -> NamesListResponse {
|
pub fn new(names: Vec<RegisteredName>) -> NamesListResponse {
|
||||||
NamesListResponse {
|
NamesListResponse { names }
|
||||||
names: names
|
|
||||||
.into_iter()
|
|
||||||
.map(|(name_id, name)| NameEntry::new(name_id, name))
|
|
||||||
.collect(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&[NameEntry]> for NamesListResponse {
|
impl From<&[RegisteredName]> for NamesListResponse {
|
||||||
fn from(names: &[NameEntry]) -> Self {
|
fn from(names: &[RegisteredName]) -> Self {
|
||||||
NamesListResponse {
|
NamesListResponse {
|
||||||
names: names.to_vec(),
|
names: names.to_vec(),
|
||||||
}
|
}
|
||||||
@@ -40,21 +26,17 @@ impl From<&[NameEntry]> for NamesListResponse {
|
|||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct PagedNamesListResponse {
|
pub struct PagedNamesListResponse {
|
||||||
pub names: Vec<NameEntry>,
|
pub names: Vec<RegisteredName>,
|
||||||
pub per_page: usize,
|
pub per_page: usize,
|
||||||
pub start_next_after: Option<NameId>,
|
pub start_next_after: Option<NameId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PagedNamesListResponse {
|
impl PagedNamesListResponse {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
names: Vec<(NameId, RegisteredName)>,
|
names: Vec<RegisteredName>,
|
||||||
per_page: usize,
|
per_page: usize,
|
||||||
start_next_after: Option<NameId>,
|
start_next_after: Option<NameId>,
|
||||||
) -> PagedNamesListResponse {
|
) -> PagedNamesListResponse {
|
||||||
let names = names
|
|
||||||
.into_iter()
|
|
||||||
.map(|(name_id, name)| NameEntry::new(name_id, name))
|
|
||||||
.collect();
|
|
||||||
PagedNamesListResponse {
|
PagedNamesListResponse {
|
||||||
names,
|
names,
|
||||||
per_page,
|
per_page,
|
||||||
@@ -68,12 +50,3 @@ impl PagedNamesListResponse {
|
|||||||
pub struct ConfigResponse {
|
pub struct ConfigResponse {
|
||||||
pub deposit_required: Coin,
|
pub deposit_required: Coin,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RegisteredName> for ExecuteMsg {
|
|
||||||
fn from(name: RegisteredName) -> Self {
|
|
||||||
ExecuteMsg::Register {
|
|
||||||
name: name.name,
|
|
||||||
address: name.address,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
use cosmwasm_std::{Addr, Coin};
|
||||||
|
use nym_contracts_common::signing::{
|
||||||
|
ContractMessageContent, MessageType, Nonce, SignableMessage, SigningPurpose,
|
||||||
|
};
|
||||||
|
use serde::Serialize;
|
||||||
|
|
||||||
|
use crate::NameDetails;
|
||||||
|
|
||||||
|
pub type SignableNameRegisterMsg = SignableMessage<ContractMessageContent<NameRegister>>;
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct NameRegister {
|
||||||
|
name: NameDetails,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SigningPurpose for NameRegister {
|
||||||
|
fn message_type() -> MessageType {
|
||||||
|
MessageType::new("name-register")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn construct_name_register_sign_payload(
|
||||||
|
nonce: Nonce,
|
||||||
|
sender: Addr,
|
||||||
|
deposit: Coin,
|
||||||
|
name: NameDetails,
|
||||||
|
) -> SignableNameRegisterMsg {
|
||||||
|
let payload = NameRegister { name };
|
||||||
|
let proxy = None;
|
||||||
|
let content = ContractMessageContent::new(sender, proxy, vec![deposit], payload);
|
||||||
|
SignableMessage::new(nonce, content)
|
||||||
|
}
|
||||||
@@ -1,24 +1,48 @@
|
|||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
|
||||||
use cosmwasm_std::{Addr, Coin};
|
use cosmwasm_std::{Addr, Coin};
|
||||||
|
use nym_contracts_common::IdentityKey;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
/// The directory of services are indexed by [`ServiceId`].
|
/// The directory of names are indexed by [`NameId`].
|
||||||
pub type NameId = u32;
|
pub type NameId = u32;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)]
|
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)]
|
||||||
pub struct RegisteredName {
|
pub struct RegisteredName {
|
||||||
|
/// Unique id assigned to the registerd name.
|
||||||
|
pub id: NameId,
|
||||||
|
|
||||||
|
/// The registerd name details.
|
||||||
|
pub name: NameDetails,
|
||||||
|
|
||||||
|
/// name owner.
|
||||||
|
pub owner: Addr,
|
||||||
|
|
||||||
|
/// Block height at which the name was added.
|
||||||
|
pub block_height: u64,
|
||||||
|
|
||||||
|
/// The deposit used to announce the name.
|
||||||
|
pub deposit: Coin,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegisteredName {
|
||||||
|
// Shortcut for getting the actual name
|
||||||
|
pub fn entry(&self) -> &NymName {
|
||||||
|
&self.name.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, JsonSchema)]
|
||||||
|
pub struct NameDetails {
|
||||||
/// The name pointing to the nym address
|
/// The name pointing to the nym address
|
||||||
pub name: NymName,
|
pub name: NymName,
|
||||||
/// The address of the service.
|
|
||||||
|
/// The address of the name alias.
|
||||||
pub address: Address,
|
pub address: Address,
|
||||||
/// Service owner.
|
|
||||||
pub owner: Addr,
|
/// The identity key of the registered name.
|
||||||
/// Block height at which the service was added.
|
pub identity_key: IdentityKey,
|
||||||
pub block_height: u64,
|
|
||||||
/// The deposit used to announce the service.
|
|
||||||
pub deposit: Coin,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// String representation of a nym address, which is of the form
|
/// String representation of a nym address, which is of the form
|
||||||
@@ -68,6 +92,7 @@ pub enum NymNameError {
|
|||||||
InvalidName,
|
InvalidName,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Defines what names are allowed
|
||||||
fn is_valid_name_char(c: char) -> bool {
|
fn is_valid_name_char(c: char) -> bool {
|
||||||
// Normal lowercase letters
|
// Normal lowercase letters
|
||||||
(c.is_alphabetic() && c.is_lowercase())
|
(c.is_alphabetic() && c.is_lowercase())
|
||||||
@@ -98,20 +123,6 @@ impl Display for NymName {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [`RegisterdName`] together with the assigned [`NameId`].
|
|
||||||
#[derive(Serialize, Deserialize, PartialEq, Debug, Clone, JsonSchema)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub struct NameEntry {
|
|
||||||
pub name_id: NameId,
|
|
||||||
pub name: RegisteredName,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NameEntry {
|
|
||||||
pub fn new(name_id: NameId, name: RegisteredName) -> Self {
|
|
||||||
Self { name_id, name }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::NymName;
|
use super::NymName;
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ edition = "2021"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cosmwasm-std = { workspace = true }
|
cosmwasm-std = { workspace = true }
|
||||||
|
cw-controllers = { workspace = true }
|
||||||
|
cw-utils = { workspace = true }
|
||||||
nym-contracts-common = { path = "../contracts-common", version = "0.5.0" }
|
nym-contracts-common = { path = "../contracts-common", version = "0.5.0" }
|
||||||
schemars = "0.8"
|
schemars = "0.8"
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
thiserror = { workspace = true }
|
thiserror = { workspace = true }
|
||||||
cw-utils = { workspace = true }
|
|
||||||
cw-controllers = { workspace = true }
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use nym_sphinx_acknowledgements::surb_ack::SurbAckRecoveryError;
|
use nym_sphinx_acknowledgements::surb_ack::SurbAckRecoveryError;
|
||||||
use nym_sphinx_addressing::nodes::NymNodeRoutingAddressError;
|
use nym_sphinx_addressing::nodes::NymNodeRoutingAddressError;
|
||||||
use nym_sphinx_types::{NymPacketError, SphinxError};
|
use nym_sphinx_types::{NymPacketError, OutfoxError, SphinxError};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
@@ -25,4 +25,7 @@ pub enum MixProcessingError {
|
|||||||
|
|
||||||
#[error("the received packet was set to use the very old and very much deprecated 'VPN' mode")]
|
#[error("the received packet was set to use the very old and very much deprecated 'VPN' mode")]
|
||||||
ReceivedOldTypeVpnPacket,
|
ReceivedOldTypeVpnPacket,
|
||||||
|
|
||||||
|
#[error("failed to process received outfox packet: {0}")]
|
||||||
|
OutfoxProcessingError(#[from] OutfoxError),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ use tracing::instrument;
|
|||||||
|
|
||||||
type ForwardAck = MixPacket;
|
type ForwardAck = MixPacket;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct ProcessedFinalHop {
|
pub struct ProcessedFinalHop {
|
||||||
pub destination: DestinationAddressBytes,
|
pub destination: DestinationAddressBytes,
|
||||||
pub forward_ack: Option<ForwardAck>,
|
pub forward_ack: Option<ForwardAck>,
|
||||||
pub message: Vec<u8>,
|
pub message: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum MixProcessingResult {
|
pub enum MixProcessingResult {
|
||||||
/// Contains unwrapped data that should first get delayed before being sent to next hop.
|
/// Contains unwrapped data that should first get delayed before being sent to next hop.
|
||||||
ForwardHop(MixPacket, Option<SphinxDelay>),
|
ForwardHop(MixPacket, Option<SphinxDelay>),
|
||||||
@@ -141,7 +143,7 @@ impl SphinxPacketProcessor {
|
|||||||
match SurbAck::try_recover_first_hop_packet(&ack_data, packet_type) {
|
match SurbAck::try_recover_first_hop_packet(&ack_data, packet_type) {
|
||||||
Ok((first_hop, packet)) => (first_hop, packet),
|
Ok((first_hop, packet)) => (first_hop, packet),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
debug!("Failed to recover first hop from ack data: {err}");
|
info!("Failed to recover first hop from ack data: {err}");
|
||||||
return Err(err.into());
|
return Err(err.into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -205,7 +207,7 @@ impl SphinxPacketProcessor {
|
|||||||
if packet.is_final_hop() {
|
if packet.is_final_hop() {
|
||||||
self.process_final_hop(
|
self.process_final_hop(
|
||||||
DestinationAddressBytes::from_bytes(next_address),
|
DestinationAddressBytes::from_bytes(next_address),
|
||||||
packet.recover_plaintext().to_vec(),
|
packet.recover_plaintext()?.to_vec(),
|
||||||
packet_size,
|
packet_size,
|
||||||
packet_type,
|
packet_type,
|
||||||
)
|
)
|
||||||
@@ -239,7 +241,14 @@ impl SphinxPacketProcessor {
|
|||||||
|
|
||||||
// for forward packets, extract next hop and set delay (but do NOT delay here)
|
// for forward packets, extract next hop and set delay (but do NOT delay here)
|
||||||
// for final packets, extract SURBAck
|
// for final packets, extract SURBAck
|
||||||
self.perform_final_processing(processed_packet, packet_size, packet_type)
|
let final_processing_result =
|
||||||
|
self.perform_final_processing(processed_packet, packet_size, packet_type);
|
||||||
|
|
||||||
|
if final_processing_result.is_err() {
|
||||||
|
error!("{:?}", final_processing_result)
|
||||||
|
}
|
||||||
|
|
||||||
|
final_processing_result
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,12 @@ thiserror = { workspace = true }
|
|||||||
zeroize = { workspace = true }
|
zeroize = { workspace = true }
|
||||||
|
|
||||||
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
|
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
|
||||||
|
nym-pemstore = { path = "../../pemstore" }
|
||||||
nym-sphinx-addressing = { path = "../addressing" }
|
nym-sphinx-addressing = { path = "../addressing" }
|
||||||
nym-sphinx-params = { path = "../params" }
|
nym-sphinx-params = { path = "../params" }
|
||||||
|
nym-sphinx-routing = { path = "../routing" }
|
||||||
nym-sphinx-types = { path = "../types" }
|
nym-sphinx-types = { path = "../types" }
|
||||||
nym-pemstore = { path = "../../pemstore" }
|
|
||||||
nym-topology = { path = "../../topology" }
|
nym-topology = { path = "../../topology" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
serde = ["serde_crate", "generic-array"]
|
serde = ["serde_crate", "generic-array"]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use nym_sphinx_addressing::nodes::{
|
|||||||
};
|
};
|
||||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||||
use nym_sphinx_params::{PacketType, DEFAULT_NUM_MIX_HOPS};
|
use nym_sphinx_params::{PacketType, DEFAULT_NUM_MIX_HOPS};
|
||||||
use nym_sphinx_types::delays::{self, Delay};
|
use nym_sphinx_types::delays::Delay;
|
||||||
use nym_sphinx_types::{NymPacket, NymPacketError, MIN_PACKET_SIZE};
|
use nym_sphinx_types::{NymPacket, NymPacketError, MIN_PACKET_SIZE};
|
||||||
use nym_topology::{NymTopology, NymTopologyError};
|
use nym_topology::{NymTopology, NymTopologyError};
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
@@ -51,7 +51,7 @@ impl SurbAck {
|
|||||||
{
|
{
|
||||||
let route =
|
let route =
|
||||||
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
|
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
|
||||||
let delays = delays::generate_from_average_duration(route.len(), average_delay);
|
let delays = nym_sphinx_routing::generate_hop_delays(average_delay, route.len());
|
||||||
let destination = recipient.as_sphinx_destination();
|
let destination = recipient.as_sphinx_destination();
|
||||||
|
|
||||||
let surb_ack_payload = prepare_identifier(rng, ack_key, marshaled_fragment_id);
|
let surb_ack_payload = prepare_identifier(rng, ack_key, marshaled_fragment_id);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ thiserror = "1"
|
|||||||
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
|
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
|
||||||
nym-sphinx-addressing = { path = "../addressing" }
|
nym-sphinx-addressing = { path = "../addressing" }
|
||||||
nym-sphinx-params = { path = "../params" }
|
nym-sphinx-params = { path = "../params" }
|
||||||
|
nym-sphinx-routing = { path = "../routing" }
|
||||||
nym-sphinx-types = { path = "../types" }
|
nym-sphinx-types = { path = "../types" }
|
||||||
nym-topology = { path = "../../topology" }
|
nym-topology = { path = "../../topology" }
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::encryption_key::{SurbEncryptionKey, SurbEncryptionKeyError, SurbEncryptionKeySize};
|
use crate::encryption_key::{SurbEncryptionKey, SurbEncryptionKeyError, SurbEncryptionKeySize};
|
||||||
@@ -7,7 +7,7 @@ use nym_sphinx_addressing::clients::Recipient;
|
|||||||
use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN};
|
use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN};
|
||||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||||
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
||||||
use nym_sphinx_types::{delays, NymPacket, SURBMaterial, SphinxError, SURB};
|
use nym_sphinx_types::{NymPacket, SURBMaterial, SphinxError, SURB};
|
||||||
use nym_topology::{NymTopology, NymTopologyError};
|
use nym_topology::{NymTopology, NymTopologyError};
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use serde::de::{Error as SerdeError, Visitor};
|
use serde::de::{Error as SerdeError, Visitor};
|
||||||
@@ -96,7 +96,7 @@ impl ReplySurb {
|
|||||||
{
|
{
|
||||||
let route =
|
let route =
|
||||||
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
|
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
|
||||||
let delays = delays::generate_from_average_duration(route.len(), average_delay);
|
let delays = nym_sphinx_routing::generate_hop_delays(average_delay, route.len());
|
||||||
let destination = recipient.as_sphinx_destination();
|
let destination = recipient.as_sphinx_destination();
|
||||||
|
|
||||||
let surb_material = SURBMaterial::new(route, delays, destination);
|
let surb_material = SURBMaterial::new(route, delays, destination);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::ChunkingError;
|
use crate::ChunkingError;
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ nym-crypto = { path = "../../crypto" }
|
|||||||
nym-sphinx-acknowledgements = { path = "../acknowledgements" }
|
nym-sphinx-acknowledgements = { path = "../acknowledgements" }
|
||||||
nym-sphinx-addressing = { path = "../addressing" }
|
nym-sphinx-addressing = { path = "../addressing" }
|
||||||
nym-sphinx-chunking = { path = "../chunking" }
|
nym-sphinx-chunking = { path = "../chunking" }
|
||||||
nym-sphinx-params = { path = "../params" }
|
|
||||||
nym-sphinx-forwarding = { path = "../forwarding" }
|
nym-sphinx-forwarding = { path = "../forwarding" }
|
||||||
|
nym-sphinx-params = { path = "../params" }
|
||||||
|
nym-sphinx-routing = { path = "../routing" }
|
||||||
nym-sphinx-types = { path = "../types" }
|
nym-sphinx-types = { path = "../types" }
|
||||||
nym-topology = { path = "../../topology" }
|
nym-topology = { path = "../../topology" }
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use nym_sphinx_params::packet_sizes::PacketSize;
|
|||||||
use nym_sphinx_params::{
|
use nym_sphinx_params::{
|
||||||
PacketEncryptionAlgorithm, PacketHkdfAlgorithm, PacketType, DEFAULT_NUM_MIX_HOPS,
|
PacketEncryptionAlgorithm, PacketHkdfAlgorithm, PacketType, DEFAULT_NUM_MIX_HOPS,
|
||||||
};
|
};
|
||||||
use nym_sphinx_types::{delays, NymPacket};
|
use nym_sphinx_types::NymPacket;
|
||||||
use nym_topology::{NymTopology, NymTopologyError};
|
use nym_topology::{NymTopology, NymTopologyError};
|
||||||
use rand::{CryptoRng, RngCore};
|
use rand::{CryptoRng, RngCore};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
@@ -91,6 +91,7 @@ where
|
|||||||
>(rng, full_address.encryption_key());
|
>(rng, full_address.encryption_key());
|
||||||
|
|
||||||
let public_key_bytes = ephemeral_keypair.public_key().to_bytes();
|
let public_key_bytes = ephemeral_keypair.public_key().to_bytes();
|
||||||
|
|
||||||
let cover_size = packet_size.plaintext_size() - public_key_bytes.len() - ack_bytes.len();
|
let cover_size = packet_size.plaintext_size() - public_key_bytes.len() - ack_bytes.len();
|
||||||
|
|
||||||
let mut cover_content: Vec<_> = LOOP_COVER_MESSAGE_PAYLOAD
|
let mut cover_content: Vec<_> = LOOP_COVER_MESSAGE_PAYLOAD
|
||||||
@@ -119,22 +120,38 @@ where
|
|||||||
|
|
||||||
let route =
|
let route =
|
||||||
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, full_address.gateway())?;
|
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, full_address.gateway())?;
|
||||||
let delays = delays::generate_from_average_duration(route.len(), average_packet_delay);
|
let delays = nym_sphinx_routing::generate_hop_delays(average_packet_delay, route.len());
|
||||||
let destination = full_address.as_sphinx_destination();
|
let destination = full_address.as_sphinx_destination();
|
||||||
|
|
||||||
// once merged, that's an easy rng injection point for sphinx packets : )
|
|
||||||
let packet = NymPacket::sphinx_build(
|
|
||||||
packet_size.payload_size(),
|
|
||||||
packet_payload,
|
|
||||||
&route,
|
|
||||||
&destination,
|
|
||||||
&delays,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let first_hop_address =
|
let first_hop_address =
|
||||||
NymNodeRoutingAddress::try_from(route.first().unwrap().address).unwrap();
|
NymNodeRoutingAddress::try_from(route.first().unwrap().address).unwrap();
|
||||||
|
|
||||||
Ok(MixPacket::new(first_hop_address, packet, PacketType::Mix))
|
// once merged, that's an easy rng injection point for sphinx packets : )
|
||||||
|
let packet = match packet_type {
|
||||||
|
PacketType::Mix => NymPacket::sphinx_build(
|
||||||
|
packet_size.payload_size(),
|
||||||
|
packet_payload,
|
||||||
|
&route,
|
||||||
|
&destination,
|
||||||
|
&delays,
|
||||||
|
)?,
|
||||||
|
#[allow(deprecated)]
|
||||||
|
PacketType::Vpn => NymPacket::sphinx_build(
|
||||||
|
packet_size.payload_size(),
|
||||||
|
packet_payload,
|
||||||
|
&route,
|
||||||
|
&destination,
|
||||||
|
&delays,
|
||||||
|
)?,
|
||||||
|
PacketType::Outfox => NymPacket::outfox_build(
|
||||||
|
packet_payload,
|
||||||
|
&route,
|
||||||
|
&destination,
|
||||||
|
Some(packet_size.plaintext_size()),
|
||||||
|
)?,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(MixPacket::new(first_hop_address, packet, packet_type))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper function used to determine if given message represents a loop cover message.
|
/// Helper function used to determine if given message represents a loop cover message.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::packet::{FramedNymPacket, Header};
|
use crate::packet::{FramedNymPacket, Header};
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const ACK_IV_SIZE: usize = 16;
|
|||||||
|
|
||||||
const ACK_PACKET_SIZE: usize = ACK_IV_SIZE + FRAG_ID_LEN + SPHINX_PACKET_OVERHEAD;
|
const ACK_PACKET_SIZE: usize = ACK_IV_SIZE + FRAG_ID_LEN + SPHINX_PACKET_OVERHEAD;
|
||||||
const REGULAR_PACKET_SIZE: usize = 2 * 1024 + SPHINX_PACKET_OVERHEAD;
|
const REGULAR_PACKET_SIZE: usize = 2 * 1024 + SPHINX_PACKET_OVERHEAD;
|
||||||
const EXTENDED_PACKET_SIZE_8: usize = 1 * 512 + SPHINX_PACKET_OVERHEAD;
|
const EXTENDED_PACKET_SIZE_8: usize = 8 * 1024 + SPHINX_PACKET_OVERHEAD;
|
||||||
const EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + SPHINX_PACKET_OVERHEAD;
|
const EXTENDED_PACKET_SIZE_16: usize = 16 * 1024 + SPHINX_PACKET_OVERHEAD;
|
||||||
const EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + SPHINX_PACKET_OVERHEAD;
|
const EXTENDED_PACKET_SIZE_32: usize = 32 * 1024 + SPHINX_PACKET_OVERHEAD;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
#![allow(deprecated)]
|
#![allow(deprecated)]
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use nym_sphinx_addressing::clients::Recipient;
|
use nym_sphinx_addressing::clients::Recipient;
|
||||||
use nym_sphinx_types::Node;
|
use nym_sphinx_types::{delays, Delay, Node};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub trait SphinxRouteMaker {
|
pub trait SphinxRouteMaker {
|
||||||
@@ -41,3 +43,11 @@ impl SphinxRouteMaker for Vec<Node> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn generate_hop_delays(average_packet_delay: Duration, num_hops: usize) -> Vec<Delay> {
|
||||||
|
if average_packet_delay.is_zero() {
|
||||||
|
vec![nym_sphinx_types::Delay::new_from_millis(0); num_hops]
|
||||||
|
} else {
|
||||||
|
delays::generate_from_average_duration(num_hops, average_packet_delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::message::{NymMessage, ACK_OVERHEAD, OUTFOX_ACK_OVERHEAD};
|
use crate::message::{NymMessage, ACK_OVERHEAD, OUTFOX_ACK_OVERHEAD};
|
||||||
@@ -14,7 +14,7 @@ use nym_sphinx_chunking::fragment::{Fragment, FragmentIdentifier};
|
|||||||
use nym_sphinx_forwarding::packet::MixPacket;
|
use nym_sphinx_forwarding::packet::MixPacket;
|
||||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||||
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
||||||
use nym_sphinx_types::{delays, Delay, NymPacket};
|
use nym_sphinx_types::{Delay, NymPacket};
|
||||||
use nym_topology::{NymTopology, NymTopologyError};
|
use nym_topology::{NymTopology, NymTopologyError};
|
||||||
use rand::{CryptoRng, Rng};
|
use rand::{CryptoRng, Rng};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
@@ -233,7 +233,7 @@ pub trait FragmentPreparer {
|
|||||||
|
|
||||||
// including set of delays
|
// including set of delays
|
||||||
let delays =
|
let delays =
|
||||||
delays::generate_from_average_duration(route.len(), self.average_packet_delay());
|
nym_sphinx_routing::generate_hop_delays(self.average_packet_delay(), route.len());
|
||||||
|
|
||||||
// create the actual sphinx packet here. With valid route and correct payload size,
|
// create the actual sphinx packet here. With valid route and correct payload size,
|
||||||
// there's absolutely no reason for this call to fail.
|
// there's absolutely no reason for this call to fail.
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ impl SocksRequest {
|
|||||||
where
|
where
|
||||||
R: AsyncRead + Unpin,
|
R: AsyncRead + Unpin,
|
||||||
{
|
{
|
||||||
log::info!("read from stream socks5");
|
log::trace!("read from stream socks5");
|
||||||
|
|
||||||
let mut packet = [0u8; 4];
|
let mut packet = [0u8; 4];
|
||||||
// Read a byte from the stream and determine the version being requested
|
// Read a byte from the stream and determine the version being requested
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ enum TaskError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: possibly we should create a `Status` trait instead of reusing `Error`
|
// TODO: possibly we should create a `Status` trait instead of reusing `Error`
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug, PartialEq, Eq)]
|
||||||
pub enum TaskStatus {
|
pub enum TaskStatus {
|
||||||
#[error("Ready")]
|
#[error("Ready")]
|
||||||
Ready,
|
Ready,
|
||||||
@@ -177,20 +177,29 @@ impl TaskManager {
|
|||||||
drop(notify_rx);
|
drop(notify_rx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
let interrupt_future = tokio::signal::ctrl_c();
|
||||||
|
|
||||||
// in wasm we'll never get our shutdown anyway...
|
// in wasm we'll never get our shutdown anyway...
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
futures::future::pending::<()>().await;
|
let interrupt_future = futures::future::pending::<()>();
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
let wait_future = tokio::time::sleep(Duration::from_secs(self.shutdown_timer_secs));
|
||||||
|
|
||||||
|
// TODO: we should be using a `Delay` here for wasm
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
let wait_future = futures::future::pending::<()>();
|
||||||
|
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = self.notify_tx.closed() => {
|
_ = self.notify_tx.closed() => {
|
||||||
log::info!("All registered tasks succesfully shutdown");
|
log::info!("All registered tasks succesfully shutdown");
|
||||||
},
|
},
|
||||||
_ = tokio::signal::ctrl_c() => {
|
_ = interrupt_future => {
|
||||||
log::info!("Forcing shutdown");
|
log::info!("Forcing shutdown");
|
||||||
}
|
}
|
||||||
_ = tokio::time::sleep(Duration::from_secs(self.shutdown_timer_secs)) => {
|
_ = wait_future => {
|
||||||
log::info!("Timout reached, forcing shutdown");
|
log::info!("Timeout reached, forcing shutdown");
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+9
-2
@@ -1411,6 +1411,7 @@ name = "nym-name-service"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"bs58",
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
"cw-controllers",
|
"cw-controllers",
|
||||||
"cw-multi-test",
|
"cw-multi-test",
|
||||||
@@ -1418,8 +1419,10 @@ dependencies = [
|
|||||||
"cw-utils",
|
"cw-utils",
|
||||||
"cw2",
|
"cw2",
|
||||||
"nym-contracts-common",
|
"nym-contracts-common",
|
||||||
|
"nym-crypto",
|
||||||
"nym-name-service-common",
|
"nym-name-service-common",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
|
"rand_chacha 0.2.2",
|
||||||
"rstest",
|
"rstest",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1432,8 +1435,12 @@ name = "nym-name-service-common"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
|
"cw-controllers",
|
||||||
|
"cw-utils",
|
||||||
|
"nym-contracts-common",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1646,9 +1653,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.52"
|
version = "1.0.63"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224"
|
checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use super::storage;
|
use super::storage;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::constants::{
|
use crate::constants::{
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use super::storage;
|
use super::storage;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user