Compare commits

..

27 Commits

Author SHA1 Message Date
durch 1060888945 wallet tracing POC 2023-01-05 17:30:25 +01:00
Jędrzej Stuczyński 5f4926dd49 feature: use clap derive for nym-api + use stricter validation for other binaries (#2772)
* fixed all uses of deprecated clap methods

* updated all uses of clap to 4.0

* unified obtaining build information

* moved around the imports

* Moved all nym-api arguments to ApiArgs and simplified parsing

* Using common shutdown signal code

* Using clap for parsing Vec<Url>

* stricter validation of socks5-client arguments

* ibid for the native client

* ibid for the gateway

* ibid for the mixnode

* clippy
2023-01-05 10:32:57 +00:00
dependabot[bot] 1f132a4eaa build(deps): bump got and nodemon (#1624)
Bumps [got](https://github.com/sindresorhus/got) and [nodemon](https://github.com/remy/nodemon). These dependencies needed to be updated together.

Removes `got`

Updates `nodemon` from 2.0.12 to 2.0.19
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v2.0.12...v2.0.19)

---
updated-dependencies:
- dependency-name: got
  dependency-type: indirect
- dependency-name: nodemon
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:21:05 +00:00
dependabot[bot] 097d2d51cc build(deps): bump undici, hardhat and @nomiclabs/hardhat-etherscan (#1634)
Bumps [undici](https://github.com/nodejs/undici), [hardhat](https://github.com/nomiclabs/hardhat) and [@nomiclabs/hardhat-etherscan](https://github.com/nomiclabs/hardhat). These dependencies needed to be updated together.

Updates `undici` from 4.16.0 to 5.10.0
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v4.16.0...v5.10.0)

Updates `hardhat` from 2.9.2 to 2.11.2
- [Release notes](https://github.com/nomiclabs/hardhat/releases)
- [Commits](https://github.com/nomiclabs/hardhat/compare/hardhat@2.9.2...hardhat@2.11.2)

Updates `@nomiclabs/hardhat-etherscan` from 3.0.3 to 3.1.0
- [Release notes](https://github.com/nomiclabs/hardhat/releases)
- [Commits](https://github.com/nomiclabs/hardhat/compare/@nomiclabs/hardhat-etherscan@3.0.3...@nomiclabs/hardhat-etherscan@3.1.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-type: indirect
- dependency-name: hardhat
  dependency-type: direct:development
- dependency-name: "@nomiclabs/hardhat-etherscan"
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:20:56 +00:00
dependabot[bot] a2078d997b Bump loader-utils from 1.4.0 to 1.4.2 (#1763)
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.2.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.2/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.2)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:20:37 +00:00
dependabot[bot] 558d4b899d Bump deep-object-diff from 1.1.7 to 1.1.9 (#1765)
Bumps [deep-object-diff](https://github.com/mattphillips/deep-object-diff) from 1.1.7 to 1.1.9.
- [Release notes](https://github.com/mattphillips/deep-object-diff/releases)
- [Commits](https://github.com/mattphillips/deep-object-diff/commits)

---
updated-dependencies:
- dependency-name: deep-object-diff
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:20:24 +00:00
dependabot[bot] 4fcb98e839 Bump decode-uri-component in /contracts/basic-bandwidth-generation (#1838)
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:20:11 +00:00
dependabot[bot] 702bb202a3 Bump decode-uri-component from 0.2.0 to 0.2.2 (#1840)
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:59 +00:00
dependabot[bot] 71ff2c04a0 Bump express in /clients/native/examples/js-examples/websocket (#1849)
Bumps [express](https://github.com/expressjs/express) from 4.17.1 to 4.18.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:46 +00:00
dependabot[bot] cb30384eaf Bump qs and express in /clients/native/examples/js-examples/websocket (#1850)
Bumps [qs](https://github.com/ljharb/qs) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `qs` from 6.7.0 to 6.11.0
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.7.0...v6.11.0)

Updates `express` from 4.17.1 to 4.18.2
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: indirect
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:38 +00:00
dependabot[bot] e911c2fbc0 Bump qs and express in /clients/webassembly/js-example (#1851)
Bumps [qs](https://github.com/ljharb/qs) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `qs` from 6.7.0 to 6.11.0
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.7.0...v6.11.0)

Updates `express` from 4.17.1 to 4.18.2
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: indirect
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:27 +00:00
dependabot[bot] bb005a39f5 Bump qs, body-parser and express (#1852)
Bumps [qs](https://github.com/ljharb/qs), [qs](https://github.com/ljharb/qs), [body-parser](https://github.com/expressjs/body-parser) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `qs` from 6.10.1 to 6.11.0
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.10.1...v6.11.0)

Updates `qs` from 6.5.2 to 6.11.0
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.10.1...v6.11.0)

Updates `body-parser` from 1.19.0 to 1.20.1
- [Release notes](https://github.com/expressjs/body-parser/releases)
- [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/body-parser/compare/1.19.0...1.20.1)

Updates `express` from 4.17.1 to 4.18.2
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: indirect
- dependency-name: qs
  dependency-type: indirect
- dependency-name: body-parser
  dependency-type: indirect
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:19 +00:00
dependabot[bot] ea72c37083 Bump express in /contracts/basic-bandwidth-generation (#1853)
Bumps [express](https://github.com/expressjs/express) from 4.17.1 to 4.18.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:10 +00:00
dependabot[bot] a24dd8b9bc build(deps): bump json5 from 2.2.1 to 2.2.3 in /nym-api/tests (#2768)
Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:11:01 +00:00
dependabot[bot] b006c01397 build(deps): bump json5 from 2.2.1 to 2.2.3 in /testnet-faucet (#2769)
Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:10:38 +00:00
dependabot[bot] f7f2a51458 build(deps): bump json5 from 1.0.1 to 1.0.2 (#2770)
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:10:04 +00:00
Jon Häggblad 408396c900 client-core: remove generic parameter for ClientCoreError (#2765)
* client-core: remove generic parameter for ClientCoreError

* fix compilation
2023-01-04 15:41:11 +01:00
Jędrzej Stuczyński a97c913bb1 Fixed missing feature lock for coconut-exlusive fields (#2767) 2023-01-04 14:00:55 +00:00
Jędrzej Stuczyński dba5a9caef Renamed 'nym-validator-api' package name to 'nym-api' (#2766) 2023-01-04 13:00:37 +00:00
Pierre Dommerc 3e39573feb feat(wallet-buy): pass wallet address as url param (#2752) 2023-01-04 13:26:09 +01:00
Jędrzej Stuczyński ac312e9109 feature: standarise arguments (#2762)
* Renamed "address" argument in "sign" command to "wallet-address"

* Ability to optionally describe mixnode with command line arguments

* renamed 'validators' arguments to 'nym-apis' in mixnode binary

* cleaned up gateway validator-related url arguments

* fixup! Renamed "address" argument in "sign" command to "wallet-address"

* renamed 'use_anonymous_sender_tag' to 'use_anonymous_replies'

* 'nymd_endpoints => 'nymd_validators'

* more consistency for nymd_validators and nym_apis urls arguments

* updated changelog
2023-01-04 09:59:08 +00:00
Jędrzej Stuczyński 8a2a7dc0ce bugfix: don't start rewarding unless rewarding.enabled is explicitly set to true (#2753)
* start rewarded set updater based on config flag

* removed dead code annotation

* updated changelog
2023-01-04 09:44:32 +00:00
Fouad 9684b7ffbd merge resolve 2022-12-22 15:45:02 +01:00
farbanas 29f48efe49 feat: release v1.1.5 of nym-wallet 2022-12-22 12:13:44 +01:00
Drazen Urch bdc285dbbb Add numeric family ids to explorer-api (#2707) 2022-12-21 23:37:32 +01:00
benedetta davico a02a1b0385 Merge pull request #2728 from nymtech/feat/2722-ne-ui
make fields match button height
2022-12-21 15:09:32 +01:00
Gala a746738d48 make fields match button height 2022-12-19 13:40:26 +01:00
139 changed files with 6121 additions and 9195 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ GEOIPUPDATE_LICENSE_KEY=xxx
# List of space-separated database edition IDs. Edition IDs may
# consist of letters, digits, and dashes. For example, GeoIP2-City
# would download the GeoIP2 City database (GeoIP2-City).
GEOIPUPDATE_EDITION_IDS=GeoLite2-City
GEOIPUPDATE_EDITION_IDS=GeoLite2-Country
# The number of hours between geoipupdate runs. If this is not set
# or is set to 0, geoipupdate will run once and exit.
GEOIPUPDATE_FREQUENCY=72
+7
View File
@@ -13,9 +13,16 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- all-binaries: improved error logging ([#2686])
- native client: bring shutdown logic up to the same level as socks5-client
- nym-api, coconut-dkg contract: automatic, time-based dkg epoch state advancement ([#2670])
- all-binaries: standarised argument names (note: old names should still be accepted) ([#2762]
### Fixed
- nym-api: should now correctly use `rewarding.enabled` config flag ([#2753])
[#2686]: https://github.com/nymtech/nym/pull/2686
[#2670]: https://github.com/nymtech/nym/pull/2670
[#2753]: https://github.com/nymtech/nym/pull/2753
[#2762]: https://github.com/nymtech/nym/pull/2762
## [v1.1.4] (2022-12-20)
Generated
+146 -94
View File
@@ -426,6 +426,13 @@ dependencies = [
"serde",
]
[[package]]
name = "build-information"
version = "0.1.0"
dependencies = [
"vergen 7.2.1",
]
[[package]]
name = "bumpalo"
version = "3.9.1"
@@ -598,41 +605,51 @@ version = "3.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "190814073e85d238f31ff738fcb0bf6910cedeb73376c87cd69291028966fd83"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"clap_lex",
"clap_lex 0.2.4",
"indexmap",
"once_cell",
"strsim",
"termcolor",
"textwrap 0.15.0",
]
[[package]]
name = "clap_complete"
version = "3.2.4"
name = "clap"
version = "4.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4179da71abd56c26b54dd0c248cc081c1f43b0a1a7e8448e28e57a29baa993d"
checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e"
dependencies = [
"clap 3.2.8",
"atty",
"bitflags",
"clap_derive",
"clap_lex 0.3.0",
"once_cell",
"strsim",
"termcolor",
]
[[package]]
name = "clap_complete"
version = "4.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10861370d2ba66b0f5989f83ebf35db6421713fd92351790e7fdd6c36774c56b"
dependencies = [
"clap 4.0.26",
]
[[package]]
name = "clap_complete_fig"
version = "3.2.4"
version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed37b4c0c1214673eba6ad8ea31666626bf72be98ffb323067d973c48b4964b9"
checksum = "46b30e010e669cd021e5004f3be26cff6b7c08d2a8a0d65b48d43a8cc0efd6c3"
dependencies = [
"clap 3.2.8",
"clap 4.0.26",
"clap_complete",
]
[[package]]
name = "clap_derive"
version = "3.2.7"
version = "4.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "759bf187376e1afa7b85b959e6a664a3e7a95203415dba952ad19139e798f902"
checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
dependencies = [
"heck 0.4.0",
"proc-macro-error",
@@ -650,6 +667,15 @@ dependencies = [
"os_str_bytes",
]
[[package]]
name = "clap_lex"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "client-connections"
version = "0.1.0"
@@ -766,7 +792,7 @@ dependencies = [
name = "completions"
version = "0.1.0"
dependencies = [
"clap 3.2.8",
"clap 4.0.26",
"clap_complete",
"clap_complete_fig",
]
@@ -1005,7 +1031,7 @@ version = "0.1.0"
dependencies = [
"bip39",
"cfg-if 0.1.10",
"clap 3.2.8",
"clap 4.0.26",
"coconut-interface",
"completions",
"config",
@@ -1765,7 +1791,7 @@ name = "explorer-api"
version = "1.1.1"
dependencies = [
"chrono",
"clap 3.2.8",
"clap 4.0.26",
"contracts-common",
"dotenv",
"humantime-serde",
@@ -1778,6 +1804,9 @@ dependencies = [
"network-defaults",
"okapi",
"pretty_env_logger",
"rand 0.8.5",
"rand_pcg 0.3.1",
"rand_seeder",
"reqwest",
"rocket",
"rocket_cors",
@@ -3202,6 +3231,72 @@ dependencies = [
"libc",
]
[[package]]
name = "nym-api"
version = "1.1.4"
dependencies = [
"anyhow",
"async-trait",
"bip39",
"bs58",
"build-information",
"cfg-if 1.0.0",
"clap 4.0.26",
"coconut-bandwidth-contract-common",
"coconut-dkg-common",
"coconut-interface",
"config",
"console-subscriber",
"contracts-common",
"cosmwasm-std",
"credential-storage",
"credentials",
"crypto",
"cw-utils",
"cw3",
"dirs",
"dkg",
"dotenv",
"futures",
"gateway-client",
"getset",
"humantime-serde",
"inclusion-probability",
"lazy_static",
"log",
"logging",
"mixnet-contract-common",
"multisig-contract-common",
"nym-api-requests",
"nymcoconut",
"nymsphinx",
"okapi",
"pemstore",
"pin-project",
"pretty_env_logger",
"rand 0.7.3",
"rand 0.8.5",
"reqwest",
"rocket",
"rocket_cors",
"rocket_okapi",
"schemars",
"serde",
"serde_json",
"sqlx 0.6.2",
"tap",
"task",
"thiserror",
"time 0.3.17",
"tokio",
"tokio-stream",
"topology",
"ts-rs",
"url",
"validator-client",
"version-checker",
]
[[package]]
name = "nym-api-requests"
version = "0.1.0"
@@ -3240,7 +3335,7 @@ dependencies = [
"base64",
"bip39",
"bs58",
"clap 3.2.8",
"clap 4.0.26",
"clap_complete",
"clap_complete_fig",
"dotenv",
@@ -3264,7 +3359,7 @@ dependencies = [
"bip39",
"bs58",
"cfg-if 1.0.0",
"clap 3.2.8",
"clap 4.0.26",
"comfy-table",
"cosmrs",
"cosmwasm-std",
@@ -3290,7 +3385,8 @@ dependencies = [
name = "nym-client"
version = "1.1.4"
dependencies = [
"clap 3.2.8",
"build-information",
"clap 4.0.26",
"client-connections",
"client-core",
"coconut-interface",
@@ -3303,6 +3399,7 @@ dependencies = [
"futures",
"gateway-client",
"gateway-requests",
"lazy_static",
"log",
"logging",
"network-defaults",
@@ -3320,7 +3417,6 @@ dependencies = [
"topology",
"url",
"validator-client",
"vergen 5.1.17",
"version-checker",
"websocket-requests",
]
@@ -3333,7 +3429,8 @@ dependencies = [
"async-trait",
"bip39",
"bs58",
"clap 3.2.8",
"build-information",
"clap 4.0.26",
"coconut-interface",
"colored",
"completions",
@@ -3346,6 +3443,7 @@ dependencies = [
"futures",
"gateway-requests",
"humantime-serde",
"lazy_static",
"log",
"logging",
"mixnet-client",
@@ -3368,7 +3466,6 @@ dependencies = [
"tokio-util 0.7.3",
"url",
"validator-client",
"vergen 5.1.17",
"version-checker",
]
@@ -3378,7 +3475,8 @@ version = "1.1.4"
dependencies = [
"anyhow",
"bs58",
"clap 3.2.8",
"build-information",
"clap 4.0.26",
"colored",
"completions",
"config",
@@ -3410,7 +3508,6 @@ dependencies = [
"topology",
"url",
"validator-client",
"vergen 5.1.17",
"version-checker",
]
@@ -3419,7 +3516,7 @@ name = "nym-network-requester"
version = "1.1.4"
dependencies = [
"async-trait",
"clap 3.2.8",
"clap 4.0.26",
"client-connections",
"completions",
"dirs",
@@ -3482,7 +3579,8 @@ dependencies = [
name = "nym-socks5-client"
version = "1.1.4"
dependencies = [
"clap 3.2.8",
"build-information",
"clap 4.0.26",
"client-connections",
"client-core",
"coconut-interface",
@@ -3495,6 +3593,7 @@ dependencies = [
"futures",
"gateway-client",
"gateway-requests",
"lazy_static",
"log",
"logging",
"network-defaults",
@@ -3515,7 +3614,6 @@ dependencies = [
"topology",
"url",
"validator-client",
"vergen 5.1.17",
"version-checker",
]
@@ -3545,70 +3643,6 @@ dependencies = [
"vesting-contract-common",
]
[[package]]
name = "nym-validator-api"
version = "1.1.4"
dependencies = [
"anyhow",
"async-trait",
"bs58",
"cfg-if 1.0.0",
"clap 3.2.8",
"coconut-bandwidth-contract-common",
"coconut-dkg-common",
"coconut-interface",
"config",
"console-subscriber",
"contracts-common",
"cosmwasm-std",
"credential-storage",
"credentials",
"crypto",
"cw-utils",
"cw3",
"dirs",
"dkg",
"dotenv",
"futures",
"gateway-client",
"getset",
"humantime-serde",
"inclusion-probability",
"log",
"logging",
"mixnet-contract-common",
"multisig-contract-common",
"nym-api-requests",
"nymcoconut",
"nymsphinx",
"okapi",
"pemstore",
"pin-project",
"pretty_env_logger",
"rand 0.7.3",
"rand 0.8.5",
"reqwest",
"rocket",
"rocket_cors",
"rocket_okapi",
"schemars",
"serde",
"serde_json",
"sqlx 0.6.2",
"tap",
"task",
"thiserror",
"time 0.3.17",
"tokio",
"tokio-stream",
"topology",
"ts-rs",
"url",
"validator-client",
"vergen 7.2.1",
"version-checker",
]
[[package]]
name = "nym-wallet-types"
version = "1.0.0"
@@ -4390,7 +4424,7 @@ dependencies = [
"rand_isaac",
"rand_jitter",
"rand_os",
"rand_pcg",
"rand_pcg 0.1.2",
"rand_xorshift",
"winapi",
]
@@ -4554,6 +4588,24 @@ dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_pcg"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e"
dependencies = [
"rand_core 0.6.3",
]
[[package]]
name = "rand_seeder"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf2890aaef0aa82719a50e808de264f9484b74b442e1a3a0e5ee38243ac40bdb"
dependencies = [
"rand_core 0.6.3",
]
[[package]]
name = "rand_xorshift"
version = "0.1.1"
+1
View File
@@ -30,6 +30,7 @@ members = [
"common/coconut-interface",
"common/commands",
"common/config",
"common/build-information",
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
"common/cosmwasm-smart-contracts/coconut-dkg",
"common/cosmwasm-smart-contracts/contracts-common",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "client-core"
version = "1.1.5"
version = "1.1.4"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
edition = "2021"
rust-version = "1.66"
@@ -230,7 +230,7 @@ where
mixnet_message_sender: MixnetMessageSender,
ack_sender: AcknowledgementSender,
shutdown: TaskClient,
) -> Result<GatewayClient, ClientCoreError<B>> {
) -> Result<GatewayClient, ClientCoreError> {
let gateway_id = self.gateway_config.gateway_id.clone();
if gateway_id.is_empty() {
return Err(ClientCoreError::GatewayIdUnknown);
@@ -285,7 +285,7 @@ where
refresh_rate: Duration,
topology_accessor: TopologyAccessor,
shutdown: TaskClient,
) -> Result<(), ClientCoreError<B>> {
) -> Result<(), ClientCoreError> {
let topology_refresher_config = TopologyRefresherConfig::new(
nym_api_urls,
refresh_rate,
@@ -328,12 +328,17 @@ where
async fn setup_persistent_reply_storage(
backend: B,
shutdown: TaskClient,
) -> Result<CombinedReplyStorage, ClientCoreError<B>> {
) -> Result<CombinedReplyStorage, ClientCoreError>
where
<B as ReplyStorageBackend>::StorageError: Sync + Send,
{
let persistent_storage = PersistentReplyStorage::new(backend);
let mem_store = persistent_storage
.load_state_from_backend()
.await
.map_err(|err| ClientCoreError::SurbStorageError { source: err })?;
.map_err(|err| ClientCoreError::SurbStorageError {
source: Box::new(err),
})?;
let store_clone = mem_store.clone();
spawn_future(async move {
@@ -345,7 +350,10 @@ where
Ok(mem_store)
}
pub async fn start_base(mut self) -> Result<BaseClient, ClientCoreError<B>> {
pub async fn start_base(mut self) -> Result<BaseClient, ClientCoreError>
where
<B as ReplyStorageBackend>::StorageError: Sync + Send,
{
info!("Starting nym client");
// channels for inter-component communication
// TODO: make the channels be internally created by the relevant components
@@ -14,13 +14,15 @@ use time::OffsetDateTime;
async fn setup_fresh_backend<P: AsRef<Path>>(
db_path: P,
debug_config: &DebugConfig,
) -> Result<fs_backend::Backend, ClientCoreError<fs_backend::Backend>> {
) -> Result<fs_backend::Backend, ClientCoreError> {
info!("creating fresh surb database");
let mut storage_backend = match fs_backend::Backend::init(db_path).await {
Ok(backend) => backend,
Err(err) => {
error!("failed to setup persistent storage backend for our reply needs: {err}");
return Err(ClientCoreError::SurbStorageError { source: err });
return Err(ClientCoreError::SurbStorageError {
source: Box::new(err),
});
}
};
@@ -34,7 +36,9 @@ async fn setup_fresh_backend<P: AsRef<Path>>(
storage_backend
.init_fresh(&mem_store)
.await
.map_err(|err| ClientCoreError::SurbStorageError { source: err })?;
.map_err(|err| ClientCoreError::SurbStorageError {
source: Box::new(err),
})?;
Ok(storage_backend)
}
@@ -63,7 +67,7 @@ fn archive_corrupted_database<P: AsRef<Path>>(db_path: P) -> io::Result<()> {
pub async fn setup_fs_reply_surb_backend<P: AsRef<Path>>(
db_path: P,
debug_config: &DebugConfig,
) -> Result<fs_backend::Backend, ClientCoreError<fs_backend::Backend>> {
) -> Result<fs_backend::Backend, ClientCoreError> {
// if the database file doesnt exist, initialise fresh storage, otherwise attempt to load the existing one
let db_path = db_path.as_ref();
if db_path.exists() {
+4 -3
View File
@@ -1,14 +1,13 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_storage::ReplyStorageBackend;
use crypto::asymmetric::identity::Ed25519RecoveryError;
use gateway_client::error::GatewayClientError;
use topology::NymTopologyError;
use validator_client::ValidatorClientError;
#[derive(thiserror::Error, Debug)]
pub enum ClientCoreError<B: ReplyStorageBackend> {
pub enum ClientCoreError {
#[error("I/O error: {0}")]
IoError(#[from] std::io::Error),
@@ -40,7 +39,9 @@ pub enum ClientCoreError<B: ReplyStorageBackend> {
InsufficientNetworkTopology(#[from] NymTopologyError),
#[error("experienced a failure with our reply surb persistent storage: {source}")]
SurbStorageError { source: B::StorageError },
SurbStorageError {
source: Box<dyn std::error::Error + Send + Sync>,
},
#[error("The gateway id is invalid - {0}")]
UnableToCreatePublicKeyFromGatewayId(Ed25519RecoveryError),
+6 -14
View File
@@ -1,7 +1,6 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_storage::ReplyStorageBackend;
use crate::{
client::key_manager::KeyManager,
config::{persistence::key_pathfinder::ClientKeyPathfinder, Config},
@@ -17,13 +16,10 @@ use tap::TapFallible;
use topology::{filter::VersionFilterable, gateway};
use url::Url;
pub(super) async fn query_gateway_details<B>(
pub(super) async fn query_gateway_details(
validator_servers: Vec<Url>,
chosen_gateway_id: Option<String>,
) -> Result<gateway::Node, ClientCoreError<B>>
where
B: ReplyStorageBackend,
{
) -> Result<gateway::Node, ClientCoreError> {
let nym_api = validator_servers
.choose(&mut thread_rng())
.ok_or(ClientCoreError::ListOfNymApisIsEmpty)?;
@@ -55,13 +51,10 @@ where
}
}
async fn register_with_gateway<B>(
async fn register_with_gateway(
gateway: &gateway::Node,
our_identity: Arc<identity::KeyPair>,
) -> Result<Arc<SharedKeys>, ClientCoreError<B>>
where
B: ReplyStorageBackend,
{
) -> Result<Arc<SharedKeys>, ClientCoreError> {
let timeout = Duration::from_millis(1500);
let mut gateway_client = GatewayClient::new_init(
gateway.clients_address(),
@@ -81,13 +74,12 @@ where
Ok(shared_keys)
}
pub(super) async fn register_with_gateway_and_store_keys<T, B>(
pub(super) async fn register_with_gateway_and_store_keys<T>(
gateway_details: gateway::Node,
config: &Config<T>,
) -> Result<(), ClientCoreError<B>>
) -> Result<(), ClientCoreError>
where
T: NymConfig,
B: ReplyStorageBackend,
{
let mut rng = OsRng;
let mut key_manager = KeyManager::new(&mut rng);
+15 -28
View File
@@ -12,7 +12,6 @@ use tap::TapFallible;
use config::NymConfig;
use crypto::asymmetric::{encryption, identity};
use crate::client::replies::reply_storage::ReplyStorageBackend;
use crate::{
config::{
persistence::key_pathfinder::ClientKeyPathfinder, ClientCoreConfigTrait, Config,
@@ -63,13 +62,13 @@ impl Display for InitResults {
/// Convenience function for setting up the gateway for a client. Depending on the arguments given
/// it will do the sensible thing.
pub async fn setup_gateway<B, C, T>(
pub async fn setup_gateway<C, T>(
register_gateway: bool,
// TODO: this should get refactored to instead take Option<identity::PublicKey>
user_chosen_gateway_id: Option<String>,
config: &Config<T>,
) -> Result<GatewayEndpointConfig, ClientCoreError<B>>
) -> Result<GatewayEndpointConfig, ClientCoreError>
where
B: ReplyStorageBackend,
C: NymConfig + ClientCoreConfigTrait,
T: NymConfig,
{
@@ -79,19 +78,18 @@ where
} else if let Some(user_chosen_gateway_id) = user_chosen_gateway_id {
config_gateway_with_existing_keys(user_chosen_gateway_id, config).await
} else {
reuse_existing_gateway_config::<B, C>(&id)
reuse_existing_gateway_config::<C>(&id)
}
}
/// Get the gateway details by querying the validator-api. Either pick one at random or use
/// the chosen one if it's among the available ones.
/// Saves keys to disk, specified by the paths in `config`.
pub async fn register_with_gateway<B, T>(
pub async fn register_with_gateway<T>(
user_chosen_gateway_id: Option<String>,
config: &Config<T>,
) -> Result<GatewayEndpointConfig, ClientCoreError<B>>
) -> Result<GatewayEndpointConfig, ClientCoreError>
where
B: ReplyStorageBackend,
T: NymConfig,
{
println!("Configuring gateway");
@@ -111,12 +109,11 @@ where
/// create any keys.
/// This assumes that the user knows what they are doing, and that the existing keys are valid for
/// the gateway being used
pub async fn config_gateway_with_existing_keys<B, T>(
pub async fn config_gateway_with_existing_keys<T>(
user_chosen_gateway_id: String,
config: &Config<T>,
) -> Result<GatewayEndpointConfig, ClientCoreError<B>>
) -> Result<GatewayEndpointConfig, ClientCoreError>
where
B: ReplyStorageBackend,
T: NymConfig,
{
println!("Using gateway provided by user, keeping existing keys");
@@ -127,11 +124,8 @@ where
}
/// Read and reuse the existing gateway configuration from a file that was generate earlier.
pub fn reuse_existing_gateway_config<B, T>(
id: &str,
) -> Result<GatewayEndpointConfig, ClientCoreError<B>>
pub fn reuse_existing_gateway_config<T>(id: &str) -> Result<GatewayEndpointConfig, ClientCoreError>
where
B: ReplyStorageBackend,
T: NymConfig + ClientCoreConfigTrait,
{
println!("Not registering gateway, will reuse existing config and keys");
@@ -150,19 +144,15 @@ where
}
/// Get the client address by loading the keys from stored files.
pub fn get_client_address_from_stored_keys<B, T>(
pub fn get_client_address_from_stored_keys<T>(
config: &Config<T>,
) -> Result<Recipient, ClientCoreError<B>>
) -> Result<Recipient, ClientCoreError>
where
T: config::NymConfig,
B: ReplyStorageBackend,
{
fn load_identity_keys<B>(
fn load_identity_keys(
pathfinder: &ClientKeyPathfinder,
) -> Result<identity::KeyPair, ClientCoreError<B>>
where
B: ReplyStorageBackend,
{
) -> Result<identity::KeyPair, ClientCoreError> {
let identity_keypair: identity::KeyPair =
pemstore::load_keypair(&pemstore::KeyPairPath::new(
pathfinder.private_identity_key().to_owned(),
@@ -172,12 +162,9 @@ where
Ok(identity_keypair)
}
fn load_sphinx_keys<B>(
fn load_sphinx_keys(
pathfinder: &ClientKeyPathfinder,
) -> Result<encryption::KeyPair, ClientCoreError<B>>
where
B: ReplyStorageBackend,
{
) -> Result<encryption::KeyPair, ClientCoreError> {
let sphinx_keypair: encryption::KeyPair =
pemstore::load_keypair(&pemstore::KeyPairPath::new(
pathfinder.private_encryption_key().to_owned(),
+1 -1
View File
@@ -8,7 +8,7 @@ edition = "2021"
[dependencies]
bip39 = "1.0.1"
cfg-if = "0.1"
clap = { version = "3.2", features = ["cargo", "derive"] }
clap = { version = "4.0", features = ["cargo", "derive"] }
rand = "0.7.3"
serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0"
+3 -3
View File
@@ -31,7 +31,7 @@ cfg_if::cfg_if! {
#[tokio::main]
async fn main() -> Result<()> {
let args = Cli::parse();
setup_env(args.config_env_file.clone());
setup_env(args.config_env_file.as_ref());
let bin_name = "nym-credential-client";
match args.command {
@@ -42,8 +42,8 @@ cfg_if::cfg_if! {
let state = deposit(&r.nymd_url, &r.mnemonic, r.amount).await?;
get_credential(&state, shared_storage).await?;
}
Command::Completions(c) => c.generate(&mut crate::Cli::into_app(), bin_name),
Command::GenerateFigSpec => fig_generate(&mut crate::Cli::into_app(), bin_name)
Command::Completions(c) => c.generate(&mut crate::Cli::command(), bin_name),
Command::GenerateFigSpec => fig_generate(&mut crate::Cli::command(), bin_name)
}
Ok(())
+4 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.1.5"
version = "1.1.4"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
@@ -20,8 +20,9 @@ futures = "0.3" # bunch of futures stuff, however, now that I think about it, it
# and the single instance of abortable we have should really be refactored anyway
url = "2.2"
clap = { version = "3.2", features = ["cargo", "derive"] }
clap = { version = "4.0", features = ["cargo", "derive"] }
dirs = "4.0"
lazy_static = "1.4.0"
log = "0.4" # self explanatory
pretty_env_logger = "0.4" # for formatting log messages
rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use
@@ -33,6 +34,7 @@ tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] }
tokio-tungstenite = "0.14" # websocket
## internal
build-information = { path = "../../common/build-information" }
client-core = { path = "../client-core", features = ["fs-surb-storage"] }
client-connections = { path = "../../common/client-connections" }
coconut-interface = { path = "../../common/coconut-interface", optional = true }
@@ -58,6 +60,3 @@ coconut = ["coconut-interface", "credentials", "credentials/coconut", "gateway-r
[dev-dependencies]
serde_json = "1.0" # for the "textsend" example
[build-dependencies]
vergen = { version = "5", default-features = false, features = ["build", "git", "rustc", "cargo"] }
File diff suppressed because it is too large Load Diff
+18 -14
View File
@@ -8,6 +8,7 @@ use crate::{
};
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::identity;
use nymsphinx::addressing::clients::Recipient;
use serde::Serialize;
use std::fmt::Display;
@@ -21,7 +22,7 @@ pub(crate) struct Init {
/// Id of the gateway we are going to connect to.
#[clap(long)]
gateway: Option<String>,
gateway: Option<identity::PublicKey>,
/// Force register gateway. WARNING: this will overwrite any existing keys for the given id,
/// potentially causing loss of access.
@@ -29,12 +30,14 @@ pub(crate) struct Init {
force_register_gateway: bool,
/// Comma separated list of rest endpoints of the nymd validators
#[clap(long)]
nymd_validators: Option<String>,
#[cfg(feature = "coconut")]
#[clap(long, value_delimiter = ',')]
nymd_validators: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the API validators
#[clap(long)]
api_validators: Option<String>,
#[clap(long, alias = "api_validators", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
/// Whether to not start the websocket
#[clap(long)]
@@ -46,11 +49,11 @@ pub(crate) struct Init {
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hidden = true)]
#[clap(long, hide = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hidden = true)]
#[clap(long, hide = true)]
no_cover: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
@@ -67,13 +70,14 @@ pub(crate) struct Init {
impl From<Init> for OverrideConfig {
fn from(init_config: Init) -> Self {
OverrideConfig {
nymd_validators: init_config.nymd_validators,
api_validators: init_config.api_validators,
nym_apis: init_config.nym_apis,
disable_socket: init_config.disable_socket,
port: init_config.port,
fastmode: init_config.fastmode,
no_cover: init_config.no_cover,
#[cfg(feature = "coconut")]
nymd_validators: init_config.nymd_validators,
#[cfg(feature = "coconut")]
enabled_credentials_mode: init_config.enabled_credentials_mode,
}
@@ -127,16 +131,16 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> {
let register_gateway = !already_init || user_wants_force_register;
// Attempt to use a user-provided gateway, if possible
let user_chosen_gateway_id = args.gateway.clone();
let user_chosen_gateway_id = args.gateway;
// Load and potentially override config
let mut config = override_config(Config::new(id), OverrideConfig::from(args.clone()));
// Setup gateway by either registering a new one, or creating a new config from the selected
// one but with keys kept, or reusing the gateway configuration.
let gateway = client_core::init::setup_gateway::<_, Config, _>(
let gateway = client_core::init::setup_gateway::<Config, _>(
register_gateway,
user_chosen_gateway_id,
user_chosen_gateway_id.map(|id| id.to_base58_string()),
config.get_base(),
)
.await
@@ -152,14 +156,14 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> {
let address = client_core::init::get_client_address_from_stored_keys(config.get_base())?;
let init_results = InitResults::new(&config, &address);
println!("{}", init_results);
println!("{init_results}");
// Output summary to a json file, if specified
if args.output_json {
client_core::init::output_to_json(&init_results, "client_init_results.json");
}
println!("\nThe address of this client is: {}\n", address);
println!("\nThe address of this client is: {address}\n");
Ok(())
}
+27 -54
View File
@@ -1,54 +1,30 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::error::Error;
use crate::client::config::{Config, SocketType};
use build_information::BinaryBuildInformation;
use clap::CommandFactory;
use clap::{Parser, Subcommand};
use completions::{fig_generate, ArgShell};
use lazy_static::lazy_static;
use std::error::Error;
pub(crate) mod init;
pub(crate) mod run;
pub(crate) mod upgrade;
fn long_version() -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
env!("VERGEN_BUILD_TIMESTAMP"),
"Build Version:",
env!("VERGEN_BUILD_SEMVER"),
"Commit SHA:",
env!("VERGEN_GIT_SHA"),
"Commit Date:",
env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
"Commit Branch:",
env!("VERGEN_GIT_BRANCH"),
"rustc Version:",
env!("VERGEN_RUSTC_SEMVER"),
"rustc Channel:",
env!("VERGEN_RUSTC_CHANNEL"),
"cargo Profile:",
env!("VERGEN_CARGO_PROFILE"),
)
lazy_static! {
pub static ref PRETTY_BUILD_INFORMATION: String =
BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print();
}
fn long_version_static() -> &'static str {
Box::leak(long_version().into_boxed_str())
// Helper for passing LONG_VERSION to clap
fn pretty_build_info_static() -> &'static str {
&PRETTY_BUILD_INFORMATION
}
#[derive(Parser)]
#[clap(author = "Nymtech", version, long_version = long_version_static(), about)]
#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)]
pub(crate) struct Cli {
/// Path pointing to an env file that configures the client.
#[clap(short, long)]
@@ -76,13 +52,14 @@ pub(crate) enum Commands {
// Configuration that can be overridden.
pub(crate) struct OverrideConfig {
nymd_validators: Option<String>,
api_validators: Option<String>,
nym_apis: Option<Vec<url::Url>>,
disable_socket: bool,
port: Option<u16>,
fastmode: bool,
no_cover: bool,
#[cfg(feature = "coconut")]
nymd_validators: Option<Vec<url::Url>>,
#[cfg(feature = "coconut")]
enabled_credentials_mode: bool,
}
@@ -94,34 +71,21 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Syn
Commands::Init(m) => init::execute(m).await?,
Commands::Run(m) => run::execute(m).await?,
Commands::Upgrade(m) => upgrade::execute(m),
Commands::Completions(s) => s.generate(&mut Cli::into_app(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut Cli::into_app(), bin_name),
Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name),
}
Ok(())
}
pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Config {
if let Some(raw_validators) = args.nymd_validators {
config
.get_base_mut()
.set_custom_validators(config::parse_validators(&raw_validators));
} else if std::env::var(network_defaults::var_names::CONFIGURED).is_ok() {
let raw_validators = std::env::var(network_defaults::var_names::NYMD_VALIDATOR)
.expect("nymd validator not set");
config
.get_base_mut()
.set_custom_validators(config::parse_validators(&raw_validators));
}
if let Some(raw_validators) = args.api_validators {
config
.get_base_mut()
.set_custom_nym_apis(config::parse_validators(&raw_validators));
if let Some(nym_apis) = args.nym_apis {
config.get_base_mut().set_custom_nym_apis(nym_apis);
} else if std::env::var(network_defaults::var_names::CONFIGURED).is_ok() {
let raw_validators = std::env::var(network_defaults::var_names::API_VALIDATOR)
.expect("api validator not set");
config
.get_base_mut()
.set_custom_nym_apis(config::parse_validators(&raw_validators));
.set_custom_nym_apis(config::parse_urls(&raw_validators));
}
if args.disable_socket {
@@ -134,6 +98,15 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
#[cfg(feature = "coconut")]
{
if let Some(nymd_validators) = args.nymd_validators {
config.get_base_mut().set_custom_validators(nymd_validators);
} else if std::env::var(network_defaults::var_names::CONFIGURED).is_ok() {
let raw_validators = std::env::var(network_defaults::var_names::NYMD_VALIDATOR)
.expect("nymd validator not set");
config
.get_base_mut()
.set_custom_validators(config::parse_urls(&raw_validators));
}
if args.enabled_credentials_mode {
config.get_base_mut().with_disabled_credentials(false)
}
+15 -10
View File
@@ -1,4 +1,4 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::error::Error;
@@ -11,6 +11,7 @@ use crate::{
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::identity;
use log::*;
use version_checker::is_minor_version_compatible;
@@ -21,17 +22,19 @@ pub(crate) struct Run {
id: String,
/// Comma separated list of rest endpoints of the nymd validators
#[clap(long)]
nymd_validators: Option<String>,
#[cfg(feature = "coconut")]
#[clap(long, value_delimiter = ',')]
nymd_validators: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the API validators
#[clap(long)]
api_validators: Option<String>,
#[clap(long, alias = "api_validators", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
/// Id of the gateway we want to connect to. If overridden, it is user's responsibility to
/// ensure prior registration happened
#[clap(long)]
gateway: Option<String>,
gateway: Option<identity::PublicKey>,
/// Whether to not start the websocket
#[clap(long)]
@@ -43,11 +46,11 @@ pub(crate) struct Run {
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hidden = true)]
#[clap(long, hide = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hidden = true)]
#[clap(long, hide = true)]
no_cover: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
@@ -60,12 +63,14 @@ pub(crate) struct Run {
impl From<Run> for OverrideConfig {
fn from(run_config: Run) -> Self {
OverrideConfig {
nymd_validators: run_config.nymd_validators,
api_validators: run_config.api_validators,
nym_apis: run_config.nym_apis,
disable_socket: run_config.disable_socket,
port: run_config.port,
fastmode: run_config.fastmode,
no_cover: run_config.no_cover,
#[cfg(feature = "coconut")]
nymd_validators: run_config.nymd_validators,
#[cfg(feature = "coconut")]
enabled_credentials_mode: run_config.enabled_credentials_mode,
}
+1 -2
View File
@@ -1,4 +1,3 @@
use client_core::client::replies::reply_storage::fs_backend;
use client_core::error::ClientCoreError;
#[derive(thiserror::Error, Debug)]
@@ -7,7 +6,7 @@ pub enum ClientError {
IoError(#[from] std::io::Error),
#[error("client-core error: {0}")]
ClientCoreError(#[from] ClientCoreError<fs_backend::Backend>),
ClientCoreError(#[from] ClientCoreError),
#[error("Failed to load config for: {0}")]
FailedToLoadConfig(String),
+1 -1
View File
@@ -18,7 +18,7 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
println!("{}", banner());
let args = commands::Cli::parse();
setup_env(args.config_env_file.clone());
setup_env(args.config_env_file.as_ref());
commands::execute(&args).await
}
+4 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-socks5-client"
version = "1.1.5"
version = "1.1.4"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021"
@@ -11,9 +11,10 @@ name = "nym_socks5"
path = "src/lib.rs"
[dependencies]
clap = { version = "3.2", features = ["cargo", "derive"] }
clap = { version = "4.0", features = ["cargo", "derive"] }
dirs = "4.0"
futures = "0.3"
lazy_static = "1.4.0"
log = "0.4"
pin-project = "1.0"
pretty_env_logger = "0.4"
@@ -26,6 +27,7 @@ tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] }
url = "2.2"
# internal
build-information = { path = "../../common/build-information" }
client-core = { path = "../client-core", features = ["fs-surb-storage"] }
client-connections = { path = "../../common/client-connections" }
coconut-interface = { path = "../../common/coconut-interface", optional = true }
@@ -51,6 +53,3 @@ version-checker = { path = "../../common/version-checker" }
[features]
coconut = ["coconut-interface", "credentials", "gateway-requests/coconut", "gateway-client/coconut", "credentials/coconut", "client-core/coconut"]
eth = []
[build-dependencies]
vergen = { version = "5", default-features = false, features = ["build", "git", "rustc", "cargo"] }
-8
View File
@@ -1,8 +0,0 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use vergen::{vergen, Config};
fn main() {
vergen(Config::default()).expect("failed to extract build metadata")
}
+23 -17
View File
@@ -8,6 +8,7 @@ use crate::{
};
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::identity;
use nymsphinx::addressing::clients::Recipient;
use serde::Serialize;
use std::fmt::Display;
@@ -21,19 +22,20 @@ pub(crate) struct Init {
/// Address of the socks5 provider to send messages to.
#[clap(long)]
provider: String,
provider: Recipient,
/// Specifies whether this client is going to use an anonymous sender tag for communication with the service provider.
/// While this is going to hide its actual address information, it will make the actual communication
/// slower and consume nearly double the bandwidth as it will require sending reply SURBs.
///
/// Note that some service providers might not support this.
#[clap(long)]
use_anonymous_sender_tag: bool,
// the alias here is included for backwards compatibility (1.1.4 and before)
#[clap(long, alias = "use_anonymous_sender_tag")]
use_reply_surbs: bool,
/// Id of the gateway we are going to connect to.
#[clap(long)]
gateway: Option<String>,
gateway: Option<identity::PublicKey>,
/// Force register gateway. WARNING: this will overwrite any existing keys for the given id,
/// potentially causing loss of access.
@@ -41,12 +43,14 @@ pub(crate) struct Init {
force_register_gateway: bool,
/// Comma separated list of rest endpoints of the nymd validators
#[clap(long)]
nymd_validators: Option<String>,
#[cfg(feature = "coconut")]
#[clap(long, value_delimiter = ',')]
nymd_validators: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the API validators
#[clap(long)]
api_validators: Option<String>,
#[clap(long, alias = "api_validators", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
/// Port for the socket to listen on in all subsequent runs
#[clap(short, long)]
@@ -54,11 +58,11 @@ pub(crate) struct Init {
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hidden = true)]
#[clap(long, hide = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hidden = true)]
#[clap(long, hide = true)]
no_cover: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
@@ -75,12 +79,14 @@ pub(crate) struct Init {
impl From<Init> for OverrideConfig {
fn from(init_config: Init) -> Self {
OverrideConfig {
nymd_validators: init_config.nymd_validators,
api_validators: init_config.api_validators,
nym_apis: init_config.nym_apis,
port: init_config.port,
use_anonymous_sender_tag: init_config.use_anonymous_sender_tag,
use_anonymous_replies: init_config.use_reply_surbs,
fastmode: init_config.fastmode,
no_cover: init_config.no_cover,
#[cfg(feature = "coconut")]
nymd_validators: init_config.nymd_validators,
#[cfg(feature = "coconut")]
enabled_credentials_mode: init_config.enabled_credentials_mode,
}
@@ -135,19 +141,19 @@ pub(crate) async fn execute(args: &Init) -> Result<(), Socks5ClientError> {
let register_gateway = !already_init || user_wants_force_register;
// Attempt to use a user-provided gateway, if possible
let user_chosen_gateway_id = args.gateway.clone();
let user_chosen_gateway_id = args.gateway;
// Load and potentially override config
let mut config = override_config(
Config::new(id, provider_address),
Config::new(id, &provider_address.to_string()),
OverrideConfig::from(args.clone()),
);
// Setup gateway by either registering a new one, or creating a new config from the selected
// one but with keys kept, or reusing the gateway configuration.
let gateway = client_core::init::setup_gateway::<_, Config, _>(
let gateway = client_core::init::setup_gateway::<Config, _>(
register_gateway,
user_chosen_gateway_id,
user_chosen_gateway_id.map(|id| id.to_base58_string()),
config.get_base(),
)
.await
+31 -56
View File
@@ -1,55 +1,31 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::error::Error;
use crate::client::config::Config;
use build_information::BinaryBuildInformation;
use clap::CommandFactory;
use clap::{Parser, Subcommand};
use completions::{fig_generate, ArgShell};
use config::parse_validators;
use config::parse_urls;
use lazy_static::lazy_static;
use std::error::Error;
pub mod init;
pub(crate) mod run;
pub(crate) mod upgrade;
fn long_version() -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
env!("VERGEN_BUILD_TIMESTAMP"),
"Build Version:",
env!("VERGEN_BUILD_SEMVER"),
"Commit SHA:",
env!("VERGEN_GIT_SHA"),
"Commit Date:",
env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
"Commit Branch:",
env!("VERGEN_GIT_BRANCH"),
"rustc Version:",
env!("VERGEN_RUSTC_SEMVER"),
"rustc Channel:",
env!("VERGEN_RUSTC_CHANNEL"),
"cargo Profile:",
env!("VERGEN_CARGO_PROFILE"),
)
lazy_static! {
pub static ref PRETTY_BUILD_INFORMATION: String =
BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print();
}
fn long_version_static() -> &'static str {
Box::leak(long_version().into_boxed_str())
// Helper for passing LONG_VERSION to clap
fn pretty_build_info_static() -> &'static str {
&PRETTY_BUILD_INFORMATION
}
#[derive(Parser)]
#[clap(author = "Nymtech", version, long_version = long_version_static(), about)]
#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)]
pub(crate) struct Cli {
/// Path pointing to an env file that configures the client.
#[clap(short, long)]
@@ -79,13 +55,14 @@ pub(crate) enum Commands {
// Configuration that can be overridden.
pub(crate) struct OverrideConfig {
nymd_validators: Option<String>,
api_validators: Option<String>,
nym_apis: Option<Vec<url::Url>>,
port: Option<u16>,
use_anonymous_sender_tag: bool,
use_anonymous_replies: bool,
fastmode: bool,
no_cover: bool,
#[cfg(feature = "coconut")]
nymd_validators: Option<Vec<url::Url>>,
#[cfg(feature = "coconut")]
enabled_credentials_mode: bool,
}
@@ -97,33 +74,22 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Syn
Commands::Init(m) => init::execute(m).await?,
Commands::Run(m) => run::execute(m).await?,
Commands::Upgrade(m) => upgrade::execute(m),
Commands::Completions(s) => s.generate(&mut Cli::into_app(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut Cli::into_app(), bin_name),
Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name),
}
Ok(())
}
pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Config {
if let Some(raw_validators) = args.nymd_validators {
config
.get_base_mut()
.set_custom_validators(parse_validators(&raw_validators));
} else if let Ok(raw_validators) = std::env::var(network_defaults::var_names::NYMD_VALIDATOR) {
config
.get_base_mut()
.set_custom_validators(parse_validators(&raw_validators));
}
if let Some(raw_validators) = args.api_validators {
config
.get_base_mut()
.set_custom_nym_apis(parse_validators(&raw_validators));
if let Some(nym_apis) = args.nym_apis {
config.get_base_mut().set_custom_nym_apis(nym_apis);
} else if let Ok(raw_validators) = std::env::var(network_defaults::var_names::API_VALIDATOR) {
config
.get_base_mut()
.set_custom_nym_apis(parse_validators(&raw_validators));
.set_custom_nym_apis(parse_urls(&raw_validators));
}
if args.use_anonymous_sender_tag {
if args.use_anonymous_replies {
config = config.with_anonymous_replies(true)
}
@@ -133,6 +99,15 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
#[cfg(feature = "coconut")]
{
if let Some(nymd_validators) = args.nymd_validators {
config.get_base_mut().set_custom_validators(nymd_validators);
} else if let Ok(raw_validators) =
std::env::var(network_defaults::var_names::NYMD_VALIDATOR)
{
config
.get_base_mut()
.set_custom_validators(parse_urls(&raw_validators));
}
if args.enabled_credentials_mode {
config.get_base_mut().with_disabled_credentials(false)
}
+19 -13
View File
@@ -9,7 +9,9 @@ use crate::{
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::identity;
use log::*;
use nymsphinx::addressing::clients::Recipient;
use version_checker::is_minor_version_compatible;
#[derive(Args, Clone)]
@@ -27,25 +29,27 @@ pub(crate) struct Run {
/// slower and consume nearly double the bandwidth as it will require sending reply SURBs.
///
/// Note that some service providers might not support this.
#[clap(long)]
use_anonymous_sender_tag: bool,
// the alias here is included for backwards compatibility (1.1.4 and before)
#[clap(long, alias = "use_anonymous_sender_tag")]
use_anonymous_replies: bool,
/// Address of the socks5 provider to send messages to.
#[clap(long)]
provider: Option<String>,
provider: Option<Recipient>,
/// Id of the gateway we want to connect to. If overridden, it is user's responsibility to
/// ensure prior registration happened
#[clap(long)]
gateway: Option<String>,
gateway: Option<identity::PublicKey>,
/// Comma separated list of rest endpoints of the nymd validators
#[clap(long)]
nymd_validators: Option<String>,
#[cfg(feature = "coconut")]
#[clap(long, value_delimiter = ',')]
nymd_validators: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the Nym APIs
#[clap(long)]
nym_apis: Option<String>,
#[clap(long, value_delimiter = ',')]
nym_apis: Option<Vec<url::Url>>,
/// Port for the socket to listen on
#[clap(short, long)]
@@ -53,11 +57,11 @@ pub(crate) struct Run {
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hidden = true)]
#[clap(long, hide = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hidden = true)]
#[clap(long, hide = true)]
no_cover: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
@@ -70,12 +74,14 @@ pub(crate) struct Run {
impl From<Run> for OverrideConfig {
fn from(run_config: Run) -> Self {
OverrideConfig {
nymd_validators: run_config.nymd_validators,
api_validators: run_config.nym_apis,
nym_apis: run_config.nym_apis,
port: run_config.port,
use_anonymous_sender_tag: run_config.use_anonymous_sender_tag,
use_anonymous_replies: run_config.use_anonymous_replies,
fastmode: run_config.fastmode,
no_cover: run_config.no_cover,
#[cfg(feature = "coconut")]
nymd_validators: run_config.nymd_validators,
#[cfg(feature = "coconut")]
enabled_credentials_mode: run_config.enabled_credentials_mode,
}
+1 -2
View File
@@ -1,5 +1,4 @@
use crate::socks::types::SocksProxyError;
use client_core::client::replies::reply_storage::fs_backend;
use client_core::error::ClientCoreError;
use socks5_requests::ConnectionId;
@@ -9,7 +8,7 @@ pub enum Socks5ClientError {
IoError(#[from] std::io::Error),
#[error("client-core error: {0}")]
ClientCoreError(#[from] ClientCoreError<fs_backend::Backend>),
ClientCoreError(#[from] ClientCoreError),
#[error("SOCKS proxy error")]
SocksProxyError(SocksProxyError),
+1 -1
View File
@@ -18,7 +18,7 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
println!("{}", banner());
let args = commands::Cli::parse();
setup_env(args.config_env_file.clone());
setup_env(args.config_env_file.as_ref());
commands::execute(&args).await
}
File diff suppressed because it is too large Load Diff
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "build-information"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[build-dependencies]
vergen = { version = "7", default-features = false, features = ["build", "git", "rustc", "cargo"] }
@@ -1,4 +1,4 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use vergen::{vergen, Config};
+86
View File
@@ -0,0 +1,86 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// TODO: at a later date this crate should probably also expose `ContractBuildInformation`
// and be used by our smart contracts
pub struct BinaryBuildInformation {
// VERGEN_BUILD_TIMESTAMP
/// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.
pub build_timestamp: &'static str,
// VERGEN_BUILD_SEMVER
/// Provides the build version, for example `0.1.0-9-g46f83e1`.
pub build_version: &'static str,
// VERGEN_GIT_SHA
/// Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.
pub commit_sha: &'static str,
// VERGEN_GIT_COMMIT_TIMESTAMP
/// Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.
pub commit_timestamp: &'static str,
// VERGEN_GIT_BRANCH
/// Provides the name of the git branch that was used for the build, for example `master`.
pub commit_branch: &'static str,
// VERGEN_RUSTC_SEMVER
/// Provides the rustc version that was used for the build, for example `1.52.0-nightly`.
pub rustc_version: &'static str,
// VERGEN_RUSTC_CHANNEL
/// Provides the rustc channel that was used for the build, for example `nightly`.
pub rustc_channel: &'static str,
// VERGEN_CARGO_PROFILE
/// Provides the cargo profile that was used for the build, for example `debug`.
pub cargo_profile: &'static str,
}
impl BinaryBuildInformation {
// explicitly require the build_version to be passed as it's binary specific
pub const fn new(build_version: &'static str) -> Self {
BinaryBuildInformation {
build_timestamp: env!("VERGEN_BUILD_TIMESTAMP"),
build_version,
commit_sha: env!("VERGEN_GIT_SHA"),
commit_timestamp: env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
commit_branch: env!("VERGEN_GIT_BRANCH"),
rustc_version: env!("VERGEN_RUSTC_SEMVER"),
rustc_channel: env!("VERGEN_RUSTC_CHANNEL"),
cargo_profile: env!("VERGEN_CARGO_PROFILE"),
}
}
pub fn pretty_print(&self) -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
self.build_timestamp,
"Build Version:",
self.build_version,
"Commit SHA:",
self.commit_sha,
"Commit Date:",
self.commit_timestamp,
"Commit Branch:",
self.commit_branch,
"rustc Version:",
self.rustc_version,
"rustc Channel:",
self.rustc_channel,
"cargo Profile:",
self.cargo_profile,
)
}
}
+1 -1
View File
@@ -10,7 +10,7 @@ bip39 = "1.0.1"
bs58 = "0.4"
comfy-table = "6.0.0"
cfg-if = "1.0.0"
clap = { version = "3.2", features = ["derive"] }
clap = { version = "4.0", features = ["derive"] }
handlebars = "3.0.1"
humantime-serde = "1.0"
k256 = { version = "0.10", features = ["ecdsa", "sha256"] }
+1 -1
View File
@@ -32,7 +32,7 @@ pub struct ClientArgs {
pub fn get_network_details(args: &ClientArgs) -> Result<NymNetworkDetails, ContextError> {
// let the network defaults crate handle setting up the env vars if the file arg is set, otherwise
// it will default to what is already in env vars, falling back to mainnet
setup_env(args.config_env_file.clone());
setup_env(args.config_env_file.as_ref());
// override the env vars with user supplied arguments, if set
if let Some(nymd_url) = args.nymd_url.as_ref() {
+3 -3
View File
@@ -6,6 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "3.2", features = ["derive"] }
clap_complete = "3.2"
clap_complete_fig = "3.2"
clap = { version = "4.0", features = ["derive"] }
clap_complete = "4.0"
clap_complete_fig = "4.0"
+3 -3
View File
@@ -1,5 +1,5 @@
use clap::builder::Command;
use clap::clap_derive::ArgEnum;
use clap::clap_derive::ValueEnum;
use clap::Args;
use clap_complete::generator::generate;
use clap_complete::Shell as ClapShell;
@@ -14,7 +14,7 @@ pub fn fig_generate(command: &mut Command, name: &str) {
)
}
#[derive(ArgEnum, Copy, Clone)]
#[derive(ValueEnum, Copy, Clone)]
pub enum Shell {
Bash,
Elvish,
@@ -25,7 +25,7 @@ pub enum Shell {
#[derive(Args, Copy, Clone)]
pub struct ArgShell {
#[clap(arg_enum, value_name = "SHELL")]
#[clap(value_enum, value_name = "SHELL")]
shell: Shell,
}
+5 -4
View File
@@ -118,13 +118,14 @@ pub trait NymConfig: Default + Serialize + DeserializeOwned {
}
}
pub fn parse_validators(raw: &str) -> Vec<url::Url> {
// this function is only used for parsing values from the network defaults and thus the "expect" there are fine
pub fn parse_urls(raw: &str) -> Vec<url::Url> {
raw.split(',')
.map(|raw_validator| {
raw_validator
.map(|raw_url| {
raw_url
.trim()
.parse()
.expect("one of the provided validator api urls is invalid")
.expect("one of the provided nym api urls is invalid")
})
.collect()
}
@@ -56,7 +56,6 @@ impl Family {
self.proxy.as_ref()
}
#[allow(dead_code)]
pub fn label(&self) -> &str {
&self.label
}
@@ -7,6 +7,7 @@ pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATUR
use nymsphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH};
use pemstore::traits::{PemStorableKey, PemStorableKeyPair};
use std::fmt::{self, Display, Formatter};
use std::str::FromStr;
use thiserror::Error;
#[cfg(feature = "rand")]
@@ -141,6 +142,14 @@ impl PublicKey {
}
}
impl FromStr for PublicKey {
type Err = Ed25519RecoveryError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
PublicKey::from_base58_string(s)
}
}
#[cfg(feature = "serde")]
impl Serialize for PublicKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+1 -1
View File
@@ -289,7 +289,7 @@ impl ValidatorDetails {
}
}
pub fn setup_env(config_env_file: Option<PathBuf>) {
pub fn setup_env(config_env_file: Option<&PathBuf>) {
match std::env::var(var_names::CONFIGURED) {
// if the configuration is not already set in the env vars
Err(std::env::VarError::NotPresent) => {
@@ -10,6 +10,7 @@ use nymsphinx_types::Destination;
use serde::de::{Error as SerdeError, Unexpected, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt::{self, Formatter};
use std::str::FromStr;
use thiserror::Error;
// Not entirely sure whether this is the correct place for those, but let's see how it's going
@@ -225,6 +226,14 @@ impl std::fmt::Display for Recipient {
}
}
impl FromStr for Recipient {
type Err = RecipientFormattingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Recipient::try_from_base58_string(s)
}
}
#[cfg(test)]
mod tests {
use super::*;
File diff suppressed because it is too large Load Diff
@@ -1,12 +1,12 @@
{
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.5",
"@nomiclabs/hardhat-etherscan": "^3.0.3",
"@nomiclabs/hardhat-etherscan": "^3.1.0",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"chai": "^4.3.6",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.6.1",
"hardhat": "^2.9.2",
"hardhat": "^2.11.2",
"solidity-coverage": "^0.7.20"
},
"dependencies": {
File diff suppressed because it is too large Load Diff
@@ -16,7 +16,7 @@
},
"dependencies": {
"@types/node": "^14.14.22",
"nodemon": "^2.0.7",
"nodemon": "^2.0.20",
"@nymproject/nym-validator-client" : "0.18.0",
"save-dev": "0.0.1-security",
"tasktimer": "^3.0.0",
+1 -1
View File
@@ -1,2 +1,2 @@
# The path to the geoip database file
GEOIP_DB_PATH=./geo_ip/GeoLite2-City.mmdb
GEOIP_DB_PATH=./geo_ip/GeoLite2-Country.mmdb
+5 -2
View File
@@ -1,13 +1,13 @@
[package]
name = "explorer-api"
version = "1.1.2"
version = "1.1.1"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chrono = { version = "0.4.19", features = ["serde"] }
clap = { version = "3.2", features = ["cargo", "derive"] }
clap = { version = "4.0", features = ["cargo", "derive"] }
humantime-serde = "1.0"
isocountry = "0.3.2"
itertools = "0.10.3"
@@ -25,6 +25,9 @@ thiserror = "1.0.29"
tokio = {version = "1.21.2", features = ["full"] }
maxminddb = "0.23.0"
dotenv = "0.15.0"
rand = "0.8.5"
rand_seeder = "0.2.3"
rand_pcg = "0.3.1"
mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet-contract" }
contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" }
+1 -1
View File
@@ -40,7 +40,7 @@ It should be previously installed thanks to `geoipupdate` service.
For example:
```shell
GEOIP_DB_PATH=./geo_ip/GeoLite2-City.mmdb cargo run
GEOIP_DB_PATH=./geo_ip/GeoLite2-Country.mmdb cargo run
```
Note: explorer-api binary reads the provided `.env` file.
+26
View File
@@ -0,0 +1,26 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::geo_ip::location::Location;
use crate::state::ExplorerApiStateContext;
use rocket::response::status;
use rocket::serde::json::Json;
use rocket::{Route, State};
use rocket_okapi::okapi::openapi3::OpenApi;
use rocket_okapi::settings::OpenApiSettings;
pub fn nym_terms_make_default_routes(settings: &OpenApiSettings) -> (Vec<Route>, OpenApi) {
openapi_get_routes_spec![settings: terms]
}
#[openapi(tag = "terms")]
#[get("/")]
pub(crate) async fn terms(
_state: &State<ExplorerApiStateContext>,
location: Location,
) -> Result<Json<String>, status::Forbidden<String>> {
if location.iso_alpha2 == "US" {
return Err(status::Forbidden(Some("US government sucks".to_string())));
}
Ok(Json("Nym Terms & Conditions: Welcome".to_string()))
}
+1
View File
@@ -0,0 +1 @@
pub(crate) mod http;
+6 -11
View File
@@ -3,14 +3,14 @@
use isocountry::CountryCode;
use log::warn;
use maxminddb::{geoip2::City, MaxMindDBError, Reader};
use maxminddb::{geoip2::Country, MaxMindDBError, Reader};
use std::{
net::{IpAddr, ToSocketAddrs},
str::FromStr,
sync::Arc,
};
const DEFAULT_DATABASE_PATH: &str = "./geo_ip/GeoLite2-City.mmdb";
const DEFAULT_DATABASE_PATH: &str = "./geo_ip/GeoLite2-Country.mmdb";
const FAKE_PORT: u16 = 1234;
#[derive(Debug)]
@@ -38,8 +38,6 @@ pub(crate) struct Location {
pub(crate) iso_alpha3: String,
/// English country short name (ISO 3166-1)
pub(crate) name: String,
pub(crate) latitude: Option<f64>,
pub(crate) longitude: Option<f64>,
}
impl GeoIp {
@@ -88,7 +86,7 @@ impl GeoIp {
error!("No registered GeoIP database");
GeoIpError::InternalError
})?
.lookup::<City>(ip);
.lookup::<Country>(ip);
match &result {
Ok(v) => Ok(Some(
Location::try_from(v).map_err(|_| GeoIpError::InternalError)?,
@@ -101,11 +99,11 @@ impl GeoIp {
}
}
impl<'a> TryFrom<&City<'a>> for Location {
impl<'a> TryFrom<&Country<'a>> for Location {
type Error = String;
fn try_from(city: &City) -> Result<Self, Self::Error> {
let data = city.country.as_ref().ok_or_else(|| {
fn try_from(country: &Country) -> Result<Self, Self::Error> {
let data = country.country.as_ref().ok_or_else(|| {
warn!("No Country data found");
"No Country data found"
})?;
@@ -121,13 +119,10 @@ impl<'a> TryFrom<&City<'a>> for Location {
warn!("{}", &message);
message
})?;
Ok(Location {
iso_alpha2,
iso_alpha3: String::from(iso_codes.alpha3()),
name: String::from(iso_codes.name()),
latitude: city.location.as_ref().and_then(|l| l.latitude),
longitude: city.location.as_ref().and_then(|l| l.longitude),
})
}
}
+2
View File
@@ -5,6 +5,7 @@ use rocket::{Build, Request, Rocket};
use rocket_cors::{AllowedHeaders, AllowedOrigins};
use rocket_okapi::swagger_ui::make_swagger_ui;
use crate::buy_terms::http::nym_terms_make_default_routes;
use crate::country_statistics::http::country_statistics_make_default_routes;
use crate::gateways::http::gateways_make_default_routes;
use crate::http::swagger::get_docs;
@@ -56,6 +57,7 @@ fn configure_rocket(state: ExplorerApiStateContext) -> Rocket<Build> {
"/overview" => overview_make_default_routes(&openapi_settings),
"/ping" => ping_make_default_routes(&openapi_settings),
"/validators" => validators_make_default_routes(&openapi_settings),
"/terms" => nym_terms_make_default_routes(&openapi_settings),
};
building_rocket
+3 -30
View File
@@ -8,8 +8,9 @@ use dotenv::dotenv;
use log::info;
use logging::setup_logging;
use network_defaults::setup_env;
use task::TaskManager;
use task::{wait_for_signal, TaskManager};
mod buy_terms;
pub(crate) mod cache;
mod client;
pub(crate) mod commands;
@@ -34,7 +35,7 @@ async fn main() {
dotenv().ok();
setup_logging();
let args = commands::Cli::parse();
setup_env(args.config_env_file);
setup_env(args.config_env_file.as_ref());
let mut explorer_api = ExplorerApi::new();
explorer_api.run().await;
}
@@ -87,31 +88,3 @@ impl ExplorerApi {
log::info!("Stopping explorer API");
}
}
#[cfg(unix)]
async fn wait_for_signal() {
use tokio::signal::unix::{signal, SignalKind};
let mut sigterm = signal(SignalKind::terminate()).expect("Failed to setup SIGTERM channel");
let mut sigquit = signal(SignalKind::quit()).expect("Failed to setup SIGQUIT channel");
tokio::select! {
_ = tokio::signal::ctrl_c() => {
log::info!("Received SIGINT");
},
_ = sigterm.recv() => {
log::info!("Received SIGTERM");
}
_ = sigquit.recv() => {
log::info!("Received SIGQUIT");
}
}
}
#[cfg(not(unix))]
async fn wait_for_signal() {
tokio::select! {
_ = tokio::signal::ctrl_c() => {
log::info!("Received SIGINT");
},
}
}
+1
View File
@@ -40,6 +40,7 @@ pub(crate) struct PrettyDetailedMixNodeBond {
pub estimated_delegators_apy: f64,
pub operating_cost: Coin,
pub profit_margin_percent: Percent,
pub family_id: Option<u16>,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)]
-4
View File
@@ -36,8 +36,6 @@ pub(crate) struct Location {
pub(crate) two_letter_iso_country_code: String,
pub(crate) three_letter_iso_country_code: String,
pub(crate) country_name: String,
pub(crate) latitude: Option<f64>,
pub(crate) longitude: Option<f64>,
}
impl Location {
@@ -46,8 +44,6 @@ impl Location {
country_name: location.name,
two_letter_iso_country_code: location.iso_alpha2,
three_letter_iso_country_code: location.iso_alpha3,
latitude: location.latitude,
longitude: location.longitude,
}
}
}
+1
View File
@@ -6,6 +6,7 @@ use std::time::Duration;
pub(crate) mod http;
pub(crate) mod location;
pub(crate) mod models;
pub(crate) mod utils;
pub(crate) const CACHE_REFRESH_RATE: Duration = Duration::from_secs(30);
pub(crate) const CACHE_ENTRY_TTL: Duration = Duration::from_secs(60);
+4
View File
@@ -13,6 +13,7 @@ use tokio::sync::{RwLock, RwLockReadGuard};
use crate::helpers::best_effort_small_dec_to_f64;
use validator_client::models::MixNodeBondAnnotated;
use super::utils::family_numerical_id;
use crate::mix_node::models::{MixnodeStatus, PrettyDetailedMixNodeBond};
use crate::mix_nodes::location::{Location, LocationCache, LocationCacheItem};
use crate::mix_nodes::CACHE_ENTRY_TTL;
@@ -140,6 +141,8 @@ impl ThreadsafeMixNodesCache {
let denom = &node.mixnode_details.original_pledge().denom;
let rewarding_info = &node.mixnode_details.rewarding_details;
let family_id = node.family.as_ref().map(family_numerical_id);
PrettyDetailedMixNodeBond {
mix_id,
location: location.and_then(|l| l.location.clone()),
@@ -157,6 +160,7 @@ impl ThreadsafeMixNodesCache {
estimated_delegators_apy: best_effort_small_dec_to_f64(node.estimated_delegators_apy),
operating_cost: rewarding_info.cost_params.interval_operating_cost.clone(),
profit_margin_percent: rewarding_info.cost_params.profit_margin_percent,
family_id,
}
}
+13
View File
@@ -1,9 +1,15 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use mixnet_contract_common::families::FamilyHead;
use rand::Rng;
use rand_pcg::Pcg64;
use rand_seeder::Seeder;
use crate::mix_nodes::location::GeoLocation;
use isocountry::CountryCode;
#[allow(dead_code)]
pub(crate) fn map_2_letter_to_3_letter_country_code(geo: &GeoLocation) -> String {
match CountryCode::for_alpha2(&geo.country_code) {
Ok(three_letter_country_code) => three_letter_country_code.alpha3().to_string(),
@@ -16,3 +22,10 @@ pub(crate) fn map_2_letter_to_3_letter_country_code(geo: &GeoLocation) -> String
}
}
}
// We don't need numerical IDs anywhere, so to avoid modifying the contract storage again and
// since this is for explorer ergonomics, it will generate a deterministic random u16 based on the family Identity.
pub(crate) fn family_numerical_id(fh: &FamilyHead) -> u16 {
let mut rng: Pcg64 = Seeder::from(fh.identity()).make_rng();
rng.gen()
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@nym/network-explorer",
"version": "1.0.1",
"version": "1.0.0",
"private": true,
"license": "Apache-2.0",
"dependencies": {
+2 -2
View File
@@ -5,7 +5,7 @@ import { Tooltip } from '@nymproject/react/tooltip/Tooltip';
import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard';
import { Box } from '@mui/system';
import { cellStyles } from './Universal-DataGrid';
import { unymToNym } from '../utils/currency';
import { currencyToString } from '../utils/currency';
import { GatewayEnrichedRowType } from './Gateways';
import { MixnodeRowType } from './MixNodes';
@@ -38,7 +38,7 @@ function formatCellValues(val: string | number, field: string) {
);
}
if (field === 'bond') {
return unymToNym(val, 6);
return currencyToString(val.toString());
}
return val;
}
-3
View File
@@ -7,7 +7,6 @@ export type GatewayRowType = {
bond: number;
host: string;
location: string;
version: string;
};
export type GatewayEnrichedRowType = GatewayRowType & {
@@ -27,7 +26,6 @@ export function gatewayToGridRow(arrayOfGateways: GatewayResponse): GatewayRowTy
location: gw?.gateway?.location || '',
bond: gw.pledge_amount.amount || 0,
host: gw.gateway.host || '',
version: gw.gateway.version || '',
}));
}
@@ -42,7 +40,6 @@ export function gatewayEnrichedToGridRow(
location: gateway?.gateway?.location || '',
bond: gateway.pledge_amount.amount || 0,
host: gateway.gateway.host || '',
version: gateway.gateway.version || '',
clientsPort: gateway.gateway.clients_port || 0,
mixPort: gateway.gateway.mix_port || 0,
routingScore: `${report.most_recent}%`,
+6 -1
View File
@@ -4,6 +4,8 @@ import Select, { SelectChangeEvent } from '@mui/material/Select';
import { Filters } from './Filters/Filters';
import { useIsMobile } from '../hooks/useIsMobile';
const fieldsHeight = '42.25px';
type TableToolBarProps = {
onChangeSearch: (arg: string) => void;
onChangePageSize: (event: SelectChangeEvent<string>) => void;
@@ -35,7 +37,7 @@ export const TableToolbar: React.FC<TableToolBarProps> = ({
}}
>
<Box sx={{ display: 'flex', flexDirection: isMobile ? 'column-reverse' : 'row', alignItems: 'middle' }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', height: fieldsHeight }}>
{childrenBefore}
<Select
labelId="simple-select-label"
@@ -65,6 +67,9 @@ export const TableToolbar: React.FC<TableToolBarProps> = ({
sx={{
width: isMobile ? '100%' : 200,
marginBottom: isMobile ? 2 : 0,
'& > :not(style)': {
height: fieldsHeight,
},
}}
value={searchTerm}
data-testid="search-box"
@@ -58,12 +58,6 @@ const columns: ColumnsType[] = [
headerAlign: 'left',
flex: 1,
},
{
field: 'version',
title: 'Version',
headerAlign: 'left',
flex: 1,
},
];
/**
+3 -21
View File
@@ -10,7 +10,7 @@ import { TableToolbar } from '../../components/TableToolbar';
import { CustomColumnHeading } from '../../components/CustomColumnHeading';
import { Title } from '../../components/Title';
import { cellStyles, UniversalDataGrid } from '../../components/Universal-DataGrid';
import { unymToNym } from '../../utils/currency';
import { currencyToString } from '../../utils/currency';
import { Tooltip } from '../../components/Tooltip';
import { BIG_DIPPER } from '../../api/constants';
import { splice } from '../../utils';
@@ -77,7 +77,7 @@ export const PageGateways: React.FC = () => {
to={`/network-components/gateway/${params.row.identityKey}`}
data-testid="pledge-amount"
>
{unymToNym(params.value, 6)}
{currencyToString(params.value)}
</MuiLink>
),
},
@@ -128,7 +128,7 @@ export const PageGateways: React.FC = () => {
field: 'owner',
headerName: 'Owner',
renderHeader: () => <CustomColumnHeading headingTitle="Owner" />,
width: 180,
width: 380,
headerAlign: 'left',
headerClassName: 'MuiDataGrid-header-override',
renderCell: (params: GridRenderCellParams) => (
@@ -142,24 +142,6 @@ export const PageGateways: React.FC = () => {
</MuiLink>
),
},
{
field: 'version',
headerName: 'Version',
renderHeader: () => <CustomColumnHeading headingTitle="Version" />,
width: 150,
headerAlign: 'left',
headerClassName: 'MuiDataGrid-header-override',
renderCell: (params: GridRenderCellParams) => (
<MuiLink
sx={{ ...cellStyles }}
href={`${BIG_DIPPER}/account/${params.value}`}
target="_blank"
data-testid="owner"
>
{params.value}
</MuiLink>
),
},
];
const handlePageSize = (event: SelectChangeEvent<string>) => {
+2 -2
View File
@@ -164,10 +164,10 @@ const PageMixnodeDetailWithState: React.FC = () => {
{mixNode && (
<ContentCard title="Location">
{mixNode?.error && <ComponentError text="There was a problem retrieving this mixnode location" />}
{mixNode?.data?.location?.latitude && mixNode?.data?.location?.longitude && (
{mixNode.data && mixNode?.data?.location && (
<WorldMap
loading={mixNode.isLoading}
userLocation={[mixNode.data.location.longitude, mixNode.data.location.latitude]}
userLocation={[mixNode?.data?.location?.lng, mixNode?.data?.location?.lat]}
/>
)}
</ContentCard>
+2 -2
View File
@@ -77,8 +77,8 @@ export interface MixNodeResponseItem {
status: MixnodeStatus;
location: {
country_name: string;
latitude?: number;
longitude?: number;
lat: number;
lng: number;
three_letter_iso_country_code: string;
two_letter_iso_country_code: string;
};
+5 -9
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-gateway"
version = "1.1.5"
version = "1.1.4"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
@@ -19,13 +19,14 @@ anyhow = "1.0.53"
async-trait = { version = "0.1.51" }
bip39 = "1.0.1"
bs58 = "0.4.0"
clap = { version = "3.2", features = ["cargo", "derive"] }
clap = { version = "4.0", features = ["cargo", "derive"] }
colored = "2.0"
dashmap = "4.0"
dirs = "4.0"
dotenv = "0.15.0"
futures = "0.3"
humantime-serde = "1.0.1"
lazy_static = "1.4.0"
log = "0.4"
once_cell = "1.7.2"
pretty_env_logger = "0.4"
@@ -51,6 +52,7 @@ tokio-util = { version = "0.7.3", features = ["codec"] }
url = { version = "2.2", features = ["serde"] }
# internal
build-information = { path = "../common/build-information" }
coconut-interface = { path = "../common/coconut-interface", optional = true }
credentials = { path = "../common/credentials" }
config = { path = "../common/config" }
@@ -85,10 +87,4 @@ sqlx = { version = "0.5", features = [
"sqlite",
"macros",
"migrate",
] }
vergen = { version = "5", default-features = false, features = [
"build",
"git",
"rustc",
"cargo",
] }
] }
-3
View File
@@ -1,6 +1,5 @@
use sqlx::{Connection, SqliteConnection};
use std::env;
use vergen::{vergen, Config};
#[tokio::main]
async fn main() {
@@ -23,6 +22,4 @@ async fn main() {
// for some strange reason we need to add a leading `/` to the windows path even though it's
// not a valid windows path... but hey, it works...
println!("cargo:rustc-env=DATABASE_URL=sqlite:///{}", &database_path);
vergen(Config::default()).expect("failed to extract build metadata")
}
+27 -18
View File
@@ -1,4 +1,4 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{
@@ -8,6 +8,9 @@ use crate::{
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::{encryption, identity};
use std::net::IpAddr;
use std::path::PathBuf;
use validator_client::nymd;
#[derive(Args, Clone)]
pub struct Init {
@@ -17,11 +20,11 @@ pub struct Init {
/// The custom host on which the gateway will be running for receiving sphinx packets
#[clap(long)]
host: String,
host: IpAddr,
/// The wallet address you will use to bond this gateway, e.g. nymt1z9egw0knv47nmur0p8vk4rcx59h9gg4zuxrrr9
#[clap(long)]
wallet_address: String,
wallet_address: nymd::AccountId,
/// The port on which the gateway will be listening for sphinx packets
#[clap(long)]
@@ -33,23 +36,27 @@ pub struct Init {
/// The host that will be reported to the directory server
#[clap(long)]
// TODO: could this be changed to `Option<url::Url>`?
announce_host: Option<String>,
/// Path to sqlite database containing all gateway persistent data
#[clap(long)]
datastore: Option<String>,
datastore: Option<PathBuf>,
/// Comma separated list of endpoints of nym APIs
#[clap(long)]
nym_apis: Option<String>,
#[clap(long, alias = "validator_apis", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
/// Comma separated list of endpoints of the validator
#[clap(long)]
validators: Option<String>,
#[cfg(feature = "coconut")]
#[clap(long, alias = "validators", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nymd_validators: Option<Vec<url::Url>>,
/// Cosmos wallet mnemonic needed for double spending protection
#[clap(long)]
mnemonic: Option<String>,
mnemonic: Option<bip39::Mnemonic>,
/// Set this gateway to work only with coconut credentials; that would disallow clients to
/// bypass bandwidth credential requirement
@@ -63,7 +70,7 @@ pub struct Init {
/// URL where a statistics aggregator is running. The default value is a Nym aggregator server
#[clap(long)]
statistics_service_url: Option<String>,
statistics_service_url: Option<url::Url>,
}
impl From<Init> for OverrideConfig {
@@ -76,14 +83,15 @@ impl From<Init> for OverrideConfig {
datastore: init_config.datastore,
announce_host: init_config.announce_host,
nym_apis: init_config.nym_apis,
validators: init_config.validators,
mnemonic: init_config.mnemonic,
#[cfg(feature = "coconut")]
only_coconut_credentials: init_config.only_coconut_credentials,
enabled_statistics: init_config.enabled_statistics,
statistics_service_url: init_config.statistics_service_url,
#[cfg(feature = "coconut")]
nymd_validators: init_config.nymd_validators,
#[cfg(feature = "coconut")]
only_coconut_credentials: init_config.only_coconut_credentials,
}
}
}
@@ -159,18 +167,19 @@ mod tests {
async fn create_gateway_with_in_mem_storage() {
let args = Init {
id: "foo-id".to_string(),
host: "foo-host".to_string(),
wallet_address: "n1z9egw0knv47nmur0p8vk4rcx59h9gg4zjx9ede".to_string(),
host: "1.1.1.1".parse().unwrap(),
wallet_address: "n1z9egw0knv47nmur0p8vk4rcx59h9gg4zjx9ede".parse().unwrap(),
mix_port: Some(42),
clients_port: Some(43),
announce_host: Some("foo-announce-host".to_string()),
datastore: Some("foo-datastore".to_string()),
datastore: Some("/foo-datastore".parse().unwrap()),
nym_apis: None,
validators: None,
mnemonic: None,
statistics_service_url: None,
enabled_statistics: None,
#[cfg(feature = "coconut")]
nymd_validators: None,
#[cfg(feature = "coconut")]
only_coconut_credentials: false,
};
std::env::set_var(BECH32_PREFIX, "n");
+34 -37
View File
@@ -1,19 +1,20 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::{process, str::FromStr};
use crate::{config::Config, Cli};
use clap::CommandFactory;
use clap::Subcommand;
use colored::Colorize;
use completions::{fig_generate, ArgShell};
use config::parse_validators;
use crypto::bech32_address_validation;
use network_defaults::mainnet::read_var_if_not_default;
use network_defaults::var_names::{
API_VALIDATOR, BECH32_PREFIX, CONFIGURED, NYMD_VALIDATOR, STATISTICS_SERVICE_DOMAIN_ADDRESS,
API_VALIDATOR, BECH32_PREFIX, CONFIGURED, STATISTICS_SERVICE_DOMAIN_ADDRESS,
};
use std::net::IpAddr;
use std::path::PathBuf;
use std::process;
use validator_client::nymd::{self};
pub(crate) mod init;
pub(crate) mod node_details;
@@ -47,18 +48,19 @@ pub(crate) enum Commands {
// Configuration that can be overridden.
pub(crate) struct OverrideConfig {
host: Option<String>,
wallet_address: Option<String>,
host: Option<IpAddr>,
wallet_address: Option<nymd::AccountId>,
mix_port: Option<u16>,
clients_port: Option<u16>,
datastore: Option<String>,
datastore: Option<PathBuf>,
announce_host: Option<String>,
enabled_statistics: Option<bool>,
statistics_service_url: Option<String>,
nym_apis: Option<String>,
validators: Option<String>,
mnemonic: Option<String>,
statistics_service_url: Option<url::Url>,
nym_apis: Option<Vec<url::Url>>,
mnemonic: Option<bip39::Mnemonic>,
#[cfg(feature = "coconut")]
nymd_validators: Option<Vec<url::Url>>,
#[cfg(feature = "coconut")]
only_coconut_credentials: bool,
}
@@ -72,8 +74,8 @@ pub(crate) async fn execute(args: Cli) {
Commands::Run(m) => run::execute(m).await,
Commands::Sign(m) => sign::execute(m),
Commands::Upgrade(m) => upgrade::execute(m).await,
Commands::Completions(s) => s.generate(&mut crate::Cli::into_app(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::into_app(), bin_name),
Commands::Completions(s) => s.generate(&mut crate::Cli::command(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::command(), bin_name),
}
}
@@ -103,12 +105,8 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
config = config.with_enabled_statistics(enabled_statistics);
}
if let Some(raw_url) = args.statistics_service_url {
config = config.with_custom_statistics_service_url(
raw_url
.parse()
.expect("the provided statistics service url is invalid!"),
);
if let Some(url) = args.statistics_service_url {
config = config.with_custom_statistics_service_url(url);
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(raw_url) = read_var_if_not_default(STATISTICS_SERVICE_DOMAIN_ADDRESS) {
config = config.with_custom_statistics_service_url(
@@ -119,26 +117,18 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
}
}
if let Some(raw_validators) = args.nym_apis {
config = config.with_custom_nym_apis(parse_validators(&raw_validators));
if let Some(nym_apis) = args.nym_apis {
config = config.with_custom_nym_apis(nym_apis);
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(raw_validators) = read_var_if_not_default(API_VALIDATOR) {
config = config.with_custom_nym_apis(::config::parse_validators(&raw_validators))
}
}
if let Some(ref raw_validators) = args.validators {
config = config.with_custom_validator_nymd(parse_validators(raw_validators));
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(raw_validators) = read_var_if_not_default(NYMD_VALIDATOR) {
config = config.with_custom_validator_nymd(::config::parse_validators(&raw_validators))
config = config.with_custom_nym_apis(::config::parse_urls(&raw_validators))
}
}
if let Some(wallet_address) = args.wallet_address {
let trimmed = wallet_address.trim();
validate_bech32_address_or_exit(trimmed);
config = config.with_wallet_address(trimmed);
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(wallet_address.as_ref());
config = config.with_wallet_address(wallet_address);
}
if let Some(datastore_path) = args.datastore {
@@ -146,13 +136,20 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
}
if let Some(cosmos_mnemonic) = args.mnemonic {
config = config.with_cosmos_mnemonic(
bip39::Mnemonic::from_str(&cosmos_mnemonic).expect("Provided mnemonic is invalid"),
);
config = config.with_cosmos_mnemonic(cosmos_mnemonic);
}
#[cfg(feature = "coconut")]
{
use network_defaults::var_names::NYMD_VALIDATOR;
if let Some(nymd_validators) = args.nymd_validators {
config = config.with_custom_validator_nymd(nymd_validators);
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(raw_validators) = read_var_if_not_default(NYMD_VALIDATOR) {
config = config.with_custom_validator_nymd(::config::parse_urls(&raw_validators))
}
}
config = config.with_only_coconut_credentials(args.only_coconut_credentials);
}
+23 -15
View File
@@ -1,4 +1,4 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{
@@ -8,6 +8,9 @@ use crate::{
use clap::Args;
use config::NymConfig;
use log::*;
use std::net::IpAddr;
use std::path::PathBuf;
use validator_client::nymd;
#[derive(Args, Clone)]
pub struct Run {
@@ -17,11 +20,11 @@ pub struct Run {
/// The custom host on which the gateway will be running for receiving sphinx packets
#[clap(long)]
host: Option<String>,
host: Option<IpAddr>,
/// The wallet address you will use to bond this gateway, e.g. nymt1z9egw0knv47nmur0p8vk4rcx59h9gg4zuxrrr9
#[clap(long)]
wallet_address: Option<String>,
wallet_address: Option<nymd::AccountId>,
/// The port on which the gateway will be listening for sphinx packets
#[clap(long)]
@@ -33,23 +36,27 @@ pub struct Run {
/// The host that will be reported to the directory server
#[clap(long)]
// TODO: could this be changed to `Option<url::Url>`?
announce_host: Option<String>,
/// Path to sqlite database containing all gateway persistent data
#[clap(long)]
datastore: Option<String>,
datastore: Option<PathBuf>,
/// Comma separated list of endpoints of the nym APIs
#[clap(long)]
nym_apis: Option<String>,
/// Comma separated list of endpoints of nym APIs
#[clap(long, alias = "validator_apis", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
/// Comma separated list of endpoints of the validator
#[clap(long)]
validators: Option<String>,
#[cfg(feature = "coconut")]
#[clap(long, alias = "validators", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nymd_validators: Option<Vec<url::Url>>,
/// Cosmos wallet mnemonic
#[clap(long)]
mnemonic: Option<String>,
mnemonic: Option<bip39::Mnemonic>,
/// Set this gateway to work only with coconut credentials; that would disallow clients to
/// bypass bandwidth credential requirement
@@ -63,7 +70,7 @@ pub struct Run {
/// URL where a statistics aggregator is running. The default value is a Nym aggregator server
#[clap(long)]
statistics_service_url: Option<String>,
statistics_service_url: Option<url::Url>,
}
impl From<Run> for OverrideConfig {
@@ -76,14 +83,15 @@ impl From<Run> for OverrideConfig {
datastore: run_config.datastore,
announce_host: run_config.announce_host,
nym_apis: run_config.nym_apis,
validators: run_config.validators,
mnemonic: run_config.mnemonic,
#[cfg(feature = "coconut")]
only_coconut_credentials: run_config.only_coconut_credentials,
enabled_statistics: run_config.enabled_statistics,
statistics_service_url: run_config.statistics_service_url,
#[cfg(feature = "coconut")]
nymd_validators: run_config.nymd_validators,
#[cfg(feature = "coconut")]
only_coconut_credentials: run_config.only_coconut_credentials,
}
}
}
+14 -15
View File
@@ -1,8 +1,9 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::commands::validate_bech32_address_or_exit;
use crate::{
commands::{validate_bech32_address_or_exit, version_check},
commands::version_check,
config::{persistence::pathfinder::GatewayPathfinder, Config},
};
use anyhow::{anyhow, Result};
@@ -10,9 +11,10 @@ use clap::{ArgGroup, Args};
use config::NymConfig;
use crypto::asymmetric::identity;
use log::error;
use validator_client::nymd;
#[derive(Args, Clone)]
#[clap(group(ArgGroup::new("sign").required(true).args(&["address", "text"])))]
#[clap(group(ArgGroup::new("sign").required(true).args(&["wallet_address", "text"])))]
pub struct Sign {
/// The id of the mixnode you want to sign with
#[clap(long)]
@@ -20,7 +22,7 @@ pub struct Sign {
/// Signs your blockchain address with your identity key
#[clap(long)]
address: Option<String>,
wallet_address: Option<nymd::AccountId>,
/// Signs an arbitrary piece of text with your identity key
#[clap(long)]
@@ -29,7 +31,7 @@ pub struct Sign {
enum SignedTarget {
Text(String),
Address(String),
Address(nymd::AccountId),
}
impl TryFrom<Sign> for SignedTarget {
@@ -38,7 +40,7 @@ impl TryFrom<Sign> for SignedTarget {
fn try_from(args: Sign) -> Result<Self, Self::Error> {
if let Some(text) = args.text {
Ok(SignedTarget::Text(text))
} else if let Some(address) = args.address {
} else if let Some(address) = args.wallet_address {
Ok(SignedTarget::Address(address))
} else {
// This is unreachable, and hopefully clap will support it explicitly by outputting an
@@ -58,15 +60,12 @@ pub fn load_identity_keys(pathfinder: &GatewayPathfinder) -> identity::KeyPair {
identity_keypair
}
fn print_signed_address(private_key: &identity::PrivateKey, raw_address: &str) {
let trimmed = raw_address.trim();
validate_bech32_address_or_exit(trimmed);
let signature = private_key.sign_text(trimmed);
fn print_signed_address(private_key: &identity::PrivateKey, wallet_address: nymd::AccountId) {
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(wallet_address.as_ref());
println!(
"The base58-encoded signature on '{}' is: {}",
trimmed, signature
);
let signature = private_key.sign_text(wallet_address.as_ref());
println!("The base58-encoded signature on '{wallet_address}' is: {signature}",);
}
fn print_signed_text(private_key: &identity::PrivateKey, text: &str) {
@@ -113,6 +112,6 @@ pub fn execute(args: &Sign) {
match signed_target {
SignedTarget::Text(text) => print_signed_text(identity_keypair.private_key(), &text),
SignedTarget::Address(addr) => print_signed_address(identity_keypair.private_key(), &addr),
SignedTarget::Address(addr) => print_signed_address(identity_keypair.private_key(), addr),
}
}
+1 -1
View File
@@ -103,7 +103,7 @@ fn minor_0_12_upgrade(
print_start_upgrade(config_version, &to_version);
let upgraded_config = config.with_custom_version(to_version.to_string().as_ref());
let upgraded_config = config.with_custom_version(to_version.to_string());
upgraded_config.save_to_file(None).unwrap_or_else(|err| {
eprintln!("failed to overwrite config file! - {err}");
+15 -21
View File
@@ -4,7 +4,6 @@
use crate::config::template::config_template;
use config::defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
use config::NymConfig;
use log::error;
use network_defaults::mainnet::{API_VALIDATOR, NYMD_VALIDATOR, STATISTICS_SERVICE_DOMAIN_ADDRESS};
use serde::{Deserialize, Serialize};
use std::net::IpAddr;
@@ -12,6 +11,7 @@ use std::path::PathBuf;
use std::str::FromStr;
use std::time::Duration;
use url::Url;
use validator_client::nymd;
pub mod persistence;
mod template;
@@ -149,6 +149,7 @@ impl Config {
self
}
#[cfg(feature = "coconut")]
pub fn with_custom_validator_nymd(mut self, validator_nymd_urls: Vec<Url>) -> Self {
self.gateway.validator_nymd_urls = validator_nymd_urls;
self
@@ -159,16 +160,8 @@ impl Config {
self
}
pub fn with_listening_address<S: Into<String>>(mut self, listening_address: S) -> Self {
let listening_address_string = listening_address.into();
if let Ok(ip_addr) = listening_address_string.parse() {
self.gateway.listening_address = ip_addr;
} else {
error!(
"failed to change listening address. the provided value ({}) was invalid",
listening_address_string
);
}
pub fn with_listening_address(mut self, listening_address: IpAddr) -> Self {
self.gateway.listening_address = listening_address;
self
}
@@ -192,18 +185,18 @@ impl Config {
self
}
pub fn with_custom_persistent_store<S: Into<String>>(mut self, store_dir: S) -> Self {
self.gateway.persistent_storage = PathBuf::from(store_dir.into());
pub fn with_custom_persistent_store(mut self, store_dir: PathBuf) -> Self {
self.gateway.persistent_storage = store_dir;
self
}
pub fn with_custom_version(mut self, version: &str) -> Self {
self.gateway.version = version.to_string();
pub fn with_custom_version<S: Into<String>>(mut self, version: S) -> Self {
self.gateway.version = version.into();
self
}
pub fn with_wallet_address(mut self, wallet_address: &str) -> Self {
self.gateway.wallet_address = wallet_address.to_string();
pub fn with_wallet_address(mut self, wallet_address: nymd::AccountId) -> Self {
self.gateway.wallet_address = Some(wallet_address);
self
}
@@ -302,8 +295,8 @@ impl Config {
&self.gateway.version
}
pub fn get_wallet_address(&self) -> &str {
&self.gateway.wallet_address
pub fn get_wallet_address(&self) -> Option<nymd::AccountId> {
self.gateway.wallet_address.clone()
}
}
@@ -377,7 +370,8 @@ pub struct Gateway {
persistent_storage: PathBuf,
/// The Cosmos wallet address that will control this gateway
wallet_address: String,
// the only reason this is an Option is because of the lack of existence of a sane default value
wallet_address: Option<nymd::AccountId>,
}
impl Gateway {
@@ -423,7 +417,7 @@ impl Default for Gateway {
cosmos_mnemonic: bip39::Mnemonic::from_str("exact antique hybrid width raise anchor puzzle degree fee quit long crack net vague hip despair write put useless civil mechanic broom music day").unwrap(),
nym_root_directory: Config::default_root_directory(),
persistent_storage: Default::default(),
wallet_address: "nymXXXXXXXX".to_string(),
wallet_address: None,
}
}
}
+11 -44
View File
@@ -1,24 +1,28 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use build_information::BinaryBuildInformation;
use clap::{crate_version, Parser};
use lazy_static::lazy_static;
use logging::setup_logging;
use network_defaults::setup_env;
use once_cell::sync::OnceCell;
mod commands;
mod config;
mod node;
static LONG_VERSION: OnceCell<String> = OnceCell::new();
lazy_static! {
pub static ref PRETTY_BUILD_INFORMATION: String =
BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print();
}
// Helper for passing LONG_ABOUT to clap
fn long_version_static() -> &'static str {
LONG_VERSION.get().expect("Failed to get long about text")
// Helper for passing LONG_VERSION to clap
fn pretty_build_info_static() -> &'static str {
&PRETTY_BUILD_INFORMATION
}
#[derive(Parser)]
#[clap(author = "Nymtech", version, about, long_version = long_version_static())]
#[clap(author = "Nymtech", version, about, long_version = pretty_build_info_static())]
struct Cli {
/// Path pointing to an env file that configures the gateway.
#[clap(short, long)]
@@ -32,12 +36,9 @@ struct Cli {
async fn main() {
setup_logging();
println!("{}", banner());
LONG_VERSION
.set(long_version())
.expect("Failed to set long about text");
let args = Cli::parse();
setup_env(args.config_env_file.clone());
setup_env(args.config_env_file.as_ref());
commands::execute(args).await;
}
@@ -58,37 +59,6 @@ fn banner() -> String {
)
}
fn long_version() -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
env!("VERGEN_BUILD_TIMESTAMP"),
"Build Version:",
env!("VERGEN_BUILD_SEMVER"),
"Commit SHA:",
env!("VERGEN_GIT_SHA"),
"Commit Date:",
env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
"Commit Branch:",
env!("VERGEN_GIT_BRANCH"),
"rustc Version:",
env!("VERGEN_RUSTC_SEMVER"),
"rustc Channel:",
env!("VERGEN_RUSTC_CHANNEL"),
"cargo Profile:",
env!("VERGEN_CARGO_PROFILE")
)
}
#[cfg(test)]
mod tests {
use super::*;
@@ -96,9 +66,6 @@ mod tests {
#[test]
fn verify_cli() {
LONG_VERSION
.set(long_version())
.expect("Failed to set long about text");
Cli::command().debug_assert();
}
}
+15 -9
View File
@@ -1,19 +1,20 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use self::storage::PersistentStorage;
use crate::commands::sign::load_identity_keys;
use crate::commands::validate_bech32_address_or_exit;
use crate::config::persistence::pathfinder::GatewayPathfinder;
use crate::config::Config;
use crate::node::client_handling::active_clients::ActiveClientsStore;
use crate::node::client_handling::websocket;
use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler;
use crate::node::statistics::collector::GatewayStatisticsCollector;
use crate::node::storage::Storage;
use colored::Colorize;
use crypto::asymmetric::{encryption, identity};
use log::*;
use mixnet_client::forwarder::{MixForwardingSender, PacketForwarder};
#[cfg(feature = "coconut")]
use network_defaults::NymNetworkDetails;
use rand::seq::SliceRandom;
use rand::thread_rng;
use statistics_common::collector::StatisticsSender;
@@ -21,16 +22,15 @@ use std::net::SocketAddr;
use std::process;
use std::sync::Arc;
use crate::config::persistence::pathfinder::GatewayPathfinder;
#[cfg(feature = "coconut")]
use crate::node::client_handling::websocket::connection_handler::coconut::CoconutVerifier;
#[cfg(feature = "coconut")]
use credentials::coconut::utils::obtain_aggregate_verification_key;
#[cfg(feature = "coconut")]
use network_defaults::NymNetworkDetails;
#[cfg(feature = "coconut")]
use validator_client::{Client, CoconutApiClient};
use self::storage::PersistentStorage;
pub(crate) mod client_handling;
pub(crate) mod mixnet_handling;
pub(crate) mod statistics;
@@ -117,9 +117,15 @@ where
fn generate_owner_signature(&self) -> String {
let pathfinder = GatewayPathfinder::new_from_config(&self.config);
let identity_keypair = load_identity_keys(&pathfinder);
let address = self.config.get_wallet_address();
validate_bech32_address_or_exit(address);
let verification_code = identity_keypair.private_key().sign_text(address);
let Some(address) = self.config.get_wallet_address() else {
let error_message = "Error: gateway hasn't set its wallet address".red();
println!("{error_message}");
println!("Exiting...");
process::exit(1);
};
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(address.as_ref());
let verification_code = identity_keypair.private_key().sign_text(address.as_ref());
verification_code
}
+3 -5
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-mixnode"
version = "1.1.5"
version = "1.1.4"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
@@ -18,7 +18,7 @@ rust-version = "1.58.1"
[dependencies]
anyhow = "1.0.40"
bs58 = "0.4.0"
clap = { version = "3.2", features = ["cargo", "derive"] }
clap = { version = "4.0", features = ["cargo", "derive"] }
colored = "2.0"
cupid = "0.6.1"
dirs = "4.0"
@@ -38,6 +38,7 @@ toml = "0.5.8"
url = { version = "2.2", features = ["serde"] }
## internal
build-information = { path = "../common/build-information" }
config = { path="../common/config" }
crypto = { path="../common/crypto" }
completions = { path="../common/completions" }
@@ -57,6 +58,3 @@ tokio = { version="1.21.2", features = ["rt-multi-thread", "net", "signal", "tes
nymsphinx-types = { path = "../common/nymsphinx/types" }
nymsphinx-params = { path = "../common/nymsphinx/params" }
[build-dependencies]
vergen = { version = "5", default-features = false, features = ["build", "git", "rustc", "cargo"] }
-8
View File
@@ -1,8 +0,0 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use vergen::{vergen, Config};
fn main() {
vergen(Config::default()).expect("failed to extract build metadata")
}
+46 -24
View File
@@ -1,3 +1,6 @@
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::config::Config;
use crate::node::node_description::NodeDescription;
use clap::Args;
@@ -11,9 +14,32 @@ pub(crate) struct Describe {
/// The id of the mixnode you want to describe
#[clap(long)]
id: String,
/// Human readable name of this node
#[clap(long)]
name: Option<String>,
/// Description of this node
#[clap(long)]
description: Option<String>,
/// Link associated with this node, for example `https://mixnode.yourdomain.com`
#[clap(long)]
link: Option<String>,
/// Physical location of this node, for example `City: London, Country: UK`
#[clap(long)]
location: Option<String>,
}
pub(crate) fn execute(args: &Describe) {
fn read_user_input() -> String {
io::stdout().flush().unwrap();
let mut buf = String::new();
io::stdin().read_line(&mut buf).unwrap();
buf.trim().to_string()
}
pub(crate) fn execute(args: Describe) {
// ensure that the mixnode has in fact been initialized
match Config::load_from_file(Some(&args.id)) {
Ok(cfg) => cfg,
@@ -23,33 +49,29 @@ pub(crate) fn execute(args: &Describe) {
}
};
// get input from the user
print!("name: ");
io::stdout().flush().unwrap();
let mut name_buf = String::new();
io::stdin().read_line(&mut name_buf).unwrap();
let name = name_buf.trim().to_string();
print!("description: ");
io::stdout().flush().unwrap();
let mut desc_buf = String::new();
io::stdin().read_line(&mut desc_buf).unwrap();
let description = desc_buf.trim().to_string();
let example_url = "https://mixnode.yourdomain.com".bright_cyan();
let example_location = "City: London, Country: UK";
print!("link, e.g. {}: ", example_url);
io::stdout().flush().unwrap();
let mut link_buf = String::new();
io::stdin().read_line(&mut link_buf).unwrap();
let link = link_buf.trim().to_string();
// get input from the user if not provided via the arguments
let name = args.name.unwrap_or_else(|| {
print!("name: ");
read_user_input()
});
print!("location, e.g. {}: ", example_location);
io::stdout().flush().unwrap();
let mut location_buf = String::new();
io::stdin().read_line(&mut location_buf).unwrap();
let location = location_buf.trim().to_string();
let description = args.description.unwrap_or_else(|| {
print!("description: ");
read_user_input()
});
let link = args.link.unwrap_or_else(|| {
print!("link, e.g. {example_url}: ");
read_user_input()
});
let location = args.location.unwrap_or_else(|| {
print!("location, e.g. {example_location}: ");
read_user_input()
});
let node_description = NodeDescription {
name,
+11 -9
View File
@@ -1,14 +1,15 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::OverrideConfig;
use crate::config::Config;
use crate::node::MixNode;
use crate::{commands::override_config, config::persistence::pathfinder::MixNodePathfinder};
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::{encryption, identity};
use super::OverrideConfig;
use std::net::IpAddr;
use validator_client::nymd;
#[derive(Args, Clone)]
pub(crate) struct Init {
@@ -18,11 +19,11 @@ pub(crate) struct Init {
/// The host on which the mixnode will be running
#[clap(long)]
host: String,
host: IpAddr,
/// The wallet address you will use to bond this mixnode, e.g. nymt1z9egw0knv47nmur0p8vk4rcx59h9gg4zuxrrr9
#[clap(long)]
wallet_address: String,
wallet_address: nymd::AccountId,
/// The port on which the mixnode will be listening for mix packets
#[clap(long)]
@@ -40,9 +41,10 @@ pub(crate) struct Init {
#[clap(long)]
announce_host: Option<String>,
/// Comma separated list of rest endpoints of the validators
#[clap(long)]
validators: Option<String>,
/// Comma separated list of nym-api endpoints of the validators
// the alias here is included for backwards compatibility (1.1.4 and before)
#[clap(long, alias = "validators", value_delimiter = ',')]
nym_apis: Option<Vec<url::Url>>,
}
impl From<Init> for OverrideConfig {
@@ -55,7 +57,7 @@ impl From<Init> for OverrideConfig {
verloc_port: init_config.verloc_port,
http_api_port: init_config.http_api_port,
announce_host: init_config.announce_host,
validators: init_config.validators,
nym_apis: init_config.nym_apis,
}
}
}
+22 -24
View File
@@ -1,19 +1,17 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::process;
use crate::{config::Config, Cli};
use clap::CommandFactory;
use clap::Subcommand;
use colored::Colorize;
use completions::{fig_generate, ArgShell};
use config::defaults::mainnet::read_var_if_not_default;
use config::{
defaults::var_names::{API_VALIDATOR, BECH32_PREFIX, CONFIGURED},
parse_validators,
};
use config::defaults::var_names::{API_VALIDATOR, BECH32_PREFIX, CONFIGURED};
use crypto::bech32_address_validation;
use std::net::IpAddr;
use std::process;
use validator_client::nymd;
mod describe;
mod init;
@@ -52,27 +50,27 @@ pub(crate) enum Commands {
// Configuration that can be overridden.
struct OverrideConfig {
id: String,
host: Option<String>,
wallet_address: Option<String>,
host: Option<IpAddr>,
wallet_address: Option<nymd::AccountId>,
mix_port: Option<u16>,
verloc_port: Option<u16>,
http_api_port: Option<u16>,
announce_host: Option<String>,
validators: Option<String>,
nym_apis: Option<Vec<url::Url>>,
}
pub(crate) async fn execute(args: Cli) {
let bin_name = "nym-mixnode";
match &args.command {
match args.command {
Commands::Describe(m) => describe::execute(m),
Commands::Init(m) => init::execute(m),
Commands::Run(m) => run::execute(m).await,
Commands::Sign(m) => sign::execute(m),
Commands::Upgrade(m) => upgrade::execute(m),
Commands::NodeDetails(m) => node_details::execute(m),
Commands::Completions(s) => s.generate(&mut crate::Cli::into_app(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::into_app(), bin_name),
Commands::Init(m) => init::execute(&m),
Commands::Run(m) => run::execute(&m).await,
Commands::Sign(m) => sign::execute(&m),
Commands::Upgrade(m) => upgrade::execute(&m),
Commands::NodeDetails(m) => node_details::execute(&m),
Commands::Completions(s) => s.generate(&mut crate::Cli::command(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::command(), bin_name),
}
}
@@ -95,11 +93,11 @@ fn override_config(mut config: Config, args: OverrideConfig) -> Config {
config = config.with_http_api_port(port);
}
if let Some(ref raw_validators) = args.validators {
config = config.with_custom_nym_apis(parse_validators(raw_validators));
if let Some(nym_apis) = args.nym_apis {
config = config.with_custom_nym_apis(nym_apis);
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(raw_validators) = read_var_if_not_default(API_VALIDATOR) {
config = config.with_custom_nym_apis(::config::parse_validators(&raw_validators))
config = config.with_custom_nym_apis(::config::parse_urls(&raw_validators))
}
}
@@ -110,10 +108,10 @@ fn override_config(mut config: Config, args: OverrideConfig) -> Config {
config = config.announce_address_from_listening_address()
}
if let Some(ref wallet_address) = args.wallet_address {
let trimmed = wallet_address.trim();
validate_bech32_address_or_exit(trimmed);
config = config.with_wallet_address(trimmed);
if let Some(wallet_address) = args.wallet_address {
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(wallet_address.as_ref());
config = config.with_wallet_address(wallet_address);
}
config
+10 -8
View File
@@ -1,13 +1,14 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::OverrideConfig;
use crate::commands::{override_config, version_check};
use crate::config::Config;
use crate::node::MixNode;
use clap::Args;
use config::NymConfig;
use super::OverrideConfig;
use std::net::IpAddr;
use validator_client::nymd;
#[derive(Args, Clone)]
pub(crate) struct Run {
@@ -17,11 +18,11 @@ pub(crate) struct Run {
/// The custom host on which the mixnode will be running
#[clap(long)]
host: Option<String>,
host: Option<IpAddr>,
/// The wallet address you will use to bond this mixnode, e.g. nymt1z9egw0knv47nmur0p8vk4rcx59h9gg4zuxrrr9
#[clap(long)]
wallet_address: Option<String>,
wallet_address: Option<nymd::AccountId>,
/// The port on which the mixnode will be listening for mix packets
#[clap(long)]
@@ -39,9 +40,10 @@ pub(crate) struct Run {
#[clap(long)]
announce_host: Option<String>,
/// Comma separated list of rest endpoints of the validators
#[clap(long)]
validators: Option<String>,
/// Comma separated list of nym-api endpoints of the validators
// the alias here is included for backwards compatibility (1.1.4 and before)
#[clap(long, alias = "validators", value_delimiter = ',')]
nym_apis: Option<Vec<url::Url>>,
}
impl From<Run> for OverrideConfig {
@@ -54,7 +56,7 @@ impl From<Run> for OverrideConfig {
verloc_port: run_config.verloc_port,
http_api_port: run_config.http_api_port,
announce_host: run_config.announce_host,
validators: run_config.validators,
nym_apis: run_config.nym_apis,
}
}
}
+14 -15
View File
@@ -1,4 +1,4 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::convert::TryFrom;
@@ -11,19 +11,21 @@ use clap::{ArgGroup, Args};
use config::NymConfig;
use crypto::asymmetric::identity;
use log::error;
use validator_client::nymd;
use super::version_check;
#[derive(Args, Clone)]
#[clap(group(ArgGroup::new("sign").required(true).args(&["address", "text"])))]
#[clap(group(ArgGroup::new("sign").required(true).args(&["wallet_address", "text"])))]
pub(crate) struct Sign {
/// The id of the mixnode you want to sign with
#[clap(long)]
id: String,
/// Signs your blockchain address with your identity key
#[clap(long)]
address: Option<String>,
// the alias here is included for backwards compatibility (1.1.4 and before)
#[clap(long, alias = "address")]
wallet_address: Option<nymd::AccountId>,
/// Signs an arbitrary piece of text with your identity key
#[clap(long)]
@@ -32,7 +34,7 @@ pub(crate) struct Sign {
enum SignedTarget {
Text(String),
Address(String),
Address(nymd::AccountId),
}
impl TryFrom<Sign> for SignedTarget {
@@ -41,7 +43,7 @@ impl TryFrom<Sign> for SignedTarget {
fn try_from(args: Sign) -> Result<Self, Self::Error> {
if let Some(text) = args.text {
Ok(SignedTarget::Text(text))
} else if let Some(address) = args.address {
} else if let Some(address) = args.wallet_address {
Ok(SignedTarget::Address(address))
} else {
// This is unreachable, and hopefully clap will support it explicitly by outputting an
@@ -52,15 +54,12 @@ impl TryFrom<Sign> for SignedTarget {
}
}
fn print_signed_address(private_key: &identity::PrivateKey, raw_address: &str) {
let trimmed = raw_address.trim();
validate_bech32_address_or_exit(trimmed);
let signature = private_key.sign_text(trimmed);
fn print_signed_address(private_key: &identity::PrivateKey, wallet_address: nymd::AccountId) {
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(wallet_address.as_ref());
println!(
"The base58-encoded signature on '{}' is: {}",
trimmed, signature
);
let signature = private_key.sign_text(wallet_address.as_ref());
println!("The base58-encoded signature on '{wallet_address}' is: {signature}",);
}
fn print_signed_text(private_key: &identity::PrivateKey, text: &str) {
@@ -107,6 +106,6 @@ pub(crate) fn execute(args: &Sign) {
match signed_target {
SignedTarget::Text(text) => print_signed_text(identity_keypair.private_key(), &text),
SignedTarget::Address(addr) => print_signed_address(identity_keypair.private_key(), &addr),
SignedTarget::Address(addr) => print_signed_address(identity_keypair.private_key(), addr),
}
}
+10 -16
View File
@@ -13,6 +13,7 @@ use std::path::PathBuf;
use std::str::FromStr;
use std::time::Duration;
use url::Url;
use validator_client::nymd;
pub mod persistence;
mod template;
@@ -160,16 +161,8 @@ impl Config {
self
}
pub fn with_listening_address<S: Into<String>>(mut self, listening_address: S) -> Self {
let listening_address_string = listening_address.into();
if let Ok(ip_addr) = listening_address_string.parse() {
self.mixnode.listening_address = ip_addr
} else {
error!(
"failed to change listening address. the provided value ({}) was invalid",
listening_address_string
)
}
pub fn with_listening_address(mut self, listening_address: IpAddr) -> Self {
self.mixnode.listening_address = listening_address;
self
}
@@ -203,8 +196,8 @@ impl Config {
self
}
pub fn with_wallet_address(mut self, wallet_address: &str) -> Self {
self.mixnode.wallet_address = wallet_address.to_string();
pub fn with_wallet_address(mut self, wallet_address: nymd::AccountId) -> Self {
self.mixnode.wallet_address = Some(wallet_address);
self
}
@@ -317,8 +310,8 @@ impl Config {
self.verloc.retry_timeout
}
pub fn get_wallet_address(&self) -> &str {
&self.mixnode.wallet_address
pub fn get_wallet_address(&self) -> Option<nymd::AccountId> {
self.mixnode.wallet_address.clone()
}
}
@@ -377,7 +370,8 @@ struct MixNode {
nym_root_directory: PathBuf,
/// The Cosmos wallet address that will control this mixnode
wallet_address: String,
// the only reason this is an Option is because of the lack of existence of a sane default value
wallet_address: Option<nymd::AccountId>,
}
impl MixNode {
@@ -414,7 +408,7 @@ impl Default for MixNode {
public_sphinx_key_file: Default::default(),
nym_api_urls: vec![Url::from_str(API_VALIDATOR).expect("Invalid default API URL")],
nym_root_directory: Config::default_root_directory(),
wallet_address: "nymXXXXXXXX".to_string(),
wallet_address: None,
}
}
}
+10 -39
View File
@@ -1,10 +1,11 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#[macro_use]
extern crate rocket;
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use ::config::defaults::setup_env;
use build_information::BinaryBuildInformation;
use clap::{crate_version, Parser};
use lazy_static::lazy_static;
use logging::setup_logging;
@@ -14,16 +15,17 @@ mod config;
mod node;
lazy_static! {
pub static ref LONG_VERSION: String = long_version();
pub static ref PRETTY_BUILD_INFORMATION: String =
BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print();
}
// Helper for passing LONG_VERSION to clap
fn long_version_static() -> &'static str {
&LONG_VERSION
fn pretty_build_info_static() -> &'static str {
&PRETTY_BUILD_INFORMATION
}
#[derive(Parser)]
#[clap(author = "Nymtech", version, about, long_version = long_version_static())]
#[clap(author = "Nymtech", version, about, long_version = pretty_build_info_static())]
struct Cli {
/// Path pointing to an env file that configures the mixnode.
#[clap(short, long)]
@@ -39,7 +41,7 @@ async fn main() {
println!("{}", banner());
let args = Cli::parse();
setup_env(args.config_env_file.clone());
setup_env(args.config_env_file.as_ref());
commands::execute(args).await;
}
@@ -60,37 +62,6 @@ fn banner() -> String {
)
}
fn long_version() -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
env!("VERGEN_BUILD_TIMESTAMP"),
"Build Version:",
env!("VERGEN_BUILD_SEMVER"),
"Commit SHA:",
env!("VERGEN_GIT_SHA"),
"Commit Date:",
env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
"Commit Branch:",
env!("VERGEN_GIT_BRANCH"),
"rustc Version:",
env!("VERGEN_RUSTC_SEMVER"),
"rustc Channel:",
env!("VERGEN_RUSTC_CHANNEL"),
"cargo Profile:",
env!("VERGEN_CARGO_PROFILE")
)
}
#[cfg(test)]
mod tests {
use super::*;
+14 -4
View File
@@ -18,6 +18,7 @@ use crate::node::node_description::NodeDescription;
use crate::node::node_statistics::SharedNodeStats;
use crate::node::packet_delayforwarder::{DelayForwarder, PacketDelayForwardSender};
use ::crypto::asymmetric::{encryption, identity};
use colored::Colorize;
use config::NymConfig;
use log::{error, info, warn};
use mixnode_common::verloc::{self, AtomicVerlocResult, VerlocMeasurer};
@@ -87,9 +88,15 @@ impl MixNode {
fn generate_owner_signature(&self) -> String {
let pathfinder = MixNodePathfinder::new_from_config(&self.config);
let identity_keypair = Self::load_identity_keys(&pathfinder);
let address = self.config.get_wallet_address();
validate_bech32_address_or_exit(address);
let verification_code = identity_keypair.private_key().sign_text(address);
let Some(address) = self.config.get_wallet_address() else {
let error_message = "Error: mixnode hasn't set its wallet address".red();
println!("{error_message}");
println!("Exiting...");
process::exit(1);
};
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(address.as_ref());
let verification_code = identity_keypair.private_key().sign_text(address.as_ref());
verification_code
}
@@ -118,7 +125,10 @@ impl MixNode {
);
println!(
"You are bonding to wallet address: {}\n\n",
self.config.get_wallet_address()
self.config
.get_wallet_address()
.map(|addr| addr.to_string())
.unwrap_or_else(|| "UNSPECIFIED".to_string())
);
}
+6 -9
View File
@@ -2,8 +2,8 @@
# SPDX-License-Identifier: Apache-2.0
[package]
name = "nym-validator-api"
version = "1.1.5"
name = "nym-api"
version = "1.1.4"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
@@ -17,13 +17,15 @@ rust-version = "1.56"
[dependencies]
async-trait = "0.1.52"
bs58 = {version = "0.4.0", optional = true }
bip39 = "1"
cfg-if = "1.0"
clap = { version = "3.2", features = ["cargo"] }
clap = { version = "4.0", features = ["cargo", "derive"] }
console-subscriber = { version = "0.1.1", optional = true } # validator-api needs to be built with RUSTFLAGS="--cfg tokio_unstable"
dirs = "4.0"
dotenv = "0.15.0"
futures = "0.3.24"
humantime-serde = "1.0"
lazy_static = "1.4.0"
log = "0.4.17"
pin-project = "1.0"
pretty_env_logger = "0.4.0"
@@ -63,6 +65,7 @@ rocket_okapi = { version = "0.8.0-rc.2", features = ["swagger"] }
schemars = { version = "0.8", features = ["preserve_order"] }
## internal
build-information = { path = "../common/build-information" }
coconut-bandwidth-contract-common = { path = "../common/cosmwasm-smart-contracts/coconut-bandwidth-contract" }
coconut-dkg-common = { path = "../common/cosmwasm-smart-contracts/coconut-dkg", optional = true }
coconut-interface = { path = "../common/coconut-interface", optional = true }
@@ -115,12 +118,6 @@ sqlx = { version = "0.6.2", features = [
"macros",
"migrate",
] }
vergen = { version = "7", default-features = false, features = [
"build",
"git",
"rustc",
"cargo",
] }
[dev-dependencies]
cw3 = "0.13.4"
-3
View File
@@ -1,6 +1,5 @@
use sqlx::{Connection, SqliteConnection};
use std::env;
use vergen::{vergen, Config};
#[tokio::main]
async fn main() {
@@ -23,6 +22,4 @@ async fn main() {
// for some strange reason we need to add a leading `/` to the windows path even though it's
// not a valid windows path... but hey, it works...
println!("cargo:rustc-env=DATABASE_URL=sqlite:///{}", &database_path);
vergen(Config::default()).expect("failed to extract build metadata")
}
-2
View File
@@ -446,8 +446,6 @@ impl Config {
self.network_monitor.credentials_database_path.clone()
}
// TODO: Remove if still unused
#[allow(dead_code)]
pub fn get_rewarding_enabled(&self) -> bool {
self.rewarding.enabled
}
+141 -262
View File
@@ -1,4 +1,4 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#[macro_use]
@@ -6,6 +6,7 @@ extern crate rocket;
use crate::config::Config;
use crate::contract_cache::ValidatorCacheRefresher;
use crate::epoch_operations::RewardedSetUpdater;
use crate::network_monitor::NetworkMonitorBuilder;
use crate::node_status_api::uptime_updater::HistoricalUptimeUpdater;
use crate::nymd_client::Client;
@@ -15,9 +16,12 @@ use ::config::defaults::setup_env;
use ::config::defaults::var_names::{CONFIGURED, MIXNET_CONTRACT_ADDRESS, MIX_DENOM};
use ::config::NymConfig;
use anyhow::Result;
use clap::{crate_version, App, Arg, ArgMatches};
use build_information::BinaryBuildInformation;
use clap::Parser;
use contract_cache::ValidatorCache;
use lazy_static::lazy_static;
use log::{info, warn};
use logging::setup_logging;
use node_status_api::NodeStatusCache;
use okapi::openapi3::OpenApi;
use rocket::fairing::AdHoc;
@@ -26,27 +30,21 @@ use rocket::{Ignite, Rocket};
use rocket_cors::{AllowedHeaders, AllowedOrigins, Cors};
use rocket_okapi::mount_endpoints_and_merged_docs;
use rocket_okapi::swagger_ui::make_swagger_ui;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;
use std::{fs, process};
use task::TaskManager;
use task::{wait_for_signal, TaskManager};
use tokio::sync::Notify;
#[cfg(feature = "coconut")]
use url::Url;
use validator_client::nymd::SigningNymdClient;
use validator_client::nymd::{self, SigningNymdClient};
use crate::epoch_operations::RewardedSetUpdater;
#[cfg(feature = "coconut")]
use coconut::{
comm::QueryCommunicationChannel,
dkg::controller::{init_keypair, DkgController},
InternalSignRequest,
};
use logging::setup_logging;
#[cfg(feature = "coconut")]
use validator_client::nymd::bip32::secp256k1::elliptic_curve::rand_core::OsRng;
use rand::rngs::OsRng;
pub(crate) mod config;
pub(crate) mod contract_cache;
@@ -60,150 +58,92 @@ mod swagger;
#[cfg(feature = "coconut")]
mod coconut;
const ID: &str = "id";
const CONFIG_ENV_FILE: &str = "config-env-file";
const MONITORING_ENABLED: &str = "enable-monitor";
const REWARDING_ENABLED: &str = "enable-rewarding";
const MIXNET_CONTRACT_ARG: &str = "mixnet-contract";
const MNEMONIC_ARG: &str = "mnemonic";
const WRITE_CONFIG_ARG: &str = "save-config";
const NYMD_VALIDATOR_ARG: &str = "nymd-validator";
const ENABLED_CREDENTIALS_MODE_ARG_NAME: &str = "enabled-credentials-mode";
#[cfg(feature = "coconut")]
const ANNOUNCE_ADDRESS: &str = "announce-address";
#[cfg(feature = "coconut")]
const COCONUT_ENABLED: &str = "enable-coconut";
const REWARDING_MONITOR_THRESHOLD_ARG: &str = "monitor-threshold";
const MIN_MIXNODE_RELIABILITY_ARG: &str = "min_mixnode_reliability";
const MIN_GATEWAY_RELIABILITY_ARG: &str = "min_gateway_reliability";
fn long_version() -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
env!("VERGEN_BUILD_TIMESTAMP"),
"Build Version:",
env!("VERGEN_BUILD_SEMVER"),
"Commit SHA:",
env!("VERGEN_GIT_SHA"),
"Commit Date:",
env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
"Commit Branch:",
env!("VERGEN_GIT_BRANCH"),
"rustc Version:",
env!("VERGEN_RUSTC_SEMVER"),
"rustc Channel:",
env!("VERGEN_RUSTC_CHANNEL"),
"cargo Profile:",
env!("VERGEN_CARGO_PROFILE")
)
lazy_static! {
pub static ref PRETTY_BUILD_INFORMATION: String =
BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print();
}
fn parse_args() -> ArgMatches {
let build_details = long_version();
let base_app = App::new("Nym API")
.version(crate_version!())
.long_version(&*build_details)
.author("Nymtech")
.arg(
Arg::with_name(CONFIG_ENV_FILE)
.help("Path pointing to an env file that configures the Nym API")
.long(CONFIG_ENV_FILE)
.short('c')
.takes_value(true)
)
.arg(
Arg::with_name(ID)
.help("Id of the nym-api we want to run")
.long(ID)
.takes_value(true)
)
.arg(
Arg::with_name(MONITORING_ENABLED)
.help("specifies whether a network monitoring is enabled on this API")
.long(MONITORING_ENABLED)
.short('m')
)
.arg(
Arg::with_name(REWARDING_ENABLED)
.help("specifies whether a network rewarding is enabled on this API")
.long(REWARDING_ENABLED)
.short('r')
.requires_all(&[MONITORING_ENABLED, MNEMONIC_ARG])
)
.arg(
Arg::with_name(NYMD_VALIDATOR_ARG)
.help("Endpoint to nymd instance from which the monitor will grab nodes to test")
.long(NYMD_VALIDATOR_ARG)
.takes_value(true)
)
.arg(Arg::with_name(MIXNET_CONTRACT_ARG)
.long(MIXNET_CONTRACT_ARG)
.help("Address of the mixnet contract managing the network")
.takes_value(true),
)
.arg(Arg::with_name(MNEMONIC_ARG)
.long(MNEMONIC_ARG)
.help("Mnemonic of the network monitor used for rewarding operators")
.takes_value(true)
)
.arg(
Arg::with_name(WRITE_CONFIG_ARG)
.help("specifies whether a config file based on provided arguments should be saved to a file")
.long(WRITE_CONFIG_ARG)
.short('w')
)
.arg(
Arg::with_name(REWARDING_MONITOR_THRESHOLD_ARG)
.help("Specifies the minimum percentage of monitor test run data present in order to distribute rewards for given interval.")
.takes_value(true)
.long(REWARDING_MONITOR_THRESHOLD_ARG)
)
.arg(
Arg::with_name(MIN_MIXNODE_RELIABILITY_ARG)
.long(MIN_MIXNODE_RELIABILITY_ARG)
.help("Mixnodes with reliability lower the this get blacklisted by network monitor, get no traffic and cannot be selected into a rewarded set.")
.takes_value(true)
)
.arg(
Arg::with_name(MIN_GATEWAY_RELIABILITY_ARG)
.long(MIN_GATEWAY_RELIABILITY_ARG)
.help("Gateways with reliability lower the this get blacklisted by network monitor, get no traffic and cannot be selected into a rewarded set.")
.takes_value(true)
)
.arg(
Arg::with_name(ENABLED_CREDENTIALS_MODE_ARG_NAME)
.long(ENABLED_CREDENTIALS_MODE_ARG_NAME)
.help("Set this nym api to work in a enabled credentials that would attempt to use gateway with the bandwidth credential requirement")
);
// Helper for passing LONG_VERSION to clap
fn pretty_build_info_static() -> &'static str {
&PRETTY_BUILD_INFORMATION
}
// explicitly defined custom parser (as opposed to just using
// #[arg(value_parser = clap::value_parser!(u8).range(0..100))]
// for better error message
fn threshold_in_range(s: &str) -> Result<u8, String> {
let threshold: usize = s
.parse()
.map_err(|_| format!("`{s}` isn't a valid threshold number"))?;
if threshold > 100 {
Err(format!("{threshold} is not within the range 0-100"))
} else {
Ok(threshold as u8)
}
}
#[derive(Parser)]
#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)]
struct ApiArgs {
/// Path pointing to an env file that configures the Nym API.
#[clap(short, long)]
config_env_file: Option<std::path::PathBuf>,
/// Id of the nym-api we want to run
#[clap(long)]
id: Option<String>,
/// Specifies whether network monitoring is enabled on this API
#[clap(short = 'm', long)]
enable_monitor: bool,
/// Specifies whether network rewarding is enabled on this API
#[clap(short = 'r', long, requires = "enable_monitor", requires = "mnemonic")]
enable_rewarding: bool,
/// Endpoint to nymd instance from which the monitor will grab nodes to test
#[clap(long)]
nymd_validator: Option<url::Url>,
/// Address of the mixnet contract managing the network
#[clap(long)]
mixnet_contract: Option<nymd::AccountId>,
/// Mnemonic of the network monitor used for rewarding operators
// even though we're currently converting the mnemonic to string (and then back to the concrete type)
// at least we're getting immediate validation when passing the arguments
#[clap(long)]
mnemonic: Option<bip39::Mnemonic>,
/// Specifies whether a config file based on provided arguments should be saved to a file
#[clap(short = 'w', long)]
save_config: bool,
/// Specifies the minimum percentage of monitor test run data present in order to distribute rewards for given interval.
#[clap(long, value_parser = threshold_in_range)]
monitor_threshold: Option<u8>,
/// Mixnodes with reliability lower the this get blacklisted by network monitor, get no traffic and cannot be selected into a rewarded set.
#[clap(long, value_parser = threshold_in_range)]
min_mixnode_reliability: Option<u8>,
/// Gateways with reliability lower the this get blacklisted by network monitor, get no traffic and cannot be selected into a rewarded set.
#[clap(long, value_parser = threshold_in_range)]
min_gateway_reliability: Option<u8>,
/// Set this nym api to work in a enabled credentials that would attempt to use gateway with the bandwidth credential requirement
#[clap(long)]
enabled_credentials_mode: bool,
/// Announced address where coconut clients will connect.
#[cfg(feature = "coconut")]
let base_app = base_app
.arg(
Arg::with_name(ANNOUNCE_ADDRESS)
.help("Announced address where coconut clients will connect.")
.long(ANNOUNCE_ADDRESS)
.takes_value(true),
)
.arg(
Arg::with_name(COCONUT_ENABLED)
.help("Flag to indicate whether coconut signer authority is enabled on this API")
.requires_all(&[MNEMONIC_ARG, ANNOUNCE_ADDRESS])
.long(COCONUT_ENABLED),
);
base_app.get_matches()
#[clap(long)]
announce_address: Option<url::Url>,
/// Flag to indicate whether coconut signer authority is enabled on this API
#[cfg(feature = "coconut")]
#[clap(long, requires = "mnemonic", requires = "announce-address")]
enable_coconut: bool,
}
async fn wait_for_interrupt(mut shutdown: TaskManager) {
@@ -218,122 +158,55 @@ async fn wait_for_interrupt(mut shutdown: TaskManager) {
log::info!("Stopping nym API");
}
#[cfg(unix)]
async fn wait_for_signal() {
use tokio::signal::unix::{signal, SignalKind};
let mut sigterm = signal(SignalKind::terminate()).expect("Failed to setup SIGTERM channel");
let mut sigquit = signal(SignalKind::quit()).expect("Failed to setup SIGQUIT channel");
tokio::select! {
_ = tokio::signal::ctrl_c() => {
log::info!("Received SIGINT");
},
_ = sigterm.recv() => {
log::info!("Received SIGTERM");
}
_ = sigquit.recv() => {
log::info!("Received SIGQUIT");
}
}
}
#[cfg(not(unix))]
async fn wait_for_signal() {
tokio::select! {
_ = tokio::signal::ctrl_c() => {
log::info!("Received SIGINT");
},
}
}
fn override_config(mut config: Config, matches: &ArgMatches) -> Config {
if let Some(id) = matches.value_of(ID) {
fs::create_dir_all(Config::default_config_directory(Some(id)))
fn override_config(mut config: Config, args: ApiArgs) -> Config {
if let Some(id) = args.id {
fs::create_dir_all(Config::default_config_directory(Some(&id)))
.expect("Could not create config directory");
fs::create_dir_all(Config::default_data_directory(Some(id)))
fs::create_dir_all(Config::default_data_directory(Some(&id)))
.expect("Could not create data directory");
config = config.with_id(id);
config = config.with_id(&id);
}
if matches.is_present(MONITORING_ENABLED) {
config = config.with_network_monitor_enabled(true)
config = config
.with_network_monitor_enabled(args.enable_monitor)
.with_rewarding_enabled(args.enable_rewarding)
.with_disabled_credentials_mode(!args.enabled_credentials_mode);
if let Some(nymd_validator) = args.nymd_validator {
config = config.with_custom_nymd_validator(nymd_validator);
}
if matches.is_present(REWARDING_ENABLED) {
config = config.with_rewarding_enabled(true)
}
#[cfg(feature = "coconut")]
if matches.is_present(COCONUT_ENABLED) {
config = config.with_coconut_signer_enabled(true)
}
#[cfg(feature = "coconut")]
if let Some(announce_address) = matches.value_of(ANNOUNCE_ADDRESS) {
config = config.with_announce_address(
Url::parse(announce_address).expect("Could not parse announce address"),
);
}
if let Some(raw_validator) = matches.value_of(NYMD_VALIDATOR_ARG) {
let parsed = match raw_validator.parse() {
Err(err) => {
error!("Passed validator argument is invalid - {err}");
process::exit(1)
}
Ok(url) => url,
};
config = config.with_custom_nymd_validator(parsed);
}
if let Some(mixnet_contract) = matches.value_of(MIXNET_CONTRACT_ARG) {
config = config.with_custom_mixnet_contract(mixnet_contract)
if let Some(mixnet_contract) = args.mixnet_contract {
config = config.with_custom_mixnet_contract(mixnet_contract.to_string())
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(mixnet_contract) = read_var_if_not_default(MIXNET_CONTRACT_ADDRESS) {
config = config.with_custom_mixnet_contract(mixnet_contract)
}
}
if let Some(mnemonic) = matches.value_of(MNEMONIC_ARG) {
config = config.with_mnemonic(mnemonic)
if let Some(mnemonic) = args.mnemonic {
config = config.with_mnemonic(mnemonic.to_string())
}
if let Some(monitor_threshold) = matches
.value_of(REWARDING_MONITOR_THRESHOLD_ARG)
.map(|t| t.parse::<u8>())
{
let monitor_threshold =
monitor_threshold.expect("Provided monitor threshold is not a number!");
assert!(
monitor_threshold <= 100,
"Provided monitor threshold is greater than 100!"
);
if let Some(monitor_threshold) = args.monitor_threshold {
config = config.with_minimum_interval_monitor_threshold(monitor_threshold)
}
if let Some(reliability) = matches
.value_of(MIN_MIXNODE_RELIABILITY_ARG)
.map(|t| t.parse::<u8>())
{
config = config.with_min_mixnode_reliability(
reliability.expect("Provided reliability is not a u8 number!"),
)
if let Some(reliability) = args.min_mixnode_reliability {
config = config.with_min_mixnode_reliability(reliability)
}
if let Some(reliability) = matches
.value_of(MIN_GATEWAY_RELIABILITY_ARG)
.map(|t| t.parse::<u8>())
{
config = config.with_min_gateway_reliability(
reliability.expect("Provided reliability is not a u8 number!"),
)
if let Some(reliability) = args.min_gateway_reliability {
config = config.with_min_gateway_reliability(reliability)
}
if matches.is_present(ENABLED_CREDENTIALS_MODE_ARG_NAME) {
config = config.with_disabled_credentials_mode(false)
#[cfg(feature = "coconut")]
if let Some(announce_address) = args.announce_address {
config = config
.with_announce_address(announce_address)
.with_coconut_signer_enabled(args.enable_coconut);
}
if matches.is_present(WRITE_CONFIG_ARG) {
if args.save_config {
info!("Saving the configuration to a file");
if let Err(err) = config.save_to_file(None) {
error!("Failed to write config to a file - {err}");
@@ -490,11 +363,11 @@ fn get_servers() -> Vec<rocket_okapi::okapi::openapi3::Server> {
}]
}
async fn run_nym_api(matches: ArgMatches) -> Result<()> {
async fn run_nym_api(args: ApiArgs) -> Result<()> {
let system_version = env!("CARGO_PKG_VERSION");
// try to load config from the file, if it doesn't exist, use default values
let id = matches.value_of(ID);
let id = args.id.as_deref();
let (config, _already_inited) = match Config::load_from_file(id) {
Ok(cfg) => (cfg, true),
Err(_) => {
@@ -503,14 +376,14 @@ async fn run_nym_api(matches: ArgMatches) -> Result<()> {
.into_string()
.unwrap();
warn!(
"Could not load the configuration file from {}. Either the file did not exist or was malformed. Using the default values instead",
config_path
"Could not load the configuration file from {config_path}. Either the file did not exist or was malformed. Using the default values instead",
);
(Config::new(), false)
}
};
let config = override_config(config, &matches);
let save_to_file = args.save_config;
let config = override_config(config, args);
#[cfg(feature = "coconut")]
if !_already_inited {
@@ -518,9 +391,16 @@ async fn run_nym_api(matches: ArgMatches) -> Result<()> {
}
// if we just wanted to write data to the config, exit
if matches.is_present(WRITE_CONFIG_ARG) {
return Ok(());
if save_to_file {
info!("Saving the configuration to a file");
if let Err(err) = config.save_to_file(None) {
error!("Failed to write config to a file - {err}");
process::exit(1)
} else {
return Ok(());
}
}
let mix_denom = std::env::var(MIX_DENOM).expect("mix denom not set");
let signing_nymd_client = Client::new_signing(&config);
@@ -584,11 +464,13 @@ async fn run_nym_api(matches: ArgMatches) -> Result<()> {
tokio::spawn(async move { validator_cache_refresher.run(shutdown_listener).await });
// spawn rewarded set updater
let mut rewarded_set_updater =
RewardedSetUpdater::new(signing_nymd_client, validator_cache.clone(), storage).await?;
let shutdown_listener = shutdown.subscribe();
tokio::spawn(async move { rewarded_set_updater.run(shutdown_listener).await.unwrap() });
if config.get_rewarding_enabled() {
let mut rewarded_set_updater =
RewardedSetUpdater::new(signing_nymd_client, validator_cache.clone(), storage)
.await?;
let shutdown_listener = shutdown.subscribe();
tokio::spawn(async move { rewarded_set_updater.run(shutdown_listener).await.unwrap() });
}
validator_cache_listener
} else {
// Spawn the validator cache refresher.
@@ -658,10 +540,7 @@ async fn main() -> Result<()> {
}}
setup_logging();
let args = parse_args();
let config_env_file = args
.value_of(CONFIG_ENV_FILE)
.map(|s| PathBuf::from_str(s).expect("invalid env config file"));
setup_env(config_env_file);
let args = ApiArgs::parse();
setup_env(args.config_env_file.as_ref());
run_nym_api(args).await
}
+3 -3
View File
@@ -2161,9 +2161,9 @@ json-stringify-safe@5.0.1:
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
json5@^2.2.1:
version "2.2.1"
resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
kleur@^3.0.3:
version "3.0.3"
+59 -22
View File
@@ -407,6 +407,13 @@ dependencies = [
"memchr",
]
[[package]]
name = "build-information"
version = "0.1.0"
dependencies = [
"vergen 7.4.4",
]
[[package]]
name = "bumpalo"
version = "3.11.0"
@@ -566,35 +573,33 @@ dependencies = [
[[package]]
name = "clap"
version = "3.2.22"
version = "4.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750"
checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"clap_lex",
"indexmap",
"once_cell",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_complete"
version = "3.2.5"
version = "4.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f7a2e0a962c45ce25afce14220bc24f9dade0a1787f185cecf96bfba7847cd8"
checksum = "10861370d2ba66b0f5989f83ebf35db6421713fd92351790e7fdd6c36774c56b"
dependencies = [
"clap",
]
[[package]]
name = "clap_complete_fig"
version = "3.2.4"
version = "4.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed37b4c0c1214673eba6ad8ea31666626bf72be98ffb323067d973c48b4964b9"
checksum = "46b30e010e669cd021e5004f3be26cff6b7c08d2a8a0d65b48d43a8cc0efd6c3"
dependencies = [
"clap",
"clap_complete",
@@ -602,9 +607,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "3.2.18"
version = "4.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
dependencies = [
"heck 0.4.0",
"proc-macro-error",
@@ -615,9 +620,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.2.4"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [
"os_str_bytes",
]
@@ -1583,7 +1588,16 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2953d1df47ac0eb70086ccabf0275aa8da8591a28bd358ee2b52bd9f9e3ff9e9"
dependencies = [
"enum-iterator-derive",
"enum-iterator-derive 0.8.1",
]
[[package]]
name = "enum-iterator"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45a0ac4aeb3a18f92eaf09c6bb9b3ac30ff61ca95514fc58cbead1c9a6bf5401"
dependencies = [
"enum-iterator-derive 1.1.0",
]
[[package]]
@@ -1597,6 +1611,17 @@ dependencies = [
"syn",
]
[[package]]
name = "enum-iterator-derive"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "828de45d0ca18782232dfb8f3ea9cc428e8ced380eb26a520baaacfc70de39ce"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "env_logger"
version = "0.7.1"
@@ -3440,6 +3465,7 @@ dependencies = [
name = "nym-socks5-client"
version = "1.1.4"
dependencies = [
"build-information",
"clap",
"client-connections",
"client-core",
@@ -3451,6 +3477,7 @@ dependencies = [
"futures",
"gateway-client",
"gateway-requests",
"lazy_static",
"log",
"logging",
"network-defaults",
@@ -3471,7 +3498,6 @@ dependencies = [
"topology",
"url",
"validator-client",
"vergen",
"version-checker",
]
@@ -6028,12 +6054,6 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d"
[[package]]
name = "thin-slice"
version = "0.1.1"
@@ -6538,7 +6558,7 @@ dependencies = [
"anyhow",
"cfg-if",
"chrono",
"enum-iterator",
"enum-iterator 0.8.1",
"getset",
"git2",
"rustc_version 0.4.0",
@@ -6546,6 +6566,23 @@ dependencies = [
"thiserror",
]
[[package]]
name = "vergen"
version = "7.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efadd36bc6fde40c6048443897d69511a19161c0756cb704ed403f8dfd2b7d1c"
dependencies = [
"anyhow",
"cfg-if",
"enum-iterator 1.1.3",
"getset",
"git2",
"rustc_version 0.4.0",
"rustversion",
"thiserror",
"time 0.3.17",
]
[[package]]
name = "version-checker"
version = "0.1.0"
@@ -6582,7 +6619,7 @@ dependencies = [
"schemars",
"serde",
"thiserror",
"vergen",
"vergen 5.1.17",
"vesting-contract-common",
]
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@nym/nym-connect",
"version": "1.1.5",
"version": "1.1.4",
"main": "index.js",
"license": "MIT",
"scripts": {
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-connect"
version = "1.1.5"
version = "1.1.4"
description = "nym-connect"
authors = ["Nym Technologies SA"]
license = ""
+2 -2
View File
@@ -130,11 +130,11 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
if let Ok(raw_validators) = std::env::var(config_common::defaults::var_names::API_VALIDATOR) {
config
.get_base_mut()
.set_custom_nym_apis(config_common::parse_validators(&raw_validators));
.set_custom_nym_apis(config_common::parse_urls(&raw_validators));
}
// Setup gateway by either registering a new one, or reusing exiting keys
let gateway = client_core::init::setup_gateway::<_, Socks5Config, _>(
let gateway = client_core::init::setup_gateway::<Socks5Config, _>(
register_gateway,
Some(chosen_gateway_id),
config.get_base(),
+1 -2
View File
@@ -1,4 +1,3 @@
use client_core::client::replies::reply_storage::fs_backend;
use client_core::error::ClientCoreError;
use serde::{Serialize, Serializer};
use thiserror::Error;
@@ -39,7 +38,7 @@ pub enum BackendError {
#[error("{source}")]
ClientCoreError {
#[from]
source: ClientCoreError<fs_backend::Backend>,
source: ClientCoreError,
},
#[error("{source}")]
ApiClientError {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"package": {
"productName": "nym-connect",
"version": "1.1.5"
"version": "1.1.4"
},
"build": {
"distDir": "../dist",
+12 -13
View File
@@ -1,9 +1,8 @@
import React from 'react';
import { Box, CircularProgress, Divider, Stack, Tooltip, Typography } from '@mui/material';
import { Box, CircularProgress, Typography } from '@mui/material';
import { DateTime } from 'luxon';
import { ConnectionStatusKind } from '../types';
import { ServiceProvider } from '../types/directory';
import { ServiceProviderInfo } from './ServiceProviderInfo';
const FONT_SIZE = '10px';
const FONT_WEIGHT = '600';
@@ -15,8 +14,8 @@ const ConnectionStatusContent: React.FC<{
switch (status) {
case ConnectionStatusKind.connected:
return (
<Typography fontWeight={FONT_WEIGHT} fontStyle={FONT_STYLE} fontSize="14px">
Connected to
<Typography fontWeight={FONT_WEIGHT} fontStyle={FONT_STYLE} textAlign="center">
Connected
</Typography>
);
case ConnectionStatusKind.disconnecting:
@@ -45,7 +44,7 @@ const ConnectionStatusContent: React.FC<{
ml={1}
textTransform="uppercase"
textAlign="center"
fontSize={FONT_SIZE}
fontSize="10px"
sx={{ wordSpacing: 3, letterSpacing: 2 }}
>
You are not protected
@@ -60,7 +59,7 @@ export const ConnectionStatus: React.FC<{
status: ConnectionStatusKind;
connectedSince?: DateTime;
serviceProvider?: ServiceProvider;
}> = ({ status, serviceProvider }) => {
}> = ({ status, connectedSince, serviceProvider }) => {
const color =
status === ConnectionStatusKind.connected || status === ConnectionStatusKind.disconnecting
? '#21D072'
@@ -71,13 +70,13 @@ export const ConnectionStatus: React.FC<{
<Box color={color} fontSize={FONT_SIZE} sx={{ mb: 1 }}>
<ConnectionStatusContent status={status} />
</Box>
{serviceProvider ? (
<Tooltip title={<ServiceProviderInfo serviceProvider={serviceProvider} />}>
<Box sx={{ cursor: 'pointer' }}>
{serviceProvider && <Typography>{serviceProvider.description}</Typography>}
</Box>
</Tooltip>
) : null}
<Box>
{serviceProvider && (
<Typography fontSize={12} textAlign="center">
To {serviceProvider.description}
</Typography>
)}
</Box>
</>
);
};
@@ -1,20 +0,0 @@
import React from 'react';
import { Divider, Stack, Typography } from '@mui/material';
import { ServiceProvider } from 'src/types/directory';
export const ServiceProviderInfo = ({ serviceProvider }: { serviceProvider: ServiceProvider }) => (
<Stack gap={1} sx={{ wordWrap: 'break-word', maxWidth: 150, p: 1 }}>
<Typography variant="body2" fontWeight="bold">
Connection info
</Typography>
<Typography variant="caption">{serviceProvider.description}</Typography>
<Divider />
<Typography variant="caption" fontWeight="bold">
Gateway <Typography variant="caption">{serviceProvider.gateway}</Typography>
</Typography>
<Divider />
<Typography variant="caption" fontWeight="bold">
Provider <Typography variant="caption">{serviceProvider.address.slice(0, 35)}...</Typography>
</Typography>
</Stack>
);
-2
View File
@@ -86,8 +86,6 @@ export const ClientContextProvider = ({ children }: { children: React.ReactNode
.catch((e) => console.log(e));
listen('socks5-event', (e: TauriEvent) => {
console.log(e);
setError(e.payload);
}).then((result) => {
unlisten.push(result);
+3 -5
View File
@@ -37,13 +37,11 @@ export const ConnectedLayout: React.FC<{
}) => (
<>
<IpAddressAndPortModal show={showInfoModal} onClose={handleCloseInfoModal} ipAddress={ipAddress} port={port} />
<Box>
<Box pb={4}>
<ConnectionStatus status={ConnectionStatusKind.connected} serviceProvider={serviceProvider} />
</Box>
<Divider sx={{ my: 2 }} />
<Box sx={{ mb: 3 }}>
<IpAddressAndPort label="Socks5 address" ipAddress={ipAddress} port={port} />
</Box>
<IpAddressAndPort label="Socks5 address" ipAddress={ipAddress} port={port} />
<Divider sx={{ my: 3 }} />
{/* <ConnectionStats stats={stats} /> */}
<ConnectionTimer connectedSince={connectedSince} />
<ConnectionButton status={status} busy={busy} onClick={onConnectClick} isError={isError} />
+2092 -712
View File
File diff suppressed because it is too large Load Diff

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