Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1e74de2d67 | |||
| a886715948 | |||
| ebac4e8564 | |||
| da81664729 | |||
| ebfb9c4bc1 | |||
| 8e7918cc45 | |||
| 24ffb8fe8c | |||
| d1bf1f2005 | |||
| c42b3f7617 | |||
| 606144dd87 | |||
| a5bcbcc1f5 | |||
| 31cd62b676 | |||
| 53366c4151 | |||
| 2ca63a6fd5 | |||
| d33baec79b | |||
| 0626e54b6a | |||
| 2a260d46f8 | |||
| 7cb5afdeab | |||
| d18f4c0380 | |||
| c9c4059c90 | |||
| 3fe33dec8b | |||
| 589074360d | |||
| 2e5406692c | |||
| 1920177b2f | |||
| f562433519 | |||
| 2affa76304 | |||
| d6aeb9142f | |||
| 70af84b6b1 | |||
| fc397053c8 | |||
| 3092c8e68e | |||
| 4a1efab5c8 | |||
| a2d57f269d | |||
| 38c4cc3345 | |||
| 06ebe56914 | |||
| 1c3140898f | |||
| 9ebe8310a1 | |||
| cf5c5f1df4 | |||
| f30cfc0be7 | |||
| 9460a9941c | |||
| eeffc0db51 | |||
| b7d6e0e1e3 | |||
| 45e0b406ac |
@@ -104,12 +104,9 @@ jobs:
|
|||||||
name: nym-binaries-artifacts
|
name: nym-binaries-artifacts
|
||||||
path: |
|
path: |
|
||||||
target/release/nym-client
|
target/release/nym-client
|
||||||
target/release/nym-gateway
|
|
||||||
target/release/nym-mixnode
|
|
||||||
target/release/nym-socks5-client
|
target/release/nym-socks5-client
|
||||||
target/release/nym-api
|
target/release/nym-api
|
||||||
target/release/nym-network-requester
|
target/release/nym-network-requester
|
||||||
target/release/nym-network-statistics
|
|
||||||
target/release/nym-cli
|
target/release/nym-cli
|
||||||
target/release/nymvisor
|
target/release/nymvisor
|
||||||
target/release/nym-node
|
target/release/nym-node
|
||||||
@@ -124,12 +121,9 @@ jobs:
|
|||||||
OUTPUT_DIR: ci-builds/${{ github.ref_name }}
|
OUTPUT_DIR: ci-builds/${{ github.ref_name }}
|
||||||
run: |
|
run: |
|
||||||
cp target/release/nym-client $OUTPUT_DIR
|
cp target/release/nym-client $OUTPUT_DIR
|
||||||
cp target/release/nym-gateway $OUTPUT_DIR
|
|
||||||
cp target/release/nym-mixnode $OUTPUT_DIR
|
|
||||||
cp target/release/nym-socks5-client $OUTPUT_DIR
|
cp target/release/nym-socks5-client $OUTPUT_DIR
|
||||||
cp target/release/nym-api $OUTPUT_DIR
|
cp target/release/nym-api $OUTPUT_DIR
|
||||||
cp target/release/nym-network-requester $OUTPUT_DIR
|
cp target/release/nym-network-requester $OUTPUT_DIR
|
||||||
cp target/release/nym-network-statistics $OUTPUT_DIR
|
|
||||||
cp target/release/nymvisor $OUTPUT_DIR
|
cp target/release/nymvisor $OUTPUT_DIR
|
||||||
cp target/release/nym-node $OUTPUT_DIR
|
cp target/release/nym-node $OUTPUT_DIR
|
||||||
cp target/release/nym-cli $OUTPUT_DIR
|
cp target/release/nym-cli $OUTPUT_DIR
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ on:
|
|||||||
- 'clients/**'
|
- 'clients/**'
|
||||||
- 'common/**'
|
- 'common/**'
|
||||||
- 'explorer-api/**'
|
- 'explorer-api/**'
|
||||||
- 'ephemera/**'
|
|
||||||
- 'gateway/**'
|
- 'gateway/**'
|
||||||
- 'integrations/**'
|
- 'integrations/**'
|
||||||
- 'mixnode/**'
|
- 'mixnode/**'
|
||||||
@@ -24,7 +23,6 @@ on:
|
|||||||
- 'clients/**'
|
- 'clients/**'
|
||||||
- 'common/**'
|
- 'common/**'
|
||||||
- 'explorer-api/**'
|
- 'explorer-api/**'
|
||||||
- 'ephemera/**'
|
|
||||||
- 'gateway/**'
|
- 'gateway/**'
|
||||||
- 'integrations/**'
|
- 'integrations/**'
|
||||||
- 'mixnode/**'
|
- 'mixnode/**'
|
||||||
|
|||||||
@@ -27,23 +27,17 @@ jobs:
|
|||||||
release_id: ${{ steps.create-release.outputs.id }}
|
release_id: ${{ steps.create-release.outputs.id }}
|
||||||
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }}
|
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].published_at }}
|
||||||
client_hash: ${{ steps.binary-hashes.outputs.client_hash }}
|
client_hash: ${{ steps.binary-hashes.outputs.client_hash }}
|
||||||
mixnode_hash: ${{ steps.binary-hashes.outputs.mixnode_hash }}
|
|
||||||
gateway_hash: ${{ steps.binary-hashes.outputs.gateway_hash }}
|
|
||||||
nymvisor_hash: ${{ steps.binary-hashes.outputs.nymvisor_hash }}
|
nymvisor_hash: ${{ steps.binary-hashes.outputs.nymvisor_hash }}
|
||||||
nymnode_hash: ${{ steps.binary-hashes.outputs.nymnode_hash }}
|
nymnode_hash: ${{ steps.binary-hashes.outputs.nymnode_hash }}
|
||||||
socks5_hash: ${{ steps.binary-hashes.outputs.socks5_hash }}
|
socks5_hash: ${{ steps.binary-hashes.outputs.socks5_hash }}
|
||||||
netreq_hash: ${{ steps.binary-hashes.outputs.netreq_hash }}
|
netreq_hash: ${{ steps.binary-hashes.outputs.netreq_hash }}
|
||||||
cli_hash: ${{ steps.binary-hashes.outputs.cli_hash }}
|
cli_hash: ${{ steps.binary-hashes.outputs.cli_hash }}
|
||||||
netstat_hash: ${{ steps.binary-hashes.outputs.netstat_hash }}
|
|
||||||
client_version: ${{ steps.binary-versions.outputs.client_version }}
|
client_version: ${{ steps.binary-versions.outputs.client_version }}
|
||||||
mixnode_version: ${{ steps.binary-versions.outputs.mixnode_version }}
|
|
||||||
gateway_version: ${{ steps.binary-versions.outputs.gateway_version }}
|
|
||||||
nymvisor_version: ${{ steps.binary-versions.outputs.nymvisor_version }}
|
nymvisor_version: ${{ steps.binary-versions.outputs.nymvisor_version }}
|
||||||
nymnode_version: ${{ steps.binary-versions.outputs.nymnode_version }}
|
nymnode_version: ${{ steps.binary-versions.outputs.nymnode_version }}
|
||||||
socks5_version: ${{ steps.binary-versions.outputs.socks5_version }}
|
socks5_version: ${{ steps.binary-versions.outputs.socks5_version }}
|
||||||
netreq_version: ${{ steps.binary-versions.outputs.netreq_version }}
|
netreq_version: ${{ steps.binary-versions.outputs.netreq_version }}
|
||||||
cli_version: ${{ steps.binary-versions.outputs.cli_version }}
|
cli_version: ${{ steps.binary-versions.outputs.cli_version }}
|
||||||
netstat_version: ${{ steps.binary-versions.outputs.netstat_version }}
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@@ -75,12 +69,9 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
target/release/explorer-api
|
target/release/explorer-api
|
||||||
target/release/nym-client
|
target/release/nym-client
|
||||||
target/release/nym-gateway
|
|
||||||
target/release/nym-mixnode
|
|
||||||
target/release/nym-socks5-client
|
target/release/nym-socks5-client
|
||||||
target/release/nym-api
|
target/release/nym-api
|
||||||
target/release/nym-network-requester
|
target/release/nym-network-requester
|
||||||
target/release/nym-network-statistics
|
|
||||||
target/release/nym-cli
|
target/release/nym-cli
|
||||||
target/release/nymvisor
|
target/release/nymvisor
|
||||||
target/release/nym-node
|
target/release/nym-node
|
||||||
@@ -94,12 +85,9 @@ jobs:
|
|||||||
files: |
|
files: |
|
||||||
target/release/explorer-api
|
target/release/explorer-api
|
||||||
target/release/nym-client
|
target/release/nym-client
|
||||||
target/release/nym-gateway
|
|
||||||
target/release/nym-mixnode
|
|
||||||
target/release/nym-socks5-client
|
target/release/nym-socks5-client
|
||||||
target/release/nym-api
|
target/release/nym-api
|
||||||
target/release/nym-network-requester
|
target/release/nym-network-requester
|
||||||
target/release/nym-network-statistics
|
|
||||||
target/release/nym-cli
|
target/release/nym-cli
|
||||||
target/release/nymvisor
|
target/release/nymvisor
|
||||||
target/release/nym-node
|
target/release/nym-node
|
||||||
|
|||||||
@@ -4,6 +4,78 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [2024.7-doubledecker] (2024-07-04)
|
||||||
|
|
||||||
|
- Add an early return in `parse_raw_str_logs` for empty raw log strings. ([#4686])
|
||||||
|
- Bump braces from 3.0.2 to 3.0.3 in /wasm/mix-fetch/internal-dev ([#4672])
|
||||||
|
- add expiry returned on import ([#4670])
|
||||||
|
- [bugfix] missing rustls feature ([#4666])
|
||||||
|
- Bump ws from 8.13.0 to 8.17.1 in /wasm/client/internal-dev-node ([#4665])
|
||||||
|
- Bump braces from 3.0.2 to 3.0.3 in /clients/native/examples/js-examples/websocket ([#4663])
|
||||||
|
- Bump ws from 8.14.2 to 8.17.1 in /sdk/typescript/packages/nodejs-client ([#4662])
|
||||||
|
- Update setup.md ([#4661])
|
||||||
|
- New clippy lints ([#4660])
|
||||||
|
- Bump braces from 3.0.2 to 3.0.3 in /nym-api/tests ([#4659])
|
||||||
|
- Bump braces from 3.0.2 to 3.0.3 in /docker/typescript_client/upload_contract ([#4658])
|
||||||
|
- Update vps-setup.md ([#4656])
|
||||||
|
- Update configuration.md ([#4655])
|
||||||
|
- Remove old PR template ([#4639])
|
||||||
|
|
||||||
|
[#4686]: https://github.com/nymtech/nym/pull/4686
|
||||||
|
[#4672]: https://github.com/nymtech/nym/pull/4672
|
||||||
|
[#4670]: https://github.com/nymtech/nym/pull/4670
|
||||||
|
[#4666]: https://github.com/nymtech/nym/pull/4666
|
||||||
|
[#4665]: https://github.com/nymtech/nym/pull/4665
|
||||||
|
[#4663]: https://github.com/nymtech/nym/pull/4663
|
||||||
|
[#4662]: https://github.com/nymtech/nym/pull/4662
|
||||||
|
[#4661]: https://github.com/nymtech/nym/pull/4661
|
||||||
|
[#4660]: https://github.com/nymtech/nym/pull/4660
|
||||||
|
[#4659]: https://github.com/nymtech/nym/pull/4659
|
||||||
|
[#4658]: https://github.com/nymtech/nym/pull/4658
|
||||||
|
[#4656]: https://github.com/nymtech/nym/pull/4656
|
||||||
|
[#4655]: https://github.com/nymtech/nym/pull/4655
|
||||||
|
[#4639]: https://github.com/nymtech/nym/pull/4639
|
||||||
|
|
||||||
|
## [2024.6-chomp] (2024-06-25)
|
||||||
|
|
||||||
|
- Remove additional code as part of Ephemera Purge and SP and contracts ([#4650])
|
||||||
|
- bugfix: make sure nym-api can handle non-cw2 (or without detailed build info) compliant contracts ([#4648])
|
||||||
|
- introduced a flag to accept toc and exposed it via self-described API ([#4647])
|
||||||
|
- bugfix: make sure to return an error on invalid public ip ([#4646])
|
||||||
|
- Add ci check for PR having an assigned milestone ([#4644])
|
||||||
|
- Removed ephemera code ([#4642])
|
||||||
|
- Remove stale peers ([#4640])
|
||||||
|
- Add generic wg private network routing ([#4636])
|
||||||
|
- Feature/new node endpoints ([#4635])
|
||||||
|
- standarised ContractBuildInformation and added it to all contracts ([#4631])
|
||||||
|
- validate nym-node public ips on startup ([#4630])
|
||||||
|
- Bump defguard wg ([#4625])
|
||||||
|
- Fix cargo warnings ([#4624])
|
||||||
|
- Update kernel peers on peer modification ([#4622])
|
||||||
|
- Handle v6 and v7 requests in the IPR, but reply with v6 ([#4620])
|
||||||
|
- fix typo ([#4619])
|
||||||
|
- Update crypto and rand crates ([#4607])
|
||||||
|
- Purge name service and service provider directory contracts ([#4603])
|
||||||
|
|
||||||
|
[#4650]: https://github.com/nymtech/nym/pull/4650
|
||||||
|
[#4648]: https://github.com/nymtech/nym/pull/4648
|
||||||
|
[#4647]: https://github.com/nymtech/nym/pull/4647
|
||||||
|
[#4646]: https://github.com/nymtech/nym/pull/4646
|
||||||
|
[#4644]: https://github.com/nymtech/nym/pull/4644
|
||||||
|
[#4642]: https://github.com/nymtech/nym/pull/4642
|
||||||
|
[#4640]: https://github.com/nymtech/nym/pull/4640
|
||||||
|
[#4636]: https://github.com/nymtech/nym/pull/4636
|
||||||
|
[#4635]: https://github.com/nymtech/nym/pull/4635
|
||||||
|
[#4631]: https://github.com/nymtech/nym/pull/4631
|
||||||
|
[#4630]: https://github.com/nymtech/nym/pull/4630
|
||||||
|
[#4625]: https://github.com/nymtech/nym/pull/4625
|
||||||
|
[#4624]: https://github.com/nymtech/nym/pull/4624
|
||||||
|
[#4622]: https://github.com/nymtech/nym/pull/4622
|
||||||
|
[#4620]: https://github.com/nymtech/nym/pull/4620
|
||||||
|
[#4619]: https://github.com/nymtech/nym/pull/4619
|
||||||
|
[#4607]: https://github.com/nymtech/nym/pull/4607
|
||||||
|
[#4603]: https://github.com/nymtech/nym/pull/4603
|
||||||
|
|
||||||
## [2024.5-ragusa] (2024-05-22)
|
## [2024.5-ragusa] (2024-05-22)
|
||||||
|
|
||||||
- Feature/nym node api location ([#4605])
|
- Feature/nym node api location ([#4605])
|
||||||
|
|||||||
Generated
+8
-8
@@ -2093,7 +2093,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "explorer-api"
|
name = "explorer-api"
|
||||||
version = "1.1.34"
|
version = "1.1.36"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap 4.5.4",
|
"clap 4.5.4",
|
||||||
@@ -3858,7 +3858,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-api"
|
name = "nym-api"
|
||||||
version = "1.1.38"
|
version = "1.1.40"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -4018,7 +4018,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-cli"
|
name = "nym-cli"
|
||||||
version = "1.1.36"
|
version = "1.1.38"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.13.1",
|
"base64 0.13.1",
|
||||||
@@ -4097,7 +4097,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-client"
|
name = "nym-client"
|
||||||
version = "1.1.35"
|
version = "1.1.37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bs58 0.5.1",
|
"bs58 0.5.1",
|
||||||
"clap 4.5.4",
|
"clap 4.5.4",
|
||||||
@@ -4910,7 +4910,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-network-requester"
|
name = "nym-network-requester"
|
||||||
version = "1.1.36"
|
version = "1.1.38"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"addr",
|
"addr",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
@@ -4979,7 +4979,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-node"
|
name = "nym-node"
|
||||||
version = "1.1.2"
|
version = "1.1.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bip39",
|
"bip39",
|
||||||
@@ -5241,7 +5241,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-socks5-client"
|
name = "nym-socks5-client"
|
||||||
version = "1.1.35"
|
version = "1.1.37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bs58 0.5.1",
|
"bs58 0.5.1",
|
||||||
"clap 4.5.4",
|
"clap 4.5.4",
|
||||||
@@ -5767,7 +5767,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nymvisor"
|
name = "nymvisor"
|
||||||
version = "0.1.1"
|
version = "0.1.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-client"
|
name = "nym-client"
|
||||||
version = "1.1.35"
|
version = "1.1.37"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||||
description = "Implementation of the Nym Client"
|
description = "Implementation of the Nym Client"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
+78
-236
@@ -744,6 +744,18 @@
|
|||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/braces": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"fill-range": "^7.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.20.2",
|
"version": "4.20.2",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz",
|
||||||
@@ -862,51 +874,6 @@
|
|||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/chokidar/node_modules/braces": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"fill-range": "^7.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/chokidar/node_modules/fill-range": {
|
|
||||||
"version": "7.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"to-regex-range": "^5.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/chokidar/node_modules/is-number": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.12.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/chokidar/node_modules/to-regex-range": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"is-number": "^7.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/chrome-trace-event": {
|
"node_modules/chrome-trace-event": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz",
|
||||||
@@ -1593,39 +1560,6 @@
|
|||||||
"node": ">=8.6.0"
|
"node": ">=8.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fast-glob/node_modules/braces": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"fill-range": "^7.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fast-glob/node_modules/fill-range": {
|
|
||||||
"version": "7.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"to-regex-range": "^5.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fast-glob/node_modules/is-number": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.12.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fast-glob/node_modules/micromatch": {
|
"node_modules/fast-glob/node_modules/micromatch": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||||
@@ -1639,18 +1573,6 @@
|
|||||||
"node": ">=8.6"
|
"node": ">=8.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fast-glob/node_modules/to-regex-range": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"is-number": "^7.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fast-json-stable-stringify": {
|
"node_modules/fast-json-stable-stringify": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||||
@@ -1683,6 +1605,18 @@
|
|||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fill-range": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"to-regex-range": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/finalhandler": {
|
"node_modules/finalhandler": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
|
||||||
@@ -2137,39 +2071,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/http-proxy-middleware/node_modules/braces": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"fill-range": "^7.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/http-proxy-middleware/node_modules/fill-range": {
|
|
||||||
"version": "7.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"to-regex-range": "^5.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/http-proxy-middleware/node_modules/is-number": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.12.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/http-proxy-middleware/node_modules/micromatch": {
|
"node_modules/http-proxy-middleware/node_modules/micromatch": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||||
@@ -2183,18 +2084,6 @@
|
|||||||
"node": ">=8.6"
|
"node": ">=8.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/http-proxy-middleware/node_modules/to-regex-range": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"is-number": "^7.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/human-signals": {
|
"node_modules/human-signals": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||||
@@ -2361,6 +2250,15 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-number": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-path-cwd": {
|
"node_modules/is-path-cwd": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
|
||||||
@@ -3853,6 +3751,18 @@
|
|||||||
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
|
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/to-regex-range": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-number": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/toidentifier": {
|
"node_modules/toidentifier": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
@@ -5213,6 +5123,15 @@
|
|||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"braces": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fill-range": "^7.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"version": "4.20.2",
|
"version": "4.20.2",
|
||||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz",
|
||||||
@@ -5283,41 +5202,6 @@
|
|||||||
"is-glob": "~4.0.1",
|
"is-glob": "~4.0.1",
|
||||||
"normalize-path": "~3.0.0",
|
"normalize-path": "~3.0.0",
|
||||||
"readdirp": "~3.6.0"
|
"readdirp": "~3.6.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"braces": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"fill-range": "^7.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fill-range": {
|
|
||||||
"version": "7.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"to-regex-range": "^5.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-number": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"to-regex-range": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"is-number": "^7.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chrome-trace-event": {
|
"chrome-trace-event": {
|
||||||
@@ -5852,30 +5736,6 @@
|
|||||||
"micromatch": "^4.0.4"
|
"micromatch": "^4.0.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"braces": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"fill-range": "^7.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fill-range": {
|
|
||||||
"version": "7.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"to-regex-range": "^5.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-number": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"micromatch": {
|
"micromatch": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||||
@@ -5885,15 +5745,6 @@
|
|||||||
"braces": "^3.0.1",
|
"braces": "^3.0.1",
|
||||||
"picomatch": "^2.2.3"
|
"picomatch": "^2.2.3"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"to-regex-range": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"is-number": "^7.0.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -5926,6 +5777,15 @@
|
|||||||
"websocket-driver": ">=0.5.1"
|
"websocket-driver": ">=0.5.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fill-range": {
|
||||||
|
"version": "7.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||||
|
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"to-regex-range": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"finalhandler": {
|
"finalhandler": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
|
||||||
@@ -6247,30 +6107,6 @@
|
|||||||
"micromatch": "^4.0.2"
|
"micromatch": "^4.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"braces": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"fill-range": "^7.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fill-range": {
|
|
||||||
"version": "7.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
|
||||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"to-regex-range": "^5.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"is-number": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"micromatch": {
|
"micromatch": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
|
||||||
@@ -6280,15 +6116,6 @@
|
|||||||
"braces": "^3.0.1",
|
"braces": "^3.0.1",
|
||||||
"picomatch": "^2.2.3"
|
"picomatch": "^2.2.3"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"to-regex-range": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"is-number": "^7.0.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -6407,6 +6234,12 @@
|
|||||||
"is-extglob": "^2.1.1"
|
"is-extglob": "^2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"is-number": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"is-path-cwd": {
|
"is-path-cwd": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
|
||||||
@@ -7524,6 +7357,15 @@
|
|||||||
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
|
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"to-regex-range": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-number": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"toidentifier": {
|
"toidentifier": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ impl From<Init> for OverrideConfig {
|
|||||||
fn from(init_config: Init) -> Self {
|
fn from(init_config: Init) -> Self {
|
||||||
OverrideConfig {
|
OverrideConfig {
|
||||||
nym_apis: init_config.common_args.nym_apis,
|
nym_apis: init_config.common_args.nym_apis,
|
||||||
|
fronting_domains: init_config.common_args.fronting_domains,
|
||||||
disable_socket: init_config.disable_socket,
|
disable_socket: init_config.disable_socket,
|
||||||
port: init_config.port,
|
port: init_config.port,
|
||||||
host: init_config.host,
|
host: init_config.host,
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ pub(crate) enum Commands {
|
|||||||
// Configuration that can be overridden.
|
// Configuration that can be overridden.
|
||||||
pub(crate) struct OverrideConfig {
|
pub(crate) struct OverrideConfig {
|
||||||
nym_apis: Option<Vec<url::Url>>,
|
nym_apis: Option<Vec<url::Url>>,
|
||||||
|
fronting_domains: Option<Vec<url::Url>>,
|
||||||
disable_socket: Option<bool>,
|
disable_socket: Option<bool>,
|
||||||
port: Option<u16>,
|
port: Option<u16>,
|
||||||
host: Option<IpAddr>,
|
host: Option<IpAddr>,
|
||||||
@@ -133,6 +134,10 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
|||||||
.with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover)
|
.with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover)
|
||||||
.with_optional(Config::with_port, args.port)
|
.with_optional(Config::with_port, args.port)
|
||||||
.with_optional(Config::with_host, args.host)
|
.with_optional(Config::with_host, args.host)
|
||||||
|
.with_optional_ext(
|
||||||
|
BaseClientConfig::with_fronting_domains,
|
||||||
|
args.fronting_domains,
|
||||||
|
)
|
||||||
.with_optional_custom_env_ext(
|
.with_optional_custom_env_ext(
|
||||||
BaseClientConfig::with_custom_nym_apis,
|
BaseClientConfig::with_custom_nym_apis,
|
||||||
args.nym_apis,
|
args.nym_apis,
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ impl From<Run> for OverrideConfig {
|
|||||||
fn from(run_config: Run) -> Self {
|
fn from(run_config: Run) -> Self {
|
||||||
OverrideConfig {
|
OverrideConfig {
|
||||||
nym_apis: run_config.common_args.nym_apis,
|
nym_apis: run_config.common_args.nym_apis,
|
||||||
|
fronting_domains: run_config.common_args.fronting_domains,
|
||||||
disable_socket: run_config.disable_socket,
|
disable_socket: run_config.disable_socket,
|
||||||
port: run_config.port,
|
port: run_config.port,
|
||||||
host: run_config.host,
|
host: run_config.host,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-socks5-client"
|
name = "nym-socks5-client"
|
||||||
version = "1.1.35"
|
version = "1.1.37"
|
||||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|||||||
@@ -117,6 +117,11 @@ impl Config {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_fronting_domains(mut self, fronting_domains: Vec<Url>) -> Self {
|
||||||
|
self.client.fronting_domains = Some(fronting_domains);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_custom_nym_apis(&mut self, nym_api_urls: Vec<Url>) {
|
pub fn set_custom_nym_apis(&mut self, nym_api_urls: Vec<Url>) {
|
||||||
self.client.nym_api_urls = nym_api_urls;
|
self.client.nym_api_urls = nym_api_urls;
|
||||||
}
|
}
|
||||||
@@ -289,6 +294,10 @@ impl Config {
|
|||||||
pub fn get_nym_api_endpoints(&self) -> Vec<Url> {
|
pub fn get_nym_api_endpoints(&self) -> Vec<Url> {
|
||||||
self.client.nym_api_urls.clone()
|
self.client.nym_api_urls.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_fronting_domains(&self) -> Option<Vec<Url>> {
|
||||||
|
self.client.fronting_domains.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
|
||||||
@@ -314,6 +323,9 @@ pub struct Client {
|
|||||||
/// Addresses to APIs running on validator from which the client gets the view of the network.
|
/// Addresses to APIs running on validator from which the client gets the view of the network.
|
||||||
#[serde(alias = "validator_api_urls")]
|
#[serde(alias = "validator_api_urls")]
|
||||||
pub nym_api_urls: Vec<Url>,
|
pub nym_api_urls: Vec<Url>,
|
||||||
|
|
||||||
|
/// Domain to use for domain fronting censorship circumvention
|
||||||
|
pub fronting_domains: Option<Vec<Url>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
@@ -340,6 +352,7 @@ impl Client {
|
|||||||
disabled_credentials_mode: true,
|
disabled_credentials_mode: true,
|
||||||
nyxd_urls,
|
nyxd_urls,
|
||||||
nym_api_urls,
|
nym_api_urls,
|
||||||
|
fronting_domains: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,6 +362,7 @@ impl Client {
|
|||||||
disabled_credentials_mode: bool,
|
disabled_credentials_mode: bool,
|
||||||
nyxd_urls: Vec<Url>,
|
nyxd_urls: Vec<Url>,
|
||||||
nym_api_urls: Vec<Url>,
|
nym_api_urls: Vec<Url>,
|
||||||
|
fronting_domains: Option<Vec<Url>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Client {
|
Client {
|
||||||
version: version.into(),
|
version: version.into(),
|
||||||
@@ -356,6 +370,7 @@ impl Client {
|
|||||||
disabled_credentials_mode,
|
disabled_credentials_mode,
|
||||||
nyxd_urls,
|
nyxd_urls,
|
||||||
nym_api_urls,
|
nym_api_urls,
|
||||||
|
fronting_domains,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ impl From<ConfigV5> for Config {
|
|||||||
id: value.client.id,
|
id: value.client.id,
|
||||||
disabled_credentials_mode: value.client.disabled_credentials_mode,
|
disabled_credentials_mode: value.client.disabled_credentials_mode,
|
||||||
nyxd_urls: value.client.nyxd_urls,
|
nyxd_urls: value.client.nyxd_urls,
|
||||||
|
fronting_domains: None, //SW need proper migrations if it gets applied
|
||||||
nym_api_urls: value.client.nym_api_urls,
|
nym_api_urls: value.client.nym_api_urls,
|
||||||
},
|
},
|
||||||
debug: DebugConfig {
|
debug: DebugConfig {
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ where
|
|||||||
hardcoded_topology.get_gateways()
|
hardcoded_topology.get_gateways()
|
||||||
} else {
|
} else {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await?
|
crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls, None).await?
|
||||||
};
|
};
|
||||||
|
|
||||||
// since we're registering with a brand new gateway,
|
// since we're registering with a brand new gateway,
|
||||||
|
|||||||
@@ -70,6 +70,13 @@ pub struct CommonClientInitArgs {
|
|||||||
)]
|
)]
|
||||||
pub nym_apis: Option<Vec<url::Url>>,
|
pub nym_apis: Option<Vec<url::Url>>,
|
||||||
|
|
||||||
|
///Comma separated list of urls to use for domain fronting
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "cli",
|
||||||
|
clap(long, value_delimiter = ',', requires = "nym_apis", hide = true)
|
||||||
|
)]
|
||||||
|
pub fronting_domains: Option<Vec<url::Url>>,
|
||||||
|
|
||||||
/// Path to .json file containing custom network specification.
|
/// Path to .json file containing custom network specification.
|
||||||
#[cfg_attr(feature = "cli", clap(long, group = "network", hide = true))]
|
#[cfg_attr(feature = "cli", clap(long, group = "network", hide = true))]
|
||||||
pub custom_mixnet: Option<PathBuf>,
|
pub custom_mixnet: Option<PathBuf>,
|
||||||
@@ -144,6 +151,16 @@ where
|
|||||||
.collect::<Vec<&str>>()
|
.collect::<Vec<&str>>()
|
||||||
.join(",")
|
.join(",")
|
||||||
);
|
);
|
||||||
|
if let Some(fronting_domains) = &core.client.fronting_domains {
|
||||||
|
log::info!(
|
||||||
|
"fronted by : {}",
|
||||||
|
fronting_domains
|
||||||
|
.iter()
|
||||||
|
.map(|url| url.host_str().unwrap_or_default())
|
||||||
|
.collect::<Vec<&str>>()
|
||||||
|
.join(",")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let key_store = OnDiskKeys::new(paths.keys.clone());
|
let key_store = OnDiskKeys::new(paths.keys.clone());
|
||||||
let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?;
|
let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?;
|
||||||
@@ -163,7 +180,12 @@ where
|
|||||||
hardcoded_topology.get_gateways()
|
hardcoded_topology.get_gateways()
|
||||||
} else {
|
} else {
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await?
|
crate::init::helpers::current_gateways(
|
||||||
|
&mut rng,
|
||||||
|
&core.client.nym_api_urls,
|
||||||
|
core.client.fronting_domains.as_ref(),
|
||||||
|
)
|
||||||
|
.await?
|
||||||
};
|
};
|
||||||
|
|
||||||
let gateway_setup = GatewaySetup::New {
|
let gateway_setup = GatewaySetup::New {
|
||||||
|
|||||||
@@ -35,6 +35,13 @@ pub struct CommonClientRunArgs {
|
|||||||
)]
|
)]
|
||||||
pub nym_apis: Option<Vec<url::Url>>,
|
pub nym_apis: Option<Vec<url::Url>>,
|
||||||
|
|
||||||
|
///Comma separated list of urls to use for domain fronting
|
||||||
|
#[cfg_attr(
|
||||||
|
feature = "cli",
|
||||||
|
clap(long, value_delimiter = ',', requires = "nym_apis", hide = true)
|
||||||
|
)]
|
||||||
|
pub fronting_domains: Option<Vec<url::Url>>,
|
||||||
|
|
||||||
/// Path to .json file containing custom network specification.
|
/// Path to .json file containing custom network specification.
|
||||||
#[cfg_attr(feature = "cli", clap(long, group = "network", hide = true))]
|
#[cfg_attr(feature = "cli", clap(long, group = "network", hide = true))]
|
||||||
pub custom_mixnet: Option<PathBuf>,
|
pub custom_mixnet: Option<PathBuf>,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
use super::packet_statistics_control::PacketStatisticsReporter;
|
use super::packet_statistics_control::PacketStatisticsReporter;
|
||||||
use super::received_buffer::ReceivedBufferMessage;
|
use super::received_buffer::ReceivedBufferMessage;
|
||||||
|
use super::topology_control::fronted_api_provider::FrontedApiTopologyProvider;
|
||||||
use super::topology_control::geo_aware_provider::GeoAwareTopologyProvider;
|
use super::topology_control::geo_aware_provider::GeoAwareTopologyProvider;
|
||||||
use crate::client::base_client::storage::helpers::store_client_keys;
|
use crate::client::base_client::storage::helpers::store_client_keys;
|
||||||
use crate::client::base_client::storage::MixnetClientStorage;
|
use crate::client::base_client::storage::MixnetClientStorage;
|
||||||
@@ -467,17 +468,29 @@ where
|
|||||||
custom_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
|
custom_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
|
||||||
config_topology: config::Topology,
|
config_topology: config::Topology,
|
||||||
nym_api_urls: Vec<Url>,
|
nym_api_urls: Vec<Url>,
|
||||||
|
fronting_domains: Option<Vec<Url>>,
|
||||||
) -> Box<dyn TopologyProvider + Send + Sync> {
|
) -> Box<dyn TopologyProvider + Send + Sync> {
|
||||||
// if no custom provider was ... provided ..., create one using nym-api
|
// if no custom provider was ... provided ..., create one using nym-api
|
||||||
custom_provider.unwrap_or_else(|| match config_topology.topology_structure {
|
custom_provider.unwrap_or_else(|| match config_topology.topology_structure {
|
||||||
config::TopologyStructure::NymApi => Box::new(NymApiTopologyProvider::new(
|
config::TopologyStructure::NymApi => match fronting_domains {
|
||||||
nym_api_provider::Config {
|
Some(domains) => Box::new(FrontedApiTopologyProvider::new(
|
||||||
min_mixnode_performance: config_topology.minimum_mixnode_performance,
|
nym_api_provider::Config {
|
||||||
min_gateway_performance: config_topology.minimum_gateway_performance,
|
min_mixnode_performance: config_topology.minimum_mixnode_performance,
|
||||||
},
|
min_gateway_performance: config_topology.minimum_gateway_performance,
|
||||||
nym_api_urls,
|
},
|
||||||
env!("CARGO_PKG_VERSION").to_string(),
|
nym_api_urls,
|
||||||
)),
|
domains,
|
||||||
|
env!("CARGO_PKG_VERSION").to_string(),
|
||||||
|
)),
|
||||||
|
None => Box::new(NymApiTopologyProvider::new(
|
||||||
|
nym_api_provider::Config {
|
||||||
|
min_mixnode_performance: config_topology.minimum_mixnode_performance,
|
||||||
|
min_gateway_performance: config_topology.minimum_gateway_performance,
|
||||||
|
},
|
||||||
|
nym_api_urls,
|
||||||
|
env!("CARGO_PKG_VERSION").to_string(),
|
||||||
|
)),
|
||||||
|
},
|
||||||
config::TopologyStructure::GeoAware(group_by) => {
|
config::TopologyStructure::GeoAware(group_by) => {
|
||||||
Box::new(GeoAwareTopologyProvider::new(
|
Box::new(GeoAwareTopologyProvider::new(
|
||||||
nym_api_urls,
|
nym_api_urls,
|
||||||
@@ -689,6 +702,7 @@ where
|
|||||||
self.custom_topology_provider.take(),
|
self.custom_topology_provider.take(),
|
||||||
self.config.debug.topology,
|
self.config.debug.topology,
|
||||||
self.config.get_nym_api_endpoints(),
|
self.config.get_nym_api_endpoints(),
|
||||||
|
self.config.get_fronting_domains(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// needs to be started as the first thing to block if required waiting for the gateway
|
// needs to be started as the first thing to block if required waiting for the gateway
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use log::{debug, error, warn};
|
||||||
|
use nym_topology::provider_trait::TopologyProvider;
|
||||||
|
use nym_topology::{NymTopology, NymTopologyError};
|
||||||
|
use rand::prelude::SliceRandom;
|
||||||
|
use rand::thread_rng;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
use super::nym_api_provider::Config;
|
||||||
|
|
||||||
|
pub(crate) struct FrontedApiTopologyProvider {
|
||||||
|
config: Config,
|
||||||
|
|
||||||
|
validator_client: nym_validator_client::client::NymApiClient,
|
||||||
|
nym_api_urls: Vec<Url>,
|
||||||
|
fronting_domains: Vec<Url>,
|
||||||
|
shuffling: Vec<usize>,
|
||||||
|
|
||||||
|
client_version: String,
|
||||||
|
currently_used_api: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FrontedApiTopologyProvider {
|
||||||
|
pub(crate) fn new(
|
||||||
|
config: Config,
|
||||||
|
nym_api_urls: Vec<Url>,
|
||||||
|
fronting_domains: Vec<Url>,
|
||||||
|
client_version: String,
|
||||||
|
) -> Self {
|
||||||
|
//SW for the PoC, we assume same lenght between fronting domains and api_urls
|
||||||
|
let mut shuffling = (0..nym_api_urls.len()).collect::<Vec<_>>();
|
||||||
|
shuffling.shuffle(&mut thread_rng());
|
||||||
|
|
||||||
|
FrontedApiTopologyProvider {
|
||||||
|
config,
|
||||||
|
validator_client: nym_validator_client::client::NymApiClient::new_fronted(
|
||||||
|
nym_api_urls[shuffling[0]].clone(),
|
||||||
|
fronting_domains[shuffling[0]].clone(),
|
||||||
|
),
|
||||||
|
nym_api_urls,
|
||||||
|
fronting_domains,
|
||||||
|
shuffling,
|
||||||
|
client_version,
|
||||||
|
currently_used_api: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn use_next_nym_api(&mut self) {
|
||||||
|
if self.nym_api_urls.len() == 1 {
|
||||||
|
warn!("There's only a single nym API available - it won't be possible to use a different one");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.currently_used_api = (self.currently_used_api + 1) % self.nym_api_urls.len();
|
||||||
|
self.validator_client.change_nym_api_with_fronting(
|
||||||
|
self.nym_api_urls[self.shuffling[self.currently_used_api]].clone(),
|
||||||
|
self.fronting_domains[self.shuffling[self.currently_used_api]].clone(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Verifies whether nodes a reasonably distributed among all mix layers.
|
||||||
|
///
|
||||||
|
/// In ideal world we would have 33% nodes on layer 1, 33% on layer 2 and 33% on layer 3.
|
||||||
|
/// However, this is a rather unrealistic expectation, instead we check whether there exists
|
||||||
|
/// a layer with more than 66% of nodes or with fewer than 15% and if so, we trigger a failure.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
///
|
||||||
|
/// * `topology`: active topology constructed from validator api data
|
||||||
|
fn check_layer_distribution(
|
||||||
|
&self,
|
||||||
|
active_topology: &NymTopology,
|
||||||
|
) -> Result<(), NymTopologyError> {
|
||||||
|
let lower_threshold = 0.15;
|
||||||
|
let upper_threshold = 0.66;
|
||||||
|
active_topology.ensure_even_layer_distribution(lower_threshold, upper_threshold)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_current_compatible_topology(&mut self) -> Option<NymTopology> {
|
||||||
|
let mixnodes = match self
|
||||||
|
.validator_client
|
||||||
|
.get_basic_mixnodes(Some(self.client_version.clone()))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Err(err) => {
|
||||||
|
error!("failed to get network mixnodes - {err}");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Ok(mixes) => mixes,
|
||||||
|
};
|
||||||
|
|
||||||
|
let gateways = match self
|
||||||
|
.validator_client
|
||||||
|
.get_basic_gateways(Some(self.client_version.clone()))
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Err(err) => {
|
||||||
|
error!("failed to get network gateways - {err}");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Ok(gateways) => gateways,
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"there are {} mixnodes and {} gateways in total (before performance filtering)",
|
||||||
|
mixnodes.len(),
|
||||||
|
gateways.len()
|
||||||
|
);
|
||||||
|
|
||||||
|
let topology = NymTopology::from_unordered(
|
||||||
|
mixnodes.iter().filter(|m| {
|
||||||
|
m.performance.round_to_integer() >= self.config.min_mixnode_performance
|
||||||
|
}),
|
||||||
|
gateways.iter().filter(|g| {
|
||||||
|
g.performance.round_to_integer() >= self.config.min_gateway_performance
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Err(err) = self.check_layer_distribution(&topology) {
|
||||||
|
warn!("The current filtered active topology has extremely skewed layer distribution. It cannot be used: {err}");
|
||||||
|
self.use_next_nym_api();
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(topology)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// hehe, wasm
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
#[async_trait]
|
||||||
|
impl TopologyProvider for FrontedApiTopologyProvider {
|
||||||
|
async fn get_new_topology(&mut self) -> Option<NymTopology> {
|
||||||
|
self.get_current_compatible_topology().await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
#[async_trait(?Send)]
|
||||||
|
impl TopologyProvider for FrontedApiTopologyProvider {
|
||||||
|
async fn get_new_topology(&mut self) -> Option<NymTopology> {
|
||||||
|
self.get_current_compatible_topology().await
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ use tokio::time::sleep;
|
|||||||
use wasmtimer::tokio::sleep;
|
use wasmtimer::tokio::sleep;
|
||||||
|
|
||||||
mod accessor;
|
mod accessor;
|
||||||
|
pub(crate) mod fronted_api_provider;
|
||||||
pub mod geo_aware_provider;
|
pub mod geo_aware_provider;
|
||||||
pub(crate) mod nym_api_provider;
|
pub(crate) mod nym_api_provider;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use nym_crypto::asymmetric::identity;
|
|||||||
use nym_gateway_client::GatewayClient;
|
use nym_gateway_client::GatewayClient;
|
||||||
use nym_topology::{filter::VersionFilterable, gateway, mix};
|
use nym_topology::{filter::VersionFilterable, gateway, mix};
|
||||||
use nym_validator_client::client::IdentityKeyRef;
|
use nym_validator_client::client::IdentityKeyRef;
|
||||||
|
use rand::seq::IteratorRandom;
|
||||||
use rand::{seq::SliceRandom, Rng};
|
use rand::{seq::SliceRandom, Rng};
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
use tungstenite::Message;
|
use tungstenite::Message;
|
||||||
@@ -59,13 +60,29 @@ impl<'a> GatewayWithLatency<'a> {
|
|||||||
pub async fn current_gateways<R: Rng>(
|
pub async fn current_gateways<R: Rng>(
|
||||||
rng: &mut R,
|
rng: &mut R,
|
||||||
nym_apis: &[Url],
|
nym_apis: &[Url],
|
||||||
|
fronting_domains: Option<&Vec<Url>>,
|
||||||
) -> Result<Vec<gateway::Node>, ClientCoreError> {
|
) -> Result<Vec<gateway::Node>, ClientCoreError> {
|
||||||
let nym_api = nym_apis
|
let client = match fronting_domains {
|
||||||
.choose(rng)
|
Some(domains) => {
|
||||||
.ok_or(ClientCoreError::ListOfNymApisIsEmpty)?;
|
let (api_url, fronting_url) = nym_apis
|
||||||
let client = nym_validator_client::client::NymApiClient::new(nym_api.clone());
|
.iter()
|
||||||
|
.zip(domains)
|
||||||
|
.choose(rng)
|
||||||
|
.ok_or(ClientCoreError::ListOfNymApisIsEmpty)?;
|
||||||
|
|
||||||
log::debug!("Fetching list of gateways from: {nym_api}");
|
nym_validator_client::client::NymApiClient::new_fronted(
|
||||||
|
api_url.clone(),
|
||||||
|
fronting_url.clone(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let nym_api = nym_apis
|
||||||
|
.choose(rng)
|
||||||
|
.ok_or(ClientCoreError::ListOfNymApisIsEmpty)?;
|
||||||
|
nym_validator_client::client::NymApiClient::new(nym_api.clone())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
log::debug!("Fetching list of gateways from: {}", client.api_url());
|
||||||
|
|
||||||
let gateways = client.get_cached_described_gateways().await?;
|
let gateways = client.get_cached_described_gateways().await?;
|
||||||
log::debug!("Found {} gateways", gateways.len());
|
log::debug!("Found {} gateways", gateways.len());
|
||||||
|
|||||||
@@ -258,6 +258,12 @@ impl NymApiClient {
|
|||||||
NymApiClient { nym_api }
|
NymApiClient { nym_api }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_fronted(api_url: Url, fronting_url: Url) -> Self {
|
||||||
|
let nym_api = nym_api::Client::new_fronted(api_url, fronting_url, None);
|
||||||
|
|
||||||
|
NymApiClient { nym_api }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn api_url(&self) -> &Url {
|
pub fn api_url(&self) -> &Url {
|
||||||
self.nym_api.current_url()
|
self.nym_api.current_url()
|
||||||
}
|
}
|
||||||
@@ -266,6 +272,15 @@ impl NymApiClient {
|
|||||||
self.nym_api.change_base_url(new_endpoint);
|
self.nym_api.change_base_url(new_endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn change_nym_api_with_fronting(
|
||||||
|
&mut self,
|
||||||
|
new_api_endpoint: Url,
|
||||||
|
new_fronting_domain: Url,
|
||||||
|
) {
|
||||||
|
self.nym_api
|
||||||
|
.change_fronted_url(new_api_endpoint, new_fronting_domain);
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn get_basic_mixnodes(
|
pub async fn get_basic_mixnodes(
|
||||||
&self,
|
&self,
|
||||||
semver_compatibility: Option<String>,
|
semver_compatibility: Option<String>,
|
||||||
|
|||||||
@@ -9,16 +9,12 @@ pub use nym_coconut_bandwidth_contract_common::event_attributes::*;
|
|||||||
pub use nym_coconut_dkg_common::event_attributes::*;
|
pub use nym_coconut_dkg_common::event_attributes::*;
|
||||||
|
|
||||||
// it seems that currently validators just emit stringified events (which are also returned as part of deliverTx response)
|
// it seems that currently validators just emit stringified events (which are also returned as part of deliverTx response)
|
||||||
// as theirs logs
|
// as their logs
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Log {
|
pub struct Log {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
// weird thing is that the first msg_index seems to always be undefined on the raw logs
|
// weird thing is that the first msg_index seems to always be undefined on the raw logs
|
||||||
pub msg_index: usize,
|
pub msg_index: usize,
|
||||||
// unless I'm missing something obvious, the "log" type in cosmjs is always an empty string
|
|
||||||
// and launchpad cosmos validator was setting it to what essentially is just the raw version of what
|
|
||||||
// we received (and we don't care about launchpad, we, as the time of writing this, work on the stargate)
|
|
||||||
// log: String,
|
|
||||||
pub events: Vec<cosmwasm_std::Event>,
|
pub events: Vec<cosmwasm_std::Event>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,8 +33,12 @@ pub fn find_attribute<'a>(
|
|||||||
.find(|attr| attr.key == attribute_key)
|
.find(|attr| attr.key == attribute_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// those two functions were separated so that the internal logic could actually be tested
|
// these two functions were separated so that the internal logic could actually be tested
|
||||||
fn parse_raw_str_logs(raw: &str) -> Result<Vec<Log>, NyxdError> {
|
fn parse_raw_str_logs(raw: &str) -> Result<Vec<Log>, NyxdError> {
|
||||||
|
if raw.is_empty() {
|
||||||
|
return Ok(Vec::new());
|
||||||
|
}
|
||||||
|
|
||||||
let logs: Vec<Log> = serde_json::from_str(raw).map_err(|_| NyxdError::MalformedLogString)?;
|
let logs: Vec<Log> = serde_json::from_str(raw).map_err(|_| NyxdError::MalformedLogString)?;
|
||||||
if logs.len() != logs.iter().unique_by(|log| log.msg_index).count() {
|
if logs.len() != logs.iter().unique_by(|log| log.msg_index).count() {
|
||||||
// this check is only here because I don't yet fully understand raw log string generation and
|
// this check is only here because I don't yet fully understand raw log string generation and
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use http::header;
|
||||||
use reqwest::header::HeaderValue;
|
use reqwest::header::HeaderValue;
|
||||||
use reqwest::{RequestBuilder, Response, StatusCode};
|
use reqwest::{RequestBuilder, Response, StatusCode};
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
@@ -96,6 +97,13 @@ impl ClientBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_host_header(mut self, host: &str) -> Self {
|
||||||
|
let mut headers = header::HeaderMap::new();
|
||||||
|
headers.insert(header::HOST, HeaderValue::from_str(host).unwrap()); //SW Handle this unwrap later
|
||||||
|
self.reqwest_client_builder = self.reqwest_client_builder.default_headers(headers);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn with_user_agent<V>(mut self, value: V) -> Self
|
pub fn with_user_agent<V>(mut self, value: V) -> Self
|
||||||
where
|
where
|
||||||
V: TryInto<HeaderValue>,
|
V: TryInto<HeaderValue>,
|
||||||
@@ -155,6 +163,23 @@ impl Client {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_fronted(base_url: Url, fronting_url: Url, timeout: Option<Duration>) -> Self {
|
||||||
|
let host = base_url.host_str().unwrap();
|
||||||
|
let mut fronted_url = base_url.clone();
|
||||||
|
fronted_url.set_host(fronting_url.host_str()).unwrap();
|
||||||
|
let builder = ClientBuilder::new::<_, String>(fronted_url)
|
||||||
|
.expect(
|
||||||
|
"we provided valid url and we were unwrapping previous construction errors anyway",
|
||||||
|
)
|
||||||
|
.with_host_header(host);
|
||||||
|
|
||||||
|
//SW polish that later if needed
|
||||||
|
match timeout {
|
||||||
|
Some(timeout) => builder.with_timeout(timeout).build::<String>().unwrap(),
|
||||||
|
None => builder.build::<String>().unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new_url<U, E>(url: U, timeout: Option<Duration>) -> Result<Self, HttpClientError<E>>
|
pub fn new_url<U, E>(url: U, timeout: Option<Duration>) -> Result<Self, HttpClientError<E>>
|
||||||
where
|
where
|
||||||
U: IntoUrl,
|
U: IntoUrl,
|
||||||
@@ -179,6 +204,21 @@ impl Client {
|
|||||||
self.base_url = new_url
|
self.base_url = new_url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn change_fronted_url(&mut self, new_api_url: Url, new_fronting_url: Url) {
|
||||||
|
let host = new_api_url.host_str().unwrap();
|
||||||
|
let mut new_fronted_url = new_api_url.clone();
|
||||||
|
new_fronted_url
|
||||||
|
.set_host(new_fronting_url.host_str())
|
||||||
|
.unwrap();
|
||||||
|
let mut headers = header::HeaderMap::new();
|
||||||
|
headers.insert(header::HOST, HeaderValue::from_str(host).unwrap()); //SW Handle this unwrap later
|
||||||
|
self.reqwest_client = reqwest::ClientBuilder::new()
|
||||||
|
.default_headers(headers)
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
self.base_url = new_fronted_url
|
||||||
|
}
|
||||||
|
|
||||||
pub fn current_url(&self) -> &Url {
|
pub fn current_url(&self) -> &Url {
|
||||||
&self.base_url
|
&self.base_url
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ pub struct NymContracts {
|
|||||||
pub group_contract_address: Option<String>,
|
pub group_contract_address: Option<String>,
|
||||||
pub multisig_contract_address: Option<String>,
|
pub multisig_contract_address: Option<String>,
|
||||||
pub coconut_dkg_contract_address: Option<String>,
|
pub coconut_dkg_contract_address: Option<String>,
|
||||||
pub service_provider_directory_contract_address: Option<String>,
|
|
||||||
pub name_service_contract_address: Option<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// I wanted to use the simpler `NetworkDetails` name, but there's a clash
|
// I wanted to use the simpler `NetworkDetails` name, but there's a clash
|
||||||
@@ -127,10 +125,6 @@ impl NymNetworkDetails {
|
|||||||
.with_group_contract(get_optional_env(var_names::GROUP_CONTRACT_ADDRESS))
|
.with_group_contract(get_optional_env(var_names::GROUP_CONTRACT_ADDRESS))
|
||||||
.with_multisig_contract(get_optional_env(var_names::MULTISIG_CONTRACT_ADDRESS))
|
.with_multisig_contract(get_optional_env(var_names::MULTISIG_CONTRACT_ADDRESS))
|
||||||
.with_coconut_dkg_contract(get_optional_env(var_names::COCONUT_DKG_CONTRACT_ADDRESS))
|
.with_coconut_dkg_contract(get_optional_env(var_names::COCONUT_DKG_CONTRACT_ADDRESS))
|
||||||
.with_service_provider_directory_contract(get_optional_env(
|
|
||||||
var_names::SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS,
|
|
||||||
))
|
|
||||||
.with_name_service_contract(get_optional_env(var_names::NAME_SERVICE_CONTRACT_ADDRESS))
|
|
||||||
.with_explorer_api(get_optional_env(var_names::EXPLORER_API))
|
.with_explorer_api(get_optional_env(var_names::EXPLORER_API))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,8 +153,6 @@ impl NymNetworkDetails {
|
|||||||
coconut_dkg_contract_address: parse_optional_str(
|
coconut_dkg_contract_address: parse_optional_str(
|
||||||
mainnet::COCONUT_DKG_CONTRACT_ADDRESS,
|
mainnet::COCONUT_DKG_CONTRACT_ADDRESS,
|
||||||
),
|
),
|
||||||
service_provider_directory_contract_address: None,
|
|
||||||
name_service_contract_address: None,
|
|
||||||
},
|
},
|
||||||
explorer_api: parse_optional_str(mainnet::EXPLORER_API),
|
explorer_api: parse_optional_str(mainnet::EXPLORER_API),
|
||||||
}
|
}
|
||||||
@@ -266,21 +258,6 @@ impl NymNetworkDetails {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn with_service_provider_directory_contract<S: Into<String>>(
|
|
||||||
mut self,
|
|
||||||
contract: Option<S>,
|
|
||||||
) -> Self {
|
|
||||||
self.contracts.service_provider_directory_contract_address = contract.map(Into::into);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
|
||||||
pub fn with_name_service_contract<S: Into<String>>(mut self, contract: Option<S>) -> Self {
|
|
||||||
self.contracts.name_service_contract_address = contract.map(Into::into);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_explorer_api<S: Into<String>>(mut self, endpoint: Option<S>) -> Self {
|
pub fn with_explorer_api<S: Into<String>>(mut self, endpoint: Option<S>) -> Self {
|
||||||
self.explorer_api = endpoint.map(Into::into);
|
self.explorer_api = endpoint.map(Into::into);
|
||||||
@@ -444,22 +421,13 @@ pub fn setup_env<P: AsRef<Path>>(config_env_file: Option<P>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name of the event triggered by the eth contract. If the event name is changed,
|
|
||||||
// this would also need to be changed; It is currently tested against the json abi
|
|
||||||
pub const ETH_EVENT_NAME: &str = "BBCredentialPurchased";
|
|
||||||
pub const ETH_BURN_FUNCTION_NAME: &str = "generateBasicBandwidthCredential";
|
|
||||||
pub const ETH_ERC20_APPROVE_FUNCTION_NAME: &str = "approve";
|
|
||||||
|
|
||||||
// Ethereum constants used for token bridge
|
|
||||||
/// How much bandwidth (in bytes) one token can buy
|
/// How much bandwidth (in bytes) one token can buy
|
||||||
pub const BYTES_PER_UTOKEN: u64 = 1024;
|
pub const BYTES_PER_UTOKEN: u64 = 1024;
|
||||||
|
|
||||||
/// How much bandwidth (in bytes) one freepass provides
|
/// How much bandwidth (in bytes) one freepass provides
|
||||||
pub const BYTES_PER_FREEPASS: u64 = 1024 * 1024 * 1024; // 1GB
|
pub const BYTES_PER_FREEPASS: u64 = 1024 * 1024 * 1024; // 1GB
|
||||||
|
|
||||||
/// Threshold for claiming more bandwidth: 1 MB
|
/// Threshold for claiming more bandwidth: 1 MB
|
||||||
pub const REMAINING_BANDWIDTH_THRESHOLD: i64 = 1024 * 1024;
|
pub const REMAINING_BANDWIDTH_THRESHOLD: i64 = 1024 * 1024;
|
||||||
/// How many ERC20 tokens should be burned to buy bandwidth
|
/// How many tokens should be burned to buy bandwidth
|
||||||
pub const TOKENS_TO_BURN: u64 = 1;
|
pub const TOKENS_TO_BURN: u64 = 1;
|
||||||
/// How many ERC20 utokens should be burned to buy bandwidth
|
/// How many ERC20 utokens should be burned to buy bandwidth
|
||||||
pub const UTOKENS_TO_BURN: u64 = TOKENS_TO_BURN * 1000000;
|
pub const UTOKENS_TO_BURN: u64 = TOKENS_TO_BURN * 1000000;
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ pub const MULTISIG_CONTRACT_ADDRESS: &str = "MULTISIG_CONTRACT_ADDRESS";
|
|||||||
pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "COCONUT_DKG_CONTRACT_ADDRESS";
|
pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "COCONUT_DKG_CONTRACT_ADDRESS";
|
||||||
pub const REWARDING_VALIDATOR_ADDRESS: &str = "REWARDING_VALIDATOR_ADDRESS";
|
pub const REWARDING_VALIDATOR_ADDRESS: &str = "REWARDING_VALIDATOR_ADDRESS";
|
||||||
pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "STATISTICS_SERVICE_DOMAIN_ADDRESS";
|
pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "STATISTICS_SERVICE_DOMAIN_ADDRESS";
|
||||||
pub const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str =
|
|
||||||
"SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS";
|
|
||||||
pub const NAME_SERVICE_CONTRACT_ADDRESS: &str = "NAME_SERVICE_CONTRACT_ADDRESS";
|
|
||||||
pub const NYXD: &str = "NYXD";
|
pub const NYXD: &str = "NYXD";
|
||||||
pub const NYM_API: &str = "NYM_API";
|
pub const NYM_API: &str = "NYM_API";
|
||||||
pub const NYXD_WEBSOCKET: &str = "NYXD_WS";
|
pub const NYXD_WEBSOCKET: &str = "NYXD_WS";
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use nym_credential_storage::models::StorableIssuedCredential;
|
|||||||
use nym_credential_storage::storage::Storage;
|
use nym_credential_storage::storage::Storage;
|
||||||
use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant;
|
use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant;
|
||||||
use nym_credentials::IssuedBandwidthCredential;
|
use nym_credentials::IssuedBandwidthCredential;
|
||||||
|
use time::OffsetDateTime;
|
||||||
use tracing::{debug, warn};
|
use tracing::{debug, warn};
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ pub async fn import_credential<S>(
|
|||||||
credentials_store: S,
|
credentials_store: S,
|
||||||
raw_credential: Vec<u8>,
|
raw_credential: Vec<u8>,
|
||||||
credential_version: impl Into<Option<u8>>,
|
credential_version: impl Into<Option<u8>>,
|
||||||
) -> Result<(), NymIdError>
|
) -> Result<Option<OffsetDateTime>, NymIdError>
|
||||||
where
|
where
|
||||||
S: Storage,
|
S: Storage,
|
||||||
<S as Storage>::StorageError: Send + Sync + 'static,
|
<S as Storage>::StorageError: Send + Sync + 'static,
|
||||||
@@ -29,9 +30,10 @@ where
|
|||||||
credential.typ()
|
credential.typ()
|
||||||
);
|
);
|
||||||
|
|
||||||
match credential.variant_data() {
|
let expiry_date = match credential.variant_data() {
|
||||||
BandwidthCredentialIssuedDataVariant::Voucher(voucher_info) => {
|
BandwidthCredentialIssuedDataVariant::Voucher(voucher_info) => {
|
||||||
debug!("with value of {}", voucher_info.value())
|
debug!("with value of {}", voucher_info.value());
|
||||||
|
None
|
||||||
}
|
}
|
||||||
BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => {
|
BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => {
|
||||||
debug!("with expiry at {}", freepass_info.expiry_date());
|
debug!("with expiry at {}", freepass_info.expiry_date());
|
||||||
@@ -42,9 +44,11 @@ where
|
|||||||
return Err(NymIdError::ExpiredCredentialImport {
|
return Err(NymIdError::ExpiredCredentialImport {
|
||||||
expiration: freepass_info.expiry_date(),
|
expiration: freepass_info.expiry_date(),
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
Some(freepass_info.expiry_date())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// SAFETY:
|
// SAFETY:
|
||||||
// for the epoch to run over u32::MAX, we'd have to advance it for few centuries every block...
|
// for the epoch to run over u32::MAX, we'd have to advance it for few centuries every block...
|
||||||
@@ -67,5 +71,5 @@ where
|
|||||||
.map_err(|source| NymIdError::StorageError {
|
.map_err(|source| NymIdError::StorageError {
|
||||||
source: Box::new(source),
|
source: Box::new(source),
|
||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(expiry_date)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -300,8 +300,8 @@ impl Fragment {
|
|||||||
#[derive(PartialEq, Clone, Debug)]
|
#[derive(PartialEq, Clone, Debug)]
|
||||||
pub(crate) struct FragmentHeader {
|
pub(crate) struct FragmentHeader {
|
||||||
/// ID associated with `FragmentSet` to which this particular `Fragment` belongs.
|
/// ID associated with `FragmentSet` to which this particular `Fragment` belongs.
|
||||||
/// Its value is restricted to (0, i32::max_value()].
|
/// Its value is restricted to (0, i32::MAX].
|
||||||
/// Note that it *excludes* 0, but *includes* i32::max_value().
|
/// Note that it *excludes* 0, but *includes* i32::MAX.
|
||||||
/// This allows the field to be represented using 31 bits.
|
/// This allows the field to be represented using 31 bits.
|
||||||
id: i32,
|
id: i32,
|
||||||
|
|
||||||
@@ -319,7 +319,7 @@ pub(crate) struct FragmentHeader {
|
|||||||
previous_fragments_set_id: Option<i32>,
|
previous_fragments_set_id: Option<i32>,
|
||||||
|
|
||||||
/// Optional ID of next `FragmentSet` into which the original message was split.
|
/// Optional ID of next `FragmentSet` into which the original message was split.
|
||||||
/// Note, this option is only valid of `current_fragment == total_fragments == u8::max_value()`
|
/// Note, this option is only valid of `current_fragment == total_fragments == u8::MAX`
|
||||||
next_fragments_set_id: Option<i32>,
|
next_fragments_set_id: Option<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,7 +414,7 @@ impl FragmentHeader {
|
|||||||
|
|
||||||
if current_fragment == 1 {
|
if current_fragment == 1 {
|
||||||
previous_fragments_set_id = Some(linked_id);
|
previous_fragments_set_id = Some(linked_id);
|
||||||
} else if total_fragments == current_fragment && current_fragment == u8::max_value() {
|
} else if total_fragments == current_fragment && current_fragment == u8::MAX {
|
||||||
next_fragments_set_id = Some(linked_id);
|
next_fragments_set_id = Some(linked_id);
|
||||||
} else {
|
} else {
|
||||||
return Err(ChunkingError::MalformedHeaderError);
|
return Err(ChunkingError::MalformedHeaderError);
|
||||||
@@ -585,14 +585,7 @@ mod fragment_tests {
|
|||||||
rng.fill_bytes(&mut msg);
|
rng.fill_bytes(&mut msg);
|
||||||
|
|
||||||
let fragment = Fragment {
|
let fragment = Fragment {
|
||||||
header: FragmentHeader::try_new(
|
header: FragmentHeader::try_new(12345, u8::MAX, u8::MAX, None, Some(1234)).unwrap(),
|
||||||
12345,
|
|
||||||
u8::max_value(),
|
|
||||||
u8::max_value(),
|
|
||||||
None,
|
|
||||||
Some(1234),
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
payload: msg,
|
payload: msg,
|
||||||
};
|
};
|
||||||
let packet_bytes = fragment.clone().into_bytes();
|
let packet_bytes = fragment.clone().into_bytes();
|
||||||
@@ -602,14 +595,7 @@ mod fragment_tests {
|
|||||||
rng.fill_bytes(&mut msg);
|
rng.fill_bytes(&mut msg);
|
||||||
|
|
||||||
let fragment = Fragment {
|
let fragment = Fragment {
|
||||||
header: FragmentHeader::try_new(
|
header: FragmentHeader::try_new(12345, u8::MAX, u8::MAX, None, Some(1234)).unwrap(),
|
||||||
12345,
|
|
||||||
u8::max_value(),
|
|
||||||
u8::max_value(),
|
|
||||||
None,
|
|
||||||
Some(1234),
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
payload: msg,
|
payload: msg,
|
||||||
};
|
};
|
||||||
let packet_bytes = fragment.clone().into_bytes();
|
let packet_bytes = fragment.clone().into_bytes();
|
||||||
@@ -822,8 +808,8 @@ mod fragment_tests {
|
|||||||
assert!(Fragment::try_new(
|
assert!(Fragment::try_new(
|
||||||
&full_payload,
|
&full_payload,
|
||||||
id,
|
id,
|
||||||
u8::max_value(),
|
u8::MAX,
|
||||||
u8::max_value(),
|
u8::MAX,
|
||||||
None,
|
None,
|
||||||
Some(link_id),
|
Some(link_id),
|
||||||
max_plaintext_size(),
|
max_plaintext_size(),
|
||||||
@@ -884,8 +870,8 @@ mod fragment_tests {
|
|||||||
assert!(Fragment::try_new(
|
assert!(Fragment::try_new(
|
||||||
&non_full_payload,
|
&non_full_payload,
|
||||||
id,
|
id,
|
||||||
u8::max_value(),
|
u8::MAX,
|
||||||
u8::max_value(),
|
u8::MAX,
|
||||||
None,
|
None,
|
||||||
Some(link_id),
|
Some(link_id),
|
||||||
max_plaintext_size(),
|
max_plaintext_size(),
|
||||||
@@ -894,8 +880,8 @@ mod fragment_tests {
|
|||||||
assert!(Fragment::try_new(
|
assert!(Fragment::try_new(
|
||||||
&non_full_payload2,
|
&non_full_payload2,
|
||||||
id,
|
id,
|
||||||
u8::max_value(),
|
u8::MAX,
|
||||||
u8::max_value(),
|
u8::MAX,
|
||||||
None,
|
None,
|
||||||
Some(link_id),
|
Some(link_id),
|
||||||
max_plaintext_size(),
|
max_plaintext_size(),
|
||||||
@@ -905,8 +891,8 @@ mod fragment_tests {
|
|||||||
assert!(Fragment::try_new(
|
assert!(Fragment::try_new(
|
||||||
&too_much_payload,
|
&too_much_payload,
|
||||||
id,
|
id,
|
||||||
u8::max_value(),
|
u8::MAX,
|
||||||
u8::max_value(),
|
u8::MAX,
|
||||||
None,
|
None,
|
||||||
Some(link_id),
|
Some(link_id),
|
||||||
max_plaintext_size(),
|
max_plaintext_size(),
|
||||||
@@ -1008,14 +994,7 @@ mod fragment_header {
|
|||||||
fn fragmented_header_cannot_be_created_with_zero_id() {
|
fn fragmented_header_cannot_be_created_with_zero_id() {
|
||||||
assert!(FragmentHeader::try_new(0, 10, 5, None, None).is_err());
|
assert!(FragmentHeader::try_new(0, 10, 5, None, None).is_err());
|
||||||
assert!(FragmentHeader::try_new(12345, 10, 5, Some(0), None).is_err());
|
assert!(FragmentHeader::try_new(12345, 10, 5, Some(0), None).is_err());
|
||||||
assert!(FragmentHeader::try_new(
|
assert!(FragmentHeader::try_new(12345, u8::MAX, u8::MAX, None, Some(0),).is_err());
|
||||||
12345,
|
|
||||||
u8::max_value(),
|
|
||||||
u8::max_value(),
|
|
||||||
None,
|
|
||||||
Some(0),
|
|
||||||
)
|
|
||||||
.is_err());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1066,14 +1045,7 @@ mod fragment_header {
|
|||||||
#[test]
|
#[test]
|
||||||
fn can_only_be_post_linked_for_last_fragment() {
|
fn can_only_be_post_linked_for_last_fragment() {
|
||||||
assert!(FragmentHeader::try_new(12345, 10, 10, None, Some(1234)).is_ok());
|
assert!(FragmentHeader::try_new(12345, 10, 10, None, Some(1234)).is_ok());
|
||||||
assert!(FragmentHeader::try_new(
|
assert!(FragmentHeader::try_new(12345, u8::MAX, u8::MAX, None, Some(1234),).is_ok());
|
||||||
12345,
|
|
||||||
u8::max_value(),
|
|
||||||
u8::max_value(),
|
|
||||||
None,
|
|
||||||
Some(1234),
|
|
||||||
)
|
|
||||||
.is_ok());
|
|
||||||
assert!(FragmentHeader::try_new(12345, 10, 2, Some(1234), None).is_err());
|
assert!(FragmentHeader::try_new(12345, 10, 2, Some(1234), None).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1117,8 +1089,7 @@ mod fragment_header {
|
|||||||
#[test]
|
#[test]
|
||||||
fn post_linked_can_be_converted_to_and_from_bytes_for_exact_number_of_bytes_provided() {
|
fn post_linked_can_be_converted_to_and_from_bytes_for_exact_number_of_bytes_provided() {
|
||||||
let fragmented_header =
|
let fragmented_header =
|
||||||
FragmentHeader::try_new(12345, u8::max_value(), u8::max_value(), None, Some(1234))
|
FragmentHeader::try_new(12345, u8::MAX, u8::MAX, None, Some(1234)).unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let header_bytes = fragmented_header.to_bytes();
|
let header_bytes = fragmented_header.to_bytes();
|
||||||
let (recovered_header, bytes_used) =
|
let (recovered_header, bytes_used) =
|
||||||
@@ -1130,8 +1101,7 @@ mod fragment_header {
|
|||||||
#[test]
|
#[test]
|
||||||
fn post_linked_can_be_converted_to_and_from_bytes_for_more_than_required_number_of_bytes() {
|
fn post_linked_can_be_converted_to_and_from_bytes_for_more_than_required_number_of_bytes() {
|
||||||
let fragmented_header =
|
let fragmented_header =
|
||||||
FragmentHeader::try_new(12345, u8::max_value(), u8::max_value(), None, Some(1234))
|
FragmentHeader::try_new(12345, u8::MAX, u8::MAX, None, Some(1234)).unwrap();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut header_bytes = fragmented_header.to_bytes();
|
let mut header_bytes = fragmented_header.to_bytes();
|
||||||
header_bytes.append(vec![1, 2, 3, 4, 5].as_mut());
|
header_bytes.append(vec![1, 2, 3, 4, 5].as_mut());
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ pub mod set;
|
|||||||
/// (or implicitly the only one), it has no lower bound on the number of `Fragment`s.
|
/// (or implicitly the only one), it has no lower bound on the number of `Fragment`s.
|
||||||
/// (Apart from the restriction of containing at least a single one). If the set is located
|
/// (Apart from the restriction of containing at least a single one). If the set is located
|
||||||
/// somewhere in the middle, *it must be* full. Finally, regardless of its position, it must also be
|
/// somewhere in the middle, *it must be* full. Finally, regardless of its position, it must also be
|
||||||
/// true that it contains no more than `u8::max_value()`, i.e. 255 `Fragment`s.
|
/// true that it contains no more than `u8::MAX`, i.e. 255 `Fragment`s.
|
||||||
/// Again, the reasoning for this is further explained in `set.rs` file. However, you might
|
/// Again, the reasoning for this is further explained in `set.rs` file. However, you might
|
||||||
/// also want to look at `fragment.rs` to understand the full context behind that design choice.
|
/// also want to look at `fragment.rs` to understand the full context behind that design choice.
|
||||||
///
|
///
|
||||||
@@ -151,7 +151,7 @@ mod tests {
|
|||||||
- MAX_NODE_ADDRESS_UNPADDED_LEN;
|
- MAX_NODE_ADDRESS_UNPADDED_LEN;
|
||||||
|
|
||||||
let plaintext_lens = vec![17, used_plaintext_len, 20, 42, 10000];
|
let plaintext_lens = vec![17, used_plaintext_len, 20, 42, 10000];
|
||||||
const SET_LEN: usize = u8::max_value() as usize;
|
const SET_LEN: usize = u8::MAX as usize;
|
||||||
|
|
||||||
for plaintext_len in plaintext_lens {
|
for plaintext_len in plaintext_lens {
|
||||||
let unlinked_len = unlinked_fragment_payload_max_len(plaintext_len);
|
let unlinked_len = unlinked_fragment_payload_max_len(plaintext_len);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ struct ReconstructionBuffer {
|
|||||||
previous_fragments_set_id: Option<i32>,
|
previous_fragments_set_id: Option<i32>,
|
||||||
/// Once all fragments are received, the value of `next_fragments_set_id` is copied
|
/// Once all fragments are received, the value of `next_fragments_set_id` is copied
|
||||||
/// from the last `Fragment` in the set (assuming the set is full, i.e. it contains
|
/// from the last `Fragment` in the set (assuming the set is full, i.e. it contains
|
||||||
/// `u8::max_value()` elements).
|
/// `u8::MAX` elements).
|
||||||
next_fragments_set_id: Option<i32>,
|
next_fragments_set_id: Option<i32>,
|
||||||
|
|
||||||
/// The actual `Fragment` data held by the `ReconstructionBuffer`. When created it is already
|
/// The actual `Fragment` data held by the `ReconstructionBuffer`. When created it is already
|
||||||
@@ -40,7 +40,7 @@ pub type ReconstructedMessage = (Vec<u8>, Vec<i32>);
|
|||||||
impl ReconstructionBuffer {
|
impl ReconstructionBuffer {
|
||||||
/// Initialises new instance of a `ReconstructionBuffer` with given size, i.e.
|
/// Initialises new instance of a `ReconstructionBuffer` with given size, i.e.
|
||||||
/// number of expected `Fragment`s in the set.
|
/// number of expected `Fragment`s in the set.
|
||||||
/// The `u8` input type of `size` argument ensures it has the `u8::max_value()` upper bound.
|
/// The `u8` input type of `size` argument ensures it has the `u8::MAX` upper bound.
|
||||||
fn new(size: u8) -> Self {
|
fn new(size: u8) -> Self {
|
||||||
// Note: `new` should have never been called with size 0 in the first place
|
// Note: `new` should have never been called with size 0 in the first place
|
||||||
// as `size` value is based on the first recovered `Fragment` in the set.
|
// as `size` value is based on the first recovered `Fragment` in the set.
|
||||||
@@ -122,8 +122,8 @@ impl ReconstructionBuffer {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.previous_fragments_set_id();
|
.previous_fragments_set_id();
|
||||||
self.next_fragments_set_id = if self.fragments.len() == u8::max_value() as usize {
|
self.next_fragments_set_id = if self.fragments.len() == u8::MAX as usize {
|
||||||
self.fragments[u8::max_value() as usize - 1]
|
self.fragments[u8::MAX as usize - 1]
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.next_fragments_set_id()
|
.next_fragments_set_id()
|
||||||
@@ -313,8 +313,8 @@ mod reconstruction_buffer {
|
|||||||
assert_eq!(None, frag);
|
assert_eq!(None, frag);
|
||||||
}
|
}
|
||||||
|
|
||||||
let buf = ReconstructionBuffer::new(u8::max_value());
|
let buf = ReconstructionBuffer::new(u8::MAX);
|
||||||
assert_eq!(u8::max_value() as usize, buf.fragments.len());
|
assert_eq!(u8::MAX as usize, buf.fragments.len());
|
||||||
for frag in buf.fragments {
|
for frag in buf.fragments {
|
||||||
assert_eq!(None, frag);
|
assert_eq!(None, frag);
|
||||||
}
|
}
|
||||||
@@ -358,11 +358,11 @@ mod reconstruction_buffer {
|
|||||||
buf.insert_fragment(Fragment::try_from_bytes(&raw_fragments[2]).unwrap());
|
buf.insert_fragment(Fragment::try_from_bytes(&raw_fragments[2]).unwrap());
|
||||||
assert_eq!(message.to_vec(), buf.reconstruct_set_data());
|
assert_eq!(message.to_vec(), buf.reconstruct_set_data());
|
||||||
|
|
||||||
let mut buf = ReconstructionBuffer::new(u8::max_value());
|
let mut buf = ReconstructionBuffer::new(u8::MAX);
|
||||||
let message = vec![
|
let message = vec![
|
||||||
42u8;
|
42u8;
|
||||||
unlinked_fragment_payload_max_len(AVAILABLE_PLAINTEXT_SIZE)
|
unlinked_fragment_payload_max_len(AVAILABLE_PLAINTEXT_SIZE)
|
||||||
* u8::max_value() as usize
|
* u8::MAX as usize
|
||||||
];
|
];
|
||||||
let raw_fragments: Vec<_> =
|
let raw_fragments: Vec<_> =
|
||||||
crate::split_into_sets(&mut rand::rngs::OsRng, &message, AVAILABLE_PLAINTEXT_SIZE)
|
crate::split_into_sets(&mut rand::rngs::OsRng, &message, AVAILABLE_PLAINTEXT_SIZE)
|
||||||
@@ -445,7 +445,7 @@ mod reconstruction_buffer {
|
|||||||
.map(|x| x.into_bytes())
|
.map(|x| x.into_bytes())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize - 1) {
|
for raw_fragment in raw_fragments.iter().take(u8::MAX as usize - 1) {
|
||||||
buf.insert_fragment(Fragment::try_from_bytes(raw_fragment).unwrap());
|
buf.insert_fragment(Fragment::try_from_bytes(raw_fragment).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -563,7 +563,7 @@ mod message_reconstructor {
|
|||||||
.map(|x| x.into_bytes())
|
.map(|x| x.into_bytes())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize) {
|
for raw_fragment in raw_fragments.iter().take(u8::MAX as usize) {
|
||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
@@ -611,7 +611,7 @@ mod message_reconstructor {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// note that first set is not fully inserted
|
// note that first set is not fully inserted
|
||||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize - 1) {
|
for raw_fragment in raw_fragments.iter().take(u8::MAX as usize - 1) {
|
||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
@@ -657,7 +657,7 @@ mod message_reconstructor {
|
|||||||
.map(|x| x.into_bytes())
|
.map(|x| x.into_bytes())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize) {
|
for raw_fragment in raw_fragments.iter().take(u8::MAX as usize) {
|
||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
@@ -699,7 +699,7 @@ mod message_reconstructor {
|
|||||||
.map(|x| x.into_bytes())
|
.map(|x| x.into_bytes())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize) {
|
for raw_fragment in raw_fragments.iter().take(u8::MAX as usize) {
|
||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
@@ -738,7 +738,7 @@ mod message_reconstructor {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// note that first set is not fully inserted
|
// note that first set is not fully inserted
|
||||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize - 1) {
|
for raw_fragment in raw_fragments.iter().take(u8::MAX as usize - 1) {
|
||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
@@ -779,7 +779,7 @@ mod message_reconstructor {
|
|||||||
.map(|x| x.into_bytes())
|
.map(|x| x.into_bytes())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize * 2) {
|
for raw_fragment in raw_fragments.iter().take(u8::MAX as usize * 2) {
|
||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
@@ -793,7 +793,7 @@ mod message_reconstructor {
|
|||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
.recover_fragment(raw_fragments[(u8::max_value() as usize) * 2].clone())
|
.recover_fragment(raw_fragments[(u8::MAX as usize) * 2].clone())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
)
|
)
|
||||||
.is_none());
|
.is_none());
|
||||||
@@ -822,11 +822,7 @@ mod message_reconstructor {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// note that first set is not fully inserted
|
// note that first set is not fully inserted
|
||||||
for raw_fragment in raw_fragments
|
for raw_fragment in raw_fragments.iter().skip(1).take(u8::MAX as usize * 2 - 1) {
|
||||||
.iter()
|
|
||||||
.skip(1)
|
|
||||||
.take(u8::max_value() as usize * 2 - 1)
|
|
||||||
{
|
|
||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
@@ -839,7 +835,7 @@ mod message_reconstructor {
|
|||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
.recover_fragment(raw_fragments[(u8::max_value() as usize) * 2].clone())
|
.recover_fragment(raw_fragments[(u8::MAX as usize) * 2].clone())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
)
|
)
|
||||||
.is_none());
|
.is_none());
|
||||||
@@ -896,7 +892,7 @@ mod message_reconstructor {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// note that first set is not fully inserted
|
// note that first set is not fully inserted
|
||||||
for raw_fragment in raw_fragments1.iter().take(u8::max_value() as usize - 1) {
|
for raw_fragment in raw_fragments1.iter().take(u8::MAX as usize - 1) {
|
||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
@@ -930,7 +926,7 @@ mod message_reconstructor {
|
|||||||
.map(|x| x.into_bytes())
|
.map(|x| x.into_bytes())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for raw_fragment in raw_fragments2.iter().take(u8::max_value() as usize) {
|
for raw_fragment in raw_fragments2.iter().take(u8::MAX as usize) {
|
||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
@@ -970,7 +966,7 @@ mod message_reconstructor {
|
|||||||
.map(|x| x.into_bytes())
|
.map(|x| x.into_bytes())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize) {
|
for raw_fragment in raw_fragments.iter().take(u8::MAX as usize) {
|
||||||
assert!(reconstructor
|
assert!(reconstructor
|
||||||
.insert_new_fragment(
|
.insert_new_fragment(
|
||||||
reconstructor
|
reconstructor
|
||||||
@@ -1252,7 +1248,7 @@ mod message_reconstructor {
|
|||||||
//
|
//
|
||||||
// we're inserting this via the buffer approach as not to trigger immediate re-assembly
|
// we're inserting this via the buffer approach as not to trigger immediate re-assembly
|
||||||
let mut reconstructor = MessageReconstructor::default();
|
let mut reconstructor = MessageReconstructor::default();
|
||||||
let mut set_buf1 = ReconstructionBuffer::new(u8::max_value());
|
let mut set_buf1 = ReconstructionBuffer::new(u8::MAX);
|
||||||
let mut set_buf2 = ReconstructionBuffer::new(1);
|
let mut set_buf2 = ReconstructionBuffer::new(1);
|
||||||
|
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
@@ -1267,7 +1263,7 @@ mod message_reconstructor {
|
|||||||
.map(|x| x.into_bytes())
|
.map(|x| x.into_bytes())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
for raw_fragment in raw_fragments.iter().take(u8::max_value() as usize) {
|
for raw_fragment in raw_fragments.iter().take(u8::MAX as usize) {
|
||||||
set_buf1.insert_fragment(Fragment::try_from_bytes(raw_fragment).unwrap());
|
set_buf1.insert_fragment(Fragment::try_from_bytes(raw_fragment).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1630,19 +1626,19 @@ mod message_reconstruction {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||||
.collect();
|
.collect();
|
||||||
assert_eq!(fragments1.len(), u8::max_value() as usize);
|
assert_eq!(fragments1.len(), u8::MAX as usize);
|
||||||
let mut fragments2: Vec<_> =
|
let mut fragments2: Vec<_> =
|
||||||
crate::split_into_sets(&mut rand::rngs::OsRng, &message2, AVAILABLE_PLAINTEXT_SIZE)
|
crate::split_into_sets(&mut rand::rngs::OsRng, &message2, AVAILABLE_PLAINTEXT_SIZE)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||||
.collect();
|
.collect();
|
||||||
assert_eq!(fragments2.len(), u8::max_value() as usize);
|
assert_eq!(fragments2.len(), u8::MAX as usize);
|
||||||
|
|
||||||
// combine and shuffle fragments
|
// combine and shuffle fragments
|
||||||
fragments1.append(fragments2.as_mut());
|
fragments1.append(fragments2.as_mut());
|
||||||
fragments1.shuffle(&mut rng);
|
fragments1.shuffle(&mut rng);
|
||||||
let fragments = fragments1;
|
let fragments = fragments1;
|
||||||
assert_eq!(fragments.len(), (u8::max_value() as usize) * 2);
|
assert_eq!(fragments.len(), (u8::MAX as usize) * 2);
|
||||||
|
|
||||||
let mut message_reconstructor = MessageReconstructor::default();
|
let mut message_reconstructor = MessageReconstructor::default();
|
||||||
for fragment in fragments.into_iter() {
|
for fragment in fragments.into_iter() {
|
||||||
@@ -1762,7 +1758,7 @@ mod message_reconstruction {
|
|||||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||||
.map(|x| x.into_bytes())
|
.map(|x| x.into_bytes())
|
||||||
.collect();
|
.collect();
|
||||||
assert_eq!(fragments.len(), 4 * (u8::max_value() as usize));
|
assert_eq!(fragments.len(), 4 * (u8::MAX as usize));
|
||||||
// shuffle the fragments
|
// shuffle the fragments
|
||||||
fragments.shuffle(&mut rng);
|
fragments.shuffle(&mut rng);
|
||||||
|
|
||||||
@@ -1811,19 +1807,19 @@ mod message_reconstruction {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||||
.collect();
|
.collect();
|
||||||
assert_eq!(fragments1.len(), 4 * (u8::max_value() as usize));
|
assert_eq!(fragments1.len(), 4 * (u8::MAX as usize));
|
||||||
let mut fragments2: Vec<_> =
|
let mut fragments2: Vec<_> =
|
||||||
crate::split_into_sets(&mut rand::rngs::OsRng, &message2, AVAILABLE_PLAINTEXT_SIZE)
|
crate::split_into_sets(&mut rand::rngs::OsRng, &message2, AVAILABLE_PLAINTEXT_SIZE)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|fragment_set| fragment_set.into_iter())
|
.flat_map(|fragment_set| fragment_set.into_iter())
|
||||||
.collect();
|
.collect();
|
||||||
assert_eq!(fragments2.len(), 4 * (u8::max_value() as usize));
|
assert_eq!(fragments2.len(), 4 * (u8::MAX as usize));
|
||||||
|
|
||||||
// combine and shuffle fragments
|
// combine and shuffle fragments
|
||||||
fragments1.append(fragments2.as_mut());
|
fragments1.append(fragments2.as_mut());
|
||||||
fragments1.shuffle(&mut rng);
|
fragments1.shuffle(&mut rng);
|
||||||
let fragments = fragments1;
|
let fragments = fragments1;
|
||||||
assert_eq!(fragments.len(), (u8::max_value() as usize) * 8);
|
assert_eq!(fragments.len(), (u8::MAX as usize) * 8);
|
||||||
|
|
||||||
let mut message_reconstructor = MessageReconstructor::default();
|
let mut message_reconstructor = MessageReconstructor::default();
|
||||||
for fragment in fragments.into_iter() {
|
for fragment in fragments.into_iter() {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use rand::Rng;
|
|||||||
/// on its payload length of the maximum number of `Fragment`s multiplied by their maximum,
|
/// on its payload length of the maximum number of `Fragment`s multiplied by their maximum,
|
||||||
/// fragmented, length.
|
/// fragmented, length.
|
||||||
pub const fn max_unlinked_set_payload_length(max_plaintext_size: usize) -> usize {
|
pub const fn max_unlinked_set_payload_length(max_plaintext_size: usize) -> usize {
|
||||||
u8::max_value() as usize * unlinked_fragment_payload_max_len(max_plaintext_size)
|
u8::MAX as usize * unlinked_fragment_payload_max_len(max_plaintext_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the set is being linked to another one, by either being the very first set, or the very last,
|
/// If the set is being linked to another one, by either being the very first set, or the very last,
|
||||||
@@ -52,8 +52,8 @@ pub const fn two_way_linked_set_payload_length(max_plaintext_size: usize) -> usi
|
|||||||
pub(crate) type FragmentSet = Vec<Fragment>;
|
pub(crate) type FragmentSet = Vec<Fragment>;
|
||||||
|
|
||||||
/// Generate a pseudo-random id for a `FragmentSet`.
|
/// Generate a pseudo-random id for a `FragmentSet`.
|
||||||
/// Its value is restricted to (0, i32::max_value()].
|
/// Its value is restricted to (0, i32::MAX].
|
||||||
/// Note that it *excludes* 0, but *includes* i32::max_value().
|
/// Note that it *excludes* 0, but *includes* i32::MAX.
|
||||||
/// This particular range allows for the id to be represented using 31bits, rather than
|
/// This particular range allows for the id to be represented using 31bits, rather than
|
||||||
/// the full length of 32 while still providing more than enough variability to
|
/// the full length of 32 while still providing more than enough variability to
|
||||||
/// distinguish different `FragmentSet`s.
|
/// distinguish different `FragmentSet`s.
|
||||||
@@ -89,13 +89,13 @@ fn prepare_unlinked_fragmented_set(
|
|||||||
/ unlinked_fragment_payload_max_len(max_plaintext_size) as f64)
|
/ unlinked_fragment_payload_max_len(max_plaintext_size) as f64)
|
||||||
.ceil() as usize;
|
.ceil() as usize;
|
||||||
|
|
||||||
debug_assert!(pre_casted_frags <= u8::max_value() as usize);
|
debug_assert!(pre_casted_frags <= u8::MAX as usize);
|
||||||
let num_fragments = pre_casted_frags as u8;
|
let num_fragments = pre_casted_frags as u8;
|
||||||
|
|
||||||
let mut fragments = Vec::with_capacity(num_fragments as usize);
|
let mut fragments = Vec::with_capacity(num_fragments as usize);
|
||||||
|
|
||||||
for i in 1..(pre_casted_frags + 1) {
|
for i in 1..(pre_casted_frags + 1) {
|
||||||
// we can't use u8 directly here as upper (NON-INCLUSIVE, so it would always fit) bound could be u8::max_value() + 1
|
// we can't use u8 directly here as upper (NON-INCLUSIVE, so it would always fit) bound could be u8::MAX + 1
|
||||||
let lb = (i - 1) * unlinked_fragment_payload_max_len(max_plaintext_size);
|
let lb = (i - 1) * unlinked_fragment_payload_max_len(max_plaintext_size);
|
||||||
let ub = usize::min(
|
let ub = usize::min(
|
||||||
message.len(),
|
message.len(),
|
||||||
@@ -131,7 +131,7 @@ fn prepare_linked_fragment_set(
|
|||||||
) -> FragmentSet {
|
) -> FragmentSet {
|
||||||
// determine number of fragments in the set:
|
// determine number of fragments in the set:
|
||||||
let num_frags_usize = if next_link_id.is_some() {
|
let num_frags_usize = if next_link_id.is_some() {
|
||||||
u8::max_value() as usize
|
u8::MAX as usize
|
||||||
} else {
|
} else {
|
||||||
// we know this set is linked, if it's not post-linked then it MUST BE pre-linked
|
// we know this set is linked, if it's not post-linked then it MUST BE pre-linked
|
||||||
let tail_len = if message.len() >= linked_fragment_payload_max_len(max_plaintext_size) {
|
let tail_len = if message.len() >= linked_fragment_payload_max_len(max_plaintext_size) {
|
||||||
@@ -142,7 +142,7 @@ fn prepare_linked_fragment_set(
|
|||||||
let pre_casted_frags = 1
|
let pre_casted_frags = 1
|
||||||
+ (tail_len as f64 / unlinked_fragment_payload_max_len(max_plaintext_size) as f64)
|
+ (tail_len as f64 / unlinked_fragment_payload_max_len(max_plaintext_size) as f64)
|
||||||
.ceil() as usize;
|
.ceil() as usize;
|
||||||
if pre_casted_frags > u8::max_value() as usize {
|
if pre_casted_frags > u8::MAX as usize {
|
||||||
panic!("message would produce too many fragments!")
|
panic!("message would produce too many fragments!")
|
||||||
};
|
};
|
||||||
pre_casted_frags
|
pre_casted_frags
|
||||||
@@ -162,7 +162,7 @@ fn prepare_linked_fragment_set(
|
|||||||
|
|
||||||
let mut fragments = Vec::with_capacity(num_frags_usize);
|
let mut fragments = Vec::with_capacity(num_frags_usize);
|
||||||
for i in 1..(num_frags_usize + 1) {
|
for i in 1..(num_frags_usize + 1) {
|
||||||
// we can't use u8 directly here as upper (NON-INCLUSIVE, so i would always fit) bound could be u8::max_value() + 1
|
// we can't use u8 directly here as upper (NON-INCLUSIVE, so i would always fit) bound could be u8::MAX + 1
|
||||||
let fragment = Fragment::try_new(
|
let fragment = Fragment::try_new(
|
||||||
&message[lb..ub],
|
&message[lb..ub],
|
||||||
id,
|
id,
|
||||||
@@ -343,7 +343,7 @@ mod tests {
|
|||||||
fn verify_post_linked_set_payload(mut set: FragmentSet, payload: &[u8]) {
|
fn verify_post_linked_set_payload(mut set: FragmentSet, payload: &[u8]) {
|
||||||
for i in (0..set.len()).rev() {
|
for i in (0..set.len()).rev() {
|
||||||
let lb = i * unlinked_fragment_payload_max_len(max_plaintext_size());
|
let lb = i * unlinked_fragment_payload_max_len(max_plaintext_size());
|
||||||
let ub = if i == (u8::max_value() as usize - 1) {
|
let ub = if i == (u8::MAX as usize - 1) {
|
||||||
i * unlinked_fragment_payload_max_len(max_plaintext_size())
|
i * unlinked_fragment_payload_max_len(max_plaintext_size())
|
||||||
+ linked_fragment_payload_max_len(max_plaintext_size())
|
+ linked_fragment_payload_max_len(max_plaintext_size())
|
||||||
} else {
|
} else {
|
||||||
@@ -365,7 +365,7 @@ mod tests {
|
|||||||
(i - 1) * unlinked_fragment_payload_max_len(max_plaintext_size())
|
(i - 1) * unlinked_fragment_payload_max_len(max_plaintext_size())
|
||||||
+ linked_fragment_payload_max_len(max_plaintext_size())
|
+ linked_fragment_payload_max_len(max_plaintext_size())
|
||||||
};
|
};
|
||||||
let ub = if i == (u8::max_value() as usize - 1) {
|
let ub = if i == (u8::MAX as usize - 1) {
|
||||||
(i - 1) * unlinked_fragment_payload_max_len(max_plaintext_size())
|
(i - 1) * unlinked_fragment_payload_max_len(max_plaintext_size())
|
||||||
+ 2 * linked_fragment_payload_max_len(max_plaintext_size())
|
+ 2 * linked_fragment_payload_max_len(max_plaintext_size())
|
||||||
} else {
|
} else {
|
||||||
@@ -434,7 +434,7 @@ mod tests {
|
|||||||
id,
|
id,
|
||||||
max_plaintext_size(),
|
max_plaintext_size(),
|
||||||
);
|
);
|
||||||
assert_eq!(u8::max_value() as usize, max_fragment_set.len());
|
assert_eq!(u8::MAX as usize, max_fragment_set.len());
|
||||||
verify_unlinked_set_payload(max_fragment_set, &max_fragments_set_payload);
|
verify_unlinked_set_payload(max_fragment_set, &max_fragments_set_payload);
|
||||||
|
|
||||||
let mut full_set_payload =
|
let mut full_set_payload =
|
||||||
@@ -442,7 +442,7 @@ mod tests {
|
|||||||
rng.fill_bytes(&mut full_set_payload);
|
rng.fill_bytes(&mut full_set_payload);
|
||||||
let full_fragment_set =
|
let full_fragment_set =
|
||||||
prepare_unlinked_fragmented_set(&full_set_payload, id, max_plaintext_size());
|
prepare_unlinked_fragmented_set(&full_set_payload, id, max_plaintext_size());
|
||||||
assert_eq!(u8::max_value() as usize, full_fragment_set.len());
|
assert_eq!(u8::MAX as usize, full_fragment_set.len());
|
||||||
verify_unlinked_set_payload(full_fragment_set, &full_set_payload);
|
verify_unlinked_set_payload(full_fragment_set, &full_set_payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,7 +515,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
max_plaintext_size(),
|
max_plaintext_size(),
|
||||||
);
|
);
|
||||||
assert_eq!(u8::max_value() as usize, max_fragment_set.len());
|
assert_eq!(u8::MAX as usize, max_fragment_set.len());
|
||||||
verify_pre_linked_set_payload(max_fragment_set, &max_fragments_set_payload);
|
verify_pre_linked_set_payload(max_fragment_set, &max_fragments_set_payload);
|
||||||
|
|
||||||
let mut full_set_payload =
|
let mut full_set_payload =
|
||||||
@@ -528,7 +528,7 @@ mod tests {
|
|||||||
None,
|
None,
|
||||||
max_plaintext_size(),
|
max_plaintext_size(),
|
||||||
);
|
);
|
||||||
assert_eq!(u8::max_value() as usize, full_fragment_set.len());
|
assert_eq!(u8::MAX as usize, full_fragment_set.len());
|
||||||
verify_pre_linked_set_payload(full_fragment_set, &full_set_payload);
|
verify_pre_linked_set_payload(full_fragment_set, &full_set_payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -561,7 +561,7 @@ mod tests {
|
|||||||
Some(link_id),
|
Some(link_id),
|
||||||
max_plaintext_size(),
|
max_plaintext_size(),
|
||||||
);
|
);
|
||||||
assert_eq!(u8::max_value() as usize, full_fragment_set.len());
|
assert_eq!(u8::MAX as usize, full_fragment_set.len());
|
||||||
verify_post_linked_set_payload(full_fragment_set, &full_set_payload);
|
verify_post_linked_set_payload(full_fragment_set, &full_set_payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,7 +608,7 @@ mod tests {
|
|||||||
Some(post_link_id),
|
Some(post_link_id),
|
||||||
max_plaintext_size(),
|
max_plaintext_size(),
|
||||||
);
|
);
|
||||||
assert_eq!(u8::max_value() as usize, full_fragment_set.len());
|
assert_eq!(u8::MAX as usize, full_fragment_set.len());
|
||||||
verify_two_way_linked_set_payload(full_fragment_set, &full_set_payload);
|
verify_two_way_linked_set_payload(full_fragment_set, &full_set_payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,8 +700,8 @@ mod tests {
|
|||||||
|
|
||||||
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
|
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
|
||||||
assert_eq!(2, sets.len());
|
assert_eq!(2, sets.len());
|
||||||
assert_eq!(sets[0].len(), u8::max_value() as usize);
|
assert_eq!(sets[0].len(), u8::MAX as usize);
|
||||||
assert_eq!(sets[1].len(), u8::max_value() as usize);
|
assert_eq!(sets[1].len(), u8::MAX as usize);
|
||||||
verify_correct_link(&sets[0], &sets[1]);
|
verify_correct_link(&sets[0], &sets[1]);
|
||||||
verify_pre_linked_set_payload(
|
verify_pre_linked_set_payload(
|
||||||
sets.pop().unwrap(),
|
sets.pop().unwrap(),
|
||||||
@@ -726,9 +726,9 @@ mod tests {
|
|||||||
rng.fill_bytes(&mut message);
|
rng.fill_bytes(&mut message);
|
||||||
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
|
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
|
||||||
assert_eq!(4, sets.len());
|
assert_eq!(4, sets.len());
|
||||||
assert_eq!(sets[0].len(), u8::max_value() as usize);
|
assert_eq!(sets[0].len(), u8::MAX as usize);
|
||||||
assert_eq!(sets[1].len(), u8::max_value() as usize);
|
assert_eq!(sets[1].len(), u8::MAX as usize);
|
||||||
assert_eq!(sets[2].len(), u8::max_value() as usize);
|
assert_eq!(sets[2].len(), u8::MAX as usize);
|
||||||
|
|
||||||
verify_correct_link(&sets[0], &sets[1]);
|
verify_correct_link(&sets[0], &sets[1]);
|
||||||
verify_correct_link(&sets[1], &sets[2]);
|
verify_correct_link(&sets[1], &sets[2]);
|
||||||
@@ -766,10 +766,10 @@ mod tests {
|
|||||||
|
|
||||||
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
|
let mut sets = split_into_sets(&mut rng, &message, max_plaintext_size());
|
||||||
assert_eq!(4, sets.len());
|
assert_eq!(4, sets.len());
|
||||||
assert_eq!(sets[0].len(), u8::max_value() as usize);
|
assert_eq!(sets[0].len(), u8::MAX as usize);
|
||||||
assert_eq!(sets[1].len(), u8::max_value() as usize);
|
assert_eq!(sets[1].len(), u8::MAX as usize);
|
||||||
assert_eq!(sets[2].len(), u8::max_value() as usize);
|
assert_eq!(sets[2].len(), u8::MAX as usize);
|
||||||
assert_eq!(sets[3].len(), u8::max_value() as usize);
|
assert_eq!(sets[3].len(), u8::MAX as usize);
|
||||||
|
|
||||||
verify_correct_link(&sets[0], &sets[1]);
|
verify_correct_link(&sets[0], &sets[1]);
|
||||||
verify_correct_link(&sets[1], &sets[2]);
|
verify_correct_link(&sets[1], &sets[2]);
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ pub async fn setup_gateway_from_api(
|
|||||||
nym_apis: &[Url],
|
nym_apis: &[Url],
|
||||||
) -> Result<InitialisationResult, WasmCoreError> {
|
) -> Result<InitialisationResult, WasmCoreError> {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
let gateways = current_gateways(&mut rng, nym_apis).await?;
|
let gateways = current_gateways(&mut rng, nym_apis, None).await?;
|
||||||
setup_gateway_wasm(client_store, force_tls, chosen_gateway, &gateways).await
|
setup_gateway_wasm(client_store, force_tls, chosen_gateway, &gateways).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Generated
+50
-187
@@ -81,12 +81,6 @@ version = "1.6.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bitflags"
|
|
||||||
version = "1.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blake2"
|
name = "blake2"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
@@ -157,13 +151,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "camino"
|
||||||
version = "1.0.94"
|
version = "1.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7"
|
checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"jobserver",
|
"serde",
|
||||||
"libc",
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo-platform"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo_metadata"
|
||||||
|
version = "0.18.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037"
|
||||||
|
dependencies = [
|
||||||
|
"camino",
|
||||||
|
"cargo-platform",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -558,6 +574,7 @@ dependencies = [
|
|||||||
"cw3-fixed-multisig",
|
"cw3-fixed-multisig",
|
||||||
"cw4",
|
"cw4",
|
||||||
"cw4-group",
|
"cw4-group",
|
||||||
|
"nym-contracts-common",
|
||||||
"nym-group-contract-common",
|
"nym-group-contract-common",
|
||||||
"nym-multisig-contract-common",
|
"nym-multisig-contract-common",
|
||||||
]
|
]
|
||||||
@@ -586,6 +603,7 @@ dependencies = [
|
|||||||
"cw-utils",
|
"cw-utils",
|
||||||
"cw2",
|
"cw2",
|
||||||
"cw4",
|
"cw4",
|
||||||
|
"nym-contracts-common",
|
||||||
"nym-group-contract-common",
|
"nym-group-contract-common",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -779,26 +797,6 @@ dependencies = [
|
|||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "enum-iterator"
|
|
||||||
version = "1.1.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "45a0ac4aeb3a18f92eaf09c6bb9b3ac30ff61ca95514fc58cbead1c9a6bf5401"
|
|
||||||
dependencies = [
|
|
||||||
"enum-iterator-derive",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "enum-iterator-derive"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "03cdc46ec28bd728e67540c528013c6a10eb69a02eb31078a1bda695438cbfb8"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 2.0.59",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ff"
|
name = "ff"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
@@ -825,15 +823,6 @@ version = "0.2.7"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f"
|
checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "form_urlencoded"
|
|
||||||
version = "1.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
|
|
||||||
dependencies = [
|
|
||||||
"percent-encoding",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "forward_ref"
|
name = "forward_ref"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@@ -871,31 +860,6 @@ dependencies = [
|
|||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "getset"
|
|
||||||
version = "0.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro-error",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.109",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "git2"
|
|
||||||
version = "0.14.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d0155506aab710a86160ddb504a480d2964d7ab5b9e62419be69e0032bc5931c"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"libc",
|
|
||||||
"libgit2-sys",
|
|
||||||
"log",
|
|
||||||
"url",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "group"
|
name = "group"
|
||||||
version = "0.12.1"
|
version = "0.12.1"
|
||||||
@@ -967,16 +931,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "idna"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-bidi",
|
|
||||||
"unicode-normalization",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "inout"
|
name = "inout"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
@@ -1001,15 +955,6 @@ version = "1.0.11"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "jobserver"
|
|
||||||
version = "0.1.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "k256"
|
name = "k256"
|
||||||
version = "0.11.6"
|
version = "0.11.6"
|
||||||
@@ -1048,36 +993,12 @@ version = "0.2.153"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libgit2-sys"
|
|
||||||
version = "0.13.5+1.4.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "51e5ea06c26926f1002dd553fded6cfcdc9784c1f60feeb58368b4d9b07b6dba"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
"libz-sys",
|
|
||||||
"pkg-config",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libm"
|
name = "libm"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "libz-sys"
|
|
||||||
version = "1.1.16"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
"pkg-config",
|
|
||||||
"vcpkg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lioness"
|
name = "lioness"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
@@ -1134,6 +1055,15 @@ dependencies = [
|
|||||||
"libm",
|
"libm",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_threads"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nym-coconut-bandwidth"
|
name = "nym-coconut-bandwidth"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -1173,8 +1103,8 @@ dependencies = [
|
|||||||
"cw4",
|
"cw4",
|
||||||
"cw4-group",
|
"cw4-group",
|
||||||
"nym-coconut-dkg-common",
|
"nym-coconut-dkg-common",
|
||||||
|
"nym-contracts-common",
|
||||||
"nym-group-contract-common",
|
"nym-group-contract-common",
|
||||||
"semver",
|
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
@@ -1199,9 +1129,11 @@ dependencies = [
|
|||||||
"bs58 0.5.1",
|
"bs58 0.5.1",
|
||||||
"cosmwasm-schema",
|
"cosmwasm-schema",
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
|
"cw-storage-plus",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"vergen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1246,11 +1178,9 @@ dependencies = [
|
|||||||
"nym-mixnet-contract-common",
|
"nym-mixnet-contract-common",
|
||||||
"nym-vesting-contract-common",
|
"nym-vesting-contract-common",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
"semver",
|
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"time",
|
"time",
|
||||||
"vergen",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1318,11 +1248,9 @@ dependencies = [
|
|||||||
"nym-mixnet-contract-common",
|
"nym-mixnet-contract-common",
|
||||||
"nym-vesting-contract-common",
|
"nym-vesting-contract-common",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
"semver",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"vergen",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1367,12 +1295,6 @@ dependencies = [
|
|||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "percent-encoding"
|
|
||||||
version = "2.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pkcs8"
|
name = "pkcs8"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
@@ -1393,12 +1315,6 @@ dependencies = [
|
|||||||
"spki 0.7.3",
|
"spki 0.7.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pkg-config"
|
|
||||||
version = "0.3.30"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "platforms"
|
name = "platforms"
|
||||||
version = "3.4.0"
|
version = "3.4.0"
|
||||||
@@ -1417,30 +1333,6 @@ version = "0.2.17"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-error"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro-error-attr",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn 1.0.109",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "proc-macro-error-attr"
|
|
||||||
version = "1.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.81"
|
version = "1.0.81"
|
||||||
@@ -1656,6 +1548,9 @@ name = "semver"
|
|||||||
version = "1.0.22"
|
version = "1.0.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
@@ -1879,7 +1774,9 @@ checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"deranged",
|
"deranged",
|
||||||
"itoa",
|
"itoa",
|
||||||
|
"libc",
|
||||||
"num-conv",
|
"num-conv",
|
||||||
|
"num_threads",
|
||||||
"powerfmt",
|
"powerfmt",
|
||||||
"serde",
|
"serde",
|
||||||
"time-core",
|
"time-core",
|
||||||
@@ -1923,58 +1820,24 @@ version = "1.17.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-bidi"
|
|
||||||
version = "0.3.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-normalization"
|
|
||||||
version = "0.1.23"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5"
|
|
||||||
dependencies = [
|
|
||||||
"tinyvec",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "url"
|
|
||||||
version = "2.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
|
|
||||||
dependencies = [
|
|
||||||
"form_urlencoded",
|
|
||||||
"idna",
|
|
||||||
"percent-encoding",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vcpkg"
|
|
||||||
version = "0.2.15"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vergen"
|
name = "vergen"
|
||||||
version = "7.4.3"
|
version = "8.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "447f9238a4553957277b3ee09d80babeae0811f1b3baefb093de1c0448437a37"
|
checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"cargo_metadata",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"enum-iterator",
|
"regex",
|
||||||
"getset",
|
|
||||||
"git2",
|
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"thiserror",
|
|
||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
- [Performance Monitoring & Testing](testing/performance.md)
|
- [Performance Monitoring & Testing](testing/performance.md)
|
||||||
<!--- [Node Setup](testing/node-setup.md)-->
|
<!--- [Node Setup](testing/node-setup.md)-->
|
||||||
- [Gateway Probe](testing/gateway-probe.md)
|
- [Gateway Probe](testing/gateway-probe.md)
|
||||||
|
- [Node API Check](testing/node-api-check.md)
|
||||||
- [Prometheus & Grafana](testing/prometheus-grafana.md)
|
- [Prometheus & Grafana](testing/prometheus-grafana.md)
|
||||||
- [ExploreNYM scripts](testing/explorenym-scripts.md)
|
- [ExploreNYM scripts](testing/explorenym-scripts.md)
|
||||||
<!-- - [Run in a Docker](testing/docker-monitor.md) -->
|
<!-- - [Run in a Docker](testing/docker-monitor.md) -->
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ As part of the transition, `allowed.list` on Exit Gateway embedded Network Reque
|
|||||||
./nym-node run --init-only --mode exit-gateway
|
./nym-node run --init-only --mode exit-gateway
|
||||||
|
|
||||||
# with a custom `--id` and other options
|
# with a custom `--id` and other options
|
||||||
./nym-node run --id <ID> --init-only --mode exit-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 true --location <COUNTRY_FULL_NAME> --wireguard-enabled false
|
./nym-node run --id <ID> --init-only --mode exit-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <COUNTRY_FULL_NAME> --wireguard-enabled false
|
||||||
|
|
||||||
# <YOUR_DOMAIN> is in format without 'https://' prefix
|
# <YOUR_DOMAIN> is in format without 'https://' prefix
|
||||||
# <COUNTRY_FULL_NAME> is format like 'Jamaica', or two-letter alpha2 (e.g. 'JM'), three-letter alpha3 (e.g. 'JAM') or three-digit numeric-3 (e.g. '388') can be provided.
|
# <COUNTRY_FULL_NAME> is format like 'Jamaica', or two-letter alpha2 (e.g. 'JM'), three-letter alpha3 (e.g. 'JAM') or three-digit numeric-3 (e.g. '388') can be provided.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Release Cycle
|
# Release Cycle
|
||||||
|
|
||||||
Nym operators community grows in quality and quantity. With node operators and developers joining the efforts to build Mixnet more robust and scalable, testing new features, sharing integration pull requests and generally taking an active part in Nym development, more transparency on the release cycle is required.
|
The Nym operator community is growing in quality and quantity. With node operators and developers joining the effort to make the Mixnet more robust and scalable, testing new features, sharing integration pull requests and generally taking an active part in Nym development, more transparency on the release cycle is required.
|
||||||
|
|
||||||
The core team therefore established a flow with different environments:
|
The core team therefore established a flow with different environments:
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ The core team therefore established a flow with different environments:
|
|||||||
|
|
||||||
## Release Flow
|
## Release Flow
|
||||||
|
|
||||||
Frequency of releases to mainnet is aimed to be every ~14 days. This time time window is an optimal compromise between periodicity and qualty assurance/testing, key factors playing an essential role in the development.
|
Frequency of releases to mainnet is aimed to be every ~14 days. This time window is an optimal compromise between periodicity and quality assurance/testing, key factors playing an essential role in development.
|
||||||
|
|
||||||
| **Stage** | **Environment** | **Branch** | **Ownership** |
|
| **Stage** | **Environment** | **Branch** | **Ownership** |
|
||||||
| :-- | :-- | :-- | :-- |
|
| :-- | :-- | :-- | :-- |
|
||||||
@@ -80,7 +80,7 @@ ENVs
|
|||||||
To track changes easily, builders and operators can visit one of the following:
|
To track changes easily, builders and operators can visit one of the following:
|
||||||
|
|
||||||
- [*CHANGELOG.md*](https://github.com/nymtech/nym/blob/master/CHANGELOG.md): Raw changelog of the merged feauters in Nym's monorepo, managed by devs and QA.
|
- [*CHANGELOG.md*](https://github.com/nymtech/nym/blob/master/CHANGELOG.md): Raw changelog of the merged feauters in Nym's monorepo, managed by devs and QA.
|
||||||
- [*Changelog page*](changelog.md): A copy of *CHANGELOG.md* with more detailed explanation, testing steps and update on documentation changes, managed by devrels.
|
- [*Changelog page*](changelog.md): A copy of *CHANGELOG.md* with more detailed explanation, testing steps and updated summary of documentation changes, managed by devrels.
|
||||||
|
|
||||||
In case you want to propose changes or resolve some of the existing [issues](https://github.com/nymtech/nym/issues), start [here](https://github.com/nymtech/nym/issues/new/choose). If you want to add content to the Operators Guide, visit [this page](legal/add-content.md).
|
In case you want to propose changes or resolve some of the existing [issues](https://github.com/nymtech/nym/issues), start [here](https://github.com/nymtech/nym/issues/new/choose). If you want to add content to the Operators Guide, visit [this page](legal/add-content.md).
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# Sandbox Testnet
|
# Sandbox Testnet
|
||||||
|
|
||||||
Nym node operators can run their nodes on Nym Sandbox testnet environment. Whether it's testing new configuration, hot features from Nym developers or just trying to setup a node for the first time, this environment is for you. Below are steps to [setup your environment](#sandbox-environment-setup) and an introduction to [Sandbox token faucet](#sandbox-token-faucet).
|
Nym node operators can run their nodes in Nym Sandbox testnet environment. Whether it's testing new configuration, hot features from Nym developers or just trying to setup a node for the first time, this environment is for you.
|
||||||
|
|
||||||
|
Below are steps to [setup your environment](#sandbox-environment-setup) and an introduction to [Sandbox token faucet](#sandbox-token-faucet).
|
||||||
|
|
||||||
```admonish warning title=""
|
```admonish warning title=""
|
||||||
This page is for Nym node operators. If you want to run NymVPN CLI over Sandbox testnet, visit our [developers portal](https://nymtech.net/developers/nymvpn/cli.html#testnet-environment).
|
This page is for Nym node operators. If you want to run NymVPN CLI over Sandbox testnet, visit our [developers portal](https://nymtech.net/developers/nymvpn/cli.html#testnet-environment).
|
||||||
@@ -10,21 +12,24 @@ This page is for Nym node operators. If you want to run NymVPN CLI over Sandbox
|
|||||||
|
|
||||||
> Any syntax in `<>` brackets is a user's unique variable. Exchange with a corresponding name without the `<>` brackets.
|
> Any syntax in `<>` brackets is a user's unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||||
|
|
||||||
To run Nym binaries in Sandbox Testnet you need to get the `.env` configuration file and point your binary to it. Follow the steps below:
|
To run Nym binaries in Sandbox testnet, you need to get `sandbox.env` configuration file and point your binary to it. Follow the steps below:
|
||||||
|
|
||||||
|
|
||||||
1. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your binaries:
|
1. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your binaries:
|
||||||
```sh
|
```sh
|
||||||
curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env
|
curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env
|
||||||
|
|
||||||
|
# In case you want to save the file elswhere, change the path in '-o' flag
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Run your `nym-node` with an additional flag `-c` or `--config-env-file` with a path to `sanbox.env` file followed by all needed commands and options. For example:
|
2. Run your `nym-node` with an additional flag `-c` or `--config-env-file` with a path to `sandbox.env` file followed by all needed commands and options. For example:
|
||||||
```sh
|
```sh
|
||||||
# this example is for mixnode mode
|
# this example is for nym-node in mixnode mode
|
||||||
./nym-node --config-env-file <PATH/TO/>sandbox.env run --mode mixnode
|
./nym-node --config-env-file <PATH/TO/>sandbox.env run --mode mixnode
|
||||||
|
|
||||||
# this example is for exit-gateway mode
|
# this example is for nym-node in exit-gateway mode
|
||||||
./nym-node --config-file-env <PATH/TO/>sandbox.env run --mode exit-gateway --id <ID> --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 true --location <COUNTRY_FULL_NAME>
|
./nym-node --config-file-env <PATH/TO/>sandbox.env run --mode exit-gateway --id <ID> --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 true --location <COUNTRY_FULL_NAME>
|
||||||
|
|
||||||
|
# In case you downloaded sandbox.env to the same directory, <PATH> is not needed
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Bond your node to Nym Sandbox environment:
|
3. Bond your node to Nym Sandbox environment:
|
||||||
@@ -35,7 +40,7 @@ curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/env
|
|||||||

|

|
||||||
|
|
||||||
~~~admonish tip
|
~~~admonish tip
|
||||||
1. If you [built Nym from source](building-nym.md), you already have `sanbox.env` as a part of the monorepo (`nym/envs/sandbox.env`). Giving that you likely to run `nym-node` from `nym/target/release`, the flag will look like this `--config-env-file ../../envs/sandbox.env`
|
1. If you [built Nym from source](building-nym.md), you already have `sanbox.env` as a part of the monorepo (`nym/envs/sandbox.env`). Giving that you are likely to run `nym-node` from `nym/target/release`, the flag will look like this `--config-env-file ../../envs/sandbox.env`
|
||||||
|
|
||||||
2. You can export the path to `sanbox.env` to your enviromental variables:
|
2. You can export the path to `sanbox.env` to your enviromental variables:
|
||||||
```sh
|
```sh
|
||||||
@@ -45,6 +50,6 @@ export NYMNODE_CONFIG_ENV_FILE_ARG=<PATH/TO/sandbox.env>
|
|||||||
|
|
||||||
## Sandbox Token Faucet
|
## Sandbox Token Faucet
|
||||||
|
|
||||||
To run your nodes in the sandbox environment, you need testnet version of NYM token, that can be aquired at [faucet.nymtech.net](https://faucet.nymtech.net).
|
To run your nodes in Sandbox environment, you need testnet version of NYM token, that can be aquired from [faucet.nymtech.net](https://faucet.nymtech.net).
|
||||||
|
|
||||||
To prevent abuse, the faucet is rate-limited - your request will fail if the requesting wallet already has 101 NYM tokens.
|
To prevent abuse, the faucet is rate-limited - your request will fail if the requesting wallet already has 101 NYM tokens.
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
# Node API Check
|
||||||
|
|
||||||
|
> Any syntax in `<>` brackets is a user's unique variable/version. Exchange with a corresponding name without the `<>` brackets.
|
||||||
|
|
||||||
|
Operating a `nym-node` is not a *"set and forget"* endeavor, it takes some work. To diagnose node performance querying APIs is a good knowledge to have. There are two main places to look for API endpoints regarding `nym-node`:
|
||||||
|
|
||||||
|
- [`openapi.json`](https://validator.nymtech.net/api/v1/openapi.json): a list of all endpoints
|
||||||
|
- [Swagger UI page](https://validator.nymtech.net/api/swagger/index.html)
|
||||||
|
|
||||||
|
Besides that, Gateway operators can check out their node performance, connectivity and much more on [harbourmaster.nymtech.net](https://harbourmaster.nymtech.net/).
|
||||||
|
|
||||||
|
### Basic API usage
|
||||||
|
|
||||||
|
For information about available endpoints and their status, you can refer to:
|
||||||
|
```
|
||||||
|
# for http
|
||||||
|
http://<IP>:8080/api/v1/swagger/#/
|
||||||
|
|
||||||
|
# for https reversed proxy
|
||||||
|
https://<DOMAIN>/api/v1/swagger/#/
|
||||||
|
```
|
||||||
|
|
||||||
|
For example to determine which mode your node is running, you can check `:8080/api/v1/roles` endpoint:
|
||||||
|
```
|
||||||
|
# for http
|
||||||
|
http://<IP_ADDRESS>:8080/api/v1/roles
|
||||||
|
|
||||||
|
# for https reversed proxy
|
||||||
|
https://<DOMAIN>/api/v1/roles
|
||||||
|
```
|
||||||
|
|
||||||
|
## `node_api_check.py`
|
||||||
|
|
||||||
|
To make this a bit easier, we made a CLI tool quering all vailable API endpoints based on node `Identity Key` (further denoted as `<ID_KEY>`) called `node_api_check.py`. To diagnose your node performance, whether by yourself or by sharing an output in our [operator channel](https://matrix.to/#/#operators:nymtech.chat), this tool provides you with a quick overview of live data. We recommend to run this checker alongside [`nym_gateway_probe`](gateway-probe.md) to triage both performance and an actual routing.
|
||||||
|
|
||||||
|
Besides querying any bonded node APIs, `nym_api_check` has a function counting all existing nodes in provided version.
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
#### Pre-requsities
|
||||||
|
|
||||||
|
**Python3**
|
||||||
|
|
||||||
|
1. Start with installing Python3:
|
||||||
|
```sh
|
||||||
|
sudo apt install Python3
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Make sure Python3 is your default Python version:
|
||||||
|
```sh
|
||||||
|
update-alternatives --install /usr/bin/python python /usr/bin/python3 1
|
||||||
|
|
||||||
|
# controll
|
||||||
|
python --version
|
||||||
|
# should return higher than 3
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Install Python modules `tabulate`, `pandas` and `argparse`:
|
||||||
|
- either using [`pip`](https://python.land/virtual-environments/installing-packages-with-pip) and then running:
|
||||||
|
```sh
|
||||||
|
pip install tabulate pandas argparse
|
||||||
|
```
|
||||||
|
- or if you installed Python3 system-wide you can install modules directly:
|
||||||
|
```sh
|
||||||
|
sudo apt install python3-tabulate python3-pandas python3-argparse
|
||||||
|
```
|
||||||
|
|
||||||
|
**Installation**
|
||||||
|
|
||||||
|
4. Get [`node_api_check.py`](https://github.com/nymtech/nym/tree/develop/scripts/node_api_check.py) and [`api_endpoints.json`](https://github.com/nymtech/nym/tree/develop/scripts/api_endpoints.json). If you [compiled from source](../binaries/building-nym.md), you already have both of these files. If you prefer to download them individually, do it by opening terminal in your desired location and running:
|
||||||
|
```sh
|
||||||
|
wget https://raw.githubusercontent.com/nymtech/nym/tree/develop/node_api_check.py
|
||||||
|
|
||||||
|
wget https://raw.githubusercontent.com/nymtech/nym/tree/develop/api_endpoints.json
|
||||||
|
```
|
||||||
|
|
||||||
|
5. Make executable:
|
||||||
|
```sh
|
||||||
|
chmod u+x node_api_check.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you are ready to check your node.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
Run with `--help` flag to see the available commands:
|
||||||
|
|
||||||
|
~~~admonish example collapsible=true title="./node_api_check.py --help"
|
||||||
|
```python
|
||||||
|
<!--cmdrun cd ../../../../scripts && python ./node_api_check.py --help-->
|
||||||
|
```
|
||||||
|
~~~
|
||||||
|
|
||||||
|
#### `query_stats`
|
||||||
|
|
||||||
|
When you want to see all the options connected to a command, add a `--help` flag after the command of your choice, like in this example:
|
||||||
|
~~~admonish example collapsible=true title="./node_api_check.py query_stats --help"
|
||||||
|
```python
|
||||||
|
<!--cmdrun cd ../../../../scripts && python ./node_api_check.py query_stats --help-->
|
||||||
|
```
|
||||||
|
~~~
|
||||||
|
|
||||||
|
The most common usage may be `./node_api_check.py query_stats <ID_KEY>` where `<ID_KEY>` is required, sustitute it with node Identity Key.
|
||||||
|
|
||||||
|
**Optional arguments**
|
||||||
|
|
||||||
|
| Flag | Shortcut | Description |
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
| `--markdown` | `-m` | returns output in markdown format |
|
||||||
|
| `--no_routing_history` | `-n` | returns output without routing history which can be lenghty |
|
||||||
|
| `--output` | `-o` | exports output to a file, possible to add a target path |
|
||||||
|
|
||||||
|
#### `version_count`
|
||||||
|
|
||||||
|
Another command is `version_count` where at least one `nym-node` version is required. In case of multiple version count, separate the versions with space. We recommend to run this command with `--markdown` flag for a nicer output. This is an example where we want to look up how many registered nodes are on versions `1.1.0`, `1.1.1`, `1.1.2` and `1.1.3`:
|
||||||
|
```sh
|
||||||
|
./node_api_check version_count 1.1.0 1.1.1 1.1.2 1.1.3 --markdown
|
||||||
|
```
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
CONFIGURED=true
|
||||||
|
|
||||||
|
RUST_LOG=info
|
||||||
|
RUST_BACKTRACE=1
|
||||||
|
NETWORK_NAME=sandbox
|
||||||
|
BECH32_PREFIX=n
|
||||||
|
MIX_DENOM=unym
|
||||||
|
MIX_DENOM_DISPLAY=nym
|
||||||
|
STAKE_DENOM=unyx
|
||||||
|
STAKE_DENOM_DISPLAY=nyx
|
||||||
|
DENOMS_EXPONENT=6
|
||||||
|
|
||||||
|
REWARDING_VALIDATOR_ADDRESS=n1duuyj2th2y0z4u4f4wtljpdz9s3pxtu0xx6zdz
|
||||||
|
MIXNET_CONTRACT_ADDRESS=n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g
|
||||||
|
COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n1mf6ptkssddfmxvhdx0ech0k03ktp6kf9yk59renau2gvht3nq2gqt5tdrk
|
||||||
|
GROUP_CONTRACT_ADDRESS=n1qg5ega6dykkxc307y25pecuufrjkxkaggkkxh7nad0vhyhtuhw3sa07c47
|
||||||
|
MULTISIG_CONTRACT_ADDRESS=n1zwv6feuzhy6a9wekh96cd57lsarmqlwxdypdsplw6zhfncqw6ftqx5a364
|
||||||
|
COCONUT_DKG_CONTRACT_ADDRESS=n1aakfpghcanxtc45gpqlx8j3rq0zcpyf49qmhm9mdjrfx036h4z5sy2vfh9
|
||||||
|
|
||||||
|
EXPLORER_API=https://canary-explorer.performance.nymte.ch/api
|
||||||
|
NYXD="https://canary-validator.performance.nymte.ch"
|
||||||
|
NYM_API="https://canary-api.performance.nymte.ch/api"
|
||||||
@@ -17,7 +17,6 @@ COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n1lp5zex6685kd22agzskhqsylpnssxnweyuvsz4edr4p
|
|||||||
GROUP_CONTRACT_ADDRESS=n1rw8fw2mpcpzzq3jpa4e52ufawnmj5a4u68p35umvgskewuw0nlzsaa5w4m
|
GROUP_CONTRACT_ADDRESS=n1rw8fw2mpcpzzq3jpa4e52ufawnmj5a4u68p35umvgskewuw0nlzsaa5w4m
|
||||||
MULTISIG_CONTRACT_ADDRESS=n1rw8fw2mpcpzzq3jpa4e52ufawnmj5a4u68p35umvgskewuw0nlzsaa5w4m
|
MULTISIG_CONTRACT_ADDRESS=n1rw8fw2mpcpzzq3jpa4e52ufawnmj5a4u68p35umvgskewuw0nlzsaa5w4m
|
||||||
COCONUT_DKG_CONTRACT_ADDRESS=n1vwtgazgpancsfel04y7syc95ausmat47cjtldqzkdmx6phyrwx2qvkv32p
|
COCONUT_DKG_CONTRACT_ADDRESS=n1vwtgazgpancsfel04y7syc95ausmat47cjtldqzkdmx6phyrwx2qvkv32p
|
||||||
EPHEMERA_CONTRACT_ADDRESS=n1vwtgazgpancsfel04y7syc95ausmat47cjtldqzkdmx6phyrwx2qvkv32p
|
|
||||||
REWARDING_VALIDATOR_ADDRESS=n1tfzd4qz3a45u8p4mr5zmzv66457uwjgcl05jdq
|
REWARDING_VALIDATOR_ADDRESS=n1tfzd4qz3a45u8p4mr5zmzv66457uwjgcl05jdq
|
||||||
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0"
|
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0"
|
||||||
NYXD="http://127.0.0.1:26657"
|
NYXD="http://127.0.0.1:26657"
|
||||||
|
|||||||
+8
-10
@@ -10,19 +10,17 @@ STAKE_DENOM=unyx
|
|||||||
STAKE_DENOM_DISPLAY=nyx
|
STAKE_DENOM_DISPLAY=nyx
|
||||||
DENOMS_EXPONENT=6
|
DENOMS_EXPONENT=6
|
||||||
|
|
||||||
MIXNET_CONTRACT_ADDRESS=n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g
|
MIXNET_CONTRACT_ADDRESS=n1hm4y6fzgxgu688jgf7ek66px6xkrtmn3gyk8fax3eawhp68c2d5qujz296
|
||||||
VESTING_CONTRACT_ADDRESS=n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw
|
COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n14y2x8a60knc5jjfeztt84kw8x8l5pwdgnqg256v0p9v4p7t2q6eswxyusw
|
||||||
COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n1aht6sekk0302hh30eje9a4lq84juwehw2hxv65kjh863ptay0sxs84mhx8
|
GROUP_CONTRACT_ADDRESS=n1qp35fcj0v9u3trhaps5v9q0lc42t4m6aty2wryss75ee8zuqnsqqdcreyq
|
||||||
GROUP_CONTRACT_ADDRESS=n17akgf5y2t775k27kulyw8durzsgfedym9wemg0qv3msc4ry0cg2senyl36
|
MULTISIG_CONTRACT_ADDRESS=n1qa4hswlcjmttulj0q9qa46jf64f93pecl6tydcsjldfe0hy5ju0sdmwzya
|
||||||
MULTISIG_CONTRACT_ADDRESS=n1075wwvq8ypag74tmzeu7a05mplwsa95g2p8wnxhhctv7hlp6y3wq9ttqcg
|
COCONUT_DKG_CONTRACT_ADDRESS=n1ayrk6wp6w5lf6njtnfjwljmtcc9vevv5sxwkz7uq24rp2pw67t0qhmmxdd
|
||||||
COCONUT_DKG_CONTRACT_ADDRESS=n1hk7jy0m6ec5gventvgsx8skrz8mrudhqhun0ufg5gaa3mrr83qyq45v2zk
|
VESTING_CONTRACT_ADDRESS=n1jlzdxnyces4hrhqz68dqk28mrw5jgwtcfq0c2funcwrmw0dx9l9s8nnnvj
|
||||||
REWARDING_VALIDATOR_ADDRESS=n1rfvpsynktze6wvn6ldskj8xgwfzzk5v6pnff39
|
REWARDING_VALIDATOR_ADDRESS=n1rfvpsynktze6wvn6ldskj8xgwfzzk5v6pnff39
|
||||||
NAME_SERVICE_CONTRACT_ADDRESS=n1qum2tr7hh4y7ruzew68c64myjec0dq2s2njf6waja5t0w879lutqadamme
|
|
||||||
SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS=n13ehuhysn5mqjeaheeuew2gjs785f6k7jm8vfsqg3jhtpkwppcmzq6m2hmz
|
|
||||||
|
|
||||||
STATISTICS_SERVICE_DOMAIN_ADDRESS="https://mainnet-stats.nymte.ch:8090"
|
|
||||||
EXPLORER_API=https://qa-network-explorer.qa.nymte.ch/api
|
EXPLORER_API=https://qa-network-explorer.qa.nymte.ch/api
|
||||||
NYXD="https://qa-validator.qa.nymte.ch"
|
NYXD="https://qa-validator.qa.nymte.ch"
|
||||||
NYM_API="https://qa-nym-api.qa.nymte.ch/api"
|
NYM_API="https://qa-nym-api.qa.nymte.ch/api"
|
||||||
|
|
||||||
EXIT_POLICY="https://nymtech.net/.wellknown/network-requester/exit-policy.txt"
|
DKG_TIME_CONFIGURATION="600,300,300,60,60,1209600"
|
||||||
|
EXIT_POLICY="https://nymtech.net/.wellknown/network-requester/exit-policy.txt"
|
||||||
|
|||||||
+1
-3
@@ -17,9 +17,7 @@ COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n1ljlwey4xdj0zs7zueepc48nkr033fca6fjgvurfvttq
|
|||||||
GROUP_CONTRACT_ADDRESS=n10v3rjnq4cjyccfykyams68ztce337gksuu6f0lvtl4meuwvkewaqru4uav
|
GROUP_CONTRACT_ADDRESS=n10v3rjnq4cjyccfykyams68ztce337gksuu6f0lvtl4meuwvkewaqru4uav
|
||||||
MULTISIG_CONTRACT_ADDRESS=n1cemnu8as0ls45v3caunpesl8jlsfw2ff9rlwnltlecp7zrxct4dsqc2y42
|
MULTISIG_CONTRACT_ADDRESS=n1cemnu8as0ls45v3caunpesl8jlsfw2ff9rlwnltlecp7zrxct4dsqc2y42
|
||||||
COCONUT_DKG_CONTRACT_ADDRESS=n1zx96qgd88vqlzcxkpwzks7kqs5ctrx36xtzfc58p7q6c4ng9anlqzc4nh8
|
COCONUT_DKG_CONTRACT_ADDRESS=n1zx96qgd88vqlzcxkpwzks7kqs5ctrx36xtzfc58p7q6c4ng9anlqzc4nh8
|
||||||
NAME_SERVICE_CONTRACT_ADDRESS=n12ne7qtmdwd0j03t9t5es8md66wq4e5xg9neladrsag8fx3y89rcs36asfp
|
|
||||||
SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS=n1ps5yutd7sufwg058qd7ac7ldnlazsvmhzqwucsfxmm445d70u8asqxpur4
|
|
||||||
EPHEMERA_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
|
|
||||||
|
|
||||||
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0"
|
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0"
|
||||||
EXPLORER_API=https://sandbox-explorer.nymtech.net/api
|
EXPLORER_API=https://sandbox-explorer.nymtech.net/api
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n16a32stm6kknhq5cc8rx77elr66pygf2hfszw7wvpq74
|
|||||||
GROUP_CONTRACT_ADDRESS=n1pd7kfgvr5tpcv0xnlv46c4jsq9jg2r799xxrcwqdm4l2jhq2pjwqrmz5ju
|
GROUP_CONTRACT_ADDRESS=n1pd7kfgvr5tpcv0xnlv46c4jsq9jg2r799xxrcwqdm4l2jhq2pjwqrmz5ju
|
||||||
MULTISIG_CONTRACT_ADDRESS=n14ph4e660eyqz0j36zlkaey4zgzexm5twkmjlqaequxr2cjm9eprqsmad6k
|
MULTISIG_CONTRACT_ADDRESS=n14ph4e660eyqz0j36zlkaey4zgzexm5twkmjlqaequxr2cjm9eprqsmad6k
|
||||||
COCONUT_DKG_CONTRACT_ADDRESS=n1ahg0erc2fs6xx3j5m8sfx3ryuzdjh6kf6qm9plsf865fltekyrfsesac6a
|
COCONUT_DKG_CONTRACT_ADDRESS=n1ahg0erc2fs6xx3j5m8sfx3ryuzdjh6kf6qm9plsf865fltekyrfsesac6a
|
||||||
NAME_SERVICE_CONTRACT_ADDRESS=n12ne7qtmdwd0j03t9t5es8md66wq4e5xg9neladrsag8fx3y89rcs36asfp
|
|
||||||
SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS=n1ps5yutd7sufwg058qd7ac7ldnlazsvmhzqwucsfxmm445d70u8asqxpur4
|
|
||||||
|
|
||||||
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0"
|
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0"
|
||||||
NYXD="https://rpc.sandbox.nymtech.net"
|
NYXD="https://rpc.sandbox.nymtech.net"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "explorer-api"
|
name = "explorer-api"
|
||||||
version = "1.1.34"
|
version = "1.1.36"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ const HM_SIZE: u8 = 100;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum GetSpError {
|
pub enum GetSpError {
|
||||||
|
#[allow(dead_code)]
|
||||||
ReqwestError(ReqwestError),
|
ReqwestError(ReqwestError),
|
||||||
|
#[allow(dead_code)]
|
||||||
Error(String),
|
Error(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,104 +0,0 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
|
||||||
|
|
||||||
use crate::node::client_handling::websocket::connection_handler::authenticated::RequestHandlingError;
|
|
||||||
use nym_bandwidth_claim_contract::msg::ExecuteMsg;
|
|
||||||
use nym_bandwidth_claim_contract::payment::LinkPaymentData;
|
|
||||||
use nym_credentials::token::bandwidth::TokenCredential;
|
|
||||||
use nym_crypto::asymmetric::identity::{PublicKey, Signature, SIGNATURE_LENGTH};
|
|
||||||
use nym_network_defaults::{ETH_EVENT_NAME, ETH_MIN_BLOCK_DEPTH};
|
|
||||||
use nym_validator_client::nxmd::traits::MixnetQueryClient;
|
|
||||||
use nym_validator_client::nyxd::{AccountId, NyxdClient, SigningNyxdClient};
|
|
||||||
use std::str::FromStr;
|
|
||||||
use web3::contract::tokens::Detokenize;
|
|
||||||
use web3::contract::{Contract, Error};
|
|
||||||
use web3::transports::Http;
|
|
||||||
use web3::types::{BlockNumber, FilterBuilder, H256};
|
|
||||||
use web3::Web3;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Burned {
|
|
||||||
/// The bandwidth bought by the client
|
|
||||||
pub bandwidth: u64,
|
|
||||||
/// Client public verification key
|
|
||||||
pub verification_key: PublicKey,
|
|
||||||
/// Signed verification key
|
|
||||||
pub signed_verification_key: Signature,
|
|
||||||
/// Address for the owner of the gateway
|
|
||||||
pub cosmos_recipient: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Burned {
|
|
||||||
pub fn verify(&self, verification_key: PublicKey) -> bool {
|
|
||||||
self.verification_key == verification_key
|
|
||||||
&& verification_key
|
|
||||||
.verify(
|
|
||||||
&self.verification_key.to_bytes(),
|
|
||||||
&self.signed_verification_key,
|
|
||||||
)
|
|
||||||
.is_ok()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Detokenize for Burned {
|
|
||||||
fn from_tokens(tokens: Vec<Token>) -> Result<Self, Error>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
if tokens.len() != 4 {
|
|
||||||
return Err(Error::InvalidOutputType(format!(
|
|
||||||
"Expected three elements, got: {:?}",
|
|
||||||
tokens
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
let bandwidth = tokens
|
|
||||||
.get(0)
|
|
||||||
.unwrap()
|
|
||||||
.clone()
|
|
||||||
.into_uint()
|
|
||||||
.ok_or_else(|| Error::InvalidOutputType(String::from("Expected Uint for bandwidth")))?
|
|
||||||
.as_u64();
|
|
||||||
let verification_key: [u8; 32] = tokens
|
|
||||||
.get(1)
|
|
||||||
.unwrap()
|
|
||||||
.clone()
|
|
||||||
.into_uint()
|
|
||||||
.ok_or_else(|| {
|
|
||||||
Error::InvalidOutputType(String::from("Expected Uint for verification key"))
|
|
||||||
})?
|
|
||||||
.into();
|
|
||||||
let verification_key = PublicKey::from_bytes(&verification_key).map_err(|_| {
|
|
||||||
Error::InvalidOutputType(format!(
|
|
||||||
"Expected verification key of 32 bytes, got: {}",
|
|
||||||
verification_key.len()
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
let signed_verification_key =
|
|
||||||
tokens.get(2).unwrap().clone().into_bytes().ok_or_else(|| {
|
|
||||||
Error::InvalidOutputType(String::from("Expected Bytes for the last two fields"))
|
|
||||||
})?;
|
|
||||||
let signed_verification_key =
|
|
||||||
Signature::from_bytes(&signed_verification_key[..SIGNATURE_LENGTH]).map_err(|_| {
|
|
||||||
Error::InvalidOutputType(format!(
|
|
||||||
"Expected signature of {} bytes, got: {}",
|
|
||||||
SIGNATURE_LENGTH,
|
|
||||||
signed_verification_key.len()
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
let cosmos_recipient = tokens
|
|
||||||
.get(3)
|
|
||||||
.unwrap()
|
|
||||||
.clone()
|
|
||||||
.into_string()
|
|
||||||
.ok_or_else(|| {
|
|
||||||
Error::InvalidOutputType(String::from("Expected utf8 encoded owner address"))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(Burned {
|
|
||||||
bandwidth,
|
|
||||||
verification_key,
|
|
||||||
signed_verification_key,
|
|
||||||
cosmos_recipient,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -318,6 +318,7 @@ impl<St> Gateway<St> {
|
|||||||
.with_shutdown(shutdown)
|
.with_shutdown(shutdown)
|
||||||
.with_custom_gateway_transceiver(Box::new(transceiver))
|
.with_custom_gateway_transceiver(Box::new(transceiver))
|
||||||
.with_wait_for_gateway(true)
|
.with_wait_for_gateway(true)
|
||||||
|
.with_minimum_gateway_performance(0)
|
||||||
.with_on_start(on_start_tx);
|
.with_on_start(on_start_tx);
|
||||||
|
|
||||||
if let Some(custom_mixnet) = &nr_opts.custom_mixnet_path {
|
if let Some(custom_mixnet) = &nr_opts.custom_mixnet_path {
|
||||||
@@ -382,6 +383,7 @@ impl<St> Gateway<St> {
|
|||||||
.with_shutdown(shutdown)
|
.with_shutdown(shutdown)
|
||||||
.with_custom_gateway_transceiver(Box::new(transceiver))
|
.with_custom_gateway_transceiver(Box::new(transceiver))
|
||||||
.with_wait_for_gateway(true)
|
.with_wait_for_gateway(true)
|
||||||
|
.with_minimum_gateway_performance(0)
|
||||||
.with_on_start(on_start_tx);
|
.with_on_start(on_start_tx);
|
||||||
|
|
||||||
if let Some(custom_mixnet) = &ip_opts.custom_mixnet_path {
|
if let Some(custom_mixnet) = &ip_opts.custom_mixnet_path {
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-api"
|
name = "nym-api"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
version = "1.1.38"
|
version = "1.1.40"
|
||||||
authors = [
|
authors = [
|
||||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
CREATE TABLE contract_mixnode_reward
|
|
||||||
(
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
mix_id INTEGER NOT NULL,
|
|
||||||
epoch INTEGER NOT NULL,
|
|
||||||
nym_api_id INTEGER NOT NULL,
|
|
||||||
reliability INTEGER NOT NULL,
|
|
||||||
timestamp INTEGER NOT NULL,
|
|
||||||
UNIQUE (mix_id, epoch)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE epoch_info
|
|
||||||
(
|
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
epoch_id INTEGER NOT NULL,
|
|
||||||
start_time INTEGER NOT NULL,
|
|
||||||
duration INTEGER NOT NULL,
|
|
||||||
UNIQUE (epoch_id)
|
|
||||||
);
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
CREATE TABLE mixnode_status
|
|
||||||
(
|
|
||||||
mix_id INTEGER NOT NULL,
|
|
||||||
reliability INTEGER NOT NULL,
|
|
||||||
timestamp INTEGER NOT NULL,
|
|
||||||
UNIQUE (mix_id, timestamp)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE rewarding_report
|
|
||||||
(
|
|
||||||
epoch_id INTEGER NOT NULL,
|
|
||||||
eligible_mixnodes INTEGER NOT NULL,
|
|
||||||
timestamp INTEGER NOT NULL,
|
|
||||||
UNIQUE (epoch_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE epoch_blocks
|
|
||||||
(
|
|
||||||
epoch_id INTEGER NOT NULL,
|
|
||||||
block_id INTEGER NOT NULL,
|
|
||||||
timestamp INTEGER NOT NULL,
|
|
||||||
UNIQUE (epoch_id, block_id)
|
|
||||||
);
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
CREATE TABLE mixnode_status
|
|
||||||
(
|
|
||||||
mix_id INTEGER NOT NULL,
|
|
||||||
reliability INTEGER NOT NULL,
|
|
||||||
timestamp INTEGER NOT NULL
|
|
||||||
);
|
|
||||||
@@ -84,7 +84,9 @@ impl From<GatewayDetails> for TestNode {
|
|||||||
|
|
||||||
pub struct TestedMixnodeStatus {
|
pub struct TestedMixnodeStatus {
|
||||||
pub db_id: i64,
|
pub db_id: i64,
|
||||||
|
#[allow(dead_code)]
|
||||||
pub mix_id: i64,
|
pub mix_id: i64,
|
||||||
|
#[allow(dead_code)]
|
||||||
pub identity_key: String,
|
pub identity_key: String,
|
||||||
pub reliability: Option<u8>,
|
pub reliability: Option<u8>,
|
||||||
pub timestamp: i64,
|
pub timestamp: i64,
|
||||||
@@ -98,6 +100,7 @@ pub struct TestedMixnodeStatus {
|
|||||||
|
|
||||||
pub struct TestedGatewayStatus {
|
pub struct TestedGatewayStatus {
|
||||||
pub db_id: i64,
|
pub db_id: i64,
|
||||||
|
#[allow(dead_code)]
|
||||||
pub identity_key: String,
|
pub identity_key: String,
|
||||||
pub reliability: Option<u8>,
|
pub reliability: Option<u8>,
|
||||||
pub timestamp: i64,
|
pub timestamp: i64,
|
||||||
|
|||||||
@@ -30,9 +30,6 @@ export interface Contracts {
|
|||||||
group_contract_address: string;
|
group_contract_address: string;
|
||||||
multisig_contract_address: string;
|
multisig_contract_address: string;
|
||||||
coconut_dkg_contract_address: string;
|
coconut_dkg_contract_address: string;
|
||||||
ephemera_contract_address: string;
|
|
||||||
service_provider_directory_contract_address: string;
|
|
||||||
name_service_contract_address: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Endpoint {
|
export interface Endpoint {
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "nym-node"
|
name = "nym-node"
|
||||||
version = "1.1.2"
|
version = "1.1.4"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
homepage.workspace = true
|
homepage.workspace = true
|
||||||
|
|||||||
@@ -179,5 +179,5 @@ pub struct AuxiliaryDetails {
|
|||||||
/// as defined at <https://nymtech.net/terms-and-conditions/operators/v1.0.0>
|
/// as defined at <https://nymtech.net/terms-and-conditions/operators/v1.0.0>
|
||||||
// make sure to include the default deserialisation as this field hasn't existed when the struct was first created
|
// make sure to include the default deserialisation as this field hasn't existed when the struct was first created
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub accepted_toc: bool,
|
pub accepted_operator_terms_and_conditions: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ pub(crate) struct Args {
|
|||||||
/// as defined at <https://nymtech.net/terms-and-conditions/operators/v1.0.0>
|
/// as defined at <https://nymtech.net/terms-and-conditions/operators/v1.0.0>
|
||||||
#[clap(
|
#[clap(
|
||||||
long,
|
long,
|
||||||
env = NYMNODE_ACCEPT_TOC,
|
env = NYMNODE_ACCEPT_OPERATOR_TERMS,
|
||||||
alias = "accept-toc",
|
|
||||||
alias = "accept-t&c",
|
alias = "accept-t&c",
|
||||||
alias = "accept-operator-terms-and-conditions"
|
alias = "accept-operator-terms",
|
||||||
|
alias = "accept-operator-t&c",
|
||||||
)]
|
)]
|
||||||
pub(crate) accept_operator_terms: bool,
|
pub(crate) accept_operator_terms_and_conditions: bool,
|
||||||
|
|
||||||
/// Forbid a new node from being initialised if configuration file for the provided specification doesn't already exist
|
/// Forbid a new node from being initialised if configuration file for the provided specification doesn't already exist
|
||||||
#[clap(
|
#[clap(
|
||||||
|
|||||||
@@ -46,11 +46,11 @@ pub(crate) async fn execute(mut args: Args) -> Result<(), NymNodeError> {
|
|||||||
let bonding_info_path = args.bonding_information_output.clone();
|
let bonding_info_path = args.bonding_information_output.clone();
|
||||||
let init_only = args.init_only;
|
let init_only = args.init_only;
|
||||||
let local = args.local;
|
let local = args.local;
|
||||||
let accepted_toc = args.accept_operator_terms;
|
let accepted_operator_terms_and_conditions = args.accept_operator_terms_and_conditions;
|
||||||
|
|
||||||
if !accepted_toc {
|
if !accepted_operator_terms_and_conditions {
|
||||||
warn!("you don't seem to have accepted the terms and conditions of a Nym node operator");
|
warn!("you don't seem to have accepted the terms and conditions of a Nym node operator");
|
||||||
warn!("please familiarise yourself with <https://nymtech.net/terms-and-conditions/operators/v1.0.0> and run the binary with '--accept-toc' flag if you agree with them");
|
warn!("please familiarise yourself with <https://nymtech.net/terms-and-conditions/operators/v1.0.0> and run the binary with '--accept-operator-terms-and-conditions' flag if you agree with them");
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = if !config_path.exists() {
|
let config = if !config_path.exists() {
|
||||||
@@ -85,7 +85,9 @@ pub(crate) async fn execute(mut args: Args) -> Result<(), NymNodeError> {
|
|||||||
}
|
}
|
||||||
check_public_ips(&config.host.public_ips, local)?;
|
check_public_ips(&config.host.public_ips, local)?;
|
||||||
|
|
||||||
let nym_node = NymNode::new(config).await?.with_accepted_toc(accepted_toc);
|
let nym_node = NymNode::new(config)
|
||||||
|
.await?
|
||||||
|
.with_accepted_operator_terms_and_conditions(accepted_operator_terms_and_conditions);
|
||||||
|
|
||||||
// if requested, write bonding info
|
// if requested, write bonding info
|
||||||
if let Some(bonding_info_path) = bonding_info_path {
|
if let Some(bonding_info_path) = bonding_info_path {
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ pub mod vars {
|
|||||||
|
|
||||||
pub const NYMNODE_MODE_ARG: &str = "NYMNODE_MODE";
|
pub const NYMNODE_MODE_ARG: &str = "NYMNODE_MODE";
|
||||||
|
|
||||||
pub const NYMNODE_ACCEPT_TOC: &str = "NYMNODE_ACCEPT_TOC";
|
pub const NYMNODE_ACCEPT_OPERATOR_TERMS: &str = "NYMNODE_ACCEPT_OPERATOR_TERMS";
|
||||||
|
|
||||||
// host:
|
// host:
|
||||||
pub const NYMNODE_PUBLIC_IPS_ARG: &str = "NYMNODE_PUBLIC_IPS";
|
pub const NYMNODE_PUBLIC_IPS_ARG: &str = "NYMNODE_PUBLIC_IPS";
|
||||||
|
|||||||
@@ -293,7 +293,7 @@ impl From<WireguardData> for nym_wireguard::WireguardData {
|
|||||||
|
|
||||||
pub(crate) struct NymNode {
|
pub(crate) struct NymNode {
|
||||||
config: Config,
|
config: Config,
|
||||||
accepted_toc: bool,
|
accepted_operator_terms_and_conditions: bool,
|
||||||
|
|
||||||
description: NodeDescription,
|
description: NodeDescription,
|
||||||
|
|
||||||
@@ -394,12 +394,15 @@ impl NymNode {
|
|||||||
exit_gateway: ExitGatewayData::new(&config.exit_gateway)?,
|
exit_gateway: ExitGatewayData::new(&config.exit_gateway)?,
|
||||||
wireguard: wireguard_data,
|
wireguard: wireguard_data,
|
||||||
config,
|
config,
|
||||||
accepted_toc: false,
|
accepted_operator_terms_and_conditions: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn with_accepted_toc(mut self, accepted_toc: bool) -> Self {
|
pub(crate) fn with_accepted_operator_terms_and_conditions(
|
||||||
self.accepted_toc = accepted_toc;
|
mut self,
|
||||||
|
accepted_operator_terms_and_conditions: bool,
|
||||||
|
) -> Self {
|
||||||
|
self.accepted_operator_terms_and_conditions = accepted_operator_terms_and_conditions;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -538,7 +541,7 @@ impl NymNode {
|
|||||||
|
|
||||||
let auxiliary_details = api_requests::v1::node::models::AuxiliaryDetails {
|
let auxiliary_details = api_requests::v1::node::models::AuxiliaryDetails {
|
||||||
location: self.config.host.location,
|
location: self.config.host.location,
|
||||||
accepted_toc: self.accepted_toc,
|
accepted_operator_terms_and_conditions: self.accepted_operator_terms_and_conditions,
|
||||||
};
|
};
|
||||||
|
|
||||||
// mixnode info
|
// mixnode info
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ use curve25519_dalek::montgomery::MontgomeryPoint;
|
|||||||
use curve25519_dalek::scalar::Scalar;
|
use curve25519_dalek::scalar::Scalar;
|
||||||
|
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use std::u8;
|
|
||||||
|
|
||||||
use crate::constants::groupelementbytes;
|
use crate::constants::groupelementbytes;
|
||||||
use crate::constants::tagbytes;
|
use crate::constants::tagbytes;
|
||||||
|
|||||||
Generated
+39
-15
@@ -293,8 +293,6 @@ dependencies = [
|
|||||||
"bs58 0.5.1",
|
"bs58 0.5.1",
|
||||||
"hmac",
|
"hmac",
|
||||||
"k256",
|
"k256",
|
||||||
"once_cell",
|
|
||||||
"pbkdf2",
|
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"ripemd",
|
"ripemd",
|
||||||
"sha2 0.10.8",
|
"sha2 0.10.8",
|
||||||
@@ -515,6 +513,38 @@ dependencies = [
|
|||||||
"system-deps 6.1.1",
|
"system-deps 6.1.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "camino"
|
||||||
|
version = "1.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo-platform"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cargo_metadata"
|
||||||
|
version = "0.18.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037"
|
||||||
|
dependencies = [
|
||||||
|
"camino",
|
||||||
|
"cargo-platform",
|
||||||
|
"semver 1.0.22",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cargo_toml"
|
name = "cargo_toml"
|
||||||
version = "0.13.3"
|
version = "0.13.3"
|
||||||
@@ -1606,7 +1636,6 @@ version = "0.13.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
|
checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitvec",
|
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"subtle 2.5.0",
|
"subtle 2.5.0",
|
||||||
]
|
]
|
||||||
@@ -3164,9 +3193,11 @@ dependencies = [
|
|||||||
"bs58 0.5.1",
|
"bs58 0.5.1",
|
||||||
"cosmwasm-schema",
|
"cosmwasm-schema",
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
|
"cw-storage-plus",
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"vergen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3748,16 +3779,6 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pbkdf2"
|
|
||||||
version = "0.12.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
|
|
||||||
dependencies = [
|
|
||||||
"digest 0.10.7",
|
|
||||||
"hmac",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "peg"
|
name = "peg"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@@ -6106,11 +6127,14 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vergen"
|
name = "vergen"
|
||||||
version = "8.2.6"
|
version = "8.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1290fd64cc4e7d3c9b07d7f333ce0ce0007253e32870e632624835cc80b83939"
|
checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"cargo_metadata",
|
||||||
|
"cfg-if",
|
||||||
|
"regex",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
"rustversion",
|
"rustversion",
|
||||||
"time",
|
"time",
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ pub(crate) const STAKE_DENOM: DenomDetails = DenomDetails::new("unyx", "nyx", 6)
|
|||||||
// -- Contract addresses --
|
// -- Contract addresses --
|
||||||
|
|
||||||
pub(crate) const MIXNET_CONTRACT_ADDRESS: &str =
|
pub(crate) const MIXNET_CONTRACT_ADDRESS: &str =
|
||||||
"n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g";
|
"n1hm4y6fzgxgu688jgf7ek66px6xkrtmn3gyk8fax3eawhp68c2d5qujz296";
|
||||||
pub(crate) const VESTING_CONTRACT_ADDRESS: &str =
|
pub(crate) const VESTING_CONTRACT_ADDRESS: &str =
|
||||||
"n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw";
|
"n1jlzdxnyces4hrhqz68dqk28mrw5jgwtcfq0c2funcwrmw0dx9l9s8nnnvj";
|
||||||
pub(crate) const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str =
|
pub(crate) const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str =
|
||||||
"n1w798gp0zqv3s9hjl3jlnwxtwhykga6rn93p46q2crsdqhaj3y4gs68f74j";
|
"n1w798gp0zqv3s9hjl3jlnwxtwhykga6rn93p46q2crsdqhaj3y4gs68f74j";
|
||||||
pub(crate) const GROUP_CONTRACT_ADDRESS: &str =
|
pub(crate) const GROUP_CONTRACT_ADDRESS: &str =
|
||||||
@@ -23,10 +23,6 @@ pub(crate) const MULTISIG_CONTRACT_ADDRESS: &str =
|
|||||||
"n1sr06m8yqg0wzqqyqvzvp5t07dj4nevx9u8qc7j4qa72qu8e3ct8qledthy";
|
"n1sr06m8yqg0wzqqyqvzvp5t07dj4nevx9u8qc7j4qa72qu8e3ct8qledthy";
|
||||||
pub(crate) const COCONUT_DKG_CONTRACT_ADDRESS: &str =
|
pub(crate) const COCONUT_DKG_CONTRACT_ADDRESS: &str =
|
||||||
"n1udfs22xpxle475m2nz7u47jfa3vngncdegmczwwdx00cmetypa3s7uyuqn";
|
"n1udfs22xpxle475m2nz7u47jfa3vngncdegmczwwdx00cmetypa3s7uyuqn";
|
||||||
pub(crate) const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str =
|
|
||||||
"n13ehuhysn5mqjeaheeuew2gjs785f6k7jm8vfsqg3jhtpkwppcmzq6m2hmz";
|
|
||||||
pub(crate) const NAME_SERVICE_CONTRACT_ADDRESS: &str =
|
|
||||||
"n1qum2tr7hh4y7ruzew68c64myjec0dq2s2njf6waja5t0w879lutqadamme";
|
|
||||||
|
|
||||||
// -- Constructor functions --
|
// -- Constructor functions --
|
||||||
|
|
||||||
@@ -58,10 +54,6 @@ pub(crate) fn network_details() -> nym_network_defaults::NymNetworkDetails {
|
|||||||
group_contract_address: parse_optional_str(GROUP_CONTRACT_ADDRESS),
|
group_contract_address: parse_optional_str(GROUP_CONTRACT_ADDRESS),
|
||||||
multisig_contract_address: parse_optional_str(MULTISIG_CONTRACT_ADDRESS),
|
multisig_contract_address: parse_optional_str(MULTISIG_CONTRACT_ADDRESS),
|
||||||
coconut_dkg_contract_address: parse_optional_str(COCONUT_DKG_CONTRACT_ADDRESS),
|
coconut_dkg_contract_address: parse_optional_str(COCONUT_DKG_CONTRACT_ADDRESS),
|
||||||
service_provider_directory_contract_address: parse_optional_str(
|
|
||||||
SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS,
|
|
||||||
),
|
|
||||||
name_service_contract_address: parse_optional_str(NAME_SERVICE_CONTRACT_ADDRESS),
|
|
||||||
},
|
},
|
||||||
explorer_api: parse_optional_str(EXPLORER_API),
|
explorer_api: parse_optional_str(EXPLORER_API),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,8 +54,6 @@ pub(crate) fn network_details() -> nym_network_defaults::NymNetworkDetails {
|
|||||||
group_contract_address: parse_optional_str(GROUP_CONTRACT_ADDRESS),
|
group_contract_address: parse_optional_str(GROUP_CONTRACT_ADDRESS),
|
||||||
multisig_contract_address: parse_optional_str(MULTISIG_CONTRACT_ADDRESS),
|
multisig_contract_address: parse_optional_str(MULTISIG_CONTRACT_ADDRESS),
|
||||||
coconut_dkg_contract_address: parse_optional_str(COCONUT_DKG_CONTRACT_ADDRESS),
|
coconut_dkg_contract_address: parse_optional_str(COCONUT_DKG_CONTRACT_ADDRESS),
|
||||||
service_provider_directory_contract_address: None,
|
|
||||||
name_service_contract_address: None,
|
|
||||||
},
|
},
|
||||||
explorer_api: parse_optional_str(EXPLORER_API),
|
explorer_api: parse_optional_str(EXPLORER_API),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"mixnode":[
|
||||||
|
"/status/mixnode/{mix_id}/report",
|
||||||
|
"/status/mixnode/{mix_id}/history",
|
||||||
|
"/status/mixnode/{mix_id}/core-status-count",
|
||||||
|
"/status/mixnode/{mix_id}/status",
|
||||||
|
"/status/mixnode/{mix_id}/reward-estimation",
|
||||||
|
"/status/mixnode/{mix_id}/compute-reward-estimation",
|
||||||
|
"/status/mixnode/{mix_id}/stake-saturation",
|
||||||
|
"/status/mixnode/{mix_id}/inclusion-probability",
|
||||||
|
"/status/mixnode/{mix_id}/avg_uptime"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
"gateway":[
|
||||||
|
"/status/gateway/{identity}/report",
|
||||||
|
"/status/gateway/{identity}/history",
|
||||||
|
"/status/gateway/{identity}/core-status-count",
|
||||||
|
"/status/gateway/{identity}/avg_uptime"
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
"swagger":[
|
||||||
|
"/roles",
|
||||||
|
"/build-information",
|
||||||
|
"/description",
|
||||||
|
"/host-information",
|
||||||
|
"/system-info",
|
||||||
|
"/gateway",
|
||||||
|
"/gateway/client-interfaces",
|
||||||
|
"/gateway/client-interfaces/mixnet-websockets",
|
||||||
|
"/gateway/client-interfaces/wireguard",
|
||||||
|
"/health",
|
||||||
|
"/ip-packet-router",
|
||||||
|
"/metrics/mixing",
|
||||||
|
"/metrics/prometheus",
|
||||||
|
"/metrics/verloc",
|
||||||
|
"/mixnode",
|
||||||
|
"/network-requester",
|
||||||
|
"/network-requester/exit-policy"
|
||||||
|
]
|
||||||
|
}
|
||||||
Executable
+401
@@ -0,0 +1,401 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
# TODO (in later versions)
|
||||||
|
# - make option to run in sandbox env
|
||||||
|
# - pull endpoints from: https://validator.nymtech.net/api/v1/openapi.json
|
||||||
|
# - try this https://stackoverflow.com/questions/15431044/can-i-set-max-retries-for-requests-request/35504626#35504626
|
||||||
|
|
||||||
|
import requests as r
|
||||||
|
import argparse
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import pandas as pd
|
||||||
|
import json
|
||||||
|
import urllib3
|
||||||
|
import time
|
||||||
|
from json import JSONDecodeError
|
||||||
|
from tabulate import tabulate
|
||||||
|
|
||||||
|
|
||||||
|
class MainFunctions:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.api_url = "https://validator.nymtech.net/api/v1"
|
||||||
|
self.api_endpoints_json = "api_endpoints.json"
|
||||||
|
self.output = Output()
|
||||||
|
|
||||||
|
def display_results(self, args):
|
||||||
|
id_key = args.id
|
||||||
|
mode, host, version, mix_id, role, node_df, node_dict, api_data, swagger_data, routing_history = self.collect_all_results(args)
|
||||||
|
print("\n============================================================")
|
||||||
|
print("\nNYM NODE INFO\n")
|
||||||
|
print(f"Type = {mode}")
|
||||||
|
if role:
|
||||||
|
print(f"Mode = {role}")
|
||||||
|
print(f"Identity Key = {id_key}")
|
||||||
|
print(f"Host = {host}")
|
||||||
|
print(f"Version = {version}")
|
||||||
|
if mix_id:
|
||||||
|
print(f"Mix ID = {mix_id}")
|
||||||
|
print("\n\nNODE RESULTS FROM UNFILTERED QUERY\n")
|
||||||
|
if args.markdown:
|
||||||
|
node_markdown = self._dataframe_to_markdown(node_df, ["RESULT"], ["API EDNPOINT"])
|
||||||
|
print(node_markdown, "\n")
|
||||||
|
else:
|
||||||
|
self.print_neat_dict(node_dict)
|
||||||
|
print(f"\n\nNODE RESULTS FROM {self.api_url.upper()}\n")
|
||||||
|
if args.markdown:
|
||||||
|
api_df = self._json_to_dataframe(api_data)
|
||||||
|
node_markdown = self._dataframe_to_markdown(api_df, ["RESULT"], ["API EDNPOINT"])
|
||||||
|
print(node_markdown, "\n")
|
||||||
|
else:
|
||||||
|
self.print_neat_dict(api_data)
|
||||||
|
if swagger_data:
|
||||||
|
print(f"\n\nNODE RESULTS FROM SWAGGER PAGE\n")
|
||||||
|
if args.markdown:
|
||||||
|
swagger_df = self._json_to_dataframe(swagger_data)
|
||||||
|
node_markdown = self._dataframe_to_markdown(swagger_df, ["RESULT"], ["API EDNPOINT"])
|
||||||
|
print(node_markdown, "\n")
|
||||||
|
else:
|
||||||
|
swagger_data = self._json_neat_format(swagger_data)
|
||||||
|
print(swagger_data)
|
||||||
|
else:
|
||||||
|
swagger_data = f"\nSwagger API endpoints of node {id_key} hosted on IP: {host} are not responding. Maybe you querying a deprecated version of nym-mixnode or the VPS ports are not open correctly.\n"
|
||||||
|
if routing_history:
|
||||||
|
print(f"\n\nNODE UPTIME HISTORY\n")
|
||||||
|
if args.markdown:
|
||||||
|
routing_history_df = self._json_to_dataframe(routing_history)
|
||||||
|
print(routing_history_df.to_markdown(index = False))
|
||||||
|
else:
|
||||||
|
self.print_neat_dict(routing_history)
|
||||||
|
routing_history = self._json_neat_format(routing_history)
|
||||||
|
else:
|
||||||
|
routing_history = " "
|
||||||
|
if args.output or args.output == "":
|
||||||
|
node_dict = self._json_neat_format(node_dict)
|
||||||
|
api_data = self._json_neat_format(api_data)
|
||||||
|
if role:
|
||||||
|
data_list = [f"Id. Key = {id_key}", f"Host = {host}", f"Type = {mode}", f"Mode = {role}", node_dict, api_data, swagger_data, routing_history]
|
||||||
|
else:
|
||||||
|
data_list = [f"Id. Key = {id_key}", f"Host = {host}", f"Type = {mode}", node_dict, api_data, swagger_data, routing_history]
|
||||||
|
self.output.concat_to_file(args, data_list)
|
||||||
|
|
||||||
|
def collect_all_results(self,args):
|
||||||
|
id_key = args.id
|
||||||
|
gateways_unfiltered, mixnodes_unfiltered = self.get_unfiltered_data()
|
||||||
|
gateways_df = self._json_to_dataframe(gateways_unfiltered)
|
||||||
|
gateways_df = self._set_index_to_empty(gateways_df)
|
||||||
|
mixnodes_df = self._json_to_dataframe(mixnodes_unfiltered)
|
||||||
|
mixnodes_df = self._set_index_to_empty(mixnodes_df)
|
||||||
|
mode, node_df, node_dict = self.get_node_df(id_key, gateways_df, mixnodes_df, gateways_unfiltered, mixnodes_unfiltered)
|
||||||
|
host, version, mix_id, role, api_data, swagger_data, routing_history = self.get_node_data(mode, node_dict, id_key, args)
|
||||||
|
return mode, host, version, mix_id, role, node_df, node_dict, api_data, swagger_data, routing_history
|
||||||
|
|
||||||
|
def get_node_df(self,id_key, gateways_df, mixnodes_df, gateways_unfiltered,mixnodes_unfiltered):
|
||||||
|
if id_key in mixnodes_df['mixnode_details.bond_information.mix_node.identity_key'].values:
|
||||||
|
node_df = mixnodes_df.loc[mixnodes_df['mixnode_details.bond_information.mix_node.identity_key'] == id_key]
|
||||||
|
node_dict = next((mn for mn in mixnodes_unfiltered if mn['mixnode_details']['bond_information']['mix_node']['identity_key'] == f"{id_key}"), None)
|
||||||
|
mode = "mixnode"
|
||||||
|
elif id_key in gateways_df["gateway_bond.gateway.identity_key"].values:
|
||||||
|
node_df = gateways_df.loc[gateways_df["gateway_bond.gateway.identity_key"] == id_key]
|
||||||
|
node_dict = next((gw for gw in gateways_unfiltered if gw['gateway_bond']['gateway']['identity_key'] == f"{id_key}"), None)
|
||||||
|
mode = "gateway"
|
||||||
|
else:
|
||||||
|
print(f"The identity key '{id_key}' does not exist.")
|
||||||
|
return mode, node_df, node_dict
|
||||||
|
|
||||||
|
def get_unfiltered_data(self):
|
||||||
|
print("INFO: Starting to query /detailed-unfiltered endpoint...")
|
||||||
|
gateways_unfiltered = r.get(f"{self.api_url}/status/gateways/detailed-unfiltered").json()
|
||||||
|
mixnodes_unfiltered = r.get(f"{self.api_url}/status/mixnodes/detailed-unfiltered").json()
|
||||||
|
return gateways_unfiltered, mixnodes_unfiltered
|
||||||
|
|
||||||
|
def get_node_data(self,mode, node_dict, id_key, args):
|
||||||
|
print("INFO: Sorting out data from the unfiltered endpoint...")
|
||||||
|
identity = id_key
|
||||||
|
endpoint_json = self.api_endpoints_json
|
||||||
|
with open(endpoint_json, "r") as f:
|
||||||
|
dicts = json.load(f)
|
||||||
|
endpoints = dicts[mode]
|
||||||
|
swagger = dicts["swagger"]
|
||||||
|
api_data = {}
|
||||||
|
swagger_data = {}
|
||||||
|
routing_history = {}
|
||||||
|
mix_id = None
|
||||||
|
role = None
|
||||||
|
if mode == "gateway":
|
||||||
|
host = node_dict["gateway_bond"]["gateway"]["host"]
|
||||||
|
version = node_dict["gateway_bond"]["gateway"]["version"]
|
||||||
|
for key in endpoints:
|
||||||
|
endpoint = key.replace("{identity}", identity)
|
||||||
|
url = f"{self.api_url}{endpoint}"
|
||||||
|
print(f"Querying {url}")
|
||||||
|
value = r.get(url).json()
|
||||||
|
api_data[endpoint] = value
|
||||||
|
routing_history = api_data[f"/status/gateway/{identity}/history"]["history"]
|
||||||
|
del api_data[f"/status/gateway/{identity}/history"]["history"]
|
||||||
|
swagger_data = self.get_swagger_data(host,swagger,swagger_data)
|
||||||
|
if swagger_data["/roles"]["network_requester_enabled"]== True and swagger_data["/roles"]["ip_packet_router_enabled"] == True:
|
||||||
|
role = "exit-gateway"
|
||||||
|
else:
|
||||||
|
role = "entry-gateway"
|
||||||
|
elif mode == "mixnode":
|
||||||
|
mix_id = str(node_dict["mixnode_details"]["bond_information"]["mix_id"])
|
||||||
|
for key in endpoints:
|
||||||
|
endpoint = key.replace("{mix_id}", mix_id)
|
||||||
|
url = f"{self.api_url}{endpoint}"
|
||||||
|
print(f"Querying {url}")
|
||||||
|
try:
|
||||||
|
value = r.get(url).json()
|
||||||
|
api_data[endpoint] = value
|
||||||
|
except (JSONDecodeError, json.JSONDecodeError, r.exceptions.JSONDecodeError):
|
||||||
|
print(f"Error: Endpoint {url} results in 404: Not Found!")
|
||||||
|
host = node_dict["mixnode_details"]["bond_information"]["mix_node"]["host"]
|
||||||
|
version = node_dict["mixnode_details"]["bond_information"]["mix_node"]["version"]
|
||||||
|
routing_history = api_data[f"/status/mixnode/{mix_id}/history"]["history"]
|
||||||
|
del api_data[f"/status/mixnode/{mix_id}/history"]["history"]
|
||||||
|
swagger_data = self.get_swagger_data(host,swagger,swagger_data)
|
||||||
|
else:
|
||||||
|
print(f"The mode type {mode} is not recognized!")
|
||||||
|
sys.exit(-1)
|
||||||
|
host = str(host)
|
||||||
|
|
||||||
|
if args.no_routing_history == True:
|
||||||
|
routing_history = None
|
||||||
|
else:
|
||||||
|
routing_history = routing_history
|
||||||
|
|
||||||
|
return host, version, mix_id, role, api_data, swagger_data, routing_history
|
||||||
|
|
||||||
|
def get_swagger_data(self,host,swagger,swagger_data):
|
||||||
|
print("INFO: Starting to query SWAGGER API endpoints...")
|
||||||
|
urls = [
|
||||||
|
f"http://{host}:8080/api/v1",
|
||||||
|
f"https://{host}/api/v1",
|
||||||
|
f"http://{host}/api/v1"
|
||||||
|
]
|
||||||
|
responding_url = self.get_swagger_response(urls)
|
||||||
|
if responding_url:
|
||||||
|
for endpoint in swagger:
|
||||||
|
print(f"Querying {responding_url}{endpoint}")
|
||||||
|
value = self.try_query_swagger(responding_url,endpoint)
|
||||||
|
if value:
|
||||||
|
swagger_data[endpoint] = value
|
||||||
|
else:
|
||||||
|
swagger_data = {}
|
||||||
|
|
||||||
|
return swagger_data
|
||||||
|
|
||||||
|
def try_query_swagger(self, base_url, endpoint):
|
||||||
|
url = f"{base_url}{endpoint}"
|
||||||
|
value = None
|
||||||
|
try:
|
||||||
|
value = r.get(url, timeout=2).json()
|
||||||
|
except (r.exceptions.ConnectionError, urllib3.exceptions.ProtocolError) as e:
|
||||||
|
print(f"Error: Connection error when querying {url}: {e}") # No break because you could be dealing with a different protocol
|
||||||
|
except (JSONDecodeError, json.JSONDecodeError, r.exceptions.JSONDecodeError, ConnectionResetError) as e:
|
||||||
|
print(f"Error: JSON decode error when querying {url}: {e}")
|
||||||
|
except r.exceptions.ConnectTimeout as e:
|
||||||
|
print(f"Error: Connection timeout when querying {url}: {e}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error: An unexpected error occurred when querying {url}: {e}")
|
||||||
|
return value
|
||||||
|
|
||||||
|
def get_swagger_response(self,urls):
|
||||||
|
responding_url = None
|
||||||
|
for base_url in urls:
|
||||||
|
endpoint = "/health"
|
||||||
|
value = self.try_query_swagger(base_url, endpoint)
|
||||||
|
if value:
|
||||||
|
responding_url = base_url
|
||||||
|
print(f"INFO: Swagger API is accessible via {responding_url}, we are going to proceed with querying Swagger endpoints...")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(f"Swagger API was unreachable via {base_url}, we cannot proceed with querying Swagger end points!")
|
||||||
|
return responding_url
|
||||||
|
|
||||||
|
|
||||||
|
def _set_index_to_empty(self, df):
|
||||||
|
index_len = pd.RangeIndex(len(df.index))
|
||||||
|
new_index = []
|
||||||
|
for x in index_len:
|
||||||
|
x = ""
|
||||||
|
new_index.append(x)
|
||||||
|
df.index = new_index
|
||||||
|
return df
|
||||||
|
|
||||||
|
def _dataframe_to_markdown(self,df,col_names, index_names=""):
|
||||||
|
df = df.T
|
||||||
|
df.index.names = index_names
|
||||||
|
df.columns = col_names
|
||||||
|
markdown = df.to_markdown()
|
||||||
|
return markdown
|
||||||
|
|
||||||
|
def format_dataframe(self, df):
|
||||||
|
df = self._json_to_dataframe(df)
|
||||||
|
df = df.T
|
||||||
|
return df
|
||||||
|
|
||||||
|
def print_neat_dict(self, dictionary, indent=4):
|
||||||
|
neat_dictionary = self._json_neat_format(dictionary)
|
||||||
|
print(neat_dictionary)
|
||||||
|
|
||||||
|
def _json_neat_format(self,dictionary,indent=4):
|
||||||
|
dictionary = json.dumps(dictionary, indent = indent)
|
||||||
|
return dictionary
|
||||||
|
|
||||||
|
def _json_to_dataframe(self,json):
|
||||||
|
df = pd.json_normalize(json)
|
||||||
|
return df
|
||||||
|
|
||||||
|
|
||||||
|
class Output():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.home = os.path.expanduser('~')
|
||||||
|
self.pwd = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
def concat_to_file(self,args, data_list):
|
||||||
|
filename = self.init_output_file(args)
|
||||||
|
with open(f"{filename}", "w") as output_file:
|
||||||
|
for name in data_list:
|
||||||
|
output_file.write(name)
|
||||||
|
output_file.write("\n")
|
||||||
|
|
||||||
|
print(f"\nResults were exported to {filename}.")
|
||||||
|
|
||||||
|
def init_output_file(self,args):
|
||||||
|
filename = self.get_filename(args)
|
||||||
|
os.system(f"touch {filename}")
|
||||||
|
return filename
|
||||||
|
|
||||||
|
def get_filename(self,args):
|
||||||
|
path = args.output
|
||||||
|
id_key = args.id
|
||||||
|
file = f"api_output_{id_key}.txt"
|
||||||
|
if path == "":
|
||||||
|
filename = file
|
||||||
|
else:
|
||||||
|
if path[-1] != "/":
|
||||||
|
path = path + "/"
|
||||||
|
if path[0] == "~":
|
||||||
|
path = self.home + path[1:]
|
||||||
|
filename = f"{path}{file}"
|
||||||
|
return filename
|
||||||
|
|
||||||
|
|
||||||
|
class VersionCount():
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.functions = MainFunctions()
|
||||||
|
self.mixnodes_version_column = 'mixnode_details.bond_information.mix_node.version'
|
||||||
|
self.gateways_version_column = 'gateway_bond.gateway.version'
|
||||||
|
|
||||||
|
def display_results(self, args):
|
||||||
|
df_final = self.fetch_results(args)
|
||||||
|
if args.markdown:
|
||||||
|
table = df_final.to_markdown(index=False)
|
||||||
|
else:
|
||||||
|
table = tabulate(df_final)
|
||||||
|
print(table)
|
||||||
|
|
||||||
|
def fetch_results(self, args):
|
||||||
|
gateways_unfiltered, mixnodes_unfiltered = self.functions.get_unfiltered_data()
|
||||||
|
df_gateways = self.functions._json_to_dataframe(gateways_unfiltered)
|
||||||
|
df_mixnodes = self.functions._json_to_dataframe(mixnodes_unfiltered)
|
||||||
|
versions = list(args.version)
|
||||||
|
mixnodes_version_column = self.mixnodes_version_column
|
||||||
|
gateways_version_column = self.gateways_version_column
|
||||||
|
mixnodes_sum = self.version_count(df_mixnodes, mixnodes_version_column, versions, "mixnode")
|
||||||
|
gateways_sum = self.version_count(df_gateways, gateways_version_column, versions, "gateway")
|
||||||
|
df_final = self.final_summary(mixnodes_sum, gateways_sum, versions)
|
||||||
|
return df_final
|
||||||
|
|
||||||
|
def version_count(self, df, column, versions, mode):
|
||||||
|
count_all = []
|
||||||
|
for version in versions:
|
||||||
|
version_sum = df[f'{column}'].value_counts()[f'{version}']
|
||||||
|
result = {"Node type": mode, "Version": version, "Summary":version_sum}
|
||||||
|
count_all.append(result)
|
||||||
|
return count_all
|
||||||
|
|
||||||
|
def final_summary(self, mixnodes_sum, gateways_sum, versions):
|
||||||
|
list_final = mixnodes_sum + gateways_sum
|
||||||
|
df_final = pd.DataFrame(list_final)
|
||||||
|
col_names = df_final.columns
|
||||||
|
total_summary = df_final['Summary'].sum()
|
||||||
|
if len(versions) > 1:
|
||||||
|
mixnodes_total = df_final.loc[df_final['Node type'] == 'mixnode', 'Summary'].sum()
|
||||||
|
gateways_total = df_final.loc[df_final['Node type'] == 'gateway', 'Summary'].sum()
|
||||||
|
df_append = pd.DataFrame([["mixnodes",f"versions: {versions}", f"{mixnodes_total}"],["gateways",f"versions: {versions}",f"{gateways_total}"]],columns=col_names)
|
||||||
|
df_final = pd.concat([df_final, df_append], ignore_index=True)
|
||||||
|
for version in versions:
|
||||||
|
version_total = df_final.loc[df_final['Version'] == f'{version}', 'Summary'].sum()
|
||||||
|
df_append = pd.DataFrame([["all nodes",f"{version}", f"{version_total}"]],columns=col_names)
|
||||||
|
df_final = pd.concat([df_final, df_append], ignore_index=True)
|
||||||
|
df_append = pd.DataFrame([["TOTAL SUMMARY",f"{versions}", f"{total_summary}"]],columns=col_names)
|
||||||
|
df_final = pd.concat([df_final, df_append], ignore_index=True)
|
||||||
|
return df_final
|
||||||
|
|
||||||
|
|
||||||
|
class ArgParser:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""init for parser"""
|
||||||
|
self.functions = MainFunctions()
|
||||||
|
self.version_count = VersionCount()
|
||||||
|
|
||||||
|
def parser_main(self):
|
||||||
|
"""Main function initializing ArgumentParser, storing arguments and executing commands."""
|
||||||
|
# Top level parser
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
prog= "Nym-node API check",
|
||||||
|
description='''Run through all endpoints and print results.'''
|
||||||
|
)
|
||||||
|
parser.add_argument("-V","--version", action="version", version='%(prog)s 0.1.1')
|
||||||
|
|
||||||
|
# sub-command parsers
|
||||||
|
subparsers = parser.add_subparsers()
|
||||||
|
parser_pull_stats = subparsers.add_parser('query_stats',help='Get all nodes API endpoints', aliases=['q','query'])
|
||||||
|
parser_version_count = subparsers.add_parser('version_count', help='Sum of nodes in given version(s)', aliases=['v','version'])
|
||||||
|
|
||||||
|
# pull_stats arguments
|
||||||
|
parser_pull_stats.add_argument("id", help="supply nym-node identity key")
|
||||||
|
parser_pull_stats.add_argument("-n","--no_routing_history", help="Display node stats without routing history", action="store_true")
|
||||||
|
parser_pull_stats.add_argument("-m","--markdown",help="Display results in markdown format", action="store_true")
|
||||||
|
parser_pull_stats.add_argument("-o","--output",help="Save results to file (in current dir or supply with path without filename)", nargs='?',const="", type=str)
|
||||||
|
parser_pull_stats.set_defaults(func=self.functions.display_results)
|
||||||
|
|
||||||
|
|
||||||
|
# version_count arguments
|
||||||
|
parser_version_count.add_argument('version', help="supply node versions separated with space", nargs='+')
|
||||||
|
parser_version_count.add_argument("-m","--markdown",help="Display results in markdown format", action="store_true")
|
||||||
|
parser_version_count.set_defaults(func=self.version_count.display_results)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
try:
|
||||||
|
func = args.func
|
||||||
|
try:
|
||||||
|
args.func(args)
|
||||||
|
except (AttributeError, KeyError) as e:
|
||||||
|
msg = f"{e}.\nPlease run python {__file__} --help"
|
||||||
|
self.panic(msg)
|
||||||
|
except UnboundLocalError as e:
|
||||||
|
msg = f"{e}.\nPlease provide a correct node identity key."
|
||||||
|
self.panic(msg)
|
||||||
|
except FileNotFoundError as e:
|
||||||
|
msg = f"{e}.\nMake sure your <PATH> supplied to --output is correct."
|
||||||
|
self.panic(msg)
|
||||||
|
except AttributeError:
|
||||||
|
parser.print_help(sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def panic(self,msg):
|
||||||
|
"""Error message print"""
|
||||||
|
print(f"error: {msg}", file=sys.stderr)
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
node_check = ArgParser()
|
||||||
|
node_check.parser_main()
|
||||||
@@ -274,7 +274,7 @@ where
|
|||||||
specification: GatewaySelectionSpecification::UniformRemote {
|
specification: GatewaySelectionSpecification::UniformRemote {
|
||||||
must_use_tls: false,
|
must_use_tls: false,
|
||||||
},
|
},
|
||||||
available_gateways: current_gateways(&mut rng, &nym_apis).await?,
|
available_gateways: current_gateways(&mut rng, &nym_apis, None).await?,
|
||||||
wg_tun_address: None,
|
wg_tun_address: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ where
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut rng = OsRng;
|
let mut rng = OsRng;
|
||||||
let available_gateways = current_gateways(&mut rng, &nym_api_endpoints).await?;
|
let available_gateways = current_gateways(&mut rng, &nym_api_endpoints, None).await?;
|
||||||
|
|
||||||
Ok(GatewaySetup::New {
|
Ok(GatewaySetup::New {
|
||||||
specification: selection_spec,
|
specification: selection_spec,
|
||||||
|
|||||||
@@ -13,11 +13,10 @@ import type { SetupMixFetchOps } from '@nymproject/mix-fetch';
|
|||||||
const defaultUrl = 'https://nymtech.net/favicon.svg';
|
const defaultUrl = 'https://nymtech.net/favicon.svg';
|
||||||
const args = { mode: 'unsafe-ignore-cors' };
|
const args = { mode: 'unsafe-ignore-cors' };
|
||||||
|
|
||||||
|
|
||||||
const mixFetchOptions: SetupMixFetchOps = {
|
const mixFetchOptions: SetupMixFetchOps = {
|
||||||
preferredGateway: '983r9LKDT9UUxx4Zsn2AH49poJ7Ep24ueR8ENfWFgCX6', // with WSS
|
preferredGateway: '6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B', // with WSS
|
||||||
preferredNetworkRequester:
|
preferredNetworkRequester:
|
||||||
'DxAc9J4eqREc8hYfDobkSc81JLkmmrhJ77zJvHShUPoi.92bnebXtBuwKiYycrpioaAiYgta5hHWkys5aSGBQg5av@983r9LKDT9UUxx4Zsn2AH49poJ7Ep24ueR8ENfWFgCX6',
|
'8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B',
|
||||||
mixFetchOverride: {
|
mixFetchOverride: {
|
||||||
requestTimeoutMs: 60_000,
|
requestTimeoutMs: 60_000,
|
||||||
},
|
},
|
||||||
@@ -82,5 +81,4 @@ export const MixFetch = () => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -13,13 +13,14 @@ const defaultUrl = 'https://nymtech.net/favicon.svg';
|
|||||||
const args = { mode: 'unsafe-ignore-cors' };
|
const args = { mode: 'unsafe-ignore-cors' };
|
||||||
|
|
||||||
const mixFetchOptions: SetupMixFetchOps = {
|
const mixFetchOptions: SetupMixFetchOps = {
|
||||||
preferredGateway: '983r9LKDT9UUxx4Zsn2AH49poJ7Ep24ueR8ENfWFgCX6', // with WSS
|
preferredGateway: '6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B', // with WSS
|
||||||
preferredNetworkRequester:
|
preferredNetworkRequester:
|
||||||
'DxAc9J4eqREc8hYfDobkSc81JLkmmrhJ77zJvHShUPoi.92bnebXtBuwKiYycrpioaAiYgta5hHWkys5aSGBQg5av@983r9LKDT9UUxx4Zsn2AH49poJ7Ep24ueR8ENfWFgCX6',
|
'8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B',
|
||||||
mixFetchOverride: {
|
mixFetchOverride: {
|
||||||
requestTimeoutMs: 60_000,
|
requestTimeoutMs: 60_000,
|
||||||
},
|
},
|
||||||
forceTls: true, // force WSS
|
forceTls: true, // force WSS
|
||||||
|
extra: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MixFetch = () => {
|
export const MixFetch = () => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Callout } from 'nextra/components'
|
import { Callout } from 'nextra/components';
|
||||||
|
|
||||||
# `mixFetch`
|
# `mixFetch`
|
||||||
|
|
||||||
@@ -7,32 +7,27 @@ An easy way to secure parts or all of your web app is to replace calls to [`fetc
|
|||||||
MixFetch works the same as vanilla `fetch` as it's a proxied wrapper around the original function.
|
MixFetch works the same as vanilla `fetch` as it's a proxied wrapper around the original function.
|
||||||
Sounds great, are there any catches? Well, there are a few (for now):
|
Sounds great, are there any catches? Well, there are a few (for now):
|
||||||
|
|
||||||
1. Currently, the operators of Network Requesters that make the final request at the egress part of the Nym mixnet to
|
1. Currently, the operators of Network Requesters that make the final request at the egress part of the Nym mixnet to the internet use a [standard allow list](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) in combination with their own configuration. If you are trying to access something that is not on the allow list, please check the FAQ page.
|
||||||
the internet use a [standard allow list](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt)
|
|
||||||
in combination with their own configuration. If you are trying to access something that is not on the allow list, please check the FAQ page.
|
|
||||||
|
|
||||||
2. CA certificates in `mixFetch` are periodically updated, so if you get a certificate error, the root certificate you need might not be valid. If that's the case, [send a PR](https://github.com/nymtech/nym/pulls) if you need changes to the Certificates.
|
2. CA certificates in `mixFetch` are periodically updated, so if you get a certificate error, the root certificate you need might not be valid. If that's the case, [send a PR](https://github.com/nymtech/nym/pulls) if you need changes to the Certificates.
|
||||||
|
|
||||||
3. If you are using `mixFetch` in a web app with HTTPS you will need to use a gateway that has Secure Websockets to
|
3. If you are using `mixFetch` in a web app with HTTPS you will need to use a gateway that has Secure Websockets to avoid getting a [mixed content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content) error.
|
||||||
avoid getting a [mixed content](https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content) error.
|
|
||||||
|
|
||||||
4. For now, mixfetch doesn't work with SURBS, altough this may change in the future.
|
4. For now, mixfetch doesn't work with SURBS, altough this may change in the future.
|
||||||
|
|
||||||
|
|
||||||
Read [this article](https://blog.nymtech.net/mixfetch-like-the-fetch-api-but-via-the-mixnet-82acfd435c62) to learn more about mixFetch.
|
Read [this article](https://blog.nymtech.net/mixfetch-like-the-fetch-api-but-via-the-mixnet-82acfd435c62) to learn more about mixFetch.
|
||||||
|
|
||||||
<Callout type="info" emoji="ℹ️">
|
<Callout type="info" emoji="ℹ️">
|
||||||
Right now Gateways are not required to run a Secure Websocket (WSS) listener, so only a subset of nodes running in Gateway mode have configured their nodes to do so.
|
Right now Gateways are not required to run a Secure Websocket (WSS) listener, so only a subset of nodes running in Gateway mode have configured their nodes to do so.
|
||||||
|
|
||||||
For the moment you have to select a Gateway that has WSS enabled from [this list](https://harbourmaster.nymtech.net/v1/services?wss=true).
|
For the moment you have to select a Gateway that has WSS enabled and Network Requester from [Harbourmaster Gateways for mixFetch list](https://harbourmaster.nymtech.net/).
|
||||||
|
|
||||||
You can also find WSS-enabled nodes by querying the `gateways/described` endpoint on the Nym API, either via the [Swagger webpage](https://validator.nymtech.net/api/swagger/index.html) or with `curl`:
|
```
|
||||||
|
|
||||||
```
|
|
||||||
curl -X 'GET' \
|
curl -X 'GET' \
|
||||||
'https://validator.nymtech.net/api/v1/gateways/described' \
|
'https://validator.nymtech.net/api/v1/gateways/described' \
|
||||||
-H 'accept: application/json'
|
-H 'accept: application/json'
|
||||||
```
|
```
|
||||||
|
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
@@ -40,9 +35,9 @@ curl -X 'GET' \
|
|||||||
import type { SetupMixFetchOps } from '@nymproject/mix-fetch';
|
import type { SetupMixFetchOps } from '@nymproject/mix-fetch';
|
||||||
|
|
||||||
const mixFetchOptions: SetupMixFetchOps = {
|
const mixFetchOptions: SetupMixFetchOps = {
|
||||||
preferredGateway: '983r9LKDT9UUxx4Zsn2AH49poJ7Ep24ueR8ENfWFgCX6', // with WSS
|
preferredGateway: '6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B', // with WSS
|
||||||
preferredNetworkRequester:
|
preferredNetworkRequester:
|
||||||
'DxAc9J4eqREc8hYfDobkSc81JLkmmrhJ77zJvHShUPoi.92bnebXtBuwKiYycrpioaAiYgta5hHWkys5aSGBQg5av@983r9LKDT9UUxx4Zsn2AH49poJ7Ep24ueR8ENfWFgCX6',
|
'8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B',
|
||||||
mixFetchOverride: {
|
mixFetchOverride: {
|
||||||
requestTimeoutMs: 60_000,
|
requestTimeoutMs: 60_000,
|
||||||
},
|
},
|
||||||
@@ -52,6 +47,7 @@ const mixFetchOptions: SetupMixFetchOps = {
|
|||||||
```
|
```
|
||||||
|
|
||||||
##### Environment Setup
|
##### Environment Setup
|
||||||
|
|
||||||
Begin by creating a directory and configuring your application environment:
|
Begin by creating a directory and configuring your application environment:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -59,6 +55,7 @@ npm create vite@latest
|
|||||||
```
|
```
|
||||||
|
|
||||||
During the environment setup, choose React and subsequently opt for Typescript if you want your application to function smoothly following this tutorial. Next, navigate to your application directory and run the following commands:
|
During the environment setup, choose React and subsequently opt for Typescript if you want your application to function smoothly following this tutorial. Next, navigate to your application directory and run the following commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd < YOUR_APP >
|
cd < YOUR_APP >
|
||||||
npm i
|
npm i
|
||||||
@@ -66,33 +63,36 @@ npm run dev
|
|||||||
```
|
```
|
||||||
|
|
||||||
##### Installation
|
##### Installation
|
||||||
|
|
||||||
Install the required package:
|
Install the required package:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install @nymproject/mix-fetch-full-fat
|
npm install @nymproject/mix-fetch-full-fat
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Imports
|
##### Imports
|
||||||
|
|
||||||
In the `src` folder, open the `App.tsx` file and delete all the code.
|
In the `src` folder, open the `App.tsx` file and delete all the code.
|
||||||
|
|
||||||
Import the client in your app:
|
Import the client in your app:
|
||||||
````js
|
|
||||||
import { mixFetch } from "@nymproject/mix-fetch-full-fat";
|
|
||||||
````
|
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { mixFetch } from '@nymproject/mix-fetch-full-fat';
|
||||||
|
```
|
||||||
|
|
||||||
##### Example: using the `mixFetch` client:
|
##### Example: using the `mixFetch` client:
|
||||||
|
|
||||||
`Get` and `Post` outputs will be observable from your console.
|
`Get` and `Post` outputs will be observable from your console.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import "./App.css";
|
import './App.css';
|
||||||
import { mixFetch, SetupMixFetchOps } from '@nymproject/mix-fetch-full-fat';
|
import { mixFetch, SetupMixFetchOps } from '@nymproject/mix-fetch-full-fat';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const mixFetchOptions: SetupMixFetchOps = {
|
const mixFetchOptions: SetupMixFetchOps = {
|
||||||
preferredGateway: '983r9LKDT9UUxx4Zsn2AH49poJ7Ep24ueR8ENfWFgCX6', // with WSS
|
preferredGateway: '6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B', // with WSS
|
||||||
preferredNetworkRequester:
|
preferredNetworkRequester:
|
||||||
'DxAc9J4eqREc8hYfDobkSc81JLkmmrhJ77zJvHShUPoi.92bnebXtBuwKiYycrpioaAiYgta5hHWkys5aSGBQg5av@983r9LKDT9UUxx4Zsn2AH49poJ7Ep24ueR8ENfWFgCX6',
|
'8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B',
|
||||||
mixFetchOverride: {
|
mixFetchOverride: {
|
||||||
requestTimeoutMs: 60_000,
|
requestTimeoutMs: 60_000,
|
||||||
},
|
},
|
||||||
@@ -100,48 +100,62 @@ const mixFetchOptions: SetupMixFetchOps = {
|
|||||||
extra: {},
|
extra: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export function HttpGET() {
|
export function HttpGET() {
|
||||||
const [html, setHtml] = React.useState('')
|
const [html, setHtml] = React.useState('');
|
||||||
async function get () {
|
async function get() {
|
||||||
//Make sure the URL is whitelisted (see 'standard allowed list') otherwise you will get a network requester filter check error
|
//Make sure the URL is whitelisted (see 'standard allowed list') otherwise you will get a network requester filter check error
|
||||||
const response = await mixFetch('https://nymtech.net/favicon.svg', { mode: 'unsafe-ignore-cors' }, mixFetchOptions)
|
const response = await mixFetch('https://nymtech.net/favicon.svg', { mode: 'unsafe-ignore-cors' }, mixFetchOptions);
|
||||||
const text = await response.text()
|
const text = await response.text();
|
||||||
console.log('response was', text)
|
console.log('response was', text);
|
||||||
setHtml(html)
|
setHtml(html);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={() => { get() }}>Get</button>
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
get();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Get
|
||||||
|
</button>
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function HttpPOST() {
|
export function HttpPOST() {
|
||||||
async function post () {
|
async function post() {
|
||||||
//Make sure the URL is whitelisted (see 'standard allowed list') otherwise you will get a network requester filter check error
|
//Make sure the URL is whitelisted (see 'standard allowed list') otherwise you will get a network requester filter check error
|
||||||
const apiResponse = await mixFetch('https://httpbin.org/post', {
|
const apiResponse = await mixFetch(
|
||||||
|
'https://httpbin.org/post',
|
||||||
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({ foo: 'bar' }),
|
body: JSON.stringify({ foo: 'bar' }),
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: { 'Content-Type': 'application/json' },
|
||||||
}, mixFetchOptions)
|
},
|
||||||
console.log(apiResponse)
|
mixFetchOptions,
|
||||||
}
|
);
|
||||||
|
console.log(apiResponse);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button onClick={() => { post() }}>Post</button>
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
post();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Post
|
||||||
|
</button>
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HttpGET/>
|
<HttpGET />
|
||||||
<HttpPOST/>
|
<HttpPOST />
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import { appendOutput, appendImageOutput } from './utils';
|
|||||||
async function main() {
|
async function main() {
|
||||||
// options for mixFetch (you can also set these with the `createMixFetch` function
|
// options for mixFetch (you can also set these with the `createMixFetch` function
|
||||||
const mixFetchOptions = {
|
const mixFetchOptions = {
|
||||||
preferredGateway: 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM', // with WSS
|
preferredGateway: '6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B', // with WSS
|
||||||
preferredNetworkRequester:
|
preferredNetworkRequester:
|
||||||
'GiRjFWrMxt58pEMuusm4yT3RxoMD1MMPrR9M2N4VWRJP.3CNZBPq4vg7v7qozjGjdPMXcvDmkbWPCgbGCjQVw9n6Z@2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW',
|
'8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B',
|
||||||
mixFetchOverride: {
|
mixFetchOverride: {
|
||||||
requestTimeoutMs: 60_000,
|
requestTimeoutMs: 60_000,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
"comlink": "^4.3.1",
|
"comlink": "^4.3.1",
|
||||||
"fake-indexeddb": "^4.0.2",
|
"fake-indexeddb": "^4.0.2",
|
||||||
"rollup-plugin-polyfill": "^4.2.0",
|
"rollup-plugin-polyfill": "^4.2.0",
|
||||||
"ws": "^8.14.2"
|
"ws": "^8.17.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-commonjs": "^24.0.1",
|
"@rollup/plugin-commonjs": "^24.0.1",
|
||||||
|
|||||||
@@ -2847,10 +2847,10 @@ wrappy@1:
|
|||||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
||||||
|
|
||||||
ws@^8.14.2:
|
ws@^8.17.1:
|
||||||
version "8.14.2"
|
version "8.17.1"
|
||||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f"
|
resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
|
||||||
integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==
|
integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
|
||||||
|
|
||||||
ws@~8.11.0:
|
ws@~8.11.0:
|
||||||
version "8.11.0"
|
version "8.11.0"
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ async function main() {
|
|||||||
const args = { mode: 'unsafe-ignore-cors' };
|
const args = { mode: 'unsafe-ignore-cors' };
|
||||||
|
|
||||||
const resp = await mixFetch(url, args, {
|
const resp = await mixFetch(url, args, {
|
||||||
preferredGateway: '2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh',
|
preferredGateway: '6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B', // with WSS
|
||||||
preferredNetworkRequester:
|
preferredNetworkRequester:
|
||||||
'GiRjFWrMxt58pEMuusm4yT3RxoMD1MMPrR9M2N4VWRJP.3CNZBPq4vg7v7qozjGjdPMXcvDmkbWPCgbGCjQVw9n6Z@2xU4CBE6QiiYt6EyBXSALwxkNvM7gqJfjHXaMkjiFmYW',
|
'8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B',
|
||||||
});
|
});
|
||||||
console.log({ resp });
|
console.log({ resp });
|
||||||
const text = await resp.text();
|
const text = await resp.text();
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ impl OnStartData {
|
|||||||
pub struct IpPacketRouter {
|
pub struct IpPacketRouter {
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
config: Config,
|
config: Config,
|
||||||
|
|
||||||
wait_for_gateway: bool,
|
wait_for_gateway: bool,
|
||||||
custom_topology_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
|
custom_topology_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
|
||||||
custom_gateway_transceiver: Option<Box<dyn GatewayTransceiver + Send + Sync>>,
|
custom_gateway_transceiver: Option<Box<dyn GatewayTransceiver + Send + Sync>>,
|
||||||
@@ -79,6 +80,12 @@ impl IpPacketRouter {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn with_minimum_gateway_performance(mut self, minimum_gateway_performance: u8) -> Self {
|
||||||
|
self.config.base.debug.topology.minimum_gateway_performance = minimum_gateway_performance;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn with_on_start(mut self, on_start: oneshot::Sender<OnStartData>) -> Self {
|
pub fn with_on_start(mut self, on_start: oneshot::Sender<OnStartData>) -> Self {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-network-requester"
|
name = "nym-network-requester"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
version = "1.1.36"
|
version = "1.1.38"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
rust-version = "1.70"
|
rust-version = "1.70"
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ pub(crate) fn new_legacy_request_version() -> RequestVersion<Socks5Request> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
pub struct OnStartData {
|
pub struct OnStartData {
|
||||||
// to add more fields as required
|
// to add more fields as required
|
||||||
pub address: Recipient,
|
pub address: Recipient,
|
||||||
@@ -221,6 +222,15 @@ impl NRServiceProviderBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
// this is a false positive, this method is actually called when used as a library
|
||||||
|
// but clippy complains about it when building the binary
|
||||||
|
#[allow(unused)]
|
||||||
|
pub fn with_minimum_gateway_performance(mut self, minimum_gateway_performance: u8) -> Self {
|
||||||
|
self.config.base.debug.topology.minimum_gateway_performance = minimum_gateway_performance;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
// this is a false positive, this method is actually called when used as a library
|
// this is a false positive, this method is actually called when used as a library
|
||||||
// but clippy complains about it when building the binary
|
// but clippy complains about it when building the binary
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nym-cli"
|
name = "nym-cli"
|
||||||
version = "1.1.36"
|
version = "1.1.38"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nymvisor"
|
name = "nymvisor"
|
||||||
version = "0.1.1"
|
version = "0.1.3"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
homepage.workspace = true
|
homepage.workspace = true
|
||||||
@@ -21,7 +21,7 @@ hex = { workspace = true }
|
|||||||
humantime = { workspace = true }
|
humantime = { workspace = true }
|
||||||
humantime-serde = { workspace = true }
|
humantime-serde = { workspace = true }
|
||||||
nix = { workspace = true, features = ["signal", "fs"] }
|
nix = { workspace = true, features = ["signal", "fs"] }
|
||||||
reqwest = { workspace = true, features = ["json", "stream"] }
|
reqwest = { workspace = true, features = ["json", "stream", "rustls-tls"] }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
sha2 = "0.10.8"
|
sha2 = "0.10.8"
|
||||||
|
|||||||
@@ -11,6 +11,6 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nymproject/nym-client-wasm": "file:../../../dist/node/wasm/client",
|
"@nymproject/nym-client-wasm": "file:../../../dist/node/wasm/client",
|
||||||
"indexeddbshim": "^13.0.0-pre.1",
|
"indexeddbshim": "^13.0.0-pre.1",
|
||||||
"ws": "^8.13.0"
|
"ws": "^8.17.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -888,10 +888,10 @@ wrappy@1:
|
|||||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||||
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
|
||||||
|
|
||||||
ws@^8.13.0:
|
ws@^8.17.1:
|
||||||
version "8.13.0"
|
version "8.17.1"
|
||||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0"
|
resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
|
||||||
integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==
|
integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
|
||||||
|
|
||||||
yallist@^4.0.0:
|
yallist@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
|
|||||||
@@ -497,11 +497,11 @@ brace-expansion@^1.1.7:
|
|||||||
concat-map "0.0.1"
|
concat-map "0.0.1"
|
||||||
|
|
||||||
braces@^3.0.2, braces@~3.0.2:
|
braces@^3.0.2, braces@~3.0.2:
|
||||||
version "3.0.2"
|
version "3.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
|
||||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
|
||||||
dependencies:
|
dependencies:
|
||||||
fill-range "^7.0.1"
|
fill-range "^7.1.1"
|
||||||
|
|
||||||
browserslist@^4.14.5:
|
browserslist@^4.14.5:
|
||||||
version "4.21.5"
|
version "4.21.5"
|
||||||
@@ -903,10 +903,10 @@ faye-websocket@^0.11.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
websocket-driver ">=0.5.1"
|
websocket-driver ">=0.5.1"
|
||||||
|
|
||||||
fill-range@^7.0.1:
|
fill-range@^7.1.1:
|
||||||
version "7.0.1"
|
version "7.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
|
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
|
||||||
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
|
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
|
||||||
dependencies:
|
dependencies:
|
||||||
to-regex-range "^5.0.1"
|
to-regex-range "^5.0.1"
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ pub trait HarbourMasterApiClientExt: ApiClient {
|
|||||||
impl HarbourMasterApiClientExt for Client {}
|
impl HarbourMasterApiClientExt for Client {}
|
||||||
|
|
||||||
// https://gitlab.nymte.ch/nym/shipyard-test-and-earn/-/blob/main/harbour-master/src/http/mod.rs#L13
|
// https://gitlab.nymte.ch/nym/shipyard-test-and-earn/-/blob/main/harbour-master/src/http/mod.rs#L13
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct PagedResult<T> {
|
pub struct PagedResult<T> {
|
||||||
pub page: u32,
|
pub page: u32,
|
||||||
@@ -47,6 +48,7 @@ pub struct PagedResult<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// https://gitlab.nymte.ch/nym/shipyard-test-and-earn/-/blob/main/harbour-master/src/http/services.rs#L32
|
// https://gitlab.nymte.ch/nym/shipyard-test-and-earn/-/blob/main/harbour-master/src/http/services.rs#L32
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct ServiceNew {
|
pub struct ServiceNew {
|
||||||
pub service_provider_client_id: String,
|
pub service_provider_client_id: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user