Compare commits

..

8 Commits

Author SHA1 Message Date
Mark Sinclair 62b16cee0e Improve error handling and cleaning for invalid versions in bonding settings 2024-08-12 16:37:49 +01:00
Jon Häggblad 3f6de8b10c Remove duplicate stat count for retransmissions (#4756) 2024-08-09 14:55:14 +02:00
import this 1e01a8e633 [DOCs/operators]: Release detailed changelog for v2024.9 topdeck (#4757)
* add changelog for new release

* add more URLs redirection for socks5 specific apps

* update exit policy page

* finish changelog - ready for review

* add tooling

* clarify tornul note comment
2024-08-07 13:20:17 +00:00
import this aaf3dca5b9 [DOCs]: Catching more broken URLs (#4755)
* urls edit

* finish PR - ready to merge
2024-08-06 18:49:46 +00:00
Bogdan-Ștefan Neacşu f939cae3d9 Update peer refresh value (#4754)
* Use a more proper timeout value

* Move const to wireguard types
2024-08-06 18:14:29 +02:00
import this 1db61f800c docs/hotfix (#4752) 2024-08-06 14:49:09 +00:00
import this 5096c1e60e [DOCs]: Create NymConnect archive page (#4750) 2024-08-06 13:22:30 +00:00
import this 7e36595d8f [DOCs/bugfix]: Fix broken URLs (#4745)
* create archive nym connect page & add redirections

* add info to socks5 page

* fix dev-portal links

* finish URL edits and redirection
2024-08-06 12:37:37 +00:00
144 changed files with 1108 additions and 1487 deletions
@@ -62,6 +62,10 @@ 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:
@@ -87,7 +91,7 @@ jobs:
- name: Upload Artifact
if: github.event_name == 'workflow_dispatch'
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: nym-binaries-artifacts
path: |
+7 -5
View File
@@ -73,27 +73,29 @@ 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
args: --workspace --examples --features wireguard
- name: Run all tests
if: matrix.os == 'custom-linux'
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace
args: --workspace --features wireguard
- 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 -- --ignored
args: --workspace --features wireguard -- --ignored
- name: Annotate with clippy checks
if: matrix.os == 'custom-linux'
@@ -101,10 +103,10 @@ jobs:
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --workspace
args: --workspace --features wireguard
- name: Clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --workspace --all-targets -- -D warnings
args: --workspace --all-targets --features wireguard -- -D warnings
+2 -2
View File
@@ -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@v4
- uses: actions/upload-artifact@v3
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@v4
uses: actions/download-artifact@v3
with:
name: report
path: .github/workflows/support-files/notifications
+5 -1
View File
@@ -51,6 +51,10 @@ 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:
@@ -63,7 +67,7 @@ jobs:
args: --workspace --release ${{ env.CARGO_FEATURES }}
- name: Upload Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: my-artifact
path: |
+2 -2
View File
@@ -26,14 +26,14 @@ jobs:
run: make contracts
- name: Upload Mixnet Contract Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
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@v4
uses: actions/upload-artifact@v3
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@v4
uses: actions/upload-artifact@v3
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@v4
uses: actions/upload-artifact@v3
with:
name: nym-wallet_1.0.0_amd64.AppImage.tar.gz
path: nym-wallet/target/release/bundle/appimage/nym-wallet*.AppImage.tar.gz
@@ -1,4 +1,4 @@
name: publish-nym-wallet-win11
name: publish-nym-wallet-win10
on:
workflow_dispatch:
release:
@@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [custom-windows-11]
platform: [windows10]
runs-on: ${{ matrix.platform }}
outputs:
@@ -62,9 +62,6 @@ 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
@@ -85,7 +82,7 @@ jobs:
run: yarn build
- name: Upload Artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
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@v4
uses: actions/upload-artifact@v3
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@v4
uses: actions/download-artifact@v3
with:
name: nyms5-apk-arch64
path: apk
+1 -1
View File
@@ -30,7 +30,7 @@ jobs:
with:
release-tag-or-name-or-id: ${{ inputs.release_tag }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v2
with:
name: Asset Hashes
path: hashes.json
-54
View File
@@ -4,60 +4,6 @@ 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
+229 -93
View File
@@ -332,6 +332,15 @@ 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"
@@ -544,7 +553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f"
dependencies = [
"bitcoin_hashes",
"rand",
"rand 0.8.5",
"rand_core 0.6.4",
"serde",
"unicode-normalization",
@@ -985,6 +994,15 @@ 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"
@@ -1850,10 +1868,11 @@ checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2"
[[package]]
name = "defguard_wireguard_rs"
version = "0.4.7"
source = "git+https://github.com/DefGuard/wireguard-rs.git?rev=v0.4.7#ef1cf3714629bf5016fb38cbb7320451dc69fb09"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ba16f17698d4b389907310af018b0c3a80b025bba9c38d947cbc6dd70921743"
dependencies = [
"base64 0.22.1",
"base64 0.21.7",
"libc",
"log",
"netlink-packet-core",
@@ -1862,7 +1881,7 @@ dependencies = [
"netlink-packet-utils",
"netlink-packet-wireguard",
"netlink-sys",
"nix 0.29.0",
"nix 0.27.1",
"serde",
"thiserror",
]
@@ -2221,7 +2240,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "explorer-api"
version = "1.1.39"
version = "1.1.38"
dependencies = [
"chrono",
"clap 4.5.7",
@@ -2240,8 +2259,8 @@ dependencies = [
"nym-validator-client",
"okapi",
"pretty_env_logger",
"rand",
"rand_pcg",
"rand 0.8.5",
"rand_pcg 0.3.1",
"rand_seeder",
"reqwest 0.12.4",
"rocket",
@@ -2440,6 +2459,12 @@ 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"
@@ -3320,7 +3345,7 @@ version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"autocfg 1.3.0",
"hashbrown 0.12.3",
"serde",
]
@@ -3735,7 +3760,7 @@ version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"autocfg 1.3.0",
"scopeguard",
]
@@ -3862,7 +3887,7 @@ version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
dependencies = [
"autocfg",
"autocfg 1.3.0",
]
[[package]]
@@ -3932,7 +3957,7 @@ dependencies = [
"nym-ordered-buffer",
"nym-service-providers-common",
"nym-socks5-requests",
"rand",
"rand 0.8.5",
"serde",
"serde-wasm-bindgen 0.6.5",
"thiserror",
@@ -3990,15 +4015,14 @@ dependencies = [
[[package]]
name = "netlink-packet-route"
version = "0.20.1"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55e5bda7ca0f9ac5e75b5debac3b75e29a8ac8e2171106a2c3bb466389a8dd83"
checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66"
dependencies = [
"anyhow",
"bitflags 2.5.0",
"bitflags 1.3.2",
"byteorder",
"libc",
"log",
"netlink-packet-core",
"netlink-packet-utils",
]
@@ -4058,6 +4082,7 @@ dependencies = [
"bitflags 2.5.0",
"cfg-if",
"libc",
"memoffset",
]
[[package]]
@@ -4070,7 +4095,6 @@ dependencies = [
"cfg-if",
"cfg_aliases",
"libc",
"memoffset",
]
[[package]]
@@ -4149,7 +4173,7 @@ version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"autocfg 1.3.0",
"libm",
]
@@ -4180,7 +4204,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "nym-api"
version = "1.1.43"
version = "1.1.42"
dependencies = [
"anyhow",
"async-trait",
@@ -4233,8 +4257,8 @@ dependencies = [
"nym-vesting-contract-common",
"okapi",
"pin-project",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"reqwest 0.12.4",
"rocket",
"rocket_cors",
@@ -4320,7 +4344,7 @@ dependencies = [
"nym-types",
"nym-wireguard",
"nym-wireguard-types",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"thiserror",
@@ -4337,7 +4361,7 @@ dependencies = [
"bincode",
"nym-sphinx",
"nym-wireguard-types",
"rand",
"rand 0.8.5",
"serde",
]
@@ -4355,7 +4379,7 @@ dependencies = [
"nym-ecash-time",
"nym-network-defaults",
"nym-validator-client",
"rand",
"rand 0.8.5",
"thiserror",
"url",
"zeroize",
@@ -4401,7 +4425,7 @@ dependencies = [
[[package]]
name = "nym-cli"
version = "1.1.41"
version = "1.1.40"
dependencies = [
"anyhow",
"base64 0.13.1",
@@ -4429,12 +4453,11 @@ name = "nym-cli-commands"
version = "1.0.0"
dependencies = [
"anyhow",
"base64 0.21.7",
"base64 0.13.1",
"bip39",
"bs58 0.5.1",
"cfg-if",
"clap 4.5.7",
"colored",
"comfy-table 6.2.0",
"cosmrs 0.17.0-pre",
"cosmwasm-std",
@@ -4467,21 +4490,21 @@ dependencies = [
"nym-types",
"nym-validator-client",
"nym-vesting-contract-common",
"rand",
"rand 0.6.5",
"serde",
"serde_json",
"tap",
"thiserror",
"time",
"tokio",
"toml 0.8.14",
"toml 0.5.11",
"url",
"zeroize",
]
[[package]]
name = "nym-client"
version = "1.1.40"
version = "1.1.39"
dependencies = [
"bs58 0.5.1",
"clap 4.5.7",
@@ -4504,7 +4527,7 @@ dependencies = [
"nym-task",
"nym-topology",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"tap",
@@ -4555,7 +4578,7 @@ dependencies = [
"nym-task",
"nym-topology",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"sha2 0.10.8",
@@ -4635,7 +4658,7 @@ dependencies = [
"nym-bin-common",
"nym-node-tester-utils",
"nym-node-tester-wasm",
"rand",
"rand 0.8.5",
"serde",
"serde-wasm-bindgen 0.6.5",
"serde_json",
@@ -4672,8 +4695,8 @@ dependencies = [
"itertools 0.13.0",
"nym-dkg",
"nym-pemstore",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"serde",
"serde_derive",
"sha2 0.9.9",
@@ -4719,7 +4742,7 @@ dependencies = [
"itertools 0.12.1",
"nym-network-defaults",
"nym-pemstore",
"rand",
"rand 0.8.5",
"rayon",
"serde",
"sha2 0.9.9",
@@ -4813,7 +4836,7 @@ dependencies = [
"nym-ecash-time",
"nym-network-defaults",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"thiserror",
"time",
@@ -4828,7 +4851,7 @@ dependencies = [
"nym-compact-ecash",
"nym-ecash-time",
"nym-network-defaults",
"rand",
"rand 0.8.5",
"serde",
"strum 0.25.0",
"thiserror",
@@ -4851,8 +4874,8 @@ dependencies = [
"hmac",
"nym-pemstore",
"nym-sphinx-types",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"serde",
"serde_bytes",
"subtle-encoding",
@@ -4874,8 +4897,8 @@ dependencies = [
"lazy_static",
"nym-contracts-common",
"nym-pemstore",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
"serde",
"serde_derive",
@@ -5005,7 +5028,7 @@ dependencies = [
"nym-wireguard",
"nym-wireguard-types",
"once_cell",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"si-scale",
@@ -5040,7 +5063,7 @@ dependencies = [
"nym-sphinx",
"nym-task",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"si-scale",
"thiserror",
@@ -5069,8 +5092,7 @@ dependencies = [
"nym-crypto",
"nym-pemstore",
"nym-sphinx",
"nym-task",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"thiserror",
@@ -5170,7 +5192,7 @@ name = "nym-inclusion-probability"
version = "0.1.0"
dependencies = [
"log",
"rand",
"rand 0.8.5",
"thiserror",
]
@@ -5183,7 +5205,7 @@ dependencies = [
"nym-bin-common",
"nym-crypto",
"nym-sphinx",
"rand",
"rand 0.8.5",
"serde",
"thiserror",
"time",
@@ -5220,7 +5242,7 @@ dependencies = [
"nym-types",
"nym-wireguard",
"nym-wireguard-types",
"rand",
"rand 0.8.5",
"reqwest 0.12.4",
"serde",
"serde_json",
@@ -5273,12 +5295,11 @@ dependencies = [
"bs58 0.4.0",
"cosmwasm-schema",
"cosmwasm-std",
"cw-controllers",
"cw2",
"humantime-serde",
"log",
"nym-contracts-common",
"rand_chacha",
"rand_chacha 0.3.1",
"schemars",
"serde",
"serde-json-wasm",
@@ -5321,7 +5342,7 @@ dependencies = [
"nym-topology",
"nym-types",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"sysinfo 0.27.8",
@@ -5354,7 +5375,7 @@ dependencies = [
"nym-sphinx-types",
"nym-task",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"thiserror",
"time",
@@ -5391,7 +5412,7 @@ dependencies = [
[[package]]
name = "nym-network-requester"
version = "1.1.41"
version = "1.1.40"
dependencies = [
"addr",
"anyhow",
@@ -5424,7 +5445,7 @@ dependencies = [
"nym-types",
"pretty_env_logger",
"publicsuffix",
"rand",
"rand 0.8.5",
"regex",
"reqwest 0.12.4",
"serde",
@@ -5442,7 +5463,7 @@ dependencies = [
[[package]]
name = "nym-node"
version = "1.1.7"
version = "1.1.6"
dependencies = [
"anyhow",
"bip39",
@@ -5471,7 +5492,7 @@ dependencies = [
"nym-types",
"nym-wireguard",
"nym-wireguard-types",
"rand",
"rand 0.8.5",
"semver 1.0.23",
"serde",
"serde_json",
@@ -5505,7 +5526,7 @@ dependencies = [
"nym-task",
"nym-wireguard",
"nym-wireguard-types",
"rand",
"rand 0.8.5",
"serde_json",
"thiserror",
"time",
@@ -5532,7 +5553,7 @@ dependencies = [
"nym-exit-policy",
"nym-http-api-client",
"nym-wireguard-types",
"rand_chacha",
"rand_chacha 0.3.1",
"schemars",
"serde",
"serde_json",
@@ -5553,7 +5574,7 @@ dependencies = [
"nym-sphinx-params",
"nym-task",
"nym-topology",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"thiserror",
@@ -5568,7 +5589,7 @@ dependencies = [
"futures",
"js-sys",
"nym-node-tester-utils",
"rand",
"rand 0.8.5",
"serde",
"serde-wasm-bindgen 0.6.5",
"thiserror",
@@ -5627,7 +5648,7 @@ dependencies = [
"fastrand 2.1.0",
"getrandom",
"log",
"rand",
"rand 0.8.5",
"rayon",
"sphinx-packet",
"thiserror",
@@ -5676,7 +5697,7 @@ dependencies = [
"nym-validator-client",
"parking_lot 0.12.3",
"pretty_env_logger",
"rand",
"rand 0.8.5",
"reqwest 0.12.4",
"tap",
"thiserror",
@@ -5716,7 +5737,7 @@ dependencies = [
[[package]]
name = "nym-socks5-client"
version = "1.1.40"
version = "1.1.39"
dependencies = [
"bs58 0.5.1",
"clap 4.5.7",
@@ -5736,7 +5757,7 @@ dependencies = [
"nym-sphinx",
"nym-topology",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"tap",
@@ -5769,7 +5790,7 @@ dependencies = [
"nym-task",
"nym-validator-client",
"pin-project",
"rand",
"rand 0.8.5",
"reqwest 0.12.4",
"schemars",
"serde",
@@ -5795,7 +5816,7 @@ dependencies = [
"nym-credential-storage",
"nym-crypto",
"nym-socks5-client-core",
"rand",
"rand 0.8.5",
"safer-ffi",
"serde",
"tokio",
@@ -5849,7 +5870,7 @@ dependencies = [
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand",
"rand 0.8.5",
"rand_distr",
"thiserror",
"tokio",
@@ -5867,7 +5888,7 @@ dependencies = [
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand",
"rand 0.8.5",
"serde",
"thiserror",
"zeroize",
@@ -5879,7 +5900,7 @@ version = "0.1.0"
dependencies = [
"nym-crypto",
"nym-sphinx-types",
"rand",
"rand 0.8.5",
"serde",
"thiserror",
]
@@ -5895,8 +5916,8 @@ dependencies = [
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"serde",
"thiserror",
"wasm-bindgen",
@@ -5910,7 +5931,7 @@ dependencies = [
"nym-sphinx-addressing",
"nym-sphinx-params",
"nym-sphinx-types",
"rand",
"rand 0.8.5",
"thiserror",
]
@@ -5927,7 +5948,7 @@ dependencies = [
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand",
"rand 0.8.5",
"thiserror",
]
@@ -5989,7 +6010,7 @@ dependencies = [
"argon2",
"generic-array 0.14.7",
"getrandom",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"thiserror",
@@ -6024,7 +6045,7 @@ dependencies = [
"nym-sphinx-addressing",
"nym-sphinx-routing",
"nym-sphinx-types",
"rand",
"rand 0.8.5",
"semver 0.11.0",
"serde",
"serde_json",
@@ -6148,7 +6169,7 @@ dependencies = [
"nym-task",
"nym-validator-client",
"nyxd-scraper",
"rand_chacha",
"rand_chacha 0.3.1",
"serde",
"serde_with",
"sha2 0.10.8",
@@ -6227,7 +6248,7 @@ dependencies = [
"nym-config",
"nym-crypto",
"nym-network-defaults",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"sha2 0.10.8",
@@ -6238,7 +6259,7 @@ dependencies = [
[[package]]
name = "nymvisor"
version = "0.1.6"
version = "0.1.5"
dependencies = [
"anyhow",
"bytes",
@@ -6437,7 +6458,7 @@ dependencies = [
"once_cell",
"opentelemetry_api",
"percent-encoding",
"rand",
"rand 0.8.5",
"thiserror",
"tokio",
"tokio-stream",
@@ -6750,7 +6771,7 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
dependencies = [
"autocfg",
"autocfg 1.3.0",
"bitflags 1.3.2",
"cfg-if",
"concurrent-queue",
@@ -7004,6 +7025,25 @@ 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"
@@ -7011,10 +7051,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_chacha 0.3.1",
"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"
@@ -7025,6 +7075,21 @@ 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"
@@ -7047,7 +7112,60 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
dependencies = [
"num-traits",
"rand",
"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",
]
[[package]]
@@ -7068,6 +7186,15 @@ 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"
@@ -7088,6 +7215,15 @@ 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"
@@ -7345,7 +7481,7 @@ dependencies = [
"num_cpus",
"parking_lot 0.12.3",
"pin-project-lite",
"rand",
"rand 0.8.5",
"ref-cast",
"rocket_codegen",
"rocket_http",
@@ -8118,7 +8254,7 @@ version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
"autocfg",
"autocfg 1.3.0",
]
[[package]]
@@ -8189,7 +8325,7 @@ dependencies = [
"hmac",
"lioness",
"log",
"rand",
"rand 0.8.5",
"rand_distr",
"sha2 0.10.8",
"subtle 2.5.0",
@@ -8733,7 +8869,7 @@ dependencies = [
"getrandom",
"peg",
"pin-project",
"rand",
"rand 0.8.5",
"reqwest 0.11.27",
"semver 1.0.23",
"serde",
@@ -8787,7 +8923,7 @@ dependencies = [
"nym-pemstore",
"nym-validator-client",
"nym-vesting-contract-common",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"sqlx",
@@ -9187,7 +9323,7 @@ dependencies = [
"indexmap 1.9.3",
"pin-project",
"pin-project-lite",
"rand",
"rand 0.8.5",
"slab",
"tokio",
"tokio-util",
@@ -9453,7 +9589,7 @@ dependencies = [
"http 0.2.12",
"httparse",
"log",
"rand",
"rand 0.8.5",
"rustls 0.21.12",
"sha1",
"thiserror",
@@ -9474,7 +9610,7 @@ dependencies = [
"http 1.1.0",
"httparse",
"log",
"rand",
"rand 0.8.5",
"rustls 0.22.4",
"rustls-pki-types",
"sha1",
@@ -9894,7 +10030,7 @@ dependencies = [
"nym-task",
"nym-topology",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"serde-wasm-bindgen 0.6.5",
"thiserror",
@@ -10529,7 +10665,7 @@ dependencies = [
"nym-credentials",
"nym-crypto",
"nym-http-api-client",
"rand",
"rand 0.8.5",
"reqwest 0.12.4",
"serde",
"thiserror",
+1 -2
View File
@@ -204,8 +204,7 @@ ctr = "0.9.1"
cupid = "0.6.1"
curve25519-dalek = "4.1"
dashmap = "5.5.3"
# 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" }
defguard_wireguard_rs = "0.4.2"
digest = "0.10.7"
dirs = "4.0"
doc-comment = "0.3"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.1.40"
version = "1.1.39"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-socks5-client"
version = "1.1.40"
version = "1.1.39"
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,9 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::error::BandwidthControllerError;
use crate::utils::{
get_aggregate_verification_key, get_coin_index_signatures, get_expiration_date_signatures,
};
use crate::utils::{get_coin_index_signatures, get_expiration_date_signatures};
use log::info;
use nym_credential_storage::storage::Storage;
use nym_credentials::ecash::bandwidth::IssuanceTicketBook;
@@ -57,7 +55,7 @@ where
))
}
pub async fn query_and_persist_required_global_data<S>(
pub async fn query_and_persist_required_global_signatures<S>(
storage: &S,
epoch_id: EpochId,
expiration_date: Date,
@@ -67,10 +65,6 @@ 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?;
+2 -4
View File
@@ -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, VerificationKeyAuth,
AnnotatedCoinIndexSignature, AnnotatedExpirationDateSignature, NymPayInfo, VerificationKeyAuth,
};
use nym_ecash_time::Date;
use nym_validator_client::nym_api::EpochId;
@@ -165,9 +165,7 @@ impl<C, St: Storage> BandwidthController<C, St> {
.get_coin_index_signatures(epoch_id, &mut api_clients)
.await?;
let pay_info = retrieved_ticketbook
.ticketbook
.generate_pay_info(provider_pk);
let pay_info = NymPayInfo::generate(provider_pk);
let spend_request = retrieved_ticketbook.ticketbook.prepare_for_spending(
&verification_key,
@@ -474,13 +474,6 @@ 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");
@@ -417,8 +417,6 @@ 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),
@@ -42,10 +42,6 @@ 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
@@ -584,7 +580,6 @@ 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,15 +31,6 @@ 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,
@@ -769,7 +760,6 @@ 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,7 +1,6 @@
// 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;
@@ -10,6 +9,7 @@ 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,8 +21,7 @@ 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.
#[deprecated]
pub fn find_attribute_in_logs<'a>(
pub fn find_attribute<'a>(
logs: &'a [Log],
event_type: &str,
attribute_key: &str,
@@ -36,7 +35,6 @@ pub fn find_attribute_in_logs<'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,24 +1,12 @@
// 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> {
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 event = tx.tx_result.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
@@ -28,23 +16,3 @@ pub fn find_event_attribute(
})?;
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)
}
+4 -5
View File
@@ -7,10 +7,9 @@ license.workspace = true
[dependencies]
anyhow = { workspace = true }
base64 = { workspace = true }
base64 = "0.13.0"
bip39 = { workspace = true }
bs58 = { workspace = true }
colored = { workspace = true }
comfy-table = { workspace = true }
cfg-if = { workspace = true }
clap = { workspace = true, features = ["derive"] }
@@ -22,13 +21,13 @@ humantime-serde = { workspace = true }
inquire = { workspace = true }
k256 = { workspace = true, features = ["ecdsa", "sha256"] }
log = { workspace = true }
rand = { workspace = true, features = ["std"] }
rand = {version = "0.6", 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 = { workspace = true }
tokio = { workspace = true, features = ["sync"]}
toml = "0.5.6"
url = { workspace = true }
tap = { workspace = true }
zeroize = { workspace = true }
@@ -9,17 +9,9 @@ use nym_credential_storage::initialise_persistent_storage;
use nym_id::import_credential;
use std::fs;
use std::path::PathBuf;
use std::str::FromStr;
#[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)
}
fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> {
bs58::decode(raw).into_vec()
}
#[derive(Debug, Parser)]
@@ -30,8 +22,8 @@ pub struct Args {
pub(crate) client_config: PathBuf,
/// Explicitly provide the encoded credential data (as base58)
#[clap(long, group = "cred_data")]
pub(crate) credential_data: Option<CredentialDataWrapper>,
#[clap(long, group = "cred_data", value_parser = parse_encoded_credential_data)]
pub(crate) credential_data: Option<Vec<u8>>,
/// Specifies the path to file containing binary credential data
#[clap(long, group = "cred_data")]
@@ -60,7 +52,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.0,
Some(data) => data,
None => {
// SAFETY: one of those arguments must have been set
fs::read(args.credential_path.unwrap())?
@@ -9,9 +9,6 @@ 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)]
@@ -21,20 +18,12 @@ pub struct Args {
pub(crate) ticketbook_type: TicketType,
/// Config file of the client that is supposed to use the credential.
#[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>,
#[clap(long)]
pub(crate) client_config: PathBuf,
}
async fn issue_client_ticketbook(
cfg: PathBuf,
typ: TicketType,
client: SigningClient,
) -> anyhow::Result<()> {
let loaded = CommonConfigsWrapper::try_load(cfg)?;
pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> {
let loaded = CommonConfigsWrapper::try_load(args.client_config)?;
if let Ok(id) = loaded.try_get_id() {
println!("loaded config file for client '{id}'");
@@ -59,40 +48,9 @@ async fn issue_client_ticketbook(
&client,
&persistent_storage,
&private_id_key.to_bytes(),
typ,
args.ticketbook_type,
)
.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,7 +3,6 @@
use clap::{Args, Subcommand};
pub mod generate_ticket;
pub mod import_ticket_book;
pub mod issue_ticket_book;
pub mod recover_ticket_book;
@@ -20,5 +19,4 @@ pub enum EcashCommands {
IssueTicketBook(issue_ticket_book::Args),
RecoverTicketBook(recover_ticket_book::Args),
ImportTicketBook(import_ticket_book::Args),
GenerateTicket(generate_ticket::Args),
}
@@ -1,178 +0,0 @@
// 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(())
}
+1 -1
View File
@@ -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;
@@ -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_legacy_gateway_bonding_sign_payload;
use nym_mixnet_contract_common::construct_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_legacy_gateway_bonding_sign_payload(nonce, address, coin, gateway);
let payload = construct_gateway_bonding_sign_payload(nonce, address, coin, gateway);
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
println!("{}", args.output.format(&wrapper))
}
@@ -10,11 +10,7 @@ pub struct Args {
}
pub fn decode_mixnode_key(args: Args) {
use base64::{engine::general_purpose::STANDARD, Engine as _};
let b64_decoded = STANDARD
.decode(args.key)
.expect("failed to decode base64 string");
let b64_decoded = base64::decode(args.key).expect("failed to decode base64 string");
let b58_encoded = bs58::encode(&b64_decoded).into_string();
println!("{b58_encoded}")
@@ -7,9 +7,7 @@ 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_legacy_mixnode_bonding_sign_payload, MixNodeCostParams,
};
use nym_mixnet_contract_common::{construct_mixnode_bonding_sign_payload, MixNodeCostParams};
use nym_network_defaults::{
DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT,
};
@@ -100,7 +98,7 @@ pub async fn create_payload(args: Args, client: SigningClient) {
let address = account_id_to_cw_addr(&client.address());
let payload =
construct_legacy_mixnode_bonding_sign_payload(nonce, address, coin, mixnode, cost_params);
construct_mixnode_bonding_sign_payload(nonce, address, coin, mixnode, cost_params);
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
println!("{}", args.output.format(&wrapper))
}
@@ -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::{MixnetQueryClient, MixnetSigningClient};
use nym_validator_client::nyxd::contract_traits::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 20, rather than 0.2)"
help = "input your profit margin as follows; (so it would be 10, rather than 0.1)"
)]
pub profit_margin_percent: Option<u8>,
@@ -27,48 +27,11 @@ 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: profit_margin_value,
profit_margin_percent: Percent::from_percentage_value(
args.profit_margin_percent.unwrap_or(10) as u64,
)
.unwrap(),
interval_operating_cost: CosmWasmCoin {
denom: denom.into(),
amount: Uint128::new(args.interval_operating_cost.unwrap_or(40_000_000)),
@@ -248,31 +248,3 @@ 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,7 +12,6 @@ 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,7 +5,6 @@ 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)]
@@ -13,9 +12,6 @@ pub enum MixnetContractError {
#[error("could not perform contract migration: {comment}")]
FailedMigration { comment: String },
#[error(transparent)]
Admin(#[from] AdminError),
#[error("{source}")]
StdErr {
#[from]
@@ -110,11 +110,6 @@ impl InitialRewardingParams {
#[cw_serde]
pub enum ExecuteMsg {
/// Change the admin
UpdateAdmin {
admin: String,
},
AssignNodeLayer {
mix_id: MixId,
layer: Layer,
@@ -297,7 +292,6 @@ 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:?}")
}
@@ -414,9 +408,6 @@ 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,18 +4,13 @@
use crate::families::FamilyHead;
use crate::{Gateway, IdentityKey, MixNode, MixNodeCostParams};
use contracts_common::signing::{
ContractMessageContent, LegacyContractMessageContent, MessageType, Nonce, SignableMessage,
SigningPurpose,
ContractMessageContent, 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)]
@@ -52,20 +47,6 @@ 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,
@@ -95,19 +76,6 @@ 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,11 +187,7 @@ impl Index<Layer> for LayerDistribution {
#[cw_serde]
pub struct ContractState {
/// Address of the contract owner.
#[deprecated(
note = "use explicit ADMIN instead. this field will be removed in future release"
)]
#[serde(default)]
pub owner: Option<Addr>,
pub owner: Addr,
/// Address of "rewarding validator" (nym-api) that's allowed to send any rewarding-related transactions.
pub rewarding_validator_address: Addr,
+11 -5
View File
@@ -3,7 +3,9 @@
use crate::errors::{Error, Result};
use log::*;
use nym_bandwidth_controller::acquire::{get_ticket_book, query_and_persist_required_global_data};
use nym_bandwidth_controller::acquire::{
get_ticket_book, query_and_persist_required_global_signatures,
};
use nym_client_core::config::disk_persistence::CommonClientPaths;
use nym_config::DEFAULT_DATA_DIR;
use nym_credential_storage::persistent_storage::PersistentStorage;
@@ -43,10 +45,14 @@ 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 alongside the master verification key
// before attempting the deposit
query_and_persist_required_global_data(storage, epoch_id, ticketbook_expiration, apis.clone())
.await?;
// 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?;
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, NymPayInfo, PayInfo, SecretKeyUser, TicketType,
CoinIndexSignature, ExpirationDateSignature, PayInfo, SecretKeyUser, TicketType,
VerificationKeyAuth, Wallet, WalletSignatures,
};
use nym_ecash_time::EcashTime;
@@ -114,10 +114,6 @@ 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,15 +81,6 @@ 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,15 +91,6 @@ 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;
-1
View File
@@ -24,7 +24,6 @@ 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,7 +25,6 @@ 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,
@@ -36,8 +35,6 @@ impl<'a> ClientHandshake<'a> {
identity,
Some(gateway_pubkey),
expects_credential_usage,
#[cfg(not(target_arch = "wasm32"))]
shutdown,
);
ClientHandshake {
@@ -25,8 +25,6 @@ pub enum HandshakeError {
MalformedRequest,
#[error("sent request was malformed")]
HandshakeFailure,
#[error("received shutdown")]
ReceivedShutdown,
#[error("timed out waiting for a handshake message")]
Timeout,
@@ -8,7 +8,6 @@ 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;
@@ -23,12 +22,11 @@ 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, shutdown);
let mut state = State::new(rng, ws_stream, identity, None, true);
GatewayHandshake {
handshake_future: Box::pin(async move {
// If any step along the way failed (that are non-network related),
@@ -8,8 +8,6 @@ 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};
@@ -33,7 +31,6 @@ 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,
@@ -44,8 +41,6 @@ where
identity,
gateway_pubkey,
expects_credential_usage,
#[cfg(not(target_arch = "wasm32"))]
shutdown,
)
.await
}
@@ -56,12 +51,11 @@ 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, shutdown).await
GatewayHandshake::new(rng, ws_stream, identity, received_init_payload).await
}
/*
@@ -13,8 +13,6 @@ 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::*;
@@ -50,10 +48,6 @@ 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> {
@@ -63,7 +57,6 @@ 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 {
@@ -73,8 +66,6 @@ impl<'a, S> State<'a, S> {
remote_pubkey,
derived_shared_keys: None,
expects_credential_usage,
#[cfg(not(target_arch = "wasm32"))]
shutdown,
}
}
@@ -208,73 +199,43 @@ 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);
};
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) => {
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))
}
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;
}
}
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"),
}
_ => {
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 {
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);
}
}
}
}
#[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);
}
}
+5 -2
View File
@@ -10,8 +10,8 @@ license.workspace = true
[dependencies]
async-trait = { workspace = true }
bincode = { workspace = true }
defguard_wireguard_rs = { workspace = true }
bincode = { workspace = true, optional = true }
defguard_wireguard_rs = { workspace = true, optional = true }
log = { workspace = true }
sqlx = { workspace = true, features = [
"runtime-tokio-rustls",
@@ -36,3 +36,6 @@ sqlx = { workspace = true, features = [
"macros",
"migrate",
] }
[features]
wireguard = ["defguard_wireguard_rs", "bincode"]
+11
View File
@@ -25,6 +25,7 @@ mod inboxes;
pub(crate) mod models;
mod shared_keys;
mod tickets;
#[cfg(feature = "wireguard")]
mod wireguard_peers;
#[async_trait]
@@ -216,6 +217,7 @@ 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,
@@ -227,12 +229,14 @@ 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.
@@ -240,6 +244,7 @@ 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>;
}
@@ -250,6 +255,7 @@ pub struct PersistentStorage {
inbox_manager: InboxManager,
bandwidth_manager: BandwidthManager,
ticket_manager: TicketStorageManager,
#[cfg(feature = "wireguard")]
wireguard_peer_manager: wireguard_peers::WgPeerManager,
}
@@ -294,6 +300,7 @@ 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),
@@ -613,6 +620,7 @@ 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,
@@ -624,6 +632,7 @@ impl Storage for PersistentStorage {
Ok(())
}
#[cfg(feature = "wireguard")]
async fn get_wireguard_peer(
&self,
peer_public_key: &str,
@@ -635,11 +644,13 @@ 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)
+3
View File
@@ -72,6 +72,7 @@ impl TryFrom<UnverifiedTicketData> for ClientTicket {
}
}
#[cfg(feature = "wireguard")]
#[derive(Debug, Clone, FromRow)]
pub struct WireguardPeer {
pub public_key: String,
@@ -86,6 +87,7 @@ 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 {
@@ -118,6 +120,7 @@ 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;
+1 -9
View File
@@ -40,17 +40,9 @@ impl SharedKeysManager {
client_address_bs58: String,
derived_aes128_ctr_blake3_hmac_keys_bs58: String,
) -> Result<i64, sqlx::Error> {
// 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 = ?
"#,
sqlx::query!("INSERT OR REPLACE INTO shared_keys(client_address_bs58, derived_aes128_ctr_blake3_hmac_keys_bs58) VALUES (?, ?)",
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
+2 -11
View File
@@ -26,17 +26,8 @@ impl WgPeerManager {
/// * `peer`: peer information needed by wireguard interface.
pub(crate) async fn insert_peer(&self, peer: &WireguardPeer) -> Result<(), sqlx::Error> {
sqlx::query!(
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,
"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
)
.execute(&self.connection_pool)
.await?;
+1 -3
View File
@@ -415,8 +415,6 @@ pub struct HealthRequest {
#[cfg(test)]
mod tests {
use time::macros::datetime;
use super::*;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
@@ -434,7 +432,7 @@ mod tests {
reply_to_hops: None,
reply_to_avg_mix_delays: None,
buffer_timeout: None,
timestamp: datetime!(2024-01-01 12:59:59.5 UTC),
timestamp: OffsetDateTime::now_utc(),
},
signature: None,
}
+2 -2
View File
@@ -17,8 +17,8 @@ pub const MIXNET_CONTRACT_ADDRESS: &str =
"n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr";
pub const VESTING_CONTRACT_ADDRESS: &str =
"n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw";
pub const ECASH_CONTRACT_ADDRESS: &str =
"n1r7s6aksyc6pqardx88k3rkgfagwvj4z4zum9mmz2sfk3zm2mha0sd4dnun";
pub const ECASH_CONTRACT_ADDRESS: &str = "";
pub const GROUP_CONTRACT_ADDRESS: &str =
"n1e2zq4886zzewpvpucmlw8v9p7zv692f6yck4zjzxh699dkcmlrfqk2knsr";
pub const MULTISIG_CONTRACT_ADDRESS: &str =
+12
View File
@@ -3,6 +3,7 @@
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::{
@@ -367,6 +368,17 @@ 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(());
+7
View File
@@ -6,10 +6,17 @@ 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;
+1 -1
View File
@@ -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" }
nym-gateway-storage = { path = "../gateway-storage", features = ["wireguard"] }
nym-network-defaults = { path = "../network-defaults" }
nym-task = { path = "../task" }
nym-wireguard-types = { path = "../wireguard-types" }
-1
View File
@@ -114,7 +114,6 @@ 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)?;
+16 -15
View File
@@ -5,19 +5,15 @@ 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, time::Duration};
use std::{collections::HashMap, sync::Arc};
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),
@@ -50,6 +46,7 @@ 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> {
@@ -64,19 +61,14 @@ impl<St: Storage> PeerController<St> {
let timeout_check_interval = tokio_stream::wrappers::IntervalStream::new(
tokio::time::interval(DEFAULT_PEER_TIMEOUT_CHECK),
);
let active_peers: HashMap<Key, Peer> = peers
let active_peers = peers
.into_iter()
.map(|peer| (peer.public_key.clone(), peer))
.collect();
let suspended_peers: HashMap<Key, Peer> = suspended_peers
let suspended_peers = 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,
@@ -86,7 +78,8 @@ impl<St: Storage> PeerController<St> {
timeout_check_interval,
active_peers,
suspended_peers,
last_seen_bandwidth,
last_seen_bandwidth: HashMap::new(),
timeout_count: 0,
}
}
@@ -149,6 +142,15 @@ 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() {
@@ -197,7 +199,6 @@ 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
};
-2
View File
@@ -1276,7 +1276,6 @@ dependencies = [
"cosmwasm-schema",
"cosmwasm-std",
"cosmwasm-storage",
"cw-controllers",
"cw-storage-plus",
"cw2",
"nym-contracts-common",
@@ -1296,7 +1295,6 @@ dependencies = [
"bs58 0.4.0",
"cosmwasm-schema",
"cosmwasm-std",
"cw-controllers",
"cw2",
"humantime-serde",
"log",
-1
View File
@@ -34,7 +34,6 @@ 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,28 +177,6 @@
"$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": [
@@ -1714,19 +1692,6 @@
"$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",
@@ -2972,21 +2937,6 @@
},
"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",
@@ -8190,6 +8140,7 @@
"description": "The current state of the mixnet contract.",
"type": "object",
"required": [
"owner",
"params",
"rewarding_denom",
"rewarding_validator_address",
@@ -8198,14 +8149,9 @@
"properties": {
"owner": {
"description": "Address of the contract owner.",
"default": null,
"deprecated": true,
"anyOf": [
"allOf": [
{
"$ref": "#/definitions/Addr"
},
{
"type": "null"
}
]
},
-22
View File
@@ -2,28 +2,6 @@
"$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": [
-13
View File
@@ -2,19 +2,6 @@
"$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",
@@ -1,15 +0,0 @@
{
"$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,6 +4,7 @@
"description": "The current state of the mixnet contract.",
"type": "object",
"required": [
"owner",
"params",
"rewarding_denom",
"rewarding_validator_address",
@@ -12,14 +13,9 @@
"properties": {
"owner": {
"description": "Address of the contract owner.",
"default": null,
"deprecated": true,
"anyOf": [
"allOf": [
{
"$ref": "#/definitions/Addr"
},
{
"type": "null"
}
]
},
-1
View File
@@ -57,7 +57,6 @@ 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";
+5 -17
View File
@@ -28,10 +28,8 @@ 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: Some(owner),
owner,
rewarding_validator_address,
vesting_contract_address,
rewarding_denom: rewarding_denom.clone(),
@@ -58,7 +56,7 @@ fn default_initial_state(
/// `msg` is the contract initialization message, sort of like a constructor call.
#[entry_point]
pub fn instantiate(
mut deps: DepsMut<'_>,
deps: DepsMut<'_>,
env: Env,
info: MessageInfo,
msg: InstantiateMsg,
@@ -74,7 +72,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.clone(),
info.sender,
rewarding_validator_address.clone(),
msg.rewarding_denom,
vesting_contract_address,
@@ -92,7 +90,7 @@ pub fn instantiate(
starting_interval,
rewarding_validator_address,
)?;
mixnet_params_storage::initialise_storage(deps.branch(), state, info.sender)?;
mixnet_params_storage::initialise_storage(deps.storage, state)?;
mixnode_storage::initialise_storage(deps.storage)?;
rewards_storage::initialise_storage(deps.storage, reward_params)?;
cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?;
@@ -110,11 +108,6 @@ 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)
}
@@ -342,9 +335,6 @@ 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)?)
}
@@ -546,7 +536,6 @@ 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
@@ -605,9 +594,8 @@ mod tests {
let res = instantiate(deps.as_mut(), env, sender, init_msg);
assert!(res.is_ok());
#[allow(deprecated)]
let expected_state = ContractState {
owner: Some(Addr::unchecked("sender")),
owner: Addr::unchecked("sender"),
rewarding_validator_address: Addr::unchecked("foomp123"),
vesting_contract_address: Addr::unchecked("bar456"),
rewarding_denom: "uatom".into(),
@@ -5,9 +5,7 @@ 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, construct_legacy_gateway_bonding_sign_payload, Gateway,
};
use mixnet_contract_common::{construct_gateway_bonding_sign_payload, Gateway};
use nym_contracts_common::signing::MessageSignature;
use nym_contracts_common::signing::Verifier;
@@ -21,31 +19,13 @@ pub(crate) fn verify_gateway_bonding_signature(
// recover the public key
let public_key = decode_ed25519_identity_key(&gateway.identity_key)?;
// reconstruct the payload, first try the current format, then attempt legacy
// reconstruct the payload
let nonce = signing_storage::get_signing_nonce(deps.storage, sender.clone())?;
let msg = construct_gateway_bonding_sign_payload(
nonce,
sender.clone(),
pledge.clone(),
gateway.clone(),
);
let msg = construct_gateway_bonding_sign_payload(nonce, sender, pledge, gateway);
if deps
.api
.verify_message(msg, signature.clone(), &public_key)?
{
if deps.api.verify_message(msg, signature, &public_key)? {
Ok(())
} else {
// 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)
}
Err(MixnetContractError::InvalidEd25519Signature)
}
}
@@ -5,12 +5,11 @@ 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_can_advance_epoch, ensure_epoch_in_progress_state, ensure_is_authorized, ensure_is_owner,
};
use cosmwasm_std::{DepsMut, Env, MessageInfo, Order, Response, Storage};
use mixnet_contract_common::error::MixnetContractError;
@@ -326,7 +325,7 @@ pub(crate) fn try_update_interval_config(
epoch_duration_secs: u64,
force_immediately: bool,
) -> Result<Response, MixnetContractError> {
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;
ensure_is_owner(info.sender, deps.storage)?;
if epochs_in_interval == 0 {
return Err(MixnetContractError::EpochsInIntervalZero);
@@ -1767,7 +1766,6 @@ mod tests {
use super::*;
use cosmwasm_std::testing::mock_info;
use cosmwasm_std::Decimal;
use cw_controllers::AdminError::NotAdmin;
use std::time::Duration;
#[test]
@@ -1833,11 +1831,11 @@ mod tests {
1000,
false,
);
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
assert_eq!(res, Err(MixnetContractError::Unauthorized));
let res =
try_update_interval_config(test.deps_mut(), env.clone(), random, 100, 1000, false);
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
assert_eq!(res, Err(MixnetContractError::Unauthorized));
let res = try_update_interval_config(test.deps_mut(), env, owner, 100, 1000, false);
assert!(res.is_ok())
@@ -2,16 +2,10 @@
// 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)
}
@@ -42,9 +36,8 @@ pub(crate) mod tests {
fn query_for_contract_settings_works() {
let mut deps = test_helpers::init_contract();
#[allow(deprecated)]
let dummy_state = ContractState {
owner: Some(Addr::unchecked("foomp")),
owner: Addr::unchecked("someowner"),
rewarding_validator_address: Addr::unchecked("monitor"),
vesting_contract_address: Addr::unchecked("foomp"),
rewarding_denom: "unym".to_string(),
@@ -1,16 +1,14 @@
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::constants::{ADMIN_STORAGE_KEY, CONTRACT_STATE_KEY};
use cosmwasm_std::{Addr, DepsMut, Storage};
use crate::constants::CONTRACT_STATE_KEY;
use cosmwasm_std::{Addr, 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
@@ -68,10 +66,8 @@ pub(crate) fn vesting_contract_address(storage: &dyn Storage) -> Result<Addr, Mi
}
pub(crate) fn initialise_storage(
deps: DepsMut<'_>,
storage: &mut dyn Storage,
initial_state: ContractState,
initial_admin: Addr,
) -> StdResult<()> {
CONTRACT_STATE.save(deps.storage, &initial_state)?;
ADMIN.set(deps, Some(initial_admin))
CONTRACT_STATE.save(storage, &initial_state)
}
@@ -2,36 +2,15 @@
// SPDX-License-Identifier: Apache-2.0
use super::storage;
use crate::mixnet_contract_settings::storage::ADMIN;
use cosmwasm_std::DepsMut;
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,
@@ -39,7 +18,9 @@ pub fn try_update_rewarding_validator_address(
) -> Result<Response, MixnetContractError> {
let mut state = storage::CONTRACT_STATE.load(deps.storage)?;
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;
if info.sender != state.owner {
return Err(MixnetContractError::Unauthorized);
}
let new_address = deps.api.addr_validate(&address)?;
let old_address = state.rewarding_validator_address;
@@ -62,7 +43,10 @@ pub(crate) fn try_update_contract_settings(
) -> Result<Response, MixnetContractError> {
let mut state = storage::CONTRACT_STATE.load(deps.storage)?;
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;
// check if this is executed by the owner, if not reject the transaction
if info.sender != state.owner {
return Err(MixnetContractError::Unauthorized);
}
let response = Response::new().add_event(new_settings_update_event(&state.params, &params));
@@ -81,7 +65,6 @@ 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() {
@@ -93,7 +76,7 @@ pub mod tests {
info,
"not-the-creator".to_string(),
);
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
assert_eq!(res, Err(MixnetContractError::Unauthorized));
let info = mock_info("creator", &[]);
let res = try_update_rewarding_validator_address(
@@ -153,7 +136,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::Admin(NotAdmin {})));
assert_eq!(res, Err(MixnetContractError::Unauthorized));
// but works fine from the creator account
let info = mock_info("creator", &[]);
@@ -5,10 +5,7 @@ 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_legacy_mixnode_bonding_sign_payload, construct_mixnode_bonding_sign_payload, MixNode,
MixNodeCostParams,
};
use mixnet_contract_common::{construct_mixnode_bonding_sign_payload, MixNode, MixNodeCostParams};
use nym_contracts_common::signing::MessageSignature;
use nym_contracts_common::signing::Verifier;
@@ -23,37 +20,13 @@ pub(crate) fn verify_mixnode_bonding_signature(
// recover the public key
let public_key = decode_ed25519_identity_key(&mixnode.identity_key)?;
// reconstruct the payload, first try the current format, then attempt legacy
// reconstruct the payload
let nonce = signing_storage::get_signing_nonce(deps.storage, sender.clone())?;
let msg = construct_mixnode_bonding_sign_payload(
nonce,
sender.clone(),
pledge.clone(),
mixnode.clone(),
cost_params.clone(),
);
let msg = construct_mixnode_bonding_sign_payload(nonce, sender, pledge, mixnode, cost_params);
if deps
.api
.verify_message(msg, signature.clone(), &public_key)?
{
if deps.api.verify_message(msg, signature, &public_key)? {
Ok(())
} else {
// 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)
}
Err(MixnetContractError::InvalidEd25519Signature)
}
}
-15
View File
@@ -2,7 +2,6 @@
// 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;
@@ -50,17 +49,3 @@ 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(())
}
+8 -10
View File
@@ -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, AttachSendTokens,
ensure_bonded, ensure_can_advance_epoch, ensure_epoch_in_progress_state, ensure_is_owner,
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> {
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;
ensure_is_owner(info.sender, deps.storage)?;
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> {
ADMIN.assert_admin(deps.as_ref(), &info.sender)?;
ensure_is_owner(info.sender, deps.storage)?;
if !updated_params.contains_updates() {
return Err(MixnetContractError::EmptyParamsChangeMsg);
@@ -1796,7 +1796,6 @@ 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;
@@ -1859,10 +1858,10 @@ pub mod tests {
42,
false,
);
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
assert_eq!(res, Err(MixnetContractError::Unauthorized));
let res = try_update_active_set_size(test.deps_mut(), env.clone(), random, 42, false);
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
assert_eq!(res, Err(MixnetContractError::Unauthorized));
let res = try_update_active_set_size(test.deps_mut(), env, owner, 42, false);
assert!(res.is_ok())
@@ -2003,7 +2002,6 @@ pub mod tests {
#[cfg(test)]
mod updating_rewarding_params {
use cosmwasm_std::Decimal;
use cw_controllers::AdminError::NotAdmin;
use mixnet_contract_common::EpochStatus;
@@ -2087,11 +2085,11 @@ pub mod tests {
update,
false,
);
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
assert_eq!(res, Err(MixnetContractError::Unauthorized));
let res =
try_update_rewarding_params(test.deps_mut(), env.clone(), random, update, false);
assert_eq!(res, Err(MixnetContractError::Admin(NotAdmin {})));
assert_eq!(res, Err(MixnetContractError::Unauthorized));
let res = try_update_rewarding_params(test.deps_mut(), env, owner, update, false);
assert!(res.is_ok())
+14
View File
@@ -194,6 +194,20 @@ 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 {
+3 -4
View File
@@ -105,11 +105,10 @@ 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::ADMIN
.query_admin(deps.as_ref())
let owner = mixnet_params_storage::CONTRACT_STATE
.load(deps.as_ref().storage)
.unwrap()
.admin
.unwrap();
.owner;
TestSetup {
deps,
+8
View File
@@ -108,3 +108,11 @@ 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"
+7 -2
View File
@@ -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,8 +54,13 @@
# 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)
@@ -0,0 +1,85 @@
# 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.
![Electrum Bitcoin wallet setup](../images/electrum_tutorial/electrum.gif)
### 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.
![Monero wallet setup](../images/monero_tutorial/monero-gui-NC.gif)
### 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.
@@ -52,10 +52,10 @@ git checkout master # master branch has the latest release version: `develop` wi
cargo build --release # build your binaries with **mainnet** configuration
```
Quite a bit of stuff gets built. The key working parts for devs are the Client binaries and the CLI tool:
Quite a bit of stuff gets built. The key working parts for devs are the Client binaries and the CLI tool:
* [websocket client](../clients/websocket-client.md): `nym-client`
* [socks5 client](../clients/socks5-client.md): `nym-socks5-client`
* [nym-cli tool](https://nymtech.net/docs/tools/nym-cli.md): `nym-cli`
* [nym-cli tool](https://nymtech.net/docs/tools/nym-cli.html): `nym-cli`
> You cannot build from GitHub's .zip or .tar.gz archive files on the releases page - the Nym build scripts automatically include the current git commit hash in the built binary during compilation, so the build will fail if you use the archive code (which isn't a Git repository). Check the code out from github using `git clone` instead.
@@ -60,7 +60,7 @@ There are 2 pieces of software that work together to send SOCKS traffic through
The `nym-socks5-client` allows you to do the following from your local machine:
* Take a TCP data stream from a application that can send traffic via SOCKS5.
* Chop up the TCP stream into multiple Sphinx packets, assigning sequence numbers to them, while leaving the TCP connection open for more data
* Send the Sphinx packets through the mixnet to a [network requester](https://nymtech.net/operators/nodes/network-requester.md). Packets are shuffled and mixed as they transit the mixnet.
* Send the Sphinx packets through the Nym Network. Packets are shuffled and mixed as they transit the mixnet.
The `nym-network-requester` then reassembles the original TCP stream using the packets' sequence numbers, and make the intended request. It will then chop up the response into Sphinx packets and send them back through the mixnet to your `nym-socks5-client`. The application will then receive its data, without even noticing that it wasn't talking to a "normal" SOCKS5 proxy!
@@ -104,8 +104,6 @@ The `--use-reply-surbs` field denotes whether you wish to send [SURBs](https://n
The `--provider` field needs to be filled with the Nym address of a Network Requester that can make network requests on your behalf. If you don't want to [run your own](https://nymtech.net/operators/nodes/network-requester.md) you can select one from the [mixnet explorer](https://explorer.nymtech.net/network-components/service-providers) by copying its `Client ID` and using this as the value of the `--provider` flag. Alternatively, you could use [this list](https://harbourmaster.nymtech.net/).
Since the nodes on this list are the infrastructure for [Nymconnect](https://nymtech.net/developers/quickstart/nymconnect-gui.html) they will support all apps on the [default whitelist](https://nymtech.net/operators/nodes/network-requester.md#network-requester-whitelist): Keybase, Telegram, Electrum, Blockstream Green, and Helios.
#### Choosing a Gateway
By default - as in the example above - your client will choose a random gateway to connect to.
@@ -1,9 +1,14 @@
# Setup
# Setup
> `nym-socks5-client` now also supports SOCKS4 and SOCKS4A protocols as well as SOCKS5.
The Nym socks5 client allows you to proxy traffic from a desktop application through the mixnet, meaning you can send and receive information from remote application servers without leaking metadata which can be used to deanonymise you, even if you're using an encrypted application such as Signal.
```admonish info
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 this client. If you want to run deprecated NymConnect, visit [NymConnect archive page](../../archive/nym-connect.md) with setup and application examples.
```
## Setup and Run
### Download or compile socks5 client
@@ -38,5 +43,3 @@ Now your client is initialised, start it with the following:
```
./nym-socks5-client run --id <ID>
```
@@ -12,4 +12,6 @@ All of these code examples will do the following:
By varying the message content, you can easily build sophisticated service provider apps. For example, instead of printing the response received from the mixnet, your service provider might take some action on behalf of the user - perhaps initiating a network request, a blockchain transaction, or writing to a local data store.
<!-- THIS PAGE IS NOT WORKING AT THE MOMENT:
> You can find an example of building both frontend and service provider code with the websocket client in the [Simple Service Provider Tutorial](https://nymtech.net/developers/tutorials/simple-service-provider/simple-service-provider.html) in the Developer Portal.
-->
@@ -1,17 +1,17 @@
# Using Your Client
The Nym native client exposes a websocket interface that your code connects to. The **default** websocket port is `1977`, you can override that in the client config if you want.
Once you have a websocket connection, interacting with the client involves piping messages down the socket and listening for incoming messages.
Once you have a websocket connection, interacting with the client involves piping messages down the socket and listening for incoming messages.
# Message Requests
There are a number of message types that you can send up the websocket as defined [here](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/requests.rs):
# Message Requests
There are a number of message types that you can send up the websocket as defined [here](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/requests.rs):
```rust,noplayground
{{#include ../../../../../clients/native/websocket-requests/src/requests.rs:55:97}}
```
## Getting your own address
When you start your app, it is best practice to ask the native client to tell you what your own address is (from the generated configuration files - see [here](https://nymtech.net/docs/architecture/addressing-system.md) for more on Nym's addressing scheme). If you are running a service, you need to do this in order to know what address to give others. In a client-side piece of code you can also use this as a test to make sure your websocket connection is running smoothly. To do this, send:
When you start your app, it is best practice to ask the native client to tell you what your own address is (from the generated configuration files <!--add link -->. If you are running a service, you need to do this in order to know what address to give others. In a client-side piece of code you can also use this as a test to make sure your websocket connection is running smoothly. To do this, send:
```json
{
@@ -28,9 +28,9 @@ You'll receive a response of the format:
}
```
See [here](https://github.com/nymtech/nym/blob/93cc281abc2cc951023b51746fa6f2ead1f56c46/clients/native/examples/python-examples/websocket/textsend.py#L16C9-L16C9) for an example of this being used.
See [here](https://github.com/nymtech/nym/blob/93cc281abc2cc951023b51746fa6f2ead1f56c46/clients/native/examples/python-examples/websocket/textsend.py#L16C9-L16C9) for an example of this being used.
> Note that all the pieces of native client example code begin with printing the selfAddress. Examples exist for Rust, Go, Javascript, and Python.
> Note that all the pieces of native client example code begin with printing the selfAddress. Examples exist for Rust, Go, Javascript, and Python.
## Sending text
If you want to send text information through the mixnet, format a message like this one and poke it into the websocket:
@@ -58,33 +58,33 @@ In some applications, e.g. where people are chatting with friends who they know,
**If that fits your security model, good. However, will probably be the case that you want to send anonymous replies using Single Use Reply Blocks (SURBs)**.
You can read more about SURBs [here](https://nymtech.net/docs/architecture/traffic-flow.md#private-replies-using-surbs) but in short they are ways for the receiver of this message to anonymously reply to you - the sender - **without them having to know your client address**.
You can read more about SURBs [here](https://nymtech.net/docs/architecture/traffic-flow.html#private-replies-using-surbs) but in short they are ways for the receiver of this message to anonymously reply to you - the sender - **without them having to know your client address**.
Your client will send along a number of `replySurbs` to the recipient of the message. These are pre-addressed Sphinx packets that the recipient can write to the payload of (i.e. write response data to), but not view the final destination of. If the recipient is unable to fit the response data into the bucket of SURBs sent to it, it will use a SURB to request more SURBs be sent to it from your client.
```json
{
"type": "sendAnonymous",
"message": "something you want to keep secret",
"recipient": "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm",
"message": "something you want to keep secret",
"recipient": "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm",
"replySurbs": 20 // however many reply SURBs to send along with your message
}
```
See ['Replying to SURB Messages'](#replying-to-surb-messages) below for an example of how to deal with incoming messages that have SURBs attached.
See ['Replying to SURB Messages'](#replying-to-surb-messages) below for an example of how to deal with incoming messages that have SURBs attached.
Deciding on the amount of SURBs to generate and send along with outgoing messages depends on the expected size of the reply. You might want to send a lot of SURBs in order to make sure you get your response as quickly as possible (but accept the minor additional latency when sending, as your client has to generate and encrypt the packets), or you might just send a few (e.g. 20) and then if your response requires more SURBs, send them along, accepting the additional latency in getting your response.
Deciding on the amount of SURBs to generate and send along with outgoing messages depends on the expected size of the reply. You might want to send a lot of SURBs in order to make sure you get your response as quickly as possible (but accept the minor additional latency when sending, as your client has to generate and encrypt the packets), or you might just send a few (e.g. 20) and then if your response requires more SURBs, send them along, accepting the additional latency in getting your response.
## Sending binary data
You can also send bytes instead of JSON. For that you have to send a binary websocket frame containing a binary encoded
Nym [`ClientRequest`](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/requests.rs#L25) containing the same information.
> As a response the `native-client` will send a `ServerResponse` to be decoded. See [Message Responses](#message-responses) below for more.
> As a response the `native-client` will send a `ServerResponse` to be decoded. See [Message Responses](#message-responses) below for more.
You can find examples of sending and receiving binary data in the [code examples](https://github.com/nymtech/nym/tree/master/clients/native/examples), and an example project from the Nym community [BTC-BC](https://github.com/sgeisler/btcbc-rs/): Bitcoin transaction transmission via Nym, a client and service provider written in Rust.
## Replying to SURB messages
Each bucket of `replySURBs`, when received as part of an incoming message, has a unique session identifier, which **only identifies the bucket of pre-addressed packets**. This is necessary to make sure that your app is replying to the correct people with the information meant for them in a situation where multiple clients are sending requests to a single service.
Each bucket of `replySURBs`, when received as part of an incoming message, has a unique session identifier, which **only identifies the bucket of pre-addressed packets**. This is necessary to make sure that your app is replying to the correct people with the information meant for them in a situation where multiple clients are sending requests to a single service.
Constructing a reply with SURBs looks something like this (where `senderTag` was parsed from the incoming message)
@@ -107,9 +107,9 @@ Errors from the app's client, or from the gateway, will be sent down the websock
```
## LaneQueueLength
This is currently only used in the [Socks Client](../socks5-client.md) to keep track of the number of Sphinx packets waiting to be sent to the mixnet via being slotted amongst cover traffic. As this value becomes larger, the client signals to the application it should slow down the speed with which it writes to the proxy. This is to stop situations arising whereby an app connected to the client appears as if it has sent (e.g.) a bunch of messages and is awaiting a reply, when they in fact have not been sent through the mixnet yet.
This is currently only used in the [Socks Client](../socks5-client.md) to keep track of the number of Sphinx packets waiting to be sent to the mixnet via being slotted amongst cover traffic. As this value becomes larger, the client signals to the application it should slow down the speed with which it writes to the proxy. This is to stop situations arising whereby an app connected to the client appears as if it has sent (e.g.) a bunch of messages and is awaiting a reply, when they in fact have not been sent through the mixnet yet.
# Message Responses
# Message Responses
Responses to your messages are defined [here](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/responses.rs):
```rust,noplayground
@@ -1,12 +1,12 @@
# Browser only
With the Typescript SDK you can run a Nym client in a webworker - meaning you can connect to the mixnet through the browser without having to worry about any other code than your web framework.
With the Typescript SDK you can run a Nym client in a webworker - meaning you can connect to the mixnet through the browser without having to worry about any other code than your web framework.
- Oreowallet have integrated `mixFetch` into their browser-extension wallet to run transactions through the mixnet.
- [Codebase](https://github.com/oreoslabs/oreowallet-extension/tree/mixFetch)
- Oreowallet have integrated `mixFetch` into their browser-extension wallet to run transactions through the mixnet.
- [Codebase](https://github.com/oreoslabs/oreowallet-extension/tree/mixFetch)
- [NoTrustVerify](https://notrustverify.ch/) have set up an example application using [`mixFetch`](https://sdk.nymtech.net/examples/mix-fetch) to fetch crypto prices from CoinGecko over the mixnet.
- [Website](https://notrustverify.github.io/mixfetch-examples/)
- [Codebase](https://github.com/notrustverify/mixfetch-examples)
- [NoTrustVerify](https://notrustverify.ch/) have set up an example application using [`mixFetch`](https://sdk.nymtech.net/examples/mix-fetch) to fetch crypto prices from CoinGecko over the mixnet.
- [Website](https://notrustverify.github.io/mixfetch-examples/)
- [Codebase](https://github.com/notrustverify/mixfetch-examples)
- There is a coconut-scheme based Credential Library playground [here](https://coco-demo.nymtech.net/). This is a WASM implementation of our Coconut libraries which generate raw Coconut credentials. Test it to create and re-randomize your own credentials. For more information on what is happening here check out the [Coconut docs](https://nymtech.net/docs/coconut.html).
@@ -1,17 +1,24 @@
# Apps Using Network Requesters
These applications utilise custom app logic in the user-facing apps in order to communicate using the mixnet as a transport layer, without having to rely on custom server-side logic. Instead, they utilise existing Nym infrastructure - [Network Requesters](https://nymtech.net/operators/nodes/network-requester-setup.html) - with a custom whitelist addition.
These applications utilise custom app logic in the user-facing apps in order to communicate using the mixnet as a transport layer, without having to rely on custom server-side logic. Instead, they utilise existing Nym infrastructure - Network Requesters - now embeded in `nym-node` running as `exit-gateway`.
If you are sending 'normal' application traffic, and/or don't require and custom logic to be happening on the 'other side' of the mixnet, this is most likely the best option to take as a developer who wishes to privacy-enhance their application.
> Nym will soon be switching from a whitelist-based approach to a blocklist-based approach to filtering traffic. As such, it will soon be even easier for developers to utilise the mixnet, as they will not have to run their own NRs or have to add their domains to the whitelist
If you are sending 'normal' application traffic, and/or don't require and custom logic to be happening on the 'other side' of the mixnet, this is most likely the best option to take as a developer who wishes to privacy-enhance their application.
> Nym will soon be switching from a whitelist-based approach to a blocklist-based approach to filtering traffic. As such, it will soon be even easier for developers to utilise the mixnet, as they will not have to run their own NRs or have to add their domains to the whitelist
<!-- I DON't THINK THIS WORKS NOW, NEED RESEARCH AND UPGRADE
- DarkFi over Nym leverages Nyms mixnet as a pluggable transport for DarkIRC, their p2p IRC variant. Users can anonymously connect to peers over the network, ensuring secure and private communication within the DarkFi ecosystem. Written in **Rust**.
- [Docs](https://darkrenaissance.github.io/darkfi/clients/nym_outbound.html?highlight=nym#3--run)
- [Github](https://github.com/darkrenaissance/darkfi/tree/master/doc)
-->
- MiniBolt is a complete guide to building a Bitcoin & Lightning full node on a personal computer. It has the capacity to run network traffic (transactions and syncing) over the mixnet, so you can privately sync your node and not expose your home IP to the wider world when interacting with the rest of the network!
- MiniBolt is a complete guide to building a Bitcoin & Lightning full node on a personal computer. It has the capacity to run network traffic (transactions and syncing) over the mixnet, so you can privately sync your node and not expose your home IP to the wider world when interacting with the rest of the network!
- [Docs](https://v2.minibolt.info/bonus-guides/system/nym-mixnet#proxying-bitcoin-core)
- [Codebase](https://github.com/minibolt-guide/minibolt)
- Email over Nym is a set of configuration options to set up a Network Requester to send and recieve emails over Nym, using something like Thunderbird.
- [Codebase](https://github.com/dial0ut/nymstr-email)
- Email over Nym is a set of configuration options to set up a Network Requester to send and recieve emails over Nym, using something like Thunderbird.
- [Codebase](https://github.com/dial0ut/nymstr-email)
+1 -1
View File
@@ -171,7 +171,7 @@ If you want to run NymVPN CLI in Nym Sandbox environment, there are a few adjust
curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env
```
2. Check available Gateways at [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways)
2. Check available Gateways at [Sandbox API](https://sandbox-nym-api1.nymtech.net/api/v1/gateways) or [Sandbox Swagger page](https://sandbox-nym-api1.nymtech.net/api/swagger/index.html)
3. Run with a flag `-c`
```sh
@@ -5,5 +5,4 @@ The following code shows how you can use the SDK to create and use a credential
{{#include ../../../../../../sdk/rust/nym-sdk/examples/bandwidth.rs}}
```
You can read more about Coconut credentials (also referred to as `zk-Nym`) [here](https://nymtech.net/docs/coconut.md).
You can read more about Coconut credentials (also referred to as `zk-Nym`) [here](https://nymtech.net/docs/coconut.html).
@@ -1,7 +1,7 @@
# Anonymous Replies with SURBs (Single Use Reply Blocks)
Both functions used to send messages through the mixnet (`send_message` and `send_plain_message`) send a pre-determined number of SURBs along with their messages by default.
You can read more about how SURBs function under the hood [here](https://nymtech.net/docs/architecture/traffic-flow.md#private-replies-using-surbs).
You can read more about how SURBs function under the hood [here](https://nymtech.net/docs/architecture/traffic-flow.html#private-replies-using-surbs).
In order to reply to an incoming message using SURBs, you can construct a `recipient` from the `sender_tag` sent along with the message you wish to reply to:
+14 -2
View File
@@ -18,8 +18,8 @@ pagetoc = true
sidebar-width = "280px"
content-max-width = "80%"
root-font-size = "70%"
# if you need to change anything in the index.hbs file you need to turn this to `false`, rebuild the book,
# probably remove the additional `comment` that gets appended to the header, and then change this back to `true`.
# if you need to change anything in the index.hbs file you need to turn this to `false`, rebuild the book,
# probably remove the additional `comment` that gets appended to the header, and then change this back to `true`.
# this is because of a bug in the `mdbook-theme` plugin
turn-off = true
@@ -103,3 +103,15 @@ copy-js = true # include Javascript code for search
[output.linkcheck]
warning-policy = "warn"
[output.html.redirect]
"/sdk/rust/examples/socks.html" = "https://nymtech.net/developers/sdk/rust/examples/socks.html"
"/clients/overview.html" = "https://nymtech.net/developers/clients-overview.html"
"/sdk/rust/rust.html" = "https://nymtech.net/developers/sdk/rust/rust.html"
"/clients/socks5-client.html" = "https://nymtech.net/developers/clients/socks5-client.html"
"/clients/webassembly-client.html" = "https://nymtech.net/developers/clients/webassembly-client.html"
"/sdk/typescript.html" = "https://sdk.nymtech.net"
"/clients/websocket-client.html" = "https://nymtech.net/developers/clients/websocket-client.html"
"/use-apps/blockstream-green" = "https://nymtech.net/developers/clients/socks5/usage.html"
"/use-apps/telegram" = "https://nymtech.net/developers/archive/nym-connect.html#telegram-via-nymconnect"
@@ -4,11 +4,12 @@
Nym is the first system we're aware of which provides integrated protection on both the network and transaction level at once. This seamless approach gives the best possible privacy protections, ensuring that nothing falls through the cracks between systems.
The diagram and brief explainer texts below give a high level overview of the difference between Nym and other comparable systems.
The diagram and brief explainer texts below give a high level overview of the difference between Nym and other comparable systems.
> If you want to dig more deeply into the way traffic is packetised and moved through the mixnet, check out the [Mixnet Traffic Flow](https://nymtech.net/docs/architecture/traffic-flow.html) page of the docs.
<img src="../images/nym-vs-animation.gif"/>
> If you want to dig more deeply into the way traffic is packetised and moved through the mixnet, check out the [Mixnet Traffic Flow](https://nymtech.net/docs/architecture/traffic-flow.html) page of the docs.
<!-- IMG DOES NOT EXIST
![](../images/nym-vs-animation.gif)
-->
### Nym vs VPNs
@@ -56,9 +56,9 @@ Quite a bit of stuff gets built. The key working parts are:
* [Nym Node](https://nymtech.net/operators/nodes/nym-node.html): `nym-node`
* [Validator](https://nymtech.net/operators/nodes/validator-setup.html)
* [websocket client](https://nymtech.net/docs/clients/websocket-client.html): `nym-client`
* [socks5 client](https://nymtech.net/docs/clients/socks5-client.html): `nym-socks5-client`
* [webassembly client](https://nymtech.net/docs/clients/webassembly-client.html): `webassembly-client`
* [websocket client](https://nymtech.net/developers/clients/websocket-client.html): `nym-client`
* [socks5 client](https://nymtech.net/developers/clients/socks5-client.html): `nym-socks5-client`
* [webassembly client](https://nymtech.net/developers/clients/webassembly-client.html): `webassembly-client`
* [nym-cli tool](https://nymtech.net/docs/tools/nym-cli.html): `nym-cli`
* [nym-api](https://nymtech.net/operators/nodes/nym-api.html): `nym-api`
* [nymvisor](https://nymtech.net/operators/nodes/nymvisor-upgrade.html): `nymvisor`
@@ -23,7 +23,7 @@ Make sure you do the preparation listed in the [preliminary steps page](initial-
## Gateway setup
Now that you have built the codebase, set up your wallet, and have a VPS with the `nym-gateway` binary, you can set up your gateway with the instructions below.
Now that you have built the codebase, set up your wallet, and have a VPS with the `nym-gateway` binary, you can set up your gateway with the instructions below.
To begin, move to `/target/release` directory from which you run the node commands:
@@ -47,10 +47,10 @@ You can also check the various arguments required for individual commands with:
## Initialising your Gateway
As Nym developers build towards [Exit Gateway](../../legal/exit-gateway.md) functionality, operators can now run their `nym-gateway` binary with inbuilt Network Requester and include the our new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt). Considering the plan to [*smoosh*](../faq/smoosh-faq.md) all the nodes into one binary and have wide opened Exit Gateways, we recommend this setup, instead of operating two separate binaries.
As Nym developers build towards [Exit Gateway](../../legal/exit-gateway.md) functionality, operators can now run their `nym-gateway` binary with inbuilt Network Requester and include the our new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt). Considering the plan to [*smoosh*](../faq/smoosh-faq.md) all the nodes into one binary and have wide opened Exit Gateways, we recommend this setup, instead of operating two separate binaries.
```admonish warning
Before you start an Exit Gateway, read our [Operators Legal Forum](../legal/exit-gateway.md) page and [*Project Smoosh FAQ*](../faq/smoosh-faq.md).
Before you start an Exit Gateway, read our [Operators Legal Forum](../../legal/exit-gateway.md) page and [*Project Smoosh FAQ*](../faq/smoosh-faq.md).
```
```admonish info
@@ -68,9 +68,9 @@ An operator can initialise the Exit Gateway functionality by adding Network Requ
```
You can see that the printed information besides *identity* and *sphinx keys* also includes a long string called *address*. This is the address to be provided to your local [socks5 client](https://nymtech.net/docs/clients/socks5-client.html) as a `--provider` if you wish to connect to your own Exit Gateway.
You can see that the printed information besides *identity* and *sphinx keys* also includes a long string called *address*. This is the address to be provided to your local [socks5 client](https://nymtech.net/docs/clients/socks5-client.html) as a `--provider` if you wish to connect to your own Exit Gateway.
Additionally
Additionally
#### Add Network Requester to an existing Gateway
@@ -83,10 +83,10 @@ See the options:
```
To setup Exit Gateway functionality with our new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) add a flag `--with-exit-policy true`.
To setup Exit Gateway functionality with our new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) add a flag `--with-exit-policy true`.
```
./nym-gateway setup-network-requester --enabled true --with-exit-policy true --id <ID>
./nym-gateway setup-network-requester --enabled true --with-exit-policy true --id <ID>
```
Say we have a Gateway with `<ID>` as `new-gateway`, originally initialised and ran without the Exit Gateway functionality. To change the setup, run:
@@ -156,7 +156,7 @@ The `run` command starts the Gateway:
## Bonding your Gateway
```admonish info
Before you bond your Gateway, please make sure the [firewall configuration](./maintenance.md#configure-your-firewall) is setup so your Gateway can be reached from the outside. You can also setup WSS and automate your Gateway to simplify the operation overhead. We highly recommend to run any of these steps before bonding to prevent disruption of your Gateway's routing score later on.
Before you bond your Gateway, please make sure the [firewall configuration](../../nodes/maintenance.md#configure-your-firewall) is setup so your Gateway can be reached from the outside. You can also setup WSS and automate your Gateway to simplify the operation overhead. We highly recommend to run any of these steps before bonding to prevent disruption of your Gateway's routing score later on.
```
### Via the Desktop wallet (recommended)
@@ -167,7 +167,7 @@ You can bond your Gateway via the Desktop wallet. **Make sure your Gateway is ru
2. Enter the `Amount`, `Operating cost` and press `Next`.
3. You will be asked to run a the `sign` command with your `gateway` - copy and paste the long signature `<PAYLOAD_GENERATED_BY_THE_WALLET>` and paste it as a value of `--contract-msg` in the following command:
3. You will be asked to run a the `sign` command with your `gateway` - copy and paste the long signature `<PAYLOAD_GENERATED_BY_THE_WALLET>` and paste it as a value of `--contract-msg` in the following command:
```
./nym-gateway sign --id <YOUR_ID> --contract-msg <PAYLOAD_GENERATED_BY_THE_WALLET>
@@ -186,7 +186,7 @@ It will look something like this (as `<YOUR_ID>` we used `supergateway`):
|_| |_|\__, |_| |_| |_|
|___/
(nym-gateway - version v1.1.<XX>)
(nym-gateway - version v1.1.<XX>)
>>> attempting to sign 2Mf8xYytgEeyJke9LA7TjhHoGQWNBEfgHZtTyy2krFJfGHSiqy7FLgTnauSkQepCZTqKN5Yfi34JQCuog9k6FGA2EjsdpNGAWHZiuUGDipyJ6UksNKRxnFKhYW7ri4MRduyZwbR98y5fQMLAwHne1Tjm9cXYCn8McfigNt77WAYwBk5bRRKmC34BJMmWcAxphcLES2v9RdSR68tkHSpy2C8STfdmAQs3tZg8bJS5Qa8pQdqx14TnfQAPLk3QYCynfUJvgcQTrg29aqCasceGRpKdQ3Tbn81MLXAGAs7JLBbiMEAhCezAr2kEN8kET1q54zXtKz6znTPgeTZoSbP8rzf4k2JKHZYWrHYF9JriXepuZTnyxAKAxvGFPBk8Z6KAQi33NRQkwd7MPyttatHna6kG9x7knffV6ebGzgRBf7NV27LurH8x4L1uUXwm1v1UYCA1WSBQ9Pp2JW69k5v5v7G9gBy8RUcZnMbeL26Qqb8WkuGcmuHhaFfoqSfV7PRHPpPT4M8uRqUyR4bjUtSJJM1yh6QSeZk9BEazzoJqPeYeGoiFDZ3LMj2jesbJweQR4caaYuRczK92UGSSqu9zBKmE45a
@@ -206,7 +206,7 @@ It will look something like this (as `<YOUR_ID>` we used `supergateway`):
* And paste it into the wallet nodal, press `Next` and confirm the transaction.
![Paste Signature](../../images/wallet-screenshots/wallet-gateway-sign.png)
![Paste Signature](../../images/wallet-screenshots/wallet-gateway-sign.png)
*This image is just an example, copy-paste your own base58-encoded signature.*
* Your Gateway is now bonded.
@@ -220,4 +220,3 @@ If you want to bond your Gateway via the CLI, then check out the [relevant secti
## Maintenance
For Gateway upgrade, firewall setup, port configuration, API endpoints, VPS suggestions, automation, WSS setup and more, see the [maintenance page](../../nodes/maintenance.md)
@@ -56,9 +56,9 @@ Quite a bit of stuff gets built. The key working parts are:
* [Nym Node](../nodes/nym-node.md): `nym-node`
* [Validator](../nodes/validator-setup.md)
* [websocket client](https://nymtech.net/docs/clients/websocket-client.html): `nym-client`
* [socks5 client](https://nymtech.net/docs/clients/socks5-client.html): `nym-socks5-client`
* [webassembly client](https://nymtech.net/docs/clients/webassembly-client.html): `webassembly-client`
* [websocket client](https://nymtech.net/developers/clients/websocket-client.html): `nym-client`
* [socks5 client](https://nymtech.net/developers/clients/socks5-client.html): `nym-socks5-client`
* [webassembly client](https://nymtech.net/developers/clients/webassembly-client.html): `webassembly-client`
* [nym-cli tool](https://nymtech.net/docs/tools/nym-cli.html): `nym-cli`
* [nym-api](../nodes/nym-api.md): `nym-api`
* [nymvisor](../nodes/nymvisor-upgrade.md): `nymvisor`

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