Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e8617c2856 | |||
| 65c8982cab | |||
| 5f7499604d | |||
| 8c021e9537 | |||
| f2d56882fe | |||
| 891fdeb4b5 | |||
| 01221a8e8c | |||
| 58c74199d1 | |||
| eb98c1bf33 | |||
| d6393c1496 | |||
| 48dfc24c33 | |||
| 61eaffe91b | |||
| 0f59fd4eee | |||
| c3aec2b01f | |||
| c023c8fb9f | |||
| 1162de3673 | |||
| 74252269bc | |||
| fe88321a50 | |||
| babc84779c | |||
| f3fcef60c3 | |||
| ed7a84a1ce | |||
| 48e18684a2 | |||
| e76c8e06be | |||
| 858b6c6094 | |||
| 7b4dc78f41 | |||
| bb7a8e84e4 | |||
| a3183ab313 | |||
| 74cd73a58f | |||
| dd89026065 | |||
| 07c80e5150 | |||
| c17f0ac3f8 | |||
| 7ae56b08b3 | |||
| 73fc2d6bb2 | |||
| a5289cd431 | |||
| ec0e1b67a0 | |||
| eafbed6c9f | |||
| 4635db73f1 | |||
| 9a43d1079a | |||
| 3238722ade | |||
| a6ad6c7d49 | |||
| cbc977c491 | |||
| f40c05a34c | |||
| 776443131e | |||
| b5eab7f07f | |||
| eeeb4b3246 | |||
| e3e4dc6db9 | |||
| 461b7bcfb7 | |||
| bbf0d06583 | |||
| 6393d6093f | |||
| c0ea599913 | |||
| 16d09a35ba | |||
| e6c5eddbe5 |
@@ -62,10 +62,6 @@ jobs:
|
||||
echo 'RUSTFLAGS="--cfg tokio_unstable"' >> $GITHUB_ENV
|
||||
if: github.event_name == 'workflow_dispatch' && inputs.add_tokio_unstable == true
|
||||
|
||||
- name: Set CARGO_FEATURES
|
||||
run: |
|
||||
echo 'CARGO_FEATURES=--features wireguard' >> $GITHUB_ENV
|
||||
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
@@ -91,7 +87,7 @@ jobs:
|
||||
|
||||
- name: Upload Artifact
|
||||
if: github.event_name == 'workflow_dispatch'
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nym-binaries-artifacts
|
||||
path: |
|
||||
|
||||
@@ -73,29 +73,27 @@ jobs:
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
# Enable wireguard by default on linux only
|
||||
args: --workspace --features wireguard
|
||||
|
||||
- name: Build all examples
|
||||
if: matrix.os == 'custom-linux'
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --workspace --examples --features wireguard
|
||||
args: --workspace --examples
|
||||
|
||||
- name: Run all tests
|
||||
if: matrix.os == 'custom-linux'
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: --workspace --features wireguard
|
||||
args: --workspace
|
||||
|
||||
- name: Run expensive tests
|
||||
if: (github.ref == 'refs/heads/develop' || github.event.pull_request.base.ref == 'develop' || github.event.pull_request.base.ref == 'master') && matrix.os == 'custom-linux'
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: --workspace --features wireguard -- --ignored
|
||||
args: --workspace -- --ignored
|
||||
|
||||
- name: Annotate with clippy checks
|
||||
if: matrix.os == 'custom-linux'
|
||||
@@ -103,10 +101,10 @@ jobs:
|
||||
continue-on-error: true
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --workspace --features wireguard
|
||||
args: --workspace
|
||||
|
||||
- name: Clippy
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: clippy
|
||||
args: --workspace --all-targets --features wireguard -- -D warnings
|
||||
args: --workspace --all-targets -- -D warnings
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
find . -name Cargo.toml -exec cargo deny --manifest-path {} check \
|
||||
advisories -A advisory-not-detected --hide-inclusion-graph \; &> \
|
||||
>(uniq &> .github/workflows/support-files/notifications/deny.message )
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: report
|
||||
path: .github/workflows/support-files/notifications/deny.message
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v2
|
||||
- name: Download report from previous job
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: report
|
||||
path: .github/workflows/support-files/notifications
|
||||
|
||||
@@ -51,10 +51,6 @@ jobs:
|
||||
echo 'RUSTFLAGS="--cfg tokio_unstable"' >> $GITHUB_ENV
|
||||
if: github.event_name == 'workflow_dispatch' && inputs.add_tokio_unstable == true
|
||||
|
||||
- name: Set CARGO_FEATURES
|
||||
run: |
|
||||
echo 'CARGO_FEATURES=--features wireguard' >> $GITHUB_ENV
|
||||
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
@@ -67,7 +63,7 @@ jobs:
|
||||
args: --workspace --release ${{ env.CARGO_FEATURES }}
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: my-artifact
|
||||
path: |
|
||||
|
||||
@@ -26,14 +26,14 @@ jobs:
|
||||
run: make contracts
|
||||
|
||||
- name: Upload Mixnet Contract Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: mixnet_contract.wasm
|
||||
path: contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm
|
||||
retention-days: 5
|
||||
|
||||
- name: Upload Vesting Contract Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: vesting_contract.wasm
|
||||
path: contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm
|
||||
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
run: yarn && yarn build
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nym-wallet.app.tar.gz
|
||||
path: nym-wallet/target/release/bundle/macos/nym-wallet.app.tar.gz
|
||||
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nym-wallet_1.0.0_amd64.AppImage.tar.gz
|
||||
path: nym-wallet/target/release/bundle/appimage/nym-wallet*.AppImage.tar.gz
|
||||
|
||||
+6
-3
@@ -1,4 +1,4 @@
|
||||
name: publish-nym-wallet-win10
|
||||
name: publish-nym-wallet-win11
|
||||
on:
|
||||
workflow_dispatch:
|
||||
release:
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [windows10]
|
||||
platform: [custom-windows-11]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
outputs:
|
||||
@@ -62,6 +62,9 @@ jobs:
|
||||
fileName: '.env'
|
||||
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
|
||||
|
||||
- name: Install Yarn
|
||||
run: npm install -g yarn
|
||||
|
||||
- name: Install project dependencies
|
||||
shell: bash
|
||||
run: cd .. && yarn --network-timeout 100000
|
||||
@@ -82,7 +85,7 @@ jobs:
|
||||
run: yarn build
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nym-wallet_1.0.0_x64_en-US.msi
|
||||
path: nym-wallet/target/release/bundle/msi/nym-wallet_1.*.msi
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
apk/nyms5-arch64-release.apk
|
||||
|
||||
- name: Upload APKs
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: nyms5-apk-arch64
|
||||
path: |
|
||||
@@ -99,7 +99,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Download binary artifact
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: nyms5-apk-arch64
|
||||
path: apk
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
with:
|
||||
release-tag-or-name-or-id: ${{ inputs.release_tag }}
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Asset Hashes
|
||||
path: hashes.json
|
||||
|
||||
@@ -4,6 +4,60 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [2024.10-caramello] (2024-09-10)
|
||||
|
||||
- Backport 4844 and 4845 ([#4857])
|
||||
- Bugfix/client registration vol2 ([#4856])
|
||||
- Remove wireguard feature flag and pass runtime enabled flag ([#4839])
|
||||
- Eliminate cancel unsafe sig awaiting ([#4834])
|
||||
- added explicit updateable admin to the mixnet contract ([#4822])
|
||||
- using legacy signing payload in CLI and verifying both variants in contract ([#4821])
|
||||
- adding ecash contract address ([#4819])
|
||||
- Check profit margin of node before defaulting to hardcoded value ([#4802])
|
||||
- Sync last_seen_bandwidth immediately ([#4774])
|
||||
- Feature/additional ecash nym cli utils ([#4773])
|
||||
- Better storage error logging ([#4772])
|
||||
- bugfix: make sure DKG parses data out of events if logs are empty ([#4764])
|
||||
- Fix clippy on rustc beta toolchain ([#4746])
|
||||
- Fix clippy for beta toolchain ([#4742])
|
||||
- Disable testnet-manager on non-unix ([#4741])
|
||||
- Don't set NYM_VPN_API to default ([#4740])
|
||||
- Update publish-nym-binaries.yml ([#4739])
|
||||
- Update ci-build-upload-binaries.yml ([#4738])
|
||||
- Add NYM_VPN_API to network config ([#4736])
|
||||
- Re-export RecipientFormattingError in nym sdk ([#4735])
|
||||
- Persist wireguard peers ([#4732])
|
||||
- Fix tokio error in 1.39 ([#4730])
|
||||
- Feature/vesting purge plus ranged cost params ([#4716])
|
||||
- Fix (some) feature unification build failures ([#4681])
|
||||
- Feature Compact Ecash : The One PR ([#4623])
|
||||
|
||||
[#4857]: https://github.com/nymtech/nym/pull/4857
|
||||
[#4856]: https://github.com/nymtech/nym/pull/4856
|
||||
[#4839]: https://github.com/nymtech/nym/pull/4839
|
||||
[#4834]: https://github.com/nymtech/nym/pull/4834
|
||||
[#4822]: https://github.com/nymtech/nym/pull/4822
|
||||
[#4821]: https://github.com/nymtech/nym/pull/4821
|
||||
[#4819]: https://github.com/nymtech/nym/pull/4819
|
||||
[#4802]: https://github.com/nymtech/nym/pull/4802
|
||||
[#4774]: https://github.com/nymtech/nym/pull/4774
|
||||
[#4773]: https://github.com/nymtech/nym/pull/4773
|
||||
[#4772]: https://github.com/nymtech/nym/pull/4772
|
||||
[#4764]: https://github.com/nymtech/nym/pull/4764
|
||||
[#4746]: https://github.com/nymtech/nym/pull/4746
|
||||
[#4742]: https://github.com/nymtech/nym/pull/4742
|
||||
[#4741]: https://github.com/nymtech/nym/pull/4741
|
||||
[#4740]: https://github.com/nymtech/nym/pull/4740
|
||||
[#4739]: https://github.com/nymtech/nym/pull/4739
|
||||
[#4738]: https://github.com/nymtech/nym/pull/4738
|
||||
[#4736]: https://github.com/nymtech/nym/pull/4736
|
||||
[#4735]: https://github.com/nymtech/nym/pull/4735
|
||||
[#4732]: https://github.com/nymtech/nym/pull/4732
|
||||
[#4730]: https://github.com/nymtech/nym/pull/4730
|
||||
[#4716]: https://github.com/nymtech/nym/pull/4716
|
||||
[#4681]: https://github.com/nymtech/nym/pull/4681
|
||||
[#4623]: https://github.com/nymtech/nym/pull/4623
|
||||
|
||||
## [2024.9-topdeck] (2024-07-26)
|
||||
|
||||
- chore: fix 1.80 lint issues ([#4731])
|
||||
|
||||
Generated
+94
-229
@@ -332,15 +332,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
|
||||
dependencies = [
|
||||
"autocfg 1.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
@@ -553,7 +544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f"
|
||||
dependencies = [
|
||||
"bitcoin_hashes",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"unicode-normalization",
|
||||
@@ -994,15 +985,6 @@ version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.1"
|
||||
@@ -1868,11 +1850,10 @@ checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
|
||||
|
||||
[[package]]
|
||||
name = "defguard_wireguard_rs"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba16f17698d4b389907310af018b0c3a80b025bba9c38d947cbc6dd70921743"
|
||||
version = "0.4.7"
|
||||
source = "git+https://github.com/DefGuard/wireguard-rs.git?rev=v0.4.7#ef1cf3714629bf5016fb38cbb7320451dc69fb09"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"base64 0.22.1",
|
||||
"libc",
|
||||
"log",
|
||||
"netlink-packet-core",
|
||||
@@ -1881,7 +1862,7 @@ dependencies = [
|
||||
"netlink-packet-utils",
|
||||
"netlink-packet-wireguard",
|
||||
"netlink-sys",
|
||||
"nix 0.27.1",
|
||||
"nix 0.29.0",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
@@ -2240,7 +2221,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "explorer-api"
|
||||
version = "1.1.38"
|
||||
version = "1.1.39"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap 4.5.7",
|
||||
@@ -2259,8 +2240,8 @@ dependencies = [
|
||||
"nym-validator-client",
|
||||
"okapi",
|
||||
"pretty_env_logger",
|
||||
"rand 0.8.5",
|
||||
"rand_pcg 0.3.1",
|
||||
"rand",
|
||||
"rand_pcg",
|
||||
"rand_seeder",
|
||||
"reqwest 0.12.4",
|
||||
"rocket",
|
||||
@@ -2459,12 +2440,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
@@ -3345,7 +3320,7 @@ version = "1.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
|
||||
dependencies = [
|
||||
"autocfg 1.3.0",
|
||||
"autocfg",
|
||||
"hashbrown 0.12.3",
|
||||
"serde",
|
||||
]
|
||||
@@ -3760,7 +3735,7 @@ version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg 1.3.0",
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
@@ -3887,7 +3862,7 @@ version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||
dependencies = [
|
||||
"autocfg 1.3.0",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3957,7 +3932,7 @@ dependencies = [
|
||||
"nym-ordered-buffer",
|
||||
"nym-service-providers-common",
|
||||
"nym-socks5-requests",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde-wasm-bindgen 0.6.5",
|
||||
"thiserror",
|
||||
@@ -4015,14 +3990,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "netlink-packet-route"
|
||||
version = "0.17.1"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66"
|
||||
checksum = "55e5bda7ca0f9ac5e75b5debac3b75e29a8ac8e2171106a2c3bb466389a8dd83"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 1.3.2",
|
||||
"bitflags 2.5.0",
|
||||
"byteorder",
|
||||
"libc",
|
||||
"log",
|
||||
"netlink-packet-core",
|
||||
"netlink-packet-utils",
|
||||
]
|
||||
@@ -4082,7 +4058,6 @@ dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4095,6 +4070,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4173,7 +4149,7 @@ version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg 1.3.0",
|
||||
"autocfg",
|
||||
"libm",
|
||||
]
|
||||
|
||||
@@ -4204,7 +4180,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
|
||||
|
||||
[[package]]
|
||||
name = "nym-api"
|
||||
version = "1.1.42"
|
||||
version = "1.1.43"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -4257,8 +4233,8 @@ dependencies = [
|
||||
"nym-vesting-contract-common",
|
||||
"okapi",
|
||||
"pin-project",
|
||||
"rand 0.8.5",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"reqwest 0.12.4",
|
||||
"rocket",
|
||||
"rocket_cors",
|
||||
@@ -4344,7 +4320,7 @@ dependencies = [
|
||||
"nym-types",
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@@ -4361,7 +4337,7 @@ dependencies = [
|
||||
"bincode",
|
||||
"nym-sphinx",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
]
|
||||
|
||||
@@ -4379,7 +4355,7 @@ dependencies = [
|
||||
"nym-ecash-time",
|
||||
"nym-network-defaults",
|
||||
"nym-validator-client",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"thiserror",
|
||||
"url",
|
||||
"zeroize",
|
||||
@@ -4425,7 +4401,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-cli"
|
||||
version = "1.1.40"
|
||||
version = "1.1.41"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.13.1",
|
||||
@@ -4453,11 +4429,12 @@ name = "nym-cli-commands"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.13.1",
|
||||
"base64 0.21.7",
|
||||
"bip39",
|
||||
"bs58 0.5.1",
|
||||
"cfg-if",
|
||||
"clap 4.5.7",
|
||||
"colored",
|
||||
"comfy-table 6.2.0",
|
||||
"cosmrs 0.17.0-pre",
|
||||
"cosmwasm-std",
|
||||
@@ -4490,21 +4467,21 @@ dependencies = [
|
||||
"nym-types",
|
||||
"nym-validator-client",
|
||||
"nym-vesting-contract-common",
|
||||
"rand 0.6.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tap",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
"toml 0.5.11",
|
||||
"toml 0.8.14",
|
||||
"url",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nym-client"
|
||||
version = "1.1.39"
|
||||
version = "1.1.40"
|
||||
dependencies = [
|
||||
"bs58 0.5.1",
|
||||
"clap 4.5.7",
|
||||
@@ -4527,7 +4504,7 @@ dependencies = [
|
||||
"nym-task",
|
||||
"nym-topology",
|
||||
"nym-validator-client",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tap",
|
||||
@@ -4578,7 +4555,7 @@ dependencies = [
|
||||
"nym-task",
|
||||
"nym-topology",
|
||||
"nym-validator-client",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
@@ -4658,7 +4635,7 @@ dependencies = [
|
||||
"nym-bin-common",
|
||||
"nym-node-tester-utils",
|
||||
"nym-node-tester-wasm",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde-wasm-bindgen 0.6.5",
|
||||
"serde_json",
|
||||
@@ -4695,8 +4672,8 @@ dependencies = [
|
||||
"itertools 0.13.0",
|
||||
"nym-dkg",
|
||||
"nym-pemstore",
|
||||
"rand 0.8.5",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"sha2 0.9.9",
|
||||
@@ -4742,7 +4719,7 @@ dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"nym-network-defaults",
|
||||
"nym-pemstore",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"rayon",
|
||||
"serde",
|
||||
"sha2 0.9.9",
|
||||
@@ -4836,7 +4813,7 @@ dependencies = [
|
||||
"nym-ecash-time",
|
||||
"nym-network-defaults",
|
||||
"nym-validator-client",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"time",
|
||||
@@ -4851,7 +4828,7 @@ dependencies = [
|
||||
"nym-compact-ecash",
|
||||
"nym-ecash-time",
|
||||
"nym-network-defaults",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"strum 0.25.0",
|
||||
"thiserror",
|
||||
@@ -4874,8 +4851,8 @@ dependencies = [
|
||||
"hmac",
|
||||
"nym-pemstore",
|
||||
"nym-sphinx-types",
|
||||
"rand 0.8.5",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"subtle-encoding",
|
||||
@@ -4897,8 +4874,8 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"nym-contracts-common",
|
||||
"nym-pemstore",
|
||||
"rand 0.8.5",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"rand_core 0.6.4",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
@@ -5028,7 +5005,7 @@ dependencies = [
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"once_cell",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"si-scale",
|
||||
@@ -5063,7 +5040,7 @@ dependencies = [
|
||||
"nym-sphinx",
|
||||
"nym-task",
|
||||
"nym-validator-client",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"si-scale",
|
||||
"thiserror",
|
||||
@@ -5092,7 +5069,8 @@ dependencies = [
|
||||
"nym-crypto",
|
||||
"nym-pemstore",
|
||||
"nym-sphinx",
|
||||
"rand 0.8.5",
|
||||
"nym-task",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@@ -5192,7 +5170,7 @@ name = "nym-inclusion-probability"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@@ -5205,7 +5183,7 @@ dependencies = [
|
||||
"nym-bin-common",
|
||||
"nym-crypto",
|
||||
"nym-sphinx",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"time",
|
||||
@@ -5242,7 +5220,7 @@ dependencies = [
|
||||
"nym-types",
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"reqwest 0.12.4",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -5295,11 +5273,12 @@ dependencies = [
|
||||
"bs58 0.4.0",
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cw-controllers",
|
||||
"cw2",
|
||||
"humantime-serde",
|
||||
"log",
|
||||
"nym-contracts-common",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_chacha",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde-json-wasm",
|
||||
@@ -5342,7 +5321,7 @@ dependencies = [
|
||||
"nym-topology",
|
||||
"nym-types",
|
||||
"nym-validator-client",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sysinfo 0.27.8",
|
||||
@@ -5375,7 +5354,7 @@ dependencies = [
|
||||
"nym-sphinx-types",
|
||||
"nym-task",
|
||||
"nym-validator-client",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"time",
|
||||
@@ -5412,7 +5391,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.40"
|
||||
version = "1.1.41"
|
||||
dependencies = [
|
||||
"addr",
|
||||
"anyhow",
|
||||
@@ -5445,7 +5424,7 @@ dependencies = [
|
||||
"nym-types",
|
||||
"pretty_env_logger",
|
||||
"publicsuffix",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"regex",
|
||||
"reqwest 0.12.4",
|
||||
"serde",
|
||||
@@ -5463,7 +5442,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-node"
|
||||
version = "1.1.6"
|
||||
version = "1.1.7"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bip39",
|
||||
@@ -5492,7 +5471,7 @@ dependencies = [
|
||||
"nym-types",
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"semver 1.0.23",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -5526,7 +5505,7 @@ dependencies = [
|
||||
"nym-task",
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"time",
|
||||
@@ -5553,7 +5532,7 @@ dependencies = [
|
||||
"nym-exit-policy",
|
||||
"nym-http-api-client",
|
||||
"nym-wireguard-types",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_chacha",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -5574,7 +5553,7 @@ dependencies = [
|
||||
"nym-sphinx-params",
|
||||
"nym-task",
|
||||
"nym-topology",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@@ -5589,7 +5568,7 @@ dependencies = [
|
||||
"futures",
|
||||
"js-sys",
|
||||
"nym-node-tester-utils",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde-wasm-bindgen 0.6.5",
|
||||
"thiserror",
|
||||
@@ -5648,7 +5627,7 @@ dependencies = [
|
||||
"fastrand 2.1.0",
|
||||
"getrandom",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"rayon",
|
||||
"sphinx-packet",
|
||||
"thiserror",
|
||||
@@ -5697,7 +5676,7 @@ dependencies = [
|
||||
"nym-validator-client",
|
||||
"parking_lot 0.12.3",
|
||||
"pretty_env_logger",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"reqwest 0.12.4",
|
||||
"tap",
|
||||
"thiserror",
|
||||
@@ -5737,7 +5716,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.39"
|
||||
version = "1.1.40"
|
||||
dependencies = [
|
||||
"bs58 0.5.1",
|
||||
"clap 4.5.7",
|
||||
@@ -5757,7 +5736,7 @@ dependencies = [
|
||||
"nym-sphinx",
|
||||
"nym-topology",
|
||||
"nym-validator-client",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tap",
|
||||
@@ -5790,7 +5769,7 @@ dependencies = [
|
||||
"nym-task",
|
||||
"nym-validator-client",
|
||||
"pin-project",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"reqwest 0.12.4",
|
||||
"schemars",
|
||||
"serde",
|
||||
@@ -5816,7 +5795,7 @@ dependencies = [
|
||||
"nym-credential-storage",
|
||||
"nym-crypto",
|
||||
"nym-socks5-client-core",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"safer-ffi",
|
||||
"serde",
|
||||
"tokio",
|
||||
@@ -5870,7 +5849,7 @@ dependencies = [
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"rand_distr",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
@@ -5888,7 +5867,7 @@ dependencies = [
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"zeroize",
|
||||
@@ -5900,7 +5879,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"nym-crypto",
|
||||
"nym-sphinx-types",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"thiserror",
|
||||
]
|
||||
@@ -5916,8 +5895,8 @@ dependencies = [
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.8.5",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand",
|
||||
"rand_chacha",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"wasm-bindgen",
|
||||
@@ -5931,7 +5910,7 @@ dependencies = [
|
||||
"nym-sphinx-addressing",
|
||||
"nym-sphinx-params",
|
||||
"nym-sphinx-types",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@@ -5948,7 +5927,7 @@ dependencies = [
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@@ -6010,7 +5989,7 @@ dependencies = [
|
||||
"argon2",
|
||||
"generic-array 0.14.7",
|
||||
"getrandom",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@@ -6045,7 +6024,7 @@ dependencies = [
|
||||
"nym-sphinx-addressing",
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"semver 0.11.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -6169,7 +6148,7 @@ dependencies = [
|
||||
"nym-task",
|
||||
"nym-validator-client",
|
||||
"nyxd-scraper",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_chacha",
|
||||
"serde",
|
||||
"serde_with",
|
||||
"sha2 0.10.8",
|
||||
@@ -6242,12 +6221,13 @@ name = "nym-wireguard-types"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"dashmap",
|
||||
"hmac",
|
||||
"log",
|
||||
"nym-config",
|
||||
"nym-crypto",
|
||||
"nym-network-defaults",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
@@ -6258,7 +6238,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nymvisor"
|
||||
version = "0.1.5"
|
||||
version = "0.1.6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -6457,7 +6437,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"opentelemetry_api",
|
||||
"percent-encoding",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
@@ -6770,7 +6750,7 @@ version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
|
||||
dependencies = [
|
||||
"autocfg 1.3.0",
|
||||
"autocfg",
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
@@ -7024,25 +7004,6 @@ version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"libc",
|
||||
"rand_chacha 0.1.1",
|
||||
"rand_core 0.4.2",
|
||||
"rand_hc",
|
||||
"rand_isaac",
|
||||
"rand_jitter",
|
||||
"rand_os",
|
||||
"rand_pcg 0.1.2",
|
||||
"rand_xorshift",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
@@ -7050,20 +7011,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_chacha",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
@@ -7074,21 +7025,6 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
@@ -7111,60 +7047,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
dependencies = [
|
||||
"cloudabi",
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.4.2",
|
||||
"rdrand",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
dependencies = [
|
||||
"autocfg 0.1.8",
|
||||
"rand_core 0.4.2",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7185,15 +7068,6 @@ dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
@@ -7214,15 +7088,6 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
@@ -7480,7 +7345,7 @@ dependencies = [
|
||||
"num_cpus",
|
||||
"parking_lot 0.12.3",
|
||||
"pin-project-lite",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"ref-cast",
|
||||
"rocket_codegen",
|
||||
"rocket_http",
|
||||
@@ -8253,7 +8118,7 @@ version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||
dependencies = [
|
||||
"autocfg 1.3.0",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8324,7 +8189,7 @@ dependencies = [
|
||||
"hmac",
|
||||
"lioness",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"rand_distr",
|
||||
"sha2 0.10.8",
|
||||
"subtle 2.5.0",
|
||||
@@ -8868,7 +8733,7 @@ dependencies = [
|
||||
"getrandom",
|
||||
"peg",
|
||||
"pin-project",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"reqwest 0.11.27",
|
||||
"semver 1.0.23",
|
||||
"serde",
|
||||
@@ -8922,7 +8787,7 @@ dependencies = [
|
||||
"nym-pemstore",
|
||||
"nym-validator-client",
|
||||
"nym-vesting-contract-common",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
@@ -9322,7 +9187,7 @@ dependencies = [
|
||||
"indexmap 1.9.3",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@@ -9588,7 +9453,7 @@ dependencies = [
|
||||
"http 0.2.12",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"rustls 0.21.12",
|
||||
"sha1",
|
||||
"thiserror",
|
||||
@@ -9609,7 +9474,7 @@ dependencies = [
|
||||
"http 1.1.0",
|
||||
"httparse",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"rustls 0.22.4",
|
||||
"rustls-pki-types",
|
||||
"sha1",
|
||||
@@ -10029,7 +9894,7 @@ dependencies = [
|
||||
"nym-task",
|
||||
"nym-topology",
|
||||
"nym-validator-client",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde-wasm-bindgen 0.6.5",
|
||||
"thiserror",
|
||||
@@ -10664,7 +10529,7 @@ dependencies = [
|
||||
"nym-credentials",
|
||||
"nym-crypto",
|
||||
"nym-http-api-client",
|
||||
"rand 0.8.5",
|
||||
"rand",
|
||||
"reqwest 0.12.4",
|
||||
"serde",
|
||||
"thiserror",
|
||||
|
||||
+2
-1
@@ -204,7 +204,8 @@ ctr = "0.9.1"
|
||||
cupid = "0.6.1"
|
||||
curve25519-dalek = "4.1"
|
||||
dashmap = "5.5.3"
|
||||
defguard_wireguard_rs = "0.4.2"
|
||||
# We want https://github.com/DefGuard/wireguard-rs/pull/64 , but there's no crates.io release being pushed out anymore
|
||||
defguard_wireguard_rs = { git = "https://github.com/DefGuard/wireguard-rs.git", rev = "v0.4.7" }
|
||||
digest = "0.10.7"
|
||||
dirs = "4.0"
|
||||
doc-comment = "0.3"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-client"
|
||||
version = "1.1.39"
|
||||
version = "1.1.40"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
description = "Implementation of the Nym Client"
|
||||
edition = "2021"
|
||||
|
||||
@@ -422,7 +422,7 @@ impl Handler {
|
||||
) {
|
||||
// We don't want a crash in the connection handler to trigger a shutdown of the whole
|
||||
// process.
|
||||
task_client.disarm();
|
||||
task_client.mark_as_success();
|
||||
|
||||
let ws_stream = match accept_async(socket).await {
|
||||
Ok(ws_stream) => ws_stream,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.39"
|
||||
version = "1.1.40"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||
edition = "2021"
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::error::BandwidthControllerError;
|
||||
use crate::utils::{get_coin_index_signatures, get_expiration_date_signatures};
|
||||
use crate::utils::{
|
||||
get_aggregate_verification_key, get_coin_index_signatures, get_expiration_date_signatures,
|
||||
};
|
||||
use log::info;
|
||||
use nym_credential_storage::storage::Storage;
|
||||
use nym_credentials::ecash::bandwidth::IssuanceTicketBook;
|
||||
@@ -55,7 +57,7 @@ where
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn query_and_persist_required_global_signatures<S>(
|
||||
pub async fn query_and_persist_required_global_data<S>(
|
||||
storage: &S,
|
||||
epoch_id: EpochId,
|
||||
expiration_date: Date,
|
||||
@@ -65,6 +67,10 @@ where
|
||||
S: Storage,
|
||||
<S as Storage>::StorageError: Send + Sync + 'static,
|
||||
{
|
||||
log::info!("Getting master verification key");
|
||||
// this will also persist the key in the storage if was not there already
|
||||
get_aggregate_verification_key(storage, epoch_id, apis.clone()).await?;
|
||||
|
||||
log::info!("Getting expiration date signatures");
|
||||
// this will also persist the signatures in the storage if they were not there already
|
||||
get_expiration_date_signatures(storage, epoch_id, expiration_date, apis.clone()).await?;
|
||||
|
||||
@@ -16,7 +16,7 @@ use nym_credential_storage::models::RetrievedTicketbook;
|
||||
use nym_credential_storage::storage::Storage;
|
||||
use nym_credentials::ecash::bandwidth::CredentialSpendingData;
|
||||
use nym_credentials_interface::{
|
||||
AnnotatedCoinIndexSignature, AnnotatedExpirationDateSignature, NymPayInfo, VerificationKeyAuth,
|
||||
AnnotatedCoinIndexSignature, AnnotatedExpirationDateSignature, VerificationKeyAuth,
|
||||
};
|
||||
use nym_ecash_time::Date;
|
||||
use nym_validator_client::nym_api::EpochId;
|
||||
@@ -165,7 +165,9 @@ impl<C, St: Storage> BandwidthController<C, St> {
|
||||
.get_coin_index_signatures(epoch_id, &mut api_clients)
|
||||
.await?;
|
||||
|
||||
let pay_info = NymPayInfo::generate(provider_pk);
|
||||
let pay_info = retrieved_ticketbook
|
||||
.ticketbook
|
||||
.generate_pay_info(provider_pk);
|
||||
|
||||
let spend_request = retrieved_ticketbook.ticketbook.prepare_for_spending(
|
||||
&verification_key,
|
||||
|
||||
@@ -455,7 +455,7 @@ where
|
||||
Err(ClientCoreError::CustomGatewaySelectionExpected)
|
||||
} else {
|
||||
// and make sure to invalidate the task client so we wouldn't cause premature shutdown
|
||||
shutdown.disarm();
|
||||
shutdown.mark_as_success();
|
||||
custom_gateway_transceiver.set_packet_router(packet_router)?;
|
||||
Ok(custom_gateway_transceiver)
|
||||
};
|
||||
@@ -562,7 +562,7 @@ where
|
||||
if topology_config.disable_refreshing {
|
||||
// if we're not spawning the refresher, don't cause shutdown immediately
|
||||
info!("The topology refesher is not going to be started");
|
||||
shutdown.disarm();
|
||||
shutdown.mark_as_success();
|
||||
} else {
|
||||
// don't spawn the refresher if we don't want to be refreshing the topology.
|
||||
// only use the initial values obtained
|
||||
|
||||
@@ -474,6 +474,13 @@ where
|
||||
Poll::Ready(Some((real_messages, conn_id))) => {
|
||||
log::trace!("handling real_messages: size: {}", real_messages.len());
|
||||
|
||||
// This is the last step in the pipeline where we know the type of the message, so
|
||||
// lets count the number of retransmissions here.
|
||||
if conn_id == TransmissionLane::Retransmission {
|
||||
self.stats_tx
|
||||
.report(PacketStatisticsEvent::RetransmissionQueued);
|
||||
}
|
||||
|
||||
// First store what we got for the given connection id
|
||||
self.transmission_buffer.store(&conn_id, real_messages);
|
||||
let real_next = self.pop_next_message().expect("we just added one");
|
||||
|
||||
@@ -46,34 +46,13 @@ const MEASUREMENTS: usize = 3;
|
||||
const CONN_TIMEOUT: Duration = Duration::from_millis(1500);
|
||||
const PING_TIMEOUT: Duration = Duration::from_millis(1000);
|
||||
|
||||
// The abstraction that some of these helpers use
|
||||
pub trait ConnectableGateway {
|
||||
fn identity(&self) -> &identity::PublicKey;
|
||||
fn clients_address(&self) -> String;
|
||||
fn is_wss(&self) -> bool;
|
||||
}
|
||||
|
||||
impl ConnectableGateway for gateway::Node {
|
||||
fn identity(&self) -> &identity::PublicKey {
|
||||
self.identity()
|
||||
}
|
||||
|
||||
fn clients_address(&self) -> String {
|
||||
self.clients_address()
|
||||
}
|
||||
|
||||
fn is_wss(&self) -> bool {
|
||||
self.clients_wss_port.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
struct GatewayWithLatency<'a, G: ConnectableGateway> {
|
||||
gateway: &'a G,
|
||||
struct GatewayWithLatency<'a> {
|
||||
gateway: &'a gateway::Node,
|
||||
latency: Duration,
|
||||
}
|
||||
|
||||
impl<'a, G: ConnectableGateway> GatewayWithLatency<'a, G> {
|
||||
fn new(gateway: &'a G, latency: Duration) -> Self {
|
||||
impl<'a> GatewayWithLatency<'a> {
|
||||
fn new(gateway: &'a gateway::Node, latency: Duration) -> Self {
|
||||
GatewayWithLatency { gateway, latency }
|
||||
}
|
||||
}
|
||||
@@ -151,14 +130,11 @@ async fn connect(endpoint: &str) -> Result<WsConn, ClientCoreError> {
|
||||
JSWebsocket::new(endpoint).map_err(|_| ClientCoreError::GatewayJsConnectionFailure)
|
||||
}
|
||||
|
||||
async fn measure_latency<G>(gateway: &G) -> Result<GatewayWithLatency<G>, ClientCoreError>
|
||||
where
|
||||
G: ConnectableGateway,
|
||||
{
|
||||
async fn measure_latency(gateway: &gateway::Node) -> Result<GatewayWithLatency, ClientCoreError> {
|
||||
let addr = gateway.clients_address();
|
||||
trace!(
|
||||
"establishing connection to {} ({addr})...",
|
||||
gateway.identity(),
|
||||
gateway.identity_key,
|
||||
);
|
||||
let mut stream = connect(&addr).await?;
|
||||
|
||||
@@ -201,7 +177,7 @@ where
|
||||
let count = results.len() as u64;
|
||||
if count == 0 {
|
||||
return Err(ClientCoreError::NoGatewayMeasurements {
|
||||
identity: gateway.identity().to_base58_string(),
|
||||
identity: gateway.identity_key.to_base58_string(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -211,11 +187,11 @@ where
|
||||
Ok(GatewayWithLatency::new(gateway, avg))
|
||||
}
|
||||
|
||||
pub async fn choose_gateway_by_latency<'a, R: Rng, G: ConnectableGateway + Clone>(
|
||||
pub async fn choose_gateway_by_latency<R: Rng>(
|
||||
rng: &mut R,
|
||||
gateways: &[G],
|
||||
gateways: &[gateway::Node],
|
||||
must_use_tls: bool,
|
||||
) -> Result<G, ClientCoreError> {
|
||||
) -> Result<gateway::Node, ClientCoreError> {
|
||||
let gateways = filter_by_tls(gateways, must_use_tls)?;
|
||||
|
||||
info!(
|
||||
@@ -247,19 +223,21 @@ pub async fn choose_gateway_by_latency<'a, R: Rng, G: ConnectableGateway + Clone
|
||||
|
||||
info!(
|
||||
"chose gateway {} with average latency of {:?}",
|
||||
chosen.gateway.identity(),
|
||||
chosen.latency
|
||||
chosen.gateway.identity_key, chosen.latency
|
||||
);
|
||||
|
||||
Ok(chosen.gateway.clone())
|
||||
}
|
||||
|
||||
fn filter_by_tls<G: ConnectableGateway>(
|
||||
gateways: &[G],
|
||||
fn filter_by_tls(
|
||||
gateways: &[gateway::Node],
|
||||
must_use_tls: bool,
|
||||
) -> Result<Vec<&G>, ClientCoreError> {
|
||||
) -> Result<Vec<&gateway::Node>, ClientCoreError> {
|
||||
if must_use_tls {
|
||||
let filtered = gateways.iter().filter(|g| g.is_wss()).collect::<Vec<_>>();
|
||||
let filtered = gateways
|
||||
.iter()
|
||||
.filter(|g| g.clients_wss_port.is_some())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if filtered.is_empty() {
|
||||
return Err(ClientCoreError::NoWssGateways);
|
||||
|
||||
@@ -417,6 +417,8 @@ impl<C, St> GatewayClient<C, St> {
|
||||
self.local_identity.as_ref(),
|
||||
self.gateway_identity,
|
||||
self.cfg.bandwidth.require_tickets,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
self.task_client.clone(),
|
||||
)
|
||||
.await
|
||||
.map_err(GatewayClientError::RegistrationFailure),
|
||||
|
||||
@@ -70,8 +70,8 @@ impl PacketRouter {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn disarm(&mut self) {
|
||||
self.shutdown.disarm();
|
||||
pub fn mark_as_success(&mut self) {
|
||||
self.shutdown.mark_as_success();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,8 +113,8 @@ impl PartiallyDelegatedRouter {
|
||||
let return_res = match ret {
|
||||
Err(err) => self.stream_return.send(Err(err)),
|
||||
Ok(_) => {
|
||||
self.packet_router.disarm();
|
||||
task_client.disarm();
|
||||
self.packet_router.mark_as_success();
|
||||
task_client.mark_as_success();
|
||||
self.stream_return.send(Ok(split_stream))
|
||||
}
|
||||
};
|
||||
|
||||
@@ -42,6 +42,10 @@ pub trait MixnetQueryClient {
|
||||
|
||||
// state/sys-params-related
|
||||
|
||||
async fn admin(&self) -> Result<cw_controllers::AdminResponse, NyxdError> {
|
||||
self.query_mixnet_contract(MixnetQueryMsg::Admin {}).await
|
||||
}
|
||||
|
||||
async fn get_mixnet_contract_version(&self) -> Result<ContractBuildInformation, NyxdError> {
|
||||
self.query_mixnet_contract(MixnetQueryMsg::GetContractVersion {})
|
||||
.await
|
||||
@@ -580,6 +584,7 @@ mod tests {
|
||||
msg: MixnetQueryMsg,
|
||||
) -> u32 {
|
||||
match msg {
|
||||
MixnetQueryMsg::Admin {} => client.admin().ignore(),
|
||||
MixnetQueryMsg::GetAllFamiliesPaged { limit, start_after } => client
|
||||
.get_all_family_members_paged(start_after, limit)
|
||||
.ignore(),
|
||||
|
||||
@@ -31,6 +31,15 @@ pub trait MixnetSigningClient {
|
||||
|
||||
// state/sys-params-related
|
||||
|
||||
async fn update_admin(
|
||||
&self,
|
||||
admin: String,
|
||||
fee: Option<Fee>,
|
||||
) -> Result<ExecuteResult, NyxdError> {
|
||||
self.execute_mixnet_contract(fee, MixnetExecuteMsg::UpdateAdmin { admin }, vec![])
|
||||
.await
|
||||
}
|
||||
|
||||
async fn update_rewarding_validator_address(
|
||||
&self,
|
||||
address: AccountId,
|
||||
@@ -760,6 +769,7 @@ mod tests {
|
||||
msg: MixnetExecuteMsg,
|
||||
) {
|
||||
match msg {
|
||||
MixnetExecuteMsg::UpdateAdmin { admin } => client.update_admin(admin, None).ignore(),
|
||||
MixnetExecuteMsg::AssignNodeLayer { mix_id, layer } => {
|
||||
client.assign_node_layer(mix_id, layer, None).ignore()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::nyxd::cosmwasm_client::types::ExecuteResult;
|
||||
use crate::nyxd::error::NyxdError;
|
||||
use cosmrs::abci::TxMsgData;
|
||||
use cosmrs::cosmwasm::MsgExecuteContractResponse;
|
||||
@@ -9,7 +10,6 @@ use log::error;
|
||||
use prost::bytes::Bytes;
|
||||
use tendermint_rpc::endpoint::broadcast;
|
||||
|
||||
use crate::nyxd::cosmwasm_client::types::ExecuteResult;
|
||||
pub use cosmrs::abci::MsgResponse;
|
||||
|
||||
pub fn parse_msg_responses(data: Bytes) -> Vec<MsgResponse> {
|
||||
|
||||
@@ -21,7 +21,8 @@ pub struct Log {
|
||||
|
||||
/// Searches in logs for the first event of the given event type and in that event
|
||||
/// for the first attribute with the given attribute key.
|
||||
pub fn find_attribute<'a>(
|
||||
#[deprecated]
|
||||
pub fn find_attribute_in_logs<'a>(
|
||||
logs: &'a [Log],
|
||||
event_type: &str,
|
||||
attribute_key: &str,
|
||||
@@ -35,6 +36,7 @@ pub fn find_attribute<'a>(
|
||||
}
|
||||
|
||||
/// Search for the proposal id in the given log. It'll be in the LAST wasm event, with attribute key "proposal_id"
|
||||
#[deprecated]
|
||||
pub fn find_proposal_id(logs: &[Log]) -> Result<u64, NyxdError> {
|
||||
let maybe_attributes = logs
|
||||
.iter()
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::nyxd::cosmwasm_client::logs::Log;
|
||||
use crate::nyxd::TxResponse;
|
||||
use cosmrs::tendermint::abci;
|
||||
|
||||
pub use abci::Event;
|
||||
|
||||
// Searches in events for an event of the given event type which contains an
|
||||
// attribute for with the given key.
|
||||
pub fn find_tx_attribute(tx: &TxResponse, event_type: &str, attribute_key: &str) -> Option<String> {
|
||||
let event = tx.tx_result.events.iter().find(|e| e.kind == event_type)?;
|
||||
find_event_attribute(&tx.tx_result.events, event_type, attribute_key)
|
||||
}
|
||||
|
||||
pub fn find_event_attribute(
|
||||
events: &[Event],
|
||||
event_type: &str,
|
||||
attribute_key: &str,
|
||||
) -> Option<String> {
|
||||
let event = events.iter().find(|e| e.kind == event_type)?;
|
||||
let attribute = event.attributes.iter().find(|&attr| {
|
||||
if let Ok(key_str) = attr.key_str() {
|
||||
key_str == attribute_key
|
||||
@@ -16,3 +28,23 @@ pub fn find_tx_attribute(tx: &TxResponse, event_type: &str, attribute_key: &str)
|
||||
})?;
|
||||
Some(attribute.value_str().ok().map(|str| str.to_string())).flatten()
|
||||
}
|
||||
|
||||
pub fn find_attribute_value_in_logs_or_events(
|
||||
logs: &[Log],
|
||||
events: &[Event],
|
||||
event_type: &str,
|
||||
attribute_key: &str,
|
||||
) -> Option<String> {
|
||||
// if logs are empty, i.e. we're using post 0.50 code, parse the events instead
|
||||
if !logs.is_empty() {
|
||||
#[allow(deprecated)]
|
||||
return crate::nyxd::cosmwasm_client::logs::find_attribute_in_logs(
|
||||
logs,
|
||||
event_type,
|
||||
attribute_key,
|
||||
)
|
||||
.map(|attr| attr.value.clone());
|
||||
}
|
||||
|
||||
find_event_attribute(events, event_type, attribute_key)
|
||||
}
|
||||
|
||||
@@ -7,9 +7,10 @@ license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
base64 = "0.13.0"
|
||||
base64 = { workspace = true }
|
||||
bip39 = { workspace = true }
|
||||
bs58 = { workspace = true }
|
||||
colored = { workspace = true }
|
||||
comfy-table = { workspace = true }
|
||||
cfg-if = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive"] }
|
||||
@@ -21,13 +22,13 @@ humantime-serde = { workspace = true }
|
||||
inquire = { workspace = true }
|
||||
k256 = { workspace = true, features = ["ecdsa", "sha256"] }
|
||||
log = { workspace = true }
|
||||
rand = {version = "0.6", features = ["std"] }
|
||||
rand = { workspace = true, features = ["std"] }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
time = { workspace = true, features = ["parsing", "formatting"] }
|
||||
tokio = { workspace = true, features = ["sync"]}
|
||||
toml = "0.5.6"
|
||||
tokio = { workspace = true, features = ["sync"] }
|
||||
toml = { workspace = true }
|
||||
url = { workspace = true }
|
||||
tap = { workspace = true }
|
||||
zeroize = { workspace = true }
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::utils::CommonConfigsWrapper;
|
||||
use anyhow::{anyhow, bail};
|
||||
use clap::Parser;
|
||||
use colored::Colorize;
|
||||
use comfy_table::Table;
|
||||
use nym_credential_storage::initialise_persistent_storage;
|
||||
use nym_credential_storage::storage::Storage;
|
||||
use nym_credentials::ecash::bandwidth::serialiser::VersionedSerialise;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
/// Specify the index of the ticket to retrieve from the ticketbook.
|
||||
/// By default, the current unspent value is used.
|
||||
#[clap(long, group = "output")]
|
||||
pub(crate) ticket_index: Option<u64>,
|
||||
|
||||
/// Specify whether we should display payments for ALL available tickets
|
||||
#[clap(long, group = "output")]
|
||||
pub(crate) full: bool,
|
||||
|
||||
/// Base58-encoded identity of the provider (must be 32 bytes long)
|
||||
#[clap(long)]
|
||||
pub(crate) provider: String,
|
||||
|
||||
/// Config file of the client that is supposed to use the credential.
|
||||
#[clap(long, group = "source")]
|
||||
pub(crate) client_config: Option<PathBuf>,
|
||||
|
||||
/// Path to the dedicated credential storage database
|
||||
#[clap(long, group = "source")]
|
||||
pub(crate) credential_storage: Option<PathBuf>,
|
||||
}
|
||||
|
||||
pub async fn execute(args: Args) -> anyhow::Result<()> {
|
||||
let credentials_store = if let Some(explicit) = args.credential_storage {
|
||||
explicit
|
||||
} else {
|
||||
// SAFETY: at least one of them MUST HAVE been specified
|
||||
let cfg = args.client_config.unwrap();
|
||||
|
||||
let loaded = CommonConfigsWrapper::try_load(cfg)?;
|
||||
|
||||
if let Ok(id) = loaded.try_get_id() {
|
||||
println!("loaded config file for client '{id}'");
|
||||
}
|
||||
|
||||
let Ok(credentials_store) = loaded.try_get_credentials_store() else {
|
||||
bail!("the loaded config does not have a credentials store information")
|
||||
};
|
||||
credentials_store
|
||||
};
|
||||
|
||||
let decoded_provider = bs58::decode(&args.provider).into_vec()?;
|
||||
if decoded_provider.len() != 32 {
|
||||
bail!("the provided provider information is malformed")
|
||||
}
|
||||
let provider_arr: [u8; 32] = decoded_provider.try_into().unwrap();
|
||||
|
||||
let persistent_storage = initialise_persistent_storage(&credentials_store).await;
|
||||
let Some(mut next_ticketbook) = persistent_storage
|
||||
.get_next_unspent_usable_ticketbook(0)
|
||||
.await?
|
||||
else {
|
||||
bail!(
|
||||
"there are no valid ticketbooks in the storage at {}",
|
||||
credentials_store.display()
|
||||
)
|
||||
};
|
||||
|
||||
let epoch_id = next_ticketbook.ticketbook.epoch_id();
|
||||
let expiration_date = next_ticketbook.ticketbook.expiration_date();
|
||||
|
||||
let verification_key = persistent_storage
|
||||
.get_master_verification_key(epoch_id)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
anyhow!("ticketbook got incorrectly imported - the master verification key is missing")
|
||||
})?;
|
||||
let expiration_signatures = persistent_storage
|
||||
.get_expiration_date_signatures(expiration_date)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
anyhow!(
|
||||
"ticketbook got incorrectly imported - the expiration date signatures are missing"
|
||||
)
|
||||
})?;
|
||||
let coin_indices_signatures = persistent_storage
|
||||
.get_coin_index_signatures(epoch_id)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
anyhow!("ticketbook got incorrectly imported - the coin index signatures are missing")
|
||||
})?;
|
||||
|
||||
let ticketbook_data = next_ticketbook.ticketbook.pack();
|
||||
|
||||
let next_ticket = args
|
||||
.ticket_index
|
||||
.unwrap_or(next_ticketbook.ticketbook.spent_tickets());
|
||||
let pay_info = next_ticketbook.ticketbook.generate_pay_info(provider_arr);
|
||||
|
||||
println!("{}", "TICKETBOOK DATA:".bold());
|
||||
println!("{}", bs58::encode(&ticketbook_data.data).into_string());
|
||||
println!();
|
||||
|
||||
// display it only for a single ticket
|
||||
if !args.full {
|
||||
println!("attempting to generate payment for ticket {next_ticket}...");
|
||||
println!();
|
||||
next_ticketbook.ticketbook.update_spent_tickets(next_ticket);
|
||||
|
||||
let req = next_ticketbook.ticketbook.prepare_for_spending(
|
||||
&verification_key,
|
||||
pay_info.into(),
|
||||
&coin_indices_signatures,
|
||||
&expiration_signatures,
|
||||
1,
|
||||
)?;
|
||||
|
||||
let payment = req.payment;
|
||||
|
||||
println!("{}", format!("PAYMENT FOR TICKET {next_ticket}: ").bold());
|
||||
println!("{}", bs58::encode(&payment.to_bytes()).into_string());
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
println!(
|
||||
"generating payment information for {} tickets. this might take a while!...",
|
||||
next_ticketbook.ticketbook.params_total_tickets()
|
||||
);
|
||||
|
||||
// otherwise generate all the payments
|
||||
let last_spent = next_ticketbook.ticketbook.spent_tickets();
|
||||
|
||||
let mut table = Table::new();
|
||||
table.set_header(vec!["index", "binary data", "spend status"]);
|
||||
|
||||
for i in 0..next_ticketbook.ticketbook.params_total_tickets() {
|
||||
let status = if i < last_spent {
|
||||
"SPENT".red()
|
||||
} else {
|
||||
"NOT SPENT".green()
|
||||
};
|
||||
|
||||
next_ticketbook.ticketbook.update_spent_tickets(i);
|
||||
|
||||
let req = next_ticketbook.ticketbook.prepare_for_spending(
|
||||
&verification_key,
|
||||
pay_info.into(),
|
||||
&coin_indices_signatures,
|
||||
&expiration_signatures,
|
||||
1,
|
||||
)?;
|
||||
|
||||
let payment = req.payment;
|
||||
let payment_bytes = payment.to_bytes();
|
||||
let len = payment_bytes.len();
|
||||
let display_size = 100;
|
||||
let remaining = len - display_size;
|
||||
|
||||
table.add_row(vec![
|
||||
i.to_string(),
|
||||
format!(
|
||||
"{}…{remaining}bytes remaining",
|
||||
bs58::encode(&payment_bytes[..display_size]).into_string()
|
||||
),
|
||||
status.to_string(),
|
||||
]);
|
||||
}
|
||||
|
||||
println!("{}", "AVAILABLE TICKETS".bold());
|
||||
println!("{table}");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
+13
-5
@@ -9,9 +9,17 @@ use nym_credential_storage::initialise_persistent_storage;
|
||||
use nym_id::import_credential;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> {
|
||||
bs58::decode(raw).into_vec()
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct CredentialDataWrapper(Vec<u8>);
|
||||
|
||||
impl FromStr for CredentialDataWrapper {
|
||||
type Err = bs58::decode::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
bs58::decode(s).into_vec().map(CredentialDataWrapper)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
@@ -22,8 +30,8 @@ pub struct Args {
|
||||
pub(crate) client_config: PathBuf,
|
||||
|
||||
/// Explicitly provide the encoded credential data (as base58)
|
||||
#[clap(long, group = "cred_data", value_parser = parse_encoded_credential_data)]
|
||||
pub(crate) credential_data: Option<Vec<u8>>,
|
||||
#[clap(long, group = "cred_data")]
|
||||
pub(crate) credential_data: Option<CredentialDataWrapper>,
|
||||
|
||||
/// Specifies the path to file containing binary credential data
|
||||
#[clap(long, group = "cred_data")]
|
||||
@@ -52,7 +60,7 @@ pub async fn execute(args: Args) -> anyhow::Result<()> {
|
||||
let credentials_store = initialise_persistent_storage(credentials_store).await;
|
||||
|
||||
let raw_credential = match args.credential_data {
|
||||
Some(data) => data,
|
||||
Some(data) => data.0,
|
||||
None => {
|
||||
// SAFETY: one of those arguments must have been set
|
||||
fs::read(args.credential_path.unwrap())?
|
||||
+47
-5
@@ -9,6 +9,9 @@ use nym_credential_storage::initialise_persistent_storage;
|
||||
use nym_credential_utils::utils;
|
||||
use nym_credentials_interface::TicketType;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use rand::rngs::OsRng;
|
||||
use rand::RngCore;
|
||||
use std::fs::create_dir_all;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
@@ -18,12 +21,20 @@ pub struct Args {
|
||||
pub(crate) ticketbook_type: TicketType,
|
||||
|
||||
/// Config file of the client that is supposed to use the credential.
|
||||
#[clap(long)]
|
||||
pub(crate) client_config: PathBuf,
|
||||
#[clap(long, group = "output")]
|
||||
pub(crate) client_config: Option<PathBuf>,
|
||||
|
||||
/// Path to the dedicated credential storage database
|
||||
#[clap(long, group = "output")]
|
||||
pub(crate) credential_storage: Option<PathBuf>,
|
||||
}
|
||||
|
||||
pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> {
|
||||
let loaded = CommonConfigsWrapper::try_load(args.client_config)?;
|
||||
async fn issue_client_ticketbook(
|
||||
cfg: PathBuf,
|
||||
typ: TicketType,
|
||||
client: SigningClient,
|
||||
) -> anyhow::Result<()> {
|
||||
let loaded = CommonConfigsWrapper::try_load(cfg)?;
|
||||
|
||||
if let Ok(id) = loaded.try_get_id() {
|
||||
println!("loaded config file for client '{id}'");
|
||||
@@ -48,9 +59,40 @@ pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> {
|
||||
&client,
|
||||
&persistent_storage,
|
||||
&private_id_key.to_bytes(),
|
||||
args.ticketbook_type,
|
||||
typ,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn issue_standalone_ticketbook(
|
||||
credentials_store: PathBuf,
|
||||
typ: TicketType,
|
||||
client: SigningClient,
|
||||
) -> anyhow::Result<()> {
|
||||
println!("attempting to issue a standalone ticketbook");
|
||||
|
||||
let mut rng = OsRng;
|
||||
let mut random_seed = [0u8; 32];
|
||||
rng.fill_bytes(&mut random_seed);
|
||||
|
||||
if let Some(parent) = credentials_store.parent() {
|
||||
create_dir_all(parent)?;
|
||||
}
|
||||
|
||||
let persistent_storage = initialise_persistent_storage(credentials_store).await;
|
||||
utils::issue_credential(&client, &persistent_storage, &random_seed, typ).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> {
|
||||
match (args.client_config, args.credential_storage) {
|
||||
(Some(cfg), None) => issue_client_ticketbook(cfg, args.ticketbook_type, client).await,
|
||||
(None, Some(storage)) => {
|
||||
issue_standalone_ticketbook(storage, args.ticketbook_type, client).await
|
||||
}
|
||||
_ => unreachable!("clap should have made this branch impossible to reach!"),
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
use clap::{Args, Subcommand};
|
||||
|
||||
pub mod generate_ticket;
|
||||
pub mod import_ticket_book;
|
||||
pub mod issue_ticket_book;
|
||||
pub mod recover_ticket_book;
|
||||
@@ -19,4 +20,5 @@ pub enum EcashCommands {
|
||||
IssueTicketBook(issue_ticket_book::Args),
|
||||
RecoverTicketBook(recover_ticket_book::Args),
|
||||
ImportTicketBook(import_ticket_book::Args),
|
||||
GenerateTicket(generate_ticket::Args),
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub mod coconut;
|
||||
pub mod context;
|
||||
pub mod ecash;
|
||||
pub mod utils;
|
||||
pub mod validator;
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@ use crate::utils::{account_id_to_cw_addr, DataWrapper};
|
||||
use clap::Parser;
|
||||
use cosmwasm_std::Coin;
|
||||
use nym_bin_common::output_format::OutputFormat;
|
||||
use nym_mixnet_contract_common::construct_gateway_bonding_sign_payload;
|
||||
use nym_mixnet_contract_common::construct_legacy_gateway_bonding_sign_payload;
|
||||
use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
|
||||
use nym_validator_client::nyxd::contract_traits::MixnetQueryClient;
|
||||
|
||||
@@ -71,7 +71,7 @@ pub async fn create_payload(args: Args, client: SigningClient) {
|
||||
|
||||
let address = account_id_to_cw_addr(&client.address());
|
||||
|
||||
let payload = construct_gateway_bonding_sign_payload(nonce, address, coin, gateway);
|
||||
let payload = construct_legacy_gateway_bonding_sign_payload(nonce, address, coin, gateway);
|
||||
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
|
||||
println!("{}", args.output.format(&wrapper))
|
||||
}
|
||||
|
||||
@@ -10,7 +10,11 @@ pub struct Args {
|
||||
}
|
||||
|
||||
pub fn decode_mixnode_key(args: Args) {
|
||||
let b64_decoded = base64::decode(args.key).expect("failed to decode base64 string");
|
||||
use base64::{engine::general_purpose::STANDARD, Engine as _};
|
||||
|
||||
let b64_decoded = STANDARD
|
||||
.decode(args.key)
|
||||
.expect("failed to decode base64 string");
|
||||
let b58_encoded = bs58::encode(&b64_decoded).into_string();
|
||||
|
||||
println!("{b58_encoded}")
|
||||
|
||||
+4
-2
@@ -7,7 +7,9 @@ use clap::Parser;
|
||||
use cosmwasm_std::{Coin, Uint128};
|
||||
use nym_bin_common::output_format::OutputFormat;
|
||||
use nym_contracts_common::Percent;
|
||||
use nym_mixnet_contract_common::{construct_mixnode_bonding_sign_payload, MixNodeCostParams};
|
||||
use nym_mixnet_contract_common::{
|
||||
construct_legacy_mixnode_bonding_sign_payload, MixNodeCostParams,
|
||||
};
|
||||
use nym_network_defaults::{
|
||||
DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT,
|
||||
};
|
||||
@@ -98,7 +100,7 @@ pub async fn create_payload(args: Args, client: SigningClient) {
|
||||
let address = account_id_to_cw_addr(&client.address());
|
||||
|
||||
let payload =
|
||||
construct_mixnode_bonding_sign_payload(nonce, address, coin, mixnode, cost_params);
|
||||
construct_legacy_mixnode_bonding_sign_payload(nonce, address, coin, mixnode, cost_params);
|
||||
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
|
||||
println!("{}", args.output.format(&wrapper))
|
||||
}
|
||||
|
||||
+43
-6
@@ -6,14 +6,14 @@ use clap::Parser;
|
||||
use cosmwasm_std::Uint128;
|
||||
use log::info;
|
||||
use nym_mixnet_contract_common::{MixNodeCostParams, Percent};
|
||||
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
|
||||
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient};
|
||||
use nym_validator_client::nyxd::CosmWasmCoin;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Args {
|
||||
#[clap(
|
||||
long,
|
||||
help = "input your profit margin as follows; (so it would be 10, rather than 0.1)"
|
||||
help = "input your profit margin as follows; (so it would be 20, rather than 0.2)"
|
||||
)]
|
||||
pub profit_margin_percent: Option<u8>,
|
||||
|
||||
@@ -27,11 +27,48 @@ pub struct Args {
|
||||
pub async fn update_cost_params(args: Args, client: SigningClient) {
|
||||
let denom = client.current_chain_details().mix_denom.base.as_str();
|
||||
|
||||
fn convert_to_percent(value: u64) -> Percent {
|
||||
Percent::from_percentage_value(value).expect("Invalid value")
|
||||
}
|
||||
|
||||
let default_profit_margin: Percent = convert_to_percent(20);
|
||||
|
||||
let mixownership_response = match client.get_owned_mixnode(&client.address()).await {
|
||||
Ok(response) => response,
|
||||
Err(_) => {
|
||||
eprintln!("Failed to obtain owned mixnode");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mix_id = match mixownership_response.mixnode_details {
|
||||
Some(details) => details.bond_information.mix_id,
|
||||
None => {
|
||||
eprintln!("Failed to obtain mixnode details");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let rewarding_response = match client.get_mixnode_rewarding_details(mix_id).await {
|
||||
Ok(details) => details,
|
||||
Err(_) => {
|
||||
eprintln!("Failed to obtain rewarding details");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let profit_margin_percent = rewarding_response
|
||||
.rewarding_details
|
||||
.map(|rd| rd.cost_params.profit_margin_percent)
|
||||
.unwrap_or(default_profit_margin);
|
||||
|
||||
let profit_margin_value = args
|
||||
.profit_margin_percent
|
||||
.map(|pm| convert_to_percent(pm as u64))
|
||||
.unwrap_or(profit_margin_percent);
|
||||
|
||||
let cost_params = MixNodeCostParams {
|
||||
profit_margin_percent: Percent::from_percentage_value(
|
||||
args.profit_margin_percent.unwrap_or(10) as u64,
|
||||
)
|
||||
.unwrap(),
|
||||
profit_margin_percent: profit_margin_value,
|
||||
interval_operating_cost: CosmWasmCoin {
|
||||
denom: denom.into(),
|
||||
amount: Uint128::new(args.interval_operating_cost.unwrap_or(40_000_000)),
|
||||
|
||||
@@ -248,3 +248,31 @@ impl<T> ContractMessageContent<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<ContractMessageContent<T>> for LegacyContractMessageContent<T> {
|
||||
fn from(value: ContractMessageContent<T>) -> Self {
|
||||
LegacyContractMessageContent {
|
||||
sender: value.sender,
|
||||
proxy: None,
|
||||
funds: value.funds,
|
||||
data: value.data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct LegacyContractMessageContent<T> {
|
||||
pub sender: Addr,
|
||||
pub proxy: Option<Addr>,
|
||||
pub funds: Vec<Coin>,
|
||||
pub data: T,
|
||||
}
|
||||
|
||||
impl<T> SigningPurpose for LegacyContractMessageContent<T>
|
||||
where
|
||||
T: SigningPurpose,
|
||||
{
|
||||
fn message_type() -> MessageType {
|
||||
T::message_type()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ repository = { workspace = true }
|
||||
bs58 = "0.4.0"
|
||||
cosmwasm-std = { workspace = true }
|
||||
cosmwasm-schema = { workspace = true }
|
||||
cw-controllers = { workspace = true }
|
||||
cw2 = { workspace = true, optional = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_repr = { workspace = true }
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::{EpochEventId, EpochState, IdentityKey, MixId, OperatingCostRange, Pr
|
||||
use contracts_common::signing::verifier::ApiVerifierError;
|
||||
use contracts_common::Percent;
|
||||
use cosmwasm_std::{Addr, Coin, Decimal, Uint128};
|
||||
use cw_controllers::AdminError;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
@@ -12,6 +13,9 @@ pub enum MixnetContractError {
|
||||
#[error("could not perform contract migration: {comment}")]
|
||||
FailedMigration { comment: String },
|
||||
|
||||
#[error(transparent)]
|
||||
Admin(#[from] AdminError),
|
||||
|
||||
#[error("{source}")]
|
||||
StdErr {
|
||||
#[from]
|
||||
@@ -254,6 +258,9 @@ pub enum MixnetContractError {
|
||||
provided: Uint128,
|
||||
range: OperatingCostRange,
|
||||
},
|
||||
|
||||
#[error("this operation is temporarily disabled. please try again later")]
|
||||
TemporarilyDisabled,
|
||||
}
|
||||
|
||||
impl MixnetContractError {
|
||||
|
||||
@@ -110,6 +110,11 @@ impl InitialRewardingParams {
|
||||
|
||||
#[cw_serde]
|
||||
pub enum ExecuteMsg {
|
||||
/// Change the admin
|
||||
UpdateAdmin {
|
||||
admin: String,
|
||||
},
|
||||
|
||||
AssignNodeLayer {
|
||||
mix_id: MixId,
|
||||
layer: Layer,
|
||||
@@ -292,6 +297,7 @@ pub enum ExecuteMsg {
|
||||
impl ExecuteMsg {
|
||||
pub fn default_memo(&self) -> String {
|
||||
match self {
|
||||
ExecuteMsg::UpdateAdmin { admin } => format!("updating contract admin to {admin}"),
|
||||
ExecuteMsg::AssignNodeLayer { mix_id, layer } => {
|
||||
format!("assigning mix {mix_id} for layer {layer:?}")
|
||||
}
|
||||
@@ -408,6 +414,9 @@ impl ExecuteMsg {
|
||||
#[cw_serde]
|
||||
#[cfg_attr(feature = "schema", derive(QueryResponses))]
|
||||
pub enum QueryMsg {
|
||||
#[cfg_attr(feature = "schema", returns(cw_controllers::AdminResponse))]
|
||||
Admin {},
|
||||
|
||||
// families
|
||||
/// Gets the list of families registered in this contract.
|
||||
#[cfg_attr(feature = "schema", returns(PagedFamiliesResponse))]
|
||||
|
||||
@@ -4,13 +4,18 @@
|
||||
use crate::families::FamilyHead;
|
||||
use crate::{Gateway, IdentityKey, MixNode, MixNodeCostParams};
|
||||
use contracts_common::signing::{
|
||||
ContractMessageContent, MessageType, Nonce, SignableMessage, SigningPurpose,
|
||||
ContractMessageContent, LegacyContractMessageContent, MessageType, Nonce, SignableMessage,
|
||||
SigningPurpose,
|
||||
};
|
||||
use cosmwasm_std::{Addr, Coin};
|
||||
use serde::Serialize;
|
||||
|
||||
pub type SignableMixNodeBondingMsg = SignableMessage<ContractMessageContent<MixnodeBondingPayload>>;
|
||||
pub type SignableGatewayBondingMsg = SignableMessage<ContractMessageContent<GatewayBondingPayload>>;
|
||||
pub type SignableLegacyMixNodeBondingMsg =
|
||||
SignableMessage<LegacyContractMessageContent<MixnodeBondingPayload>>;
|
||||
pub type SignableLegacyGatewayBondingMsg =
|
||||
SignableMessage<LegacyContractMessageContent<GatewayBondingPayload>>;
|
||||
pub type SignableFamilyJoinPermitMsg = SignableMessage<FamilyJoinPermit>;
|
||||
|
||||
#[derive(Serialize)]
|
||||
@@ -47,6 +52,20 @@ pub fn construct_mixnode_bonding_sign_payload(
|
||||
SignableMessage::new(nonce, content)
|
||||
}
|
||||
|
||||
pub fn construct_legacy_mixnode_bonding_sign_payload(
|
||||
nonce: Nonce,
|
||||
sender: Addr,
|
||||
pledge: Coin,
|
||||
mix_node: MixNode,
|
||||
cost_params: MixNodeCostParams,
|
||||
) -> SignableLegacyMixNodeBondingMsg {
|
||||
let payload = MixnodeBondingPayload::new(mix_node, cost_params);
|
||||
let content: LegacyContractMessageContent<_> =
|
||||
ContractMessageContent::new(sender, vec![pledge], payload).into();
|
||||
|
||||
SignableMessage::new(nonce, content)
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct GatewayBondingPayload {
|
||||
gateway: Gateway,
|
||||
@@ -76,6 +95,19 @@ pub fn construct_gateway_bonding_sign_payload(
|
||||
SignableMessage::new(nonce, content)
|
||||
}
|
||||
|
||||
pub fn construct_legacy_gateway_bonding_sign_payload(
|
||||
nonce: Nonce,
|
||||
sender: Addr,
|
||||
pledge: Coin,
|
||||
gateway: Gateway,
|
||||
) -> SignableLegacyGatewayBondingMsg {
|
||||
let payload = GatewayBondingPayload::new(gateway);
|
||||
let content: LegacyContractMessageContent<_> =
|
||||
ContractMessageContent::new(sender, vec![pledge], payload).into();
|
||||
|
||||
SignableMessage::new(nonce, content)
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct FamilyJoinPermit {
|
||||
// the granter of this permit
|
||||
|
||||
@@ -187,7 +187,11 @@ impl Index<Layer> for LayerDistribution {
|
||||
#[cw_serde]
|
||||
pub struct ContractState {
|
||||
/// Address of the contract owner.
|
||||
pub owner: Addr,
|
||||
#[deprecated(
|
||||
note = "use explicit ADMIN instead. this field will be removed in future release"
|
||||
)]
|
||||
#[serde(default)]
|
||||
pub owner: Option<Addr>,
|
||||
|
||||
/// Address of "rewarding validator" (nym-api) that's allowed to send any rewarding-related transactions.
|
||||
pub rewarding_validator_address: Addr,
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
|
||||
use crate::errors::{Error, Result};
|
||||
use log::*;
|
||||
use nym_bandwidth_controller::acquire::{
|
||||
get_ticket_book, query_and_persist_required_global_signatures,
|
||||
};
|
||||
use nym_bandwidth_controller::acquire::{get_ticket_book, query_and_persist_required_global_data};
|
||||
use nym_client_core::config::disk_persistence::CommonClientPaths;
|
||||
use nym_config::DEFAULT_DATA_DIR;
|
||||
use nym_credential_storage::persistent_storage::PersistentStorage;
|
||||
@@ -45,14 +43,10 @@ where
|
||||
let apis = all_ecash_api_clients(client, epoch_id).await?;
|
||||
let ticketbook_expiration = ecash_default_expiration_date();
|
||||
|
||||
// make sure we have all required coin indices and expiration date signatures before attempting the deposit
|
||||
query_and_persist_required_global_signatures(
|
||||
storage,
|
||||
epoch_id,
|
||||
ticketbook_expiration,
|
||||
apis.clone(),
|
||||
)
|
||||
.await?;
|
||||
// make sure we have all required coin indices and expiration date signatures alongside the master verification key
|
||||
// before attempting the deposit
|
||||
query_and_persist_required_global_data(storage, epoch_id, ticketbook_expiration, apis.clone())
|
||||
.await?;
|
||||
|
||||
let issuance_data = nym_bandwidth_controller::acquire::make_deposit(
|
||||
client,
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::ecash::bandwidth::CredentialSpendingData;
|
||||
use crate::ecash::utils::ecash_today;
|
||||
use crate::error::Error;
|
||||
use nym_credentials_interface::{
|
||||
CoinIndexSignature, ExpirationDateSignature, PayInfo, SecretKeyUser, TicketType,
|
||||
CoinIndexSignature, ExpirationDateSignature, NymPayInfo, PayInfo, SecretKeyUser, TicketType,
|
||||
VerificationKeyAuth, Wallet, WalletSignatures,
|
||||
};
|
||||
use nym_ecash_time::EcashTime;
|
||||
@@ -114,6 +114,10 @@ impl IssuedTicketBook {
|
||||
&self.signatures_wallet
|
||||
}
|
||||
|
||||
pub fn generate_pay_info(&self, provider_pk: [u8; 32]) -> NymPayInfo {
|
||||
NymPayInfo::generate(provider_pk)
|
||||
}
|
||||
|
||||
pub fn prepare_for_spending<BI, BE>(
|
||||
&mut self,
|
||||
verification_key: &VerificationKeyAuth,
|
||||
|
||||
@@ -81,6 +81,15 @@ impl KeyPair {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PrivateKey> for KeyPair {
|
||||
fn from(private_key: PrivateKey) -> Self {
|
||||
KeyPair {
|
||||
public_key: (&private_key).into(),
|
||||
private_key,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PemStorableKeyPair for KeyPair {
|
||||
type PrivatePemKey = PrivateKey;
|
||||
type PublicPemKey = PublicKey;
|
||||
|
||||
@@ -91,6 +91,15 @@ impl KeyPair {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PrivateKey> for KeyPair {
|
||||
fn from(private_key: PrivateKey) -> Self {
|
||||
KeyPair {
|
||||
public_key: (&private_key).into(),
|
||||
private_key,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PemStorableKeyPair for KeyPair {
|
||||
type PrivatePemKey = PrivateKey;
|
||||
type PublicPemKey = PublicKey;
|
||||
|
||||
@@ -24,6 +24,7 @@ zeroize = { workspace = true }
|
||||
nym-crypto = { path = "../crypto" }
|
||||
nym-pemstore = { path = "../pemstore" }
|
||||
nym-sphinx = { path = "../nymsphinx" }
|
||||
nym-task = { path = "../task" }
|
||||
|
||||
nym-credentials = { path = "../credentials" }
|
||||
nym-credentials-interface = { path = "../credentials-interface" }
|
||||
|
||||
@@ -25,6 +25,7 @@ impl<'a> ClientHandshake<'a> {
|
||||
identity: &'a nym_crypto::asymmetric::identity::KeyPair,
|
||||
gateway_pubkey: identity::PublicKey,
|
||||
expects_credential_usage: bool,
|
||||
#[cfg(not(target_arch = "wasm32"))] shutdown: nym_task::TaskClient,
|
||||
) -> Self
|
||||
where
|
||||
S: Stream<Item = WsItem> + Sink<WsMessage> + Unpin + Send + 'a,
|
||||
@@ -35,6 +36,8 @@ impl<'a> ClientHandshake<'a> {
|
||||
identity,
|
||||
Some(gateway_pubkey),
|
||||
expects_credential_usage,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
shutdown,
|
||||
);
|
||||
|
||||
ClientHandshake {
|
||||
|
||||
@@ -25,6 +25,8 @@ pub enum HandshakeError {
|
||||
MalformedRequest,
|
||||
#[error("sent request was malformed")]
|
||||
HandshakeFailure,
|
||||
#[error("received shutdown")]
|
||||
ReceivedShutdown,
|
||||
|
||||
#[error("timed out waiting for a handshake message")]
|
||||
Timeout,
|
||||
|
||||
@@ -8,6 +8,7 @@ use futures::future::BoxFuture;
|
||||
use futures::task::{Context, Poll};
|
||||
use futures::{Future, Sink, Stream};
|
||||
use nym_crypto::asymmetric::encryption;
|
||||
use nym_task::TaskClient;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use std::pin::Pin;
|
||||
use tungstenite::Message as WsMessage;
|
||||
@@ -22,11 +23,12 @@ impl<'a> GatewayHandshake<'a> {
|
||||
ws_stream: &'a mut S,
|
||||
identity: &'a nym_crypto::asymmetric::identity::KeyPair,
|
||||
received_init_payload: Vec<u8>,
|
||||
shutdown: TaskClient,
|
||||
) -> Self
|
||||
where
|
||||
S: Stream<Item = WsItem> + Sink<WsMessage> + Unpin + Send + 'a,
|
||||
{
|
||||
let mut state = State::new(rng, ws_stream, identity, None, true);
|
||||
let mut state = State::new(rng, ws_stream, identity, None, true, shutdown);
|
||||
GatewayHandshake {
|
||||
handshake_future: Box::pin(async move {
|
||||
// If any step along the way failed (that are non-network related),
|
||||
|
||||
@@ -8,6 +8,8 @@ use self::gateway::GatewayHandshake;
|
||||
pub use self::shared_key::{SharedKeySize, SharedKeys};
|
||||
use futures::{Sink, Stream};
|
||||
use nym_crypto::asymmetric::identity;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use nym_task::TaskClient;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use tungstenite::{Error as WsError, Message as WsMessage};
|
||||
|
||||
@@ -31,6 +33,7 @@ pub async fn client_handshake<'a, S>(
|
||||
identity: &'a identity::KeyPair,
|
||||
gateway_pubkey: identity::PublicKey,
|
||||
expects_credential_usage: bool,
|
||||
#[cfg(not(target_arch = "wasm32"))] shutdown: TaskClient,
|
||||
) -> Result<SharedKeys, HandshakeError>
|
||||
where
|
||||
S: Stream<Item = WsItem> + Sink<WsMessage> + Unpin + Send + 'a,
|
||||
@@ -41,6 +44,8 @@ where
|
||||
identity,
|
||||
gateway_pubkey,
|
||||
expects_credential_usage,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
shutdown,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -51,11 +56,12 @@ pub async fn gateway_handshake<'a, S>(
|
||||
ws_stream: &'a mut S,
|
||||
identity: &'a identity::KeyPair,
|
||||
received_init_payload: Vec<u8>,
|
||||
shutdown: TaskClient,
|
||||
) -> Result<SharedKeys, HandshakeError>
|
||||
where
|
||||
S: Stream<Item = WsItem> + Sink<WsMessage> + Unpin + Send + 'a,
|
||||
{
|
||||
GatewayHandshake::new(rng, ws_stream, identity, received_init_payload).await
|
||||
GatewayHandshake::new(rng, ws_stream, identity, received_init_payload, shutdown).await
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -13,6 +13,8 @@ use nym_crypto::{
|
||||
symmetric::stream_cipher,
|
||||
};
|
||||
use nym_sphinx::params::{GatewayEncryptionAlgorithm, GatewaySharedKeyHkdfAlgorithm};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use nym_task::TaskClient;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use tracing::log::*;
|
||||
|
||||
@@ -48,6 +50,10 @@ pub(crate) struct State<'a, S> {
|
||||
// this field is really out of place here, however, we need to propagate this information somehow
|
||||
// in order to establish correct protocol for backwards compatibility reasons
|
||||
expects_credential_usage: bool,
|
||||
|
||||
// channel to receive shutdown signal
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
shutdown: TaskClient,
|
||||
}
|
||||
|
||||
impl<'a, S> State<'a, S> {
|
||||
@@ -57,6 +63,7 @@ impl<'a, S> State<'a, S> {
|
||||
identity: &'a identity::KeyPair,
|
||||
remote_pubkey: Option<identity::PublicKey>,
|
||||
expects_credential_usage: bool,
|
||||
#[cfg(not(target_arch = "wasm32"))] shutdown: TaskClient,
|
||||
) -> Self {
|
||||
let ephemeral_keypair = encryption::KeyPair::new(rng);
|
||||
State {
|
||||
@@ -66,6 +73,8 @@ impl<'a, S> State<'a, S> {
|
||||
remote_pubkey,
|
||||
derived_shared_keys: None,
|
||||
expects_credential_usage,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
shutdown,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,46 +208,76 @@ impl<'a, S> State<'a, S> {
|
||||
self.remote_pubkey = Some(remote_pubkey)
|
||||
}
|
||||
|
||||
fn on_wg_msg(msg: Option<WsItem>) -> Result<Option<Vec<u8>>, HandshakeError> {
|
||||
let Some(msg) = msg else {
|
||||
return Err(HandshakeError::ClosedStream);
|
||||
};
|
||||
|
||||
let Ok(msg) = msg else {
|
||||
return Err(HandshakeError::NetworkError);
|
||||
};
|
||||
match msg {
|
||||
WsMessage::Text(ref ws_msg) => {
|
||||
match types::RegistrationHandshake::from_str(ws_msg) {
|
||||
Ok(reg_handshake_msg) => {
|
||||
match reg_handshake_msg {
|
||||
// hehe, that's a bit disgusting that the type system requires we explicitly ignore the
|
||||
// protocol_version field that we actually never attach at this point
|
||||
// yet another reason for the overdue refactor
|
||||
types::RegistrationHandshake::HandshakePayload { data, .. } => {
|
||||
Ok(Some(data))
|
||||
}
|
||||
types::RegistrationHandshake::HandshakeError { message } => {
|
||||
Err(HandshakeError::RemoteError(message))
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => {
|
||||
error!("Received a non-handshake message during the registration handshake! It's getting dropped. The received content was: '{msg}'");
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
error!("Received non-text message during registration handshake");
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
async fn _receive_handshake_message(&mut self) -> Result<Vec<u8>, HandshakeError>
|
||||
where
|
||||
S: Stream<Item = WsItem> + Unpin,
|
||||
{
|
||||
loop {
|
||||
let Some(msg) = self.ws_stream.next().await else {
|
||||
return Err(HandshakeError::ClosedStream);
|
||||
};
|
||||
|
||||
let Ok(msg) = msg else {
|
||||
return Err(HandshakeError::NetworkError);
|
||||
};
|
||||
|
||||
match msg {
|
||||
WsMessage::Text(ref ws_msg) => {
|
||||
match types::RegistrationHandshake::from_str(ws_msg) {
|
||||
Ok(reg_handshake_msg) => {
|
||||
return match reg_handshake_msg {
|
||||
// hehe, that's a bit disgusting that the type system requires we explicitly ignore the
|
||||
// protocol_version field that we actually never attach at this point
|
||||
// yet another reason for the overdue refactor
|
||||
types::RegistrationHandshake::HandshakePayload { data, .. } => {
|
||||
Ok(data)
|
||||
}
|
||||
types::RegistrationHandshake::HandshakeError { message } => {
|
||||
Err(HandshakeError::RemoteError(message))
|
||||
}
|
||||
};
|
||||
}
|
||||
Err(_) => {
|
||||
error!("Received a non-handshake message during the registration handshake! It's getting dropped. The received content was: '{msg}'");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
tokio::select! {
|
||||
biased;
|
||||
_ = self.shutdown.recv() => return Err(HandshakeError::ReceivedShutdown),
|
||||
msg = self.ws_stream.next() => {
|
||||
let Some(ret) = Self::on_wg_msg(msg)? else {
|
||||
continue;
|
||||
};
|
||||
return Ok(ret);
|
||||
}
|
||||
_ => error!("Received non-text message during registration handshake"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
async fn _receive_handshake_message(&mut self) -> Result<Vec<u8>, HandshakeError>
|
||||
where
|
||||
S: Stream<Item = WsItem> + Unpin,
|
||||
{
|
||||
loop {
|
||||
let msg = self.ws_stream.next().await;
|
||||
let Some(ret) = Self::on_wg_msg(msg)? else {
|
||||
continue;
|
||||
};
|
||||
return Ok(ret);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn receive_handshake_message(&mut self) -> Result<Vec<u8>, HandshakeError>
|
||||
where
|
||||
S: Stream<Item = WsItem> + Unpin,
|
||||
|
||||
@@ -10,8 +10,8 @@ license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
async-trait = { workspace = true }
|
||||
bincode = { workspace = true, optional = true }
|
||||
defguard_wireguard_rs = { workspace = true, optional = true }
|
||||
bincode = { workspace = true }
|
||||
defguard_wireguard_rs = { workspace = true }
|
||||
log = { workspace = true }
|
||||
sqlx = { workspace = true, features = [
|
||||
"runtime-tokio-rustls",
|
||||
@@ -36,6 +36,3 @@ sqlx = { workspace = true, features = [
|
||||
"macros",
|
||||
"migrate",
|
||||
] }
|
||||
|
||||
[features]
|
||||
wireguard = ["defguard_wireguard_rs", "bincode"]
|
||||
|
||||
@@ -25,7 +25,6 @@ mod inboxes;
|
||||
pub(crate) mod models;
|
||||
mod shared_keys;
|
||||
mod tickets;
|
||||
#[cfg(feature = "wireguard")]
|
||||
mod wireguard_peers;
|
||||
|
||||
#[async_trait]
|
||||
@@ -217,7 +216,6 @@ pub trait Storage: Send + Sync {
|
||||
///
|
||||
/// * `peer`: wireguard peer data to be stored
|
||||
/// * `suspended`: if peer exists, but it's currently suspended
|
||||
#[cfg(feature = "wireguard")]
|
||||
async fn insert_wireguard_peer(
|
||||
&self,
|
||||
peer: &defguard_wireguard_rs::host::Peer,
|
||||
@@ -229,14 +227,12 @@ pub trait Storage: Send + Sync {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `peer_public_key`: wireguard public key of the peer to be retrieved.
|
||||
#[cfg(feature = "wireguard")]
|
||||
async fn get_wireguard_peer(
|
||||
&self,
|
||||
peer_public_key: &str,
|
||||
) -> Result<Option<WireguardPeer>, StorageError>;
|
||||
|
||||
/// Retrieves all wireguard peers.
|
||||
#[cfg(feature = "wireguard")]
|
||||
async fn get_all_wireguard_peers(&self) -> Result<Vec<WireguardPeer>, StorageError>;
|
||||
|
||||
/// Remove a wireguard peer from the storage.
|
||||
@@ -244,7 +240,6 @@ pub trait Storage: Send + Sync {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `peer_public_key`: wireguard public key of the peer to be removed.
|
||||
#[cfg(feature = "wireguard")]
|
||||
async fn remove_wireguard_peer(&self, peer_public_key: &str) -> Result<(), StorageError>;
|
||||
}
|
||||
|
||||
@@ -255,7 +250,6 @@ pub struct PersistentStorage {
|
||||
inbox_manager: InboxManager,
|
||||
bandwidth_manager: BandwidthManager,
|
||||
ticket_manager: TicketStorageManager,
|
||||
#[cfg(feature = "wireguard")]
|
||||
wireguard_peer_manager: wireguard_peers::WgPeerManager,
|
||||
}
|
||||
|
||||
@@ -300,7 +294,6 @@ impl PersistentStorage {
|
||||
|
||||
// the cloning here are cheap as connection pool is stored behind an Arc
|
||||
Ok(PersistentStorage {
|
||||
#[cfg(feature = "wireguard")]
|
||||
wireguard_peer_manager: wireguard_peers::WgPeerManager::new(connection_pool.clone()),
|
||||
shared_key_manager: SharedKeysManager::new(connection_pool.clone()),
|
||||
inbox_manager: InboxManager::new(connection_pool.clone(), message_retrieval_limit),
|
||||
@@ -620,7 +613,6 @@ impl Storage for PersistentStorage {
|
||||
Ok(self.ticket_manager.get_epoch_signers(epoch_id).await?)
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
async fn insert_wireguard_peer(
|
||||
&self,
|
||||
peer: &defguard_wireguard_rs::host::Peer,
|
||||
@@ -632,7 +624,6 @@ impl Storage for PersistentStorage {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
async fn get_wireguard_peer(
|
||||
&self,
|
||||
peer_public_key: &str,
|
||||
@@ -644,13 +635,11 @@ impl Storage for PersistentStorage {
|
||||
Ok(peer)
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
async fn get_all_wireguard_peers(&self) -> Result<Vec<WireguardPeer>, StorageError> {
|
||||
let ret = self.wireguard_peer_manager.retrieve_all_peers().await?;
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
async fn remove_wireguard_peer(&self, peer_public_key: &str) -> Result<(), StorageError> {
|
||||
self.wireguard_peer_manager
|
||||
.remove_peer(peer_public_key)
|
||||
|
||||
@@ -72,7 +72,6 @@ impl TryFrom<UnverifiedTicketData> for ClientTicket {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
#[derive(Debug, Clone, FromRow)]
|
||||
pub struct WireguardPeer {
|
||||
pub public_key: String,
|
||||
@@ -87,7 +86,6 @@ pub struct WireguardPeer {
|
||||
pub suspended: bool,
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
impl From<defguard_wireguard_rs::host::Peer> for WireguardPeer {
|
||||
fn from(value: defguard_wireguard_rs::host::Peer) -> Self {
|
||||
WireguardPeer {
|
||||
@@ -120,7 +118,6 @@ impl From<defguard_wireguard_rs::host::Peer> for WireguardPeer {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "wireguard")]
|
||||
impl TryFrom<WireguardPeer> for defguard_wireguard_rs::host::Peer {
|
||||
type Error = crate::error::StorageError;
|
||||
|
||||
|
||||
@@ -40,9 +40,17 @@ impl SharedKeysManager {
|
||||
client_address_bs58: String,
|
||||
derived_aes128_ctr_blake3_hmac_keys_bs58: String,
|
||||
) -> Result<i64, sqlx::Error> {
|
||||
sqlx::query!("INSERT OR REPLACE INTO shared_keys(client_address_bs58, derived_aes128_ctr_blake3_hmac_keys_bs58) VALUES (?, ?)",
|
||||
// https://stackoverflow.com/a/20310838
|
||||
// we don't want to be using `INSERT OR REPLACE INTO` due to the foreign key on `available_bandwidth` if the entry already exists
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT OR IGNORE INTO shared_keys(client_address_bs58, derived_aes128_ctr_blake3_hmac_keys_bs58) VALUES (?, ?);
|
||||
UPDATE shared_keys SET derived_aes128_ctr_blake3_hmac_keys_bs58 = ? WHERE client_address_bs58 = ?
|
||||
"#,
|
||||
client_address_bs58,
|
||||
derived_aes128_ctr_blake3_hmac_keys_bs58,
|
||||
derived_aes128_ctr_blake3_hmac_keys_bs58,
|
||||
client_address_bs58,
|
||||
).execute(&self.connection_pool).await?;
|
||||
|
||||
self.client_id(&client_address_bs58).await
|
||||
|
||||
@@ -26,8 +26,17 @@ impl WgPeerManager {
|
||||
/// * `peer`: peer information needed by wireguard interface.
|
||||
pub(crate) async fn insert_peer(&self, peer: &WireguardPeer) -> Result<(), sqlx::Error> {
|
||||
sqlx::query!(
|
||||
"INSERT OR REPLACE INTO wireguard_peer(public_key, preshared_key, protocol_version, endpoint, last_handshake, tx_bytes, rx_bytes, persistent_keepalive_interval, allowed_ips, suspended) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
peer.public_key, peer.preshared_key, peer.protocol_version, peer.endpoint, peer.last_handshake, peer.tx_bytes, peer.rx_bytes, peer.persistent_keepalive_interval, peer.allowed_ips, peer.suspended
|
||||
r#"
|
||||
INSERT OR IGNORE INTO wireguard_peer(public_key, preshared_key, protocol_version, endpoint, last_handshake, tx_bytes, rx_bytes, persistent_keepalive_interval, allowed_ips, suspended)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
|
||||
|
||||
UPDATE wireguard_peer
|
||||
SET preshared_key = ?, protocol_version = ?, endpoint = ?, last_handshake = ?, tx_bytes = ?, rx_bytes = ?, persistent_keepalive_interval = ?, allowed_ips = ?, suspended = ?
|
||||
WHERE public_key = ?
|
||||
"#,
|
||||
peer.public_key, peer.preshared_key, peer.protocol_version, peer.endpoint, peer.last_handshake, peer.tx_bytes, peer.rx_bytes, peer.persistent_keepalive_interval, peer.allowed_ips, peer.suspended,
|
||||
|
||||
peer.preshared_key, peer.protocol_version, peer.endpoint, peer.last_handshake, peer.tx_bytes, peer.rx_bytes, peer.persistent_keepalive_interval, peer.allowed_ips, peer.suspended,peer.public_key,
|
||||
)
|
||||
.execute(&self.connection_pool)
|
||||
.await?;
|
||||
|
||||
@@ -415,6 +415,8 @@ pub struct HealthRequest {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use time::macros::datetime;
|
||||
|
||||
use super::*;
|
||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||
use std::str::FromStr;
|
||||
@@ -432,7 +434,7 @@ mod tests {
|
||||
reply_to_hops: None,
|
||||
reply_to_avg_mix_delays: None,
|
||||
buffer_timeout: None,
|
||||
timestamp: OffsetDateTime::now_utc(),
|
||||
timestamp: datetime!(2024-01-01 12:59:59.5 UTC),
|
||||
},
|
||||
signature: None,
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ impl PacketListener {
|
||||
// cloning the arc as each accepted socket is handled in separate task
|
||||
let connection_handler = Arc::clone(&self.connection_handler);
|
||||
let mut handler_shutdown_listener = self.shutdown.clone();
|
||||
handler_shutdown_listener.disarm();
|
||||
handler_shutdown_listener.mark_as_success();
|
||||
|
||||
tokio::select! {
|
||||
socket = listener.accept() => {
|
||||
|
||||
@@ -245,7 +245,7 @@ impl VerlocMeasurer {
|
||||
}
|
||||
|
||||
let mut shutdown_listener = self.shutdown_listener.clone().named("VerlocMeasurement");
|
||||
shutdown_listener.disarm();
|
||||
shutdown_listener.mark_as_success();
|
||||
|
||||
for chunk in nodes_to_test.chunks(self.config.tested_nodes_batch_size) {
|
||||
let mut chunk_results = Vec::with_capacity(chunk.len());
|
||||
|
||||
@@ -84,7 +84,7 @@ impl PacketSender {
|
||||
tested_node: TestedNode,
|
||||
) -> Result<VerlocMeasurement, RttError> {
|
||||
let mut shutdown_listener = self.shutdown_listener.fork(tested_node.address.to_string());
|
||||
shutdown_listener.disarm();
|
||||
shutdown_listener.mark_as_success();
|
||||
|
||||
let mut conn = match tokio::time::timeout(
|
||||
self.connection_timeout,
|
||||
|
||||
@@ -17,8 +17,8 @@ pub const MIXNET_CONTRACT_ADDRESS: &str =
|
||||
"n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr";
|
||||
pub const VESTING_CONTRACT_ADDRESS: &str =
|
||||
"n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw";
|
||||
|
||||
pub const ECASH_CONTRACT_ADDRESS: &str = "";
|
||||
pub const ECASH_CONTRACT_ADDRESS: &str =
|
||||
"n1r7s6aksyc6pqardx88k3rkgfagwvj4z4zum9mmz2sfk3zm2mha0sd4dnun";
|
||||
pub const GROUP_CONTRACT_ADDRESS: &str =
|
||||
"n1e2zq4886zzewpvpucmlw8v9p7zv692f6yck4zjzxh699dkcmlrfqk2knsr";
|
||||
pub const MULTISIG_CONTRACT_ADDRESS: &str =
|
||||
|
||||
@@ -218,7 +218,7 @@ impl SocksClient {
|
||||
packet_type: Option<PacketType>,
|
||||
) -> Self {
|
||||
// If this task fails and exits, we don't want to send shutdown signal
|
||||
shutdown_listener.disarm();
|
||||
shutdown_listener.mark_as_success();
|
||||
|
||||
let connection_id = Self::generate_random();
|
||||
|
||||
@@ -294,7 +294,7 @@ impl SocksClient {
|
||||
.shutdown()
|
||||
.await
|
||||
.map_err(|source| SocksProxyError::SocketShutdownFailure { source })?;
|
||||
self.shutdown_listener.disarm();
|
||||
self.shutdown_listener.mark_as_success();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -172,6 +172,6 @@ where
|
||||
trace!("{} - inbound closed", connection_id);
|
||||
shutdown_notify.notify_one();
|
||||
|
||||
shutdown_listener.disarm();
|
||||
shutdown_listener.mark_as_success();
|
||||
reader
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ where
|
||||
}
|
||||
|
||||
pub fn into_inner(mut self) -> (TcpStream, ConnectionReceiver) {
|
||||
self.shutdown_listener.disarm();
|
||||
self.shutdown_listener.mark_as_success();
|
||||
(
|
||||
self.socket.take().unwrap(),
|
||||
self.mix_receiver.take().unwrap(),
|
||||
|
||||
@@ -90,6 +90,6 @@ pub(super) async fn run_outbound(
|
||||
trace!("{} - outbound closed", connection_id);
|
||||
shutdown_notify.notify_one();
|
||||
|
||||
shutdown_listener.disarm();
|
||||
shutdown_listener.mark_as_success();
|
||||
(writer, mix_receiver)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
use futures::{future::pending, FutureExt, SinkExt, StreamExt};
|
||||
use log::{log, Level};
|
||||
use std::future::Future;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::{error::Error, time::Duration};
|
||||
use tokio::sync::{
|
||||
@@ -368,17 +367,6 @@ impl TaskClient {
|
||||
self.named(name)
|
||||
}
|
||||
|
||||
pub async fn run_future<Fut, T>(&mut self, fut: Fut) -> Option<T>
|
||||
where
|
||||
Fut: Future<Output = T>,
|
||||
{
|
||||
tokio::select! {
|
||||
biased;
|
||||
_ = self.recv() => None,
|
||||
res = fut => Some(res)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a dummy that will never report that we should shutdown.
|
||||
pub fn dummy() -> TaskClient {
|
||||
let (_notify_tx, notify_rx) = watch::channel(());
|
||||
@@ -470,10 +458,14 @@ impl TaskClient {
|
||||
// This listener should to *not* notify the ShutdownNotifier to shutdown when dropped. For
|
||||
// example when we clone the listener for a task handling connections, we often want to drop
|
||||
// without signal failure.
|
||||
pub fn disarm(&mut self) {
|
||||
pub fn mark_as_success(&mut self) {
|
||||
self.mode.set_should_not_signal_on_drop();
|
||||
}
|
||||
|
||||
pub fn disarm(&mut self) {
|
||||
self.mark_as_success();
|
||||
}
|
||||
|
||||
pub fn send_we_stopped(&mut self, err: SentError) {
|
||||
if self.mode.is_dummy() {
|
||||
return;
|
||||
|
||||
@@ -12,6 +12,7 @@ license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
base64 = { workspace = true }
|
||||
dashmap = { workspace = true }
|
||||
log = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
thiserror = { workspace = true }
|
||||
@@ -34,7 +35,7 @@ x25519-dalek = { workspace = true, features = ["static_secrets"] }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = "0.8.5"
|
||||
nym-crypto = { path = "../crypto", features = ["rand"] }
|
||||
nym-crypto = { path = "../crypto", features = ["rand"]}
|
||||
|
||||
|
||||
[features]
|
||||
|
||||
@@ -6,17 +6,10 @@ pub mod error;
|
||||
pub mod public_key;
|
||||
pub mod registration;
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
pub use config::Config;
|
||||
pub use error::Error;
|
||||
pub use public_key::PeerPublicKey;
|
||||
pub use registration::{ClientMac, ClientMessage, GatewayClient, InitMessage, Nonce};
|
||||
|
||||
// To avoid any problems, keep this stale check time bigger (>2x) then the bandwidth cap
|
||||
// reset time (currently that one is 24h, at UTC midnight)
|
||||
pub const DEFAULT_PEER_TIMEOUT: Duration = Duration::from_secs(60 * 60 * 24 * 3); // 3 days
|
||||
pub const DEFAULT_PEER_TIMEOUT_CHECK: Duration = Duration::from_secs(5); // 5 seconds
|
||||
|
||||
#[cfg(feature = "verify")]
|
||||
pub use registration::HmacSha256;
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
use crate::error::Error;
|
||||
use crate::PeerPublicKey;
|
||||
use base64::{engine::general_purpose, Engine};
|
||||
use dashmap::DashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::net::IpAddr;
|
||||
use std::time::SystemTime;
|
||||
use std::{fmt, ops::Deref, str::FromStr};
|
||||
@@ -17,8 +17,8 @@ use nym_crypto::asymmetric::encryption::PrivateKey;
|
||||
#[cfg(feature = "verify")]
|
||||
use sha2::Sha256;
|
||||
|
||||
pub type PendingRegistrations = HashMap<PeerPublicKey, RegistrationData>;
|
||||
pub type PrivateIPs = HashMap<IpAddr, Taken>;
|
||||
pub type PendingRegistrations = DashMap<PeerPublicKey, RegistrationData>;
|
||||
pub type PrivateIPs = DashMap<IpAddr, Taken>;
|
||||
|
||||
#[cfg(feature = "verify")]
|
||||
pub type HmacSha256 = Hmac<Sha256>;
|
||||
|
||||
@@ -23,7 +23,7 @@ x25519-dalek = { workspace = true }
|
||||
ip_network = { workspace = true }
|
||||
log.workspace = true
|
||||
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
|
||||
nym-gateway-storage = { path = "../gateway-storage", features = ["wireguard"] }
|
||||
nym-gateway-storage = { path = "../gateway-storage" }
|
||||
nym-network-defaults = { path = "../network-defaults" }
|
||||
nym-task = { path = "../task" }
|
||||
nym-wireguard-types = { path = "../wireguard-types" }
|
||||
|
||||
@@ -114,6 +114,7 @@ pub async fn start_wireguard<St: nym_gateway_storage::Storage + 'static>(
|
||||
address: wireguard_data.inner.config().private_ip.to_string(),
|
||||
port: wireguard_data.inner.config().announced_port as u32,
|
||||
peers,
|
||||
mtu: None,
|
||||
};
|
||||
wg_api.configure_interface(&interface_config)?;
|
||||
|
||||
|
||||
@@ -5,15 +5,19 @@ use chrono::{Timelike, Utc};
|
||||
use defguard_wireguard_rs::{host::Peer, key::Key, WireguardInterfaceApi};
|
||||
use nym_gateway_storage::Storage;
|
||||
use nym_wireguard_types::registration::{RemainingBandwidthData, BANDWIDTH_CAP_PER_DAY};
|
||||
use nym_wireguard_types::{DEFAULT_PEER_TIMEOUT, DEFAULT_PEER_TIMEOUT_CHECK};
|
||||
use std::time::SystemTime;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use std::{collections::HashMap, sync::Arc, time::Duration};
|
||||
use tokio::sync::mpsc;
|
||||
use tokio_stream::{wrappers::IntervalStream, StreamExt};
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::WgApiWrapper;
|
||||
|
||||
// To avoid any problems, keep this stale check time bigger (>2x) then the bandwidth cap
|
||||
// reset time (currently that one is 24h, at UTC midnight)
|
||||
const DEFAULT_PEER_TIMEOUT: Duration = Duration::from_secs(60 * 60 * 24 * 3); // 3 days
|
||||
const DEFAULT_PEER_TIMEOUT_CHECK: Duration = Duration::from_secs(60); // 1 minute
|
||||
|
||||
pub enum PeerControlRequest {
|
||||
AddPeer(Peer),
|
||||
RemovePeer(Key),
|
||||
@@ -46,7 +50,6 @@ pub struct PeerController<St: Storage> {
|
||||
active_peers: HashMap<Key, Peer>,
|
||||
suspended_peers: HashMap<Key, Peer>,
|
||||
last_seen_bandwidth: HashMap<Key, u64>,
|
||||
timeout_count: u8,
|
||||
}
|
||||
|
||||
impl<St: Storage> PeerController<St> {
|
||||
@@ -61,14 +64,19 @@ impl<St: Storage> PeerController<St> {
|
||||
let timeout_check_interval = tokio_stream::wrappers::IntervalStream::new(
|
||||
tokio::time::interval(DEFAULT_PEER_TIMEOUT_CHECK),
|
||||
);
|
||||
let active_peers = peers
|
||||
let active_peers: HashMap<Key, Peer> = peers
|
||||
.into_iter()
|
||||
.map(|peer| (peer.public_key.clone(), peer))
|
||||
.collect();
|
||||
let suspended_peers = suspended_peers
|
||||
let suspended_peers: HashMap<Key, Peer> = suspended_peers
|
||||
.into_iter()
|
||||
.map(|peer| (peer.public_key.clone(), peer))
|
||||
.collect();
|
||||
let last_seen_bandwidth = active_peers
|
||||
.iter()
|
||||
.map(|(k, p)| (k.clone(), p.rx_bytes + p.tx_bytes))
|
||||
.chain(suspended_peers.keys().map(|k| (k.clone(), 0)))
|
||||
.collect();
|
||||
|
||||
PeerController {
|
||||
storage,
|
||||
@@ -78,8 +86,7 @@ impl<St: Storage> PeerController<St> {
|
||||
timeout_check_interval,
|
||||
active_peers,
|
||||
suspended_peers,
|
||||
last_seen_bandwidth: HashMap::new(),
|
||||
timeout_count: 0,
|
||||
last_seen_bandwidth,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,15 +149,6 @@ impl<St: Storage> PeerController<St> {
|
||||
.iter()
|
||||
.map(|(key, peer)| (key.clone(), peer.rx_bytes + peer.tx_bytes))
|
||||
.collect();
|
||||
|
||||
// Do in-memory updates of bandwidth every DEFAULT_PEER_TIMEOUT_CHECK
|
||||
// and storage updates every 5 * DEFAULT_PEER_TIMEOUT_CHECK, because in-memory
|
||||
// is more important for client query preciseness
|
||||
self.timeout_count = self.timeout_count % 5 + 1;
|
||||
if !reset && self.timeout_count < 5 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if reset {
|
||||
self.active_peers = host.peers;
|
||||
for peer in self.active_peers.values() {
|
||||
@@ -199,6 +197,7 @@ impl<St: Storage> PeerController<St> {
|
||||
log::error!("Could not configure peer: {:?}", e);
|
||||
false
|
||||
} else {
|
||||
self.last_seen_bandwidth.insert(peer.public_key.clone(), peer.rx_bytes + peer.tx_bytes);
|
||||
self.active_peers.insert(peer.public_key.clone(), peer);
|
||||
true
|
||||
};
|
||||
|
||||
Generated
+2
@@ -1276,6 +1276,7 @@ dependencies = [
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cosmwasm-storage",
|
||||
"cw-controllers",
|
||||
"cw-storage-plus",
|
||||
"cw2",
|
||||
"nym-contracts-common",
|
||||
@@ -1295,6 +1296,7 @@ dependencies = [
|
||||
"bs58 0.4.0",
|
||||
"cosmwasm-schema",
|
||||
"cosmwasm-std",
|
||||
"cw-controllers",
|
||||
"cw2",
|
||||
"humantime-serde",
|
||||
"log",
|
||||
|
||||
@@ -34,6 +34,7 @@ cosmwasm-schema = { workspace = true, optional = true }
|
||||
cosmwasm-std = { workspace = true }
|
||||
cosmwasm-storage = { workspace = true }
|
||||
cosmwasm-derive = { workspace = true }
|
||||
cw-controllers = { workspace = true }
|
||||
cw2 = { workspace = true }
|
||||
cw-storage-plus = { workspace = true }
|
||||
|
||||
|
||||
@@ -177,6 +177,28 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "ExecuteMsg",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Change the admin",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"update_admin"
|
||||
],
|
||||
"properties": {
|
||||
"update_admin": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"admin"
|
||||
],
|
||||
"properties": {
|
||||
"admin": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
@@ -1692,6 +1714,19 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "QueryMsg",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"admin"
|
||||
],
|
||||
"properties": {
|
||||
"admin": {
|
||||
"type": "object",
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"description": "Gets the list of families registered in this contract.",
|
||||
"type": "object",
|
||||
@@ -2937,6 +2972,21 @@
|
||||
},
|
||||
"sudo": null,
|
||||
"responses": {
|
||||
"admin": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "AdminResponse",
|
||||
"description": "Returned from Admin.query_admin()",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"admin": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"get_all_delegations": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "PagedAllDelegationsResponse",
|
||||
@@ -8140,7 +8190,6 @@
|
||||
"description": "The current state of the mixnet contract.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"owner",
|
||||
"params",
|
||||
"rewarding_denom",
|
||||
"rewarding_validator_address",
|
||||
@@ -8149,9 +8198,14 @@
|
||||
"properties": {
|
||||
"owner": {
|
||||
"description": "Address of the contract owner.",
|
||||
"allOf": [
|
||||
"default": null,
|
||||
"deprecated": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Addr"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -2,6 +2,28 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "ExecuteMsg",
|
||||
"oneOf": [
|
||||
{
|
||||
"description": "Change the admin",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"update_admin"
|
||||
],
|
||||
"properties": {
|
||||
"update_admin": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"admin"
|
||||
],
|
||||
"properties": {
|
||||
"admin": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
||||
@@ -2,6 +2,19 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "QueryMsg",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"admin"
|
||||
],
|
||||
"properties": {
|
||||
"admin": {
|
||||
"type": "object",
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"description": "Gets the list of families registered in this contract.",
|
||||
"type": "object",
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "AdminResponse",
|
||||
"description": "Returned from Admin.query_admin()",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"admin": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
"description": "The current state of the mixnet contract.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"owner",
|
||||
"params",
|
||||
"rewarding_denom",
|
||||
"rewarding_validator_address",
|
||||
@@ -13,9 +12,14 @@
|
||||
"properties": {
|
||||
"owner": {
|
||||
"description": "Address of the contract owner.",
|
||||
"allOf": [
|
||||
"default": null,
|
||||
"deprecated": true,
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Addr"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -57,6 +57,7 @@ pub const PENDING_INTERVAL_EVENTS_NAMESPACE: &str = "pie";
|
||||
pub const LAST_EPOCH_EVENT_ID_KEY: &str = "lee";
|
||||
pub const LAST_INTERVAL_EVENT_ID_KEY: &str = "lie";
|
||||
|
||||
pub const ADMIN_STORAGE_KEY: &str = "admin";
|
||||
pub const CONTRACT_STATE_KEY: &str = "state";
|
||||
|
||||
pub const LAYER_DISTRIBUTION_KEY: &str = "layers";
|
||||
|
||||
@@ -28,8 +28,10 @@ fn default_initial_state(
|
||||
profit_margin: ProfitMarginRange,
|
||||
interval_operating_cost: OperatingCostRange,
|
||||
) -> ContractState {
|
||||
// we have to temporarily preserve this functionalities until it can be removed
|
||||
#[allow(deprecated)]
|
||||
ContractState {
|
||||
owner,
|
||||
owner: Some(owner),
|
||||
rewarding_validator_address,
|
||||
vesting_contract_address,
|
||||
rewarding_denom: rewarding_denom.clone(),
|
||||
@@ -56,7 +58,7 @@ fn default_initial_state(
|
||||
/// `msg` is the contract initialization message, sort of like a constructor call.
|
||||
#[entry_point]
|
||||
pub fn instantiate(
|
||||
deps: DepsMut<'_>,
|
||||
mut deps: DepsMut<'_>,
|
||||
env: Env,
|
||||
info: MessageInfo,
|
||||
msg: InstantiateMsg,
|
||||
@@ -72,7 +74,7 @@ pub fn instantiate(
|
||||
let rewarding_validator_address = deps.api.addr_validate(&msg.rewarding_validator_address)?;
|
||||
let vesting_contract_address = deps.api.addr_validate(&msg.vesting_contract_address)?;
|
||||
let state = default_initial_state(
|
||||
info.sender,
|
||||
info.sender.clone(),
|
||||
rewarding_validator_address.clone(),
|
||||
msg.rewarding_denom,
|
||||
vesting_contract_address,
|
||||
@@ -90,7 +92,7 @@ pub fn instantiate(
|
||||
starting_interval,
|
||||
rewarding_validator_address,
|
||||
)?;
|
||||
mixnet_params_storage::initialise_storage(deps.storage, state)?;
|
||||
mixnet_params_storage::initialise_storage(deps.branch(), state, info.sender)?;
|
||||
mixnode_storage::initialise_storage(deps.storage)?;
|
||||
rewards_storage::initialise_storage(deps.storage, reward_params)?;
|
||||
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
|
||||
@@ -108,6 +110,11 @@ pub fn execute(
|
||||
msg: ExecuteMsg,
|
||||
) -> Result<Response, MixnetContractError> {
|
||||
match msg {
|
||||
ExecuteMsg::UpdateAdmin { admin } => {
|
||||
crate::mixnet_contract_settings::transactions::try_update_contract_admin(
|
||||
deps, info, admin,
|
||||
)
|
||||
}
|
||||
ExecuteMsg::AssignNodeLayer { mix_id, layer } => {
|
||||
crate::mixnodes::transactions::assign_mixnode_layer(deps, info, mix_id, layer)
|
||||
}
|
||||
@@ -335,6 +342,9 @@ pub fn query(
|
||||
QueryMsg::GetState {} => {
|
||||
to_binary(&crate::mixnet_contract_settings::queries::query_contract_state(deps)?)
|
||||
}
|
||||
QueryMsg::Admin {} => to_binary(&crate::mixnet_contract_settings::queries::query_admin(
|
||||
deps,
|
||||
)?),
|
||||
QueryMsg::GetRewardingParams {} => {
|
||||
to_binary(&crate::rewards::queries::query_rewarding_params(deps)?)
|
||||
}
|
||||
@@ -536,6 +546,7 @@ pub fn migrate(
|
||||
cw2::ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
|
||||
|
||||
crate::queued_migrations::vesting_purge(deps.branch())?;
|
||||
crate::queued_migrations::explicit_contract_admin(deps.branch())?;
|
||||
|
||||
// due to circular dependency on contract addresses (i.e. mixnet contract requiring vesting contract address
|
||||
// and vesting contract requiring the mixnet contract address), if we ever want to deploy any new fresh
|
||||
@@ -594,8 +605,9 @@ mod tests {
|
||||
let res = instantiate(deps.as_mut(), env, sender, init_msg);
|
||||
assert!(res.is_ok());
|
||||
|
||||
#[allow(deprecated)]
|
||||
let expected_state = ContractState {
|
||||
owner: Addr::unchecked("sender"),
|
||||
owner: Some(Addr::unchecked("sender")),
|
||||
rewarding_validator_address: Addr::unchecked("foomp123"),
|
||||
vesting_contract_address: Addr::unchecked("bar456"),
|
||||
rewarding_denom: "uatom".into(),
|
||||
|
||||
@@ -5,7 +5,9 @@ use crate::signing::storage as signing_storage;
|
||||
use crate::support::helpers::decode_ed25519_identity_key;
|
||||
use cosmwasm_std::{Addr, Coin, Deps};
|
||||
use mixnet_contract_common::error::MixnetContractError;
|
||||
use mixnet_contract_common::{construct_gateway_bonding_sign_payload, Gateway};
|
||||
use mixnet_contract_common::{
|
||||
construct_gateway_bonding_sign_payload, construct_legacy_gateway_bonding_sign_payload, Gateway,
|
||||
};
|
||||
use nym_contracts_common::signing::MessageSignature;
|
||||
use nym_contracts_common::signing::Verifier;
|
||||
|
||||
@@ -19,13 +21,31 @@ pub(crate) fn verify_gateway_bonding_signature(
|
||||
// recover the public key
|
||||
let public_key = decode_ed25519_identity_key(&gateway.identity_key)?;
|
||||
|
||||
// reconstruct the payload
|
||||
// reconstruct the payload, first try the current format, then attempt legacy
|
||||
let nonce = signing_storage::get_signing_nonce(deps.storage, sender.clone())?;
|
||||
let msg = construct_gateway_bonding_sign_payload(nonce, sender, pledge, gateway);
|
||||
let msg = construct_gateway_bonding_sign_payload(
|
||||
nonce,
|
||||
sender.clone(),
|
||||
pledge.clone(),
|
||||
gateway.clone(),
|
||||
);
|
||||
|
||||
if deps.api.verify_message(msg, signature, &public_key)? {
|
||||
if deps
|
||||
.api
|
||||
.verify_message(msg, signature.clone(), &public_key)?
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(MixnetContractError::InvalidEd25519Signature)
|
||||
// attempt to use legacy
|
||||
let msg_legacy =
|
||||
construct_legacy_gateway_bonding_sign_payload(nonce, sender, pledge, gateway);
|
||||
if deps
|
||||
.api
|
||||
.verify_message(msg_legacy, signature, &public_key)?
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(MixnetContractError::InvalidEd25519Signature)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,12 @@ use super::storage;
|
||||
use crate::interval::helpers::change_interval_config;
|
||||
use crate::interval::pending_events::ContractExecutableEvent;
|
||||
use crate::interval::storage::push_new_interval_event;
|
||||
use crate::mixnet_contract_settings::storage::ADMIN;
|
||||
use crate::mixnodes::transactions::update_mixnode_layer;
|
||||
use crate::rewards;
|
||||
use crate::rewards::storage as rewards_storage;
|
||||
use crate::support::helpers::{
|
||||
ensure_can_advance_epoch, ensure_epoch_in_progress_state, ensure_is_authorized, ensure_is_owner,
|
||||
ensure_can_advance_epoch, ensure_epoch_in_progress_state, ensure_is_authorized,
|
||||
};
|
||||
use cosmwasm_std::{DepsMut, Env, MessageInfo, Order, Response, Storage};
|
||||
use mixnet_contract_common::error::MixnetContractError;
|
||||
@@ -325,7 +326,7 @@ pub(crate) fn try_update_interval_config(
|
||||
epoch_duration_secs: u64,
|
||||
force_immediately: bool,
|
||||
) -> Result<Response, MixnetContractError> {
|
||||
ensure_is_owner(info.sender, deps.storage)?;
|
||||
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;
|
||||
|
||||
if epochs_in_interval == 0 {
|
||||
return Err(MixnetContractError::EpochsInIntervalZero);
|
||||
@@ -1766,6 +1767,7 @@ mod tests {
|
||||
use super::*;
|
||||
use cosmwasm_std::testing::mock_info;
|
||||
use cosmwasm_std::Decimal;
|
||||
use cw_controllers::AdminError::NotAdmin;
|
||||
use std::time::Duration;
|
||||
|
||||
#[test]
|
||||
@@ -1831,11 +1833,11 @@ mod tests {
|
||||
1000,
|
||||
false,
|
||||
);
|
||||
assert_eq!(res, Err(MixnetContractError::Unauthorized));
|
||||
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
|
||||
|
||||
let res =
|
||||
try_update_interval_config(test.deps_mut(), env.clone(), random, 100, 1000, false);
|
||||
assert_eq!(res, Err(MixnetContractError::Unauthorized));
|
||||
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
|
||||
|
||||
let res = try_update_interval_config(test.deps_mut(), env, owner, 100, 1000, false);
|
||||
assert!(res.is_ok())
|
||||
|
||||
@@ -2,10 +2,16 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::storage;
|
||||
use crate::mixnet_contract_settings::storage::ADMIN;
|
||||
use cosmwasm_std::{Deps, StdResult};
|
||||
use cw_controllers::AdminResponse;
|
||||
use mixnet_contract_common::{ContractBuildInformation, ContractState, ContractStateParams};
|
||||
use nym_contracts_common::get_build_information;
|
||||
|
||||
pub(crate) fn query_admin(deps: Deps<'_>) -> StdResult<AdminResponse> {
|
||||
ADMIN.query_admin(deps)
|
||||
}
|
||||
|
||||
pub(crate) fn query_contract_state(deps: Deps<'_>) -> StdResult<ContractState> {
|
||||
storage::CONTRACT_STATE.load(deps.storage)
|
||||
}
|
||||
@@ -36,8 +42,9 @@ pub(crate) mod tests {
|
||||
fn query_for_contract_settings_works() {
|
||||
let mut deps = test_helpers::init_contract();
|
||||
|
||||
#[allow(deprecated)]
|
||||
let dummy_state = ContractState {
|
||||
owner: Addr::unchecked("someowner"),
|
||||
owner: Some(Addr::unchecked("foomp")),
|
||||
rewarding_validator_address: Addr::unchecked("monitor"),
|
||||
vesting_contract_address: Addr::unchecked("foomp"),
|
||||
rewarding_denom: "unym".to_string(),
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::constants::CONTRACT_STATE_KEY;
|
||||
use cosmwasm_std::{Addr, Storage};
|
||||
use crate::constants::{ADMIN_STORAGE_KEY, CONTRACT_STATE_KEY};
|
||||
use cosmwasm_std::{Addr, DepsMut, Storage};
|
||||
use cosmwasm_std::{Coin, StdResult};
|
||||
use cw_controllers::Admin;
|
||||
use cw_storage_plus::Item;
|
||||
use mixnet_contract_common::error::MixnetContractError;
|
||||
use mixnet_contract_common::{ContractState, OperatingCostRange, ProfitMarginRange};
|
||||
|
||||
pub(crate) const CONTRACT_STATE: Item<'_, ContractState> = Item::new(CONTRACT_STATE_KEY);
|
||||
pub(crate) const ADMIN: Admin = Admin::new(ADMIN_STORAGE_KEY);
|
||||
|
||||
pub fn rewarding_validator_address(storage: &dyn Storage) -> Result<Addr, MixnetContractError> {
|
||||
Ok(CONTRACT_STATE
|
||||
@@ -66,8 +68,10 @@ pub(crate) fn vesting_contract_address(storage: &dyn Storage) -> Result<Addr, Mi
|
||||
}
|
||||
|
||||
pub(crate) fn initialise_storage(
|
||||
storage: &mut dyn Storage,
|
||||
deps: DepsMut<'_>,
|
||||
initial_state: ContractState,
|
||||
initial_admin: Addr,
|
||||
) -> StdResult<()> {
|
||||
CONTRACT_STATE.save(storage, &initial_state)
|
||||
CONTRACT_STATE.save(deps.storage, &initial_state)?;
|
||||
ADMIN.set(deps, Some(initial_admin))
|
||||
}
|
||||
|
||||
@@ -2,15 +2,36 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::storage;
|
||||
use cosmwasm_std::DepsMut;
|
||||
use crate::mixnet_contract_settings::storage::ADMIN;
|
||||
use cosmwasm_std::MessageInfo;
|
||||
use cosmwasm_std::Response;
|
||||
use cosmwasm_std::{DepsMut, StdResult};
|
||||
use mixnet_contract_common::error::MixnetContractError;
|
||||
use mixnet_contract_common::events::{
|
||||
new_rewarding_validator_address_update_event, new_settings_update_event,
|
||||
};
|
||||
use mixnet_contract_common::ContractStateParams;
|
||||
|
||||
pub fn try_update_contract_admin(
|
||||
mut deps: DepsMut<'_>,
|
||||
info: MessageInfo,
|
||||
new_admin: String,
|
||||
) -> Result<Response, MixnetContractError> {
|
||||
let new_admin = deps.api.addr_validate(&new_admin)?;
|
||||
|
||||
let res = ADMIN.execute_update_admin(deps.branch(), info, Some(new_admin.clone()))?;
|
||||
|
||||
// SAFETY: we don't need to perform any authentication checks on the sender as it was performed
|
||||
// during 'execute_update_admin' call
|
||||
#[allow(deprecated)]
|
||||
storage::CONTRACT_STATE.update(deps.storage, |mut state| -> StdResult<_> {
|
||||
state.owner = Some(new_admin);
|
||||
Ok(state)
|
||||
})?;
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn try_update_rewarding_validator_address(
|
||||
deps: DepsMut<'_>,
|
||||
info: MessageInfo,
|
||||
@@ -18,9 +39,7 @@ pub fn try_update_rewarding_validator_address(
|
||||
) -> Result<Response, MixnetContractError> {
|
||||
let mut state = storage::CONTRACT_STATE.load(deps.storage)?;
|
||||
|
||||
if info.sender != state.owner {
|
||||
return Err(MixnetContractError::Unauthorized);
|
||||
}
|
||||
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;
|
||||
|
||||
let new_address = deps.api.addr_validate(&address)?;
|
||||
let old_address = state.rewarding_validator_address;
|
||||
@@ -43,10 +62,7 @@ pub(crate) fn try_update_contract_settings(
|
||||
) -> Result<Response, MixnetContractError> {
|
||||
let mut state = storage::CONTRACT_STATE.load(deps.storage)?;
|
||||
|
||||
// check if this is executed by the owner, if not reject the transaction
|
||||
if info.sender != state.owner {
|
||||
return Err(MixnetContractError::Unauthorized);
|
||||
}
|
||||
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;
|
||||
|
||||
let response = Response::new().add_event(new_settings_update_event(&state.params, ¶ms));
|
||||
|
||||
@@ -65,6 +81,7 @@ pub mod tests {
|
||||
use crate::support::tests::test_helpers;
|
||||
use cosmwasm_std::testing::mock_info;
|
||||
use cosmwasm_std::{Addr, Coin, Uint128};
|
||||
use cw_controllers::AdminError::NotAdmin;
|
||||
|
||||
#[test]
|
||||
fn update_contract_rewarding_validtor_address() {
|
||||
@@ -76,7 +93,7 @@ pub mod tests {
|
||||
info,
|
||||
"not-the-creator".to_string(),
|
||||
);
|
||||
assert_eq!(res, Err(MixnetContractError::Unauthorized));
|
||||
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
|
||||
|
||||
let info = mock_info("creator", &[]);
|
||||
let res = try_update_rewarding_validator_address(
|
||||
@@ -136,7 +153,7 @@ pub mod tests {
|
||||
// cannot be updated from non-owner account
|
||||
let info = mock_info("not-the-creator", &[]);
|
||||
let res = try_update_contract_settings(deps.as_mut(), info, new_params.clone());
|
||||
assert_eq!(res, Err(MixnetContractError::Unauthorized));
|
||||
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
|
||||
|
||||
// but works fine from the creator account
|
||||
let info = mock_info("creator", &[]);
|
||||
|
||||
@@ -5,7 +5,10 @@ use crate::signing::storage as signing_storage;
|
||||
use crate::support::helpers::decode_ed25519_identity_key;
|
||||
use cosmwasm_std::{Addr, Coin, Deps};
|
||||
use mixnet_contract_common::error::MixnetContractError;
|
||||
use mixnet_contract_common::{construct_mixnode_bonding_sign_payload, MixNode, MixNodeCostParams};
|
||||
use mixnet_contract_common::{
|
||||
construct_legacy_mixnode_bonding_sign_payload, construct_mixnode_bonding_sign_payload, MixNode,
|
||||
MixNodeCostParams,
|
||||
};
|
||||
use nym_contracts_common::signing::MessageSignature;
|
||||
use nym_contracts_common::signing::Verifier;
|
||||
|
||||
@@ -20,13 +23,37 @@ pub(crate) fn verify_mixnode_bonding_signature(
|
||||
// recover the public key
|
||||
let public_key = decode_ed25519_identity_key(&mixnode.identity_key)?;
|
||||
|
||||
// reconstruct the payload
|
||||
// reconstruct the payload, first try the current format, then attempt legacy
|
||||
let nonce = signing_storage::get_signing_nonce(deps.storage, sender.clone())?;
|
||||
let msg = construct_mixnode_bonding_sign_payload(nonce, sender, pledge, mixnode, cost_params);
|
||||
let msg = construct_mixnode_bonding_sign_payload(
|
||||
nonce,
|
||||
sender.clone(),
|
||||
pledge.clone(),
|
||||
mixnode.clone(),
|
||||
cost_params.clone(),
|
||||
);
|
||||
|
||||
if deps.api.verify_message(msg, signature, &public_key)? {
|
||||
if deps
|
||||
.api
|
||||
.verify_message(msg, signature.clone(), &public_key)?
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(MixnetContractError::InvalidEd25519Signature)
|
||||
// attempt to use legacy
|
||||
let msg_legacy = construct_legacy_mixnode_bonding_sign_payload(
|
||||
nonce,
|
||||
sender,
|
||||
pledge,
|
||||
mixnode,
|
||||
cost_params,
|
||||
);
|
||||
if deps
|
||||
.api
|
||||
.verify_message(msg_legacy, signature, &public_key)?
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(MixnetContractError::InvalidEd25519Signature)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::interval::storage as interval_storage;
|
||||
use crate::mixnet_contract_settings::storage as mixnet_params_storage;
|
||||
use cosmwasm_std::{DepsMut, Order, Storage};
|
||||
use mixnet_contract_common::error::MixnetContractError;
|
||||
use mixnet_contract_common::PendingEpochEventKind;
|
||||
@@ -49,3 +50,17 @@ pub(crate) fn vesting_purge(deps: DepsMut) -> Result<(), MixnetContractError> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn explicit_contract_admin(deps: DepsMut) -> Result<(), MixnetContractError> {
|
||||
// we need to read the deprecated field to migrate it over
|
||||
#[allow(deprecated)]
|
||||
// SAFETY: this value should ALWAYS exist on the first execution of this migration;
|
||||
// as a matter of fact, it should ALWAYS continue existing until another migration
|
||||
#[allow(clippy::expect_used)]
|
||||
let existing_admin = mixnet_params_storage::CONTRACT_STATE
|
||||
.load(deps.storage)?
|
||||
.owner
|
||||
.expect("the contract state is corrupt - there's no admin set");
|
||||
mixnet_params_storage::ADMIN.set(deps, Some(existing_admin))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ use crate::delegations::storage as delegations_storage;
|
||||
use crate::interval::storage as interval_storage;
|
||||
use crate::interval::storage::{push_new_epoch_event, push_new_interval_event};
|
||||
use crate::mixnet_contract_settings::storage as mixnet_params_storage;
|
||||
use crate::mixnet_contract_settings::storage::ADMIN;
|
||||
use crate::mixnodes::helpers::get_mixnode_details_by_owner;
|
||||
use crate::mixnodes::storage as mixnodes_storage;
|
||||
use crate::rewards::helpers;
|
||||
use crate::rewards::helpers::update_and_save_last_rewarded;
|
||||
use crate::support::helpers::{
|
||||
ensure_bonded, ensure_can_advance_epoch, ensure_epoch_in_progress_state, ensure_is_owner,
|
||||
AttachSendTokens,
|
||||
ensure_bonded, ensure_can_advance_epoch, ensure_epoch_in_progress_state, AttachSendTokens,
|
||||
};
|
||||
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
|
||||
use mixnet_contract_common::error::MixnetContractError;
|
||||
@@ -227,7 +227,7 @@ pub(crate) fn try_update_active_set_size(
|
||||
active_set_size: u32,
|
||||
force_immediately: bool,
|
||||
) -> Result<Response, MixnetContractError> {
|
||||
ensure_is_owner(info.sender, deps.storage)?;
|
||||
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;
|
||||
|
||||
let mut rewarding_params = storage::REWARDING_PARAMS.load(deps.storage)?;
|
||||
if active_set_size == 0 {
|
||||
@@ -273,7 +273,7 @@ pub(crate) fn try_update_rewarding_params(
|
||||
updated_params: IntervalRewardingParamsUpdate,
|
||||
force_immediately: bool,
|
||||
) -> Result<Response, MixnetContractError> {
|
||||
ensure_is_owner(info.sender, deps.storage)?;
|
||||
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;
|
||||
|
||||
if !updated_params.contains_updates() {
|
||||
return Err(MixnetContractError::EmptyParamsChangeMsg);
|
||||
@@ -1796,6 +1796,7 @@ pub mod tests {
|
||||
|
||||
#[cfg(test)]
|
||||
mod updating_active_set {
|
||||
use cw_controllers::AdminError::NotAdmin;
|
||||
use mixnet_contract_common::EpochStatus;
|
||||
|
||||
use crate::support::tests::test_helpers::TestSetup;
|
||||
@@ -1858,10 +1859,10 @@ pub mod tests {
|
||||
42,
|
||||
false,
|
||||
);
|
||||
assert_eq!(res, Err(MixnetContractError::Unauthorized));
|
||||
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
|
||||
|
||||
let res = try_update_active_set_size(test.deps_mut(), env.clone(), random, 42, false);
|
||||
assert_eq!(res, Err(MixnetContractError::Unauthorized));
|
||||
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
|
||||
|
||||
let res = try_update_active_set_size(test.deps_mut(), env, owner, 42, false);
|
||||
assert!(res.is_ok())
|
||||
@@ -2002,6 +2003,7 @@ pub mod tests {
|
||||
#[cfg(test)]
|
||||
mod updating_rewarding_params {
|
||||
use cosmwasm_std::Decimal;
|
||||
use cw_controllers::AdminError::NotAdmin;
|
||||
|
||||
use mixnet_contract_common::EpochStatus;
|
||||
|
||||
@@ -2085,11 +2087,11 @@ pub mod tests {
|
||||
update,
|
||||
false,
|
||||
);
|
||||
assert_eq!(res, Err(MixnetContractError::Unauthorized));
|
||||
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
|
||||
|
||||
let res =
|
||||
try_update_rewarding_params(test.deps_mut(), env.clone(), random, update, false);
|
||||
assert_eq!(res, Err(MixnetContractError::Unauthorized));
|
||||
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
|
||||
|
||||
let res = try_update_rewarding_params(test.deps_mut(), env, owner, update, false);
|
||||
assert!(res.is_ok())
|
||||
|
||||
@@ -194,20 +194,6 @@ pub(crate) fn ensure_can_advance_epoch(
|
||||
Ok(epoch_status)
|
||||
}
|
||||
|
||||
pub(crate) fn ensure_is_owner(
|
||||
sender: Addr,
|
||||
storage: &dyn Storage,
|
||||
) -> Result<(), MixnetContractError> {
|
||||
if sender
|
||||
!= crate::mixnet_contract_settings::storage::CONTRACT_STATE
|
||||
.load(storage)?
|
||||
.owner
|
||||
{
|
||||
return Err(MixnetContractError::Unauthorized);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn ensure_bonded(bond: &MixNodeBond) -> Result<(), MixnetContractError> {
|
||||
if bond.is_unbonding {
|
||||
return Err(MixnetContractError::MixnodeIsUnbonding {
|
||||
|
||||
@@ -105,10 +105,11 @@ pub mod test_helpers {
|
||||
let deps = init_contract();
|
||||
let rewarding_validator_address =
|
||||
rewarding_validator_address(deps.as_ref().storage).unwrap();
|
||||
let owner = mixnet_params_storage::CONTRACT_STATE
|
||||
.load(deps.as_ref().storage)
|
||||
let owner = mixnet_params_storage::ADMIN
|
||||
.query_admin(deps.as_ref())
|
||||
.unwrap()
|
||||
.owner;
|
||||
.admin
|
||||
.unwrap();
|
||||
|
||||
TestSetup {
|
||||
deps,
|
||||
|
||||
@@ -69,27 +69,33 @@ pub(crate) fn try_migrate_vested_delegation(
|
||||
|
||||
let storage_key =
|
||||
Delegation::generate_storage_key(mix_id, &info.sender, Some(&vesting_contract));
|
||||
let Some(mut delegation) =
|
||||
let Some(delegation) =
|
||||
delegations_storage::delegations().may_load(deps.storage, storage_key.clone())?
|
||||
else {
|
||||
return Err(MixnetContractError::NotAVestingDelegation);
|
||||
};
|
||||
|
||||
// sanity check that's meant to blow up the contract
|
||||
assert_eq!(delegation.proxy, Some(vesting_contract.clone()));
|
||||
let _ = delegation;
|
||||
|
||||
// update the delegation and save it under the correct storage key
|
||||
delegation.proxy = None;
|
||||
let updated_storage_key = Delegation::generate_storage_key(mix_id, &info.sender, None);
|
||||
delegations_storage::delegations().remove(deps.storage, storage_key)?;
|
||||
delegations_storage::delegations().save(deps.storage, updated_storage_key, &delegation)?;
|
||||
Err(MixnetContractError::TemporarilyDisabled)
|
||||
|
||||
Ok(Response::new().add_message(wasm_execute(
|
||||
vesting_contract,
|
||||
&VestingExecuteMsg::TrackMigratedDelegation {
|
||||
owner: info.sender.into_string(),
|
||||
mix_id,
|
||||
},
|
||||
vec![],
|
||||
)?))
|
||||
//
|
||||
//
|
||||
// // sanity check that's meant to blow up the contract
|
||||
// assert_eq!(delegation.proxy, Some(vesting_contract.clone()));
|
||||
//
|
||||
// // update the delegation and save it under the correct storage key
|
||||
// delegation.proxy = None;
|
||||
// let updated_storage_key = Delegation::generate_storage_key(mix_id, &info.sender, None);
|
||||
// delegations_storage::delegations().remove(deps.storage, storage_key)?;
|
||||
// delegations_storage::delegations().save(deps.storage, updated_storage_key, &delegation)?;
|
||||
//
|
||||
// Ok(Response::new().add_message(wasm_execute(
|
||||
// vesting_contract,
|
||||
// &VestingExecuteMsg::TrackMigratedDelegation {
|
||||
// owner: info.sender.into_string(),
|
||||
// mix_id,
|
||||
// },
|
||||
// vec![],
|
||||
// )?))
|
||||
}
|
||||
|
||||
@@ -108,11 +108,3 @@ copy-js = true # include Javascript code for search
|
||||
|
||||
[output.linkcheck]
|
||||
warning-policy = "warn"
|
||||
|
||||
[output.html.redirect]
|
||||
"/faq/general-faq.html" = "https://nymtech.net/developers/faq/integrations-faq.html"
|
||||
"/tutorials/simple-service-provider/user-client.html" = "https://nymtech.net/developers/examples/custom-services.html"
|
||||
"/quickstart/socks-proxy.html" = "https://nymtech.net/developers/clients/socks5/setup.html"
|
||||
"/tutorials/matrix.html" = "https://nymtech.net/developers/archive/nym-connect.html#matrix-element-via-nymconnect"
|
||||
"/tutorials/monero.html" = "https://nymtech.net/developers/archive/nym-connect.html#monero-wallet-via-nymconnect"
|
||||
"/tutorials/telegram.html" = "https://nymtech.net/developers/archive/nym-connect.html#telegram-via-nymconnect"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
- [Introduction](introduction.md)
|
||||
- [Clients Overview - Start Here!](clients-overview.md)
|
||||
|
||||
# SDKs
|
||||
# SDKs
|
||||
- [Rust SDK](sdk/rust/rust.md)
|
||||
- [Message Types](sdk/rust/message-types.md)
|
||||
- [Message Helpers](sdk/rust/message-helpers.md)
|
||||
@@ -30,7 +30,7 @@
|
||||
- [Using Your Client](clients/websocket/usage.md)
|
||||
- [Examples](clients/websocket/examples.md)
|
||||
- [Socks5 Client](clients/socks5-client.md)
|
||||
- [Setup & Run](clients/socks5/setup.md)
|
||||
- [Setup & Run](clients/socks5/setup.md)
|
||||
- [Using Your Client](clients/socks5/usage.md)
|
||||
- [Webassembly Client](clients/webassembly-client.md)
|
||||
|
||||
@@ -54,13 +54,8 @@
|
||||
# User Manuals
|
||||
- [NymVPN alpha](nymvpn/intro.md)
|
||||
- [CLI](nymvpn/cli.md)
|
||||
---
|
||||
|
||||
# Archive
|
||||
- [NymConnect Setup](archive/nym-connect.md)
|
||||
|
||||
---
|
||||
|
||||
# Misc.
|
||||
- [Code of Conduct](coc.md)
|
||||
- [Licensing](licensing.md)
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
# Archive page: NymConnect Setup
|
||||
|
||||
```admonish warning
|
||||
Since the beginning of 2024 NymConnect is no longer maintained. Nym is developing a new client called [NymVPN](https://nymvpn.com), an application routing all users traffic thorugh the mixnet.
|
||||
If users want to route their traffic through socks5 we advice to use maintained [Nym Socks5 Client](../clients/socks5/setup.md).
|
||||
```
|
||||
|
||||
In case you want to run deprecated NymConnect, follow these steps:
|
||||
|
||||
1. Navigate to our [Github repository](https://github.com/nymtech/nym/releases?q=nym-connect&expanded=true) and download NymConnect binary
|
||||
2. On Linux and Mac, make executable by opening terminal in the same directory and run:
|
||||
|
||||
```sh
|
||||
chmod +x ./nym-connect_<VERSION>.AppImage
|
||||
```
|
||||
|
||||
1. Start the application
|
||||
2. Click on `Connect` button to initialise the connection with the Mixnet
|
||||
3. Anytime you'll need to setup Host and Port in your applications, click on `IP` and `Port` to copy the values to clipboard
|
||||
4. In case you have problems such as `Gateway Issues`, try to reconnect or restart the application
|
||||
|
||||
## Connect Privacy Enhanced Applications (PEApps)
|
||||
|
||||
Here are some examples of applications which will work behind Socks5 proxy (`nym-socks5-client` or deprecated NymConnect), to enhance users privacy.
|
||||
|
||||
### Electrum Bitcoin wallet via NymConnect
|
||||
|
||||
To download Electrum visit the [official webpage](https://electrum.org/#download). To connect to the Mixnet follow these steps:
|
||||
|
||||
1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md))
|
||||
2. Start your Electrum Bitcoin wallet
|
||||
3. Go to: *Tools* -> *Network* -> *Proxy*
|
||||
4. Set *Use proxy* to ✅, choose `SOCKS5` from the drop-down and add (copy-paste) the values from your NymConnect application
|
||||
5. Now your Electrum Bitcoin wallet runs through the Mixnet and it will be connected only if your NymConnect or `nym-socks5-client` are connected.
|
||||
|
||||

|
||||
|
||||
### Monero wallet via NymConnect
|
||||
|
||||
To download Monero wallet visit [getmonero.org](https://www.getmonero.org/downloads/). To connect to the Mixnet follow these steps:
|
||||
|
||||
1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md))
|
||||
2. Start your Monero wallet
|
||||
3. Go to: *Settings* -> *Interface* -> *Socks5 proxy* -> Add values: IP address `127.0.0.1`, Port `1080` (the values copied from NymConnect)
|
||||
5. Now your Monero wallet runs through the Mixnet and it will be connected only if your NymConnect or `nym-socks5-client` are connected.
|
||||
|
||||

|
||||
|
||||
### Matrix (Element) via NymConnect
|
||||
|
||||
To download Element (chat client for Matrix) visit [element.io](https://element.io/download). To connect to the Mixnet follow these steps:
|
||||
|
||||
1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md))
|
||||
2. Start `element-desktop` with `--proxy-server` argument:
|
||||
|
||||
**Linux**
|
||||
|
||||
```sh
|
||||
element-desktop --proxy-server=socks5://127.0.0.1:1080
|
||||
```
|
||||
|
||||
**Mac**
|
||||
|
||||
```sh
|
||||
open -a Element --args --proxy-server=socks5://127.0.0.1:1080
|
||||
```
|
||||
|
||||
To make the start of Element over NymConnect simplier, you can add this command to your key-binding shortcuts in your system settings.
|
||||
|
||||
### Telegram via NymConnect
|
||||
|
||||
1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md))
|
||||
2. Start your Telegram chat application
|
||||
3. Open the Telegram proxy settings.
|
||||
- Linux: *Settings* -> *Advanced* -> *Connection type* -> *Use custom proxy*
|
||||
- MacOS: *Settings* -> *Advanced* -> *Data & Storage* -> *Connection Type* -> *Use custom Proxy*
|
||||
- Windows: *Settings* -> *Data and Storage* -> *Use proxy*
|
||||
4. Add a proxy with the *Add proxy button*.
|
||||
5. Select *SOCKS5* and make sure the port details are the same as those generated by NymConnect. Alternatively, follow this link: [https://t.me/socks?server=127.0.0.1&port=1080](https://t.me/socks?server=127.0.0.1&port=1080)
|
||||
6. *Save the proxy settings* in Telegram.
|
||||
7. Telegram is now running through the Nym Mixnet and is privacy-enhanced! This allows you to connect from regions which blocked Telegram.
|
||||
8. Note if you remain idle on Telegram for a while you might lose connectivity and your messages might not get through via SOCKS5 proxy. If that happens reconnect your NymConnect and reset the proxy again.
|
||||
|
||||
|
||||
Follow this [video](https://youtu.be/quj8H2qeOwY?t=97) to see the steps on Telegram setup.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user