Compare commits

..

48 Commits

Author SHA1 Message Date
mfahampshire 6791fab21d changed info! notice re: terminology 2024-09-05 11:02:24 +02:00
mfahampshire 490ae434b4 added zknym diagrams to images 2024-09-04 14:59:09 +02:00
mfahampshire fe91a65166 added diagrams 2024-09-04 14:58:53 +02:00
mfahampshire 5946d51e5b removed comment 2024-09-04 14:58:31 +02:00
mfahampshire 6f1f14befe tweaked archive explainer 2024-09-04 14:57:30 +02:00
mfahampshire 567c928cde rename dir from ecash to zknym 2024-09-03 15:37:37 +02:00
mfahampshire b8e2503fdd vocabulary change over all ecash docs 2024-09-03 15:35:11 +02:00
mfahampshire 4d26d683e0 small streamlining 2024-09-03 12:45:42 +02:00
mfahampshire b04dc55aba added archive warning 2024-09-03 12:45:26 +02:00
Jaya Klara Brekke bca0fc2694 Update double-spend-prot.md (#4830) 2024-09-03 09:31:16 +00:00
Jaya Klara Brekke d97d839f35 Update zknym-overview.md (#4829) 2024-09-03 09:31:01 +00:00
Jaya Klara Brekke 4bdbe7710c Update what-are-zknyms.md (#4828) 2024-09-03 09:28:07 +00:00
mfahampshire 589ee64516 refresh older imported text from archive 2024-08-30 09:33:53 +02:00
mfahampshire b20ab5dc50 tweak 2024-08-30 09:16:11 +02:00
mfahampshire 5bdff28a11 tweaked overall content 2024-08-29 18:02:52 +02:00
mfahampshire 4795a643a4 added more info from archive page 2024-08-29 18:02:38 +02:00
mfahampshire f7f6421415 first pass double spend doc 2024-08-29 18:02:22 +02:00
mfahampshire 891cfb80ea small tweak to archive coconut page 2024-08-29 18:02:06 +02:00
mfahampshire 9344296804 remove double spend stub from overview doc 2024-08-28 17:35:29 +02:00
mfahampshire 3538b5237e split out features into own pages 2024-08-28 17:33:33 +02:00
mfahampshire 5581f735d2 removed feature info from main overview doc 2024-08-28 17:33:19 +02:00
mfahampshire c0ede6a506 new structure 2024-08-28 17:33:04 +02:00
mfahampshire 5d6b84a94f added todo 2024-08-23 12:46:31 +02:00
mfahampshire 66fff0edf0 simplified subheading for zknyms 2024-08-23 12:16:37 +02:00
mfahampshire 2bdb623101 added high level examples to zknym overview page 2024-08-23 12:16:03 +02:00
mfahampshire 1f435880d7 restructure + reword + skeleton of incremental spend 2024-08-22 15:42:44 +02:00
mfahampshire 34579222c5 removed unnecessary file for moment 2024-08-22 15:42:23 +02:00
mfahampshire 2a43134327 made generic 2024-08-21 14:47:18 +02:00
mfahampshire 844bcba6e8 first pass ecash docs 2024-08-21 14:20:26 +02:00
import this f3ac17eb9d [DOCs/developers]: syntax fix (#4770)
* syntax-fix

* syntax-fix
2024-08-20 16:41:29 +02:00
import this 6296d09adf [DOCs/developers]: Update NymVPN CLI guide (#4769)
* creat guide to build nym-vpn-cli from source

* update nymvpn cli guide
2024-08-20 13:10:05 +00:00
Bogdan-Ștefan Neacşu 2ae81f6da0 Avoid race on ip and registration structures (#4766) 2024-08-20 14:51:59 +02:00
Tommy Verrall 1d5e8b62ac Merge pull request #4765 from nymtech/serinko-hotfix
docs/hotfix
2024-08-20 10:21:18 +02:00
import this 581cdd5bdf Update configuration.md 2024-08-18 11:56:56 +00:00
import this e2e49e7136 docs/hotfix 2024-08-18 11:55:28 +00:00
Jon Häggblad dff82f946f Make gateway latency check generic (#4759)
* Replace concrete gateway type with trait in latency check

* Rename to ConnectableGateway
2024-08-15 09:42:13 +02:00
Tommy Verrall ec61728654 Merge pull request #4762 from nymtech/serinko/wg_hotfix
[DOCs/operators]: serinko/hotfix
2024-08-13 17:48:36 +02:00
import this 61471e9058 add note about IPv6 2024-08-13 15:41:16 +00:00
import this ed4fd84503 serinko/hotfix 2024-08-13 15:39:31 +00:00
Jon Häggblad cb4b0403b5 Remove deprecated mark_as_success and use new disarm (#4751) 2024-08-13 15:09:48 +02:00
import this da8e513627 [DOCs/operators]: WireGuard guide & changelog update (#4760)
* wireguard documentation and changelog update

* add review comments

* add review comments
2024-08-13 13:05:52 +00:00
Jon Häggblad 3f6de8b10c Remove duplicate stat count for retransmissions (#4756) 2024-08-09 14:55:14 +02:00
import this 1e01a8e633 [DOCs/operators]: Release detailed changelog for v2024.9 topdeck (#4757)
* add changelog for new release

* add more URLs redirection for socks5 specific apps

* update exit policy page

* finish changelog - ready for review

* add tooling

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

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

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

* add info to socks5 page

* fix dev-portal links

* finish URL edits and redirection
2024-08-06 12:37:37 +00:00
105 changed files with 1476 additions and 988 deletions
-32
View File
@@ -4,38 +4,6 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
## [Unreleased]
## [2024.10-caramello] (2024-08-19)
- bugfix: make sure DKG parses data out of events if logs are empty ([#4764])
- Fix clippy on rustc beta toolchain ([#4746])
- Fix clippy for beta toolchain ([#4742])
- Disable testnet-manager on non-unix ([#4741])
- Don't set NYM_VPN_API to default ([#4740])
- Update publish-nym-binaries.yml ([#4739])
- Update ci-build-upload-binaries.yml ([#4738])
- Add NYM_VPN_API to network config ([#4736])
- Re-export RecipientFormattingError in nym sdk ([#4735])
- Persist wireguard peers ([#4732])
- Fix tokio error in 1.39 ([#4730])
- Feature/vesting purge plus ranged cost params ([#4716])
- Fix (some) feature unification build failures ([#4681])
- Feature Compact Ecash : The One PR ([#4623])
[#4764]: https://github.com/nymtech/nym/pull/4764
[#4746]: https://github.com/nymtech/nym/pull/4746
[#4742]: https://github.com/nymtech/nym/pull/4742
[#4741]: https://github.com/nymtech/nym/pull/4741
[#4740]: https://github.com/nymtech/nym/pull/4740
[#4739]: https://github.com/nymtech/nym/pull/4739
[#4738]: https://github.com/nymtech/nym/pull/4738
[#4736]: https://github.com/nymtech/nym/pull/4736
[#4735]: https://github.com/nymtech/nym/pull/4735
[#4732]: https://github.com/nymtech/nym/pull/4732
[#4730]: https://github.com/nymtech/nym/pull/4730
[#4716]: https://github.com/nymtech/nym/pull/4716
[#4681]: https://github.com/nymtech/nym/pull/4681
[#4623]: https://github.com/nymtech/nym/pull/4623
## [2024.9-topdeck] (2024-07-26)
- chore: fix 1.80 lint issues ([#4731])
Generated
+220 -83
View File
@@ -332,6 +332,15 @@ dependencies = [
"winapi",
]
[[package]]
name = "autocfg"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78"
dependencies = [
"autocfg 1.3.0",
]
[[package]]
name = "autocfg"
version = "1.3.0"
@@ -544,7 +553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f"
dependencies = [
"bitcoin_hashes",
"rand",
"rand 0.8.5",
"rand_core 0.6.4",
"serde",
"unicode-normalization",
@@ -985,6 +994,15 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "colorchoice"
version = "1.0.1"
@@ -2222,7 +2240,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "explorer-api"
version = "1.1.39"
version = "1.1.38"
dependencies = [
"chrono",
"clap 4.5.7",
@@ -2241,8 +2259,8 @@ dependencies = [
"nym-validator-client",
"okapi",
"pretty_env_logger",
"rand",
"rand_pcg",
"rand 0.8.5",
"rand_pcg 0.3.1",
"rand_seeder",
"reqwest 0.12.4",
"rocket",
@@ -2441,6 +2459,12 @@ dependencies = [
"libc",
]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "funty"
version = "2.0.0"
@@ -3321,7 +3345,7 @@ version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"autocfg 1.3.0",
"hashbrown 0.12.3",
"serde",
]
@@ -3736,7 +3760,7 @@ version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"autocfg 1.3.0",
"scopeguard",
]
@@ -3863,7 +3887,7 @@ version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
dependencies = [
"autocfg",
"autocfg 1.3.0",
]
[[package]]
@@ -3933,7 +3957,7 @@ dependencies = [
"nym-ordered-buffer",
"nym-service-providers-common",
"nym-socks5-requests",
"rand",
"rand 0.8.5",
"serde",
"serde-wasm-bindgen 0.6.5",
"thiserror",
@@ -4149,7 +4173,7 @@ version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"autocfg 1.3.0",
"libm",
]
@@ -4180,7 +4204,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "nym-api"
version = "1.1.43"
version = "1.1.42"
dependencies = [
"anyhow",
"async-trait",
@@ -4233,8 +4257,8 @@ dependencies = [
"nym-vesting-contract-common",
"okapi",
"pin-project",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"reqwest 0.12.4",
"rocket",
"rocket_cors",
@@ -4320,7 +4344,7 @@ dependencies = [
"nym-types",
"nym-wireguard",
"nym-wireguard-types",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"thiserror",
@@ -4337,7 +4361,7 @@ dependencies = [
"bincode",
"nym-sphinx",
"nym-wireguard-types",
"rand",
"rand 0.8.5",
"serde",
]
@@ -4355,7 +4379,7 @@ dependencies = [
"nym-ecash-time",
"nym-network-defaults",
"nym-validator-client",
"rand",
"rand 0.8.5",
"thiserror",
"url",
"zeroize",
@@ -4401,7 +4425,7 @@ dependencies = [
[[package]]
name = "nym-cli"
version = "1.1.41"
version = "1.1.40"
dependencies = [
"anyhow",
"base64 0.13.1",
@@ -4429,12 +4453,11 @@ name = "nym-cli-commands"
version = "1.0.0"
dependencies = [
"anyhow",
"base64 0.21.7",
"base64 0.13.1",
"bip39",
"bs58 0.5.1",
"cfg-if",
"clap 4.5.7",
"colored",
"comfy-table 6.2.0",
"cosmrs 0.17.0-pre",
"cosmwasm-std",
@@ -4467,21 +4490,21 @@ dependencies = [
"nym-types",
"nym-validator-client",
"nym-vesting-contract-common",
"rand",
"rand 0.6.5",
"serde",
"serde_json",
"tap",
"thiserror",
"time",
"tokio",
"toml 0.8.14",
"toml 0.5.11",
"url",
"zeroize",
]
[[package]]
name = "nym-client"
version = "1.1.40"
version = "1.1.39"
dependencies = [
"bs58 0.5.1",
"clap 4.5.7",
@@ -4504,7 +4527,7 @@ dependencies = [
"nym-task",
"nym-topology",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"tap",
@@ -4555,7 +4578,7 @@ dependencies = [
"nym-task",
"nym-topology",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"sha2 0.10.8",
@@ -4635,7 +4658,7 @@ dependencies = [
"nym-bin-common",
"nym-node-tester-utils",
"nym-node-tester-wasm",
"rand",
"rand 0.8.5",
"serde",
"serde-wasm-bindgen 0.6.5",
"serde_json",
@@ -4672,8 +4695,8 @@ dependencies = [
"itertools 0.13.0",
"nym-dkg",
"nym-pemstore",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"serde",
"serde_derive",
"sha2 0.9.9",
@@ -4719,7 +4742,7 @@ dependencies = [
"itertools 0.12.1",
"nym-network-defaults",
"nym-pemstore",
"rand",
"rand 0.8.5",
"rayon",
"serde",
"sha2 0.9.9",
@@ -4813,7 +4836,7 @@ dependencies = [
"nym-ecash-time",
"nym-network-defaults",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"thiserror",
"time",
@@ -4828,7 +4851,7 @@ dependencies = [
"nym-compact-ecash",
"nym-ecash-time",
"nym-network-defaults",
"rand",
"rand 0.8.5",
"serde",
"strum 0.25.0",
"thiserror",
@@ -4851,8 +4874,8 @@ dependencies = [
"hmac",
"nym-pemstore",
"nym-sphinx-types",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"serde",
"serde_bytes",
"subtle-encoding",
@@ -4874,8 +4897,8 @@ dependencies = [
"lazy_static",
"nym-contracts-common",
"nym-pemstore",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
"serde",
"serde_derive",
@@ -5005,7 +5028,7 @@ dependencies = [
"nym-wireguard",
"nym-wireguard-types",
"once_cell",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"si-scale",
@@ -5040,7 +5063,7 @@ dependencies = [
"nym-sphinx",
"nym-task",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"si-scale",
"thiserror",
@@ -5069,7 +5092,7 @@ dependencies = [
"nym-crypto",
"nym-pemstore",
"nym-sphinx",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"thiserror",
@@ -5169,7 +5192,7 @@ name = "nym-inclusion-probability"
version = "0.1.0"
dependencies = [
"log",
"rand",
"rand 0.8.5",
"thiserror",
]
@@ -5182,7 +5205,7 @@ dependencies = [
"nym-bin-common",
"nym-crypto",
"nym-sphinx",
"rand",
"rand 0.8.5",
"serde",
"thiserror",
"time",
@@ -5219,7 +5242,7 @@ dependencies = [
"nym-types",
"nym-wireguard",
"nym-wireguard-types",
"rand",
"rand 0.8.5",
"reqwest 0.12.4",
"serde",
"serde_json",
@@ -5276,7 +5299,7 @@ dependencies = [
"humantime-serde",
"log",
"nym-contracts-common",
"rand_chacha",
"rand_chacha 0.3.1",
"schemars",
"serde",
"serde-json-wasm",
@@ -5319,7 +5342,7 @@ dependencies = [
"nym-topology",
"nym-types",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"sysinfo 0.27.8",
@@ -5352,7 +5375,7 @@ dependencies = [
"nym-sphinx-types",
"nym-task",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"thiserror",
"time",
@@ -5389,7 +5412,7 @@ dependencies = [
[[package]]
name = "nym-network-requester"
version = "1.1.41"
version = "1.1.40"
dependencies = [
"addr",
"anyhow",
@@ -5422,7 +5445,7 @@ dependencies = [
"nym-types",
"pretty_env_logger",
"publicsuffix",
"rand",
"rand 0.8.5",
"regex",
"reqwest 0.12.4",
"serde",
@@ -5440,7 +5463,7 @@ dependencies = [
[[package]]
name = "nym-node"
version = "1.1.7"
version = "1.1.6"
dependencies = [
"anyhow",
"bip39",
@@ -5469,7 +5492,7 @@ dependencies = [
"nym-types",
"nym-wireguard",
"nym-wireguard-types",
"rand",
"rand 0.8.5",
"semver 1.0.23",
"serde",
"serde_json",
@@ -5503,7 +5526,7 @@ dependencies = [
"nym-task",
"nym-wireguard",
"nym-wireguard-types",
"rand",
"rand 0.8.5",
"serde_json",
"thiserror",
"time",
@@ -5530,7 +5553,7 @@ dependencies = [
"nym-exit-policy",
"nym-http-api-client",
"nym-wireguard-types",
"rand_chacha",
"rand_chacha 0.3.1",
"schemars",
"serde",
"serde_json",
@@ -5551,7 +5574,7 @@ dependencies = [
"nym-sphinx-params",
"nym-task",
"nym-topology",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"thiserror",
@@ -5566,7 +5589,7 @@ dependencies = [
"futures",
"js-sys",
"nym-node-tester-utils",
"rand",
"rand 0.8.5",
"serde",
"serde-wasm-bindgen 0.6.5",
"thiserror",
@@ -5625,7 +5648,7 @@ dependencies = [
"fastrand 2.1.0",
"getrandom",
"log",
"rand",
"rand 0.8.5",
"rayon",
"sphinx-packet",
"thiserror",
@@ -5674,7 +5697,7 @@ dependencies = [
"nym-validator-client",
"parking_lot 0.12.3",
"pretty_env_logger",
"rand",
"rand 0.8.5",
"reqwest 0.12.4",
"tap",
"thiserror",
@@ -5714,7 +5737,7 @@ dependencies = [
[[package]]
name = "nym-socks5-client"
version = "1.1.40"
version = "1.1.39"
dependencies = [
"bs58 0.5.1",
"clap 4.5.7",
@@ -5734,7 +5757,7 @@ dependencies = [
"nym-sphinx",
"nym-topology",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"tap",
@@ -5767,7 +5790,7 @@ dependencies = [
"nym-task",
"nym-validator-client",
"pin-project",
"rand",
"rand 0.8.5",
"reqwest 0.12.4",
"schemars",
"serde",
@@ -5793,7 +5816,7 @@ dependencies = [
"nym-credential-storage",
"nym-crypto",
"nym-socks5-client-core",
"rand",
"rand 0.8.5",
"safer-ffi",
"serde",
"tokio",
@@ -5847,7 +5870,7 @@ dependencies = [
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand",
"rand 0.8.5",
"rand_distr",
"thiserror",
"tokio",
@@ -5865,7 +5888,7 @@ dependencies = [
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand",
"rand 0.8.5",
"serde",
"thiserror",
"zeroize",
@@ -5877,7 +5900,7 @@ version = "0.1.0"
dependencies = [
"nym-crypto",
"nym-sphinx-types",
"rand",
"rand 0.8.5",
"serde",
"thiserror",
]
@@ -5893,8 +5916,8 @@ dependencies = [
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"serde",
"thiserror",
"wasm-bindgen",
@@ -5908,7 +5931,7 @@ dependencies = [
"nym-sphinx-addressing",
"nym-sphinx-params",
"nym-sphinx-types",
"rand",
"rand 0.8.5",
"thiserror",
]
@@ -5925,7 +5948,7 @@ dependencies = [
"nym-sphinx-routing",
"nym-sphinx-types",
"nym-topology",
"rand",
"rand 0.8.5",
"thiserror",
]
@@ -5987,7 +6010,7 @@ dependencies = [
"argon2",
"generic-array 0.14.7",
"getrandom",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"thiserror",
@@ -6022,7 +6045,7 @@ dependencies = [
"nym-sphinx-addressing",
"nym-sphinx-routing",
"nym-sphinx-types",
"rand",
"rand 0.8.5",
"semver 0.11.0",
"serde",
"serde_json",
@@ -6146,7 +6169,7 @@ dependencies = [
"nym-task",
"nym-validator-client",
"nyxd-scraper",
"rand_chacha",
"rand_chacha 0.3.1",
"serde",
"serde_with",
"sha2 0.10.8",
@@ -6219,13 +6242,12 @@ name = "nym-wireguard-types"
version = "0.1.0"
dependencies = [
"base64 0.21.7",
"dashmap",
"hmac",
"log",
"nym-config",
"nym-crypto",
"nym-network-defaults",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"sha2 0.10.8",
@@ -6236,7 +6258,7 @@ dependencies = [
[[package]]
name = "nymvisor"
version = "0.1.6"
version = "0.1.5"
dependencies = [
"anyhow",
"bytes",
@@ -6435,7 +6457,7 @@ dependencies = [
"once_cell",
"opentelemetry_api",
"percent-encoding",
"rand",
"rand 0.8.5",
"thiserror",
"tokio",
"tokio-stream",
@@ -6748,7 +6770,7 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce"
dependencies = [
"autocfg",
"autocfg 1.3.0",
"bitflags 1.3.2",
"cfg-if",
"concurrent-queue",
@@ -7002,6 +7024,25 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "rand"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
dependencies = [
"autocfg 0.1.8",
"libc",
"rand_chacha 0.1.1",
"rand_core 0.4.2",
"rand_hc",
"rand_isaac",
"rand_jitter",
"rand_os",
"rand_pcg 0.1.2",
"rand_xorshift",
"winapi",
]
[[package]]
name = "rand"
version = "0.8.5"
@@ -7009,10 +7050,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
dependencies = [
"autocfg 0.1.8",
"rand_core 0.3.1",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
@@ -7023,6 +7074,21 @@ dependencies = [
"rand_core 0.6.4",
]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]]
name = "rand_core"
version = "0.5.1"
@@ -7045,7 +7111,60 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
dependencies = [
"num-traits",
"rand",
"rand 0.8.5",
]
[[package]]
name = "rand_hc"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "rand_isaac"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "rand_jitter"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
dependencies = [
"libc",
"rand_core 0.4.2",
"winapi",
]
[[package]]
name = "rand_os"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
dependencies = [
"cloudabi",
"fuchsia-cprng",
"libc",
"rand_core 0.4.2",
"rdrand",
"winapi",
]
[[package]]
name = "rand_pcg"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
dependencies = [
"autocfg 0.1.8",
"rand_core 0.4.2",
]
[[package]]
@@ -7066,6 +7185,15 @@ dependencies = [
"rand_core 0.6.4",
]
[[package]]
name = "rand_xorshift"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "rayon"
version = "1.10.0"
@@ -7086,6 +7214,15 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"
@@ -7343,7 +7480,7 @@ dependencies = [
"num_cpus",
"parking_lot 0.12.3",
"pin-project-lite",
"rand",
"rand 0.8.5",
"ref-cast",
"rocket_codegen",
"rocket_http",
@@ -8116,7 +8253,7 @@ version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
"autocfg",
"autocfg 1.3.0",
]
[[package]]
@@ -8187,7 +8324,7 @@ dependencies = [
"hmac",
"lioness",
"log",
"rand",
"rand 0.8.5",
"rand_distr",
"sha2 0.10.8",
"subtle 2.5.0",
@@ -8731,7 +8868,7 @@ dependencies = [
"getrandom",
"peg",
"pin-project",
"rand",
"rand 0.8.5",
"reqwest 0.11.27",
"semver 1.0.23",
"serde",
@@ -8785,7 +8922,7 @@ dependencies = [
"nym-pemstore",
"nym-validator-client",
"nym-vesting-contract-common",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"sqlx",
@@ -9185,7 +9322,7 @@ dependencies = [
"indexmap 1.9.3",
"pin-project",
"pin-project-lite",
"rand",
"rand 0.8.5",
"slab",
"tokio",
"tokio-util",
@@ -9451,7 +9588,7 @@ dependencies = [
"http 0.2.12",
"httparse",
"log",
"rand",
"rand 0.8.5",
"rustls 0.21.12",
"sha1",
"thiserror",
@@ -9472,7 +9609,7 @@ dependencies = [
"http 1.1.0",
"httparse",
"log",
"rand",
"rand 0.8.5",
"rustls 0.22.4",
"rustls-pki-types",
"sha1",
@@ -9892,7 +10029,7 @@ dependencies = [
"nym-task",
"nym-topology",
"nym-validator-client",
"rand",
"rand 0.8.5",
"serde",
"serde-wasm-bindgen 0.6.5",
"thiserror",
@@ -10527,7 +10664,7 @@ dependencies = [
"nym-credentials",
"nym-crypto",
"nym-http-api-client",
"rand",
"rand 0.8.5",
"reqwest 0.12.4",
"serde",
"thiserror",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.1.40"
version = "1.1.39"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
+1 -1
View File
@@ -422,7 +422,7 @@ impl Handler {
) {
// We don't want a crash in the connection handler to trigger a shutdown of the whole
// process.
task_client.mark_as_success();
task_client.disarm();
let ws_stream = match accept_async(socket).await {
Ok(ws_stream) => ws_stream,
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-socks5-client"
version = "1.1.40"
version = "1.1.39"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021"
@@ -2,9 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::error::BandwidthControllerError;
use crate::utils::{
get_aggregate_verification_key, get_coin_index_signatures, get_expiration_date_signatures,
};
use crate::utils::{get_coin_index_signatures, get_expiration_date_signatures};
use log::info;
use nym_credential_storage::storage::Storage;
use nym_credentials::ecash::bandwidth::IssuanceTicketBook;
@@ -57,7 +55,7 @@ where
))
}
pub async fn query_and_persist_required_global_data<S>(
pub async fn query_and_persist_required_global_signatures<S>(
storage: &S,
epoch_id: EpochId,
expiration_date: Date,
@@ -67,10 +65,6 @@ where
S: Storage,
<S as Storage>::StorageError: Send + Sync + 'static,
{
log::info!("Getting master verification key");
// this will also persist the key in the storage if was not there already
get_aggregate_verification_key(storage, epoch_id, apis.clone()).await?;
log::info!("Getting expiration date signatures");
// this will also persist the signatures in the storage if they were not there already
get_expiration_date_signatures(storage, epoch_id, expiration_date, apis.clone()).await?;
+2 -4
View File
@@ -16,7 +16,7 @@ use nym_credential_storage::models::RetrievedTicketbook;
use nym_credential_storage::storage::Storage;
use nym_credentials::ecash::bandwidth::CredentialSpendingData;
use nym_credentials_interface::{
AnnotatedCoinIndexSignature, AnnotatedExpirationDateSignature, VerificationKeyAuth,
AnnotatedCoinIndexSignature, AnnotatedExpirationDateSignature, NymPayInfo, VerificationKeyAuth,
};
use nym_ecash_time::Date;
use nym_validator_client::nym_api::EpochId;
@@ -165,9 +165,7 @@ impl<C, St: Storage> BandwidthController<C, St> {
.get_coin_index_signatures(epoch_id, &mut api_clients)
.await?;
let pay_info = retrieved_ticketbook
.ticketbook
.generate_pay_info(provider_pk);
let pay_info = NymPayInfo::generate(provider_pk);
let spend_request = retrieved_ticketbook.ticketbook.prepare_for_spending(
&verification_key,
@@ -455,7 +455,7 @@ where
Err(ClientCoreError::CustomGatewaySelectionExpected)
} else {
// and make sure to invalidate the task client so we wouldn't cause premature shutdown
shutdown.mark_as_success();
shutdown.disarm();
custom_gateway_transceiver.set_packet_router(packet_router)?;
Ok(custom_gateway_transceiver)
};
@@ -562,7 +562,7 @@ where
if topology_config.disable_refreshing {
// if we're not spawning the refresher, don't cause shutdown immediately
info!("The topology refesher is not going to be started");
shutdown.mark_as_success();
shutdown.disarm();
} else {
// don't spawn the refresher if we don't want to be refreshing the topology.
// only use the initial values obtained
@@ -474,13 +474,6 @@ where
Poll::Ready(Some((real_messages, conn_id))) => {
log::trace!("handling real_messages: size: {}", real_messages.len());
// This is the last step in the pipeline where we know the type of the message, so
// lets count the number of retransmissions here.
if conn_id == TransmissionLane::Retransmission {
self.stats_tx
.report(PacketStatisticsEvent::RetransmissionQueued);
}
// First store what we got for the given connection id
self.transmission_buffer.store(&conn_id, real_messages);
let real_next = self.pop_next_message().expect("we just added one");
+40 -18
View File
@@ -46,13 +46,34 @@ const MEASUREMENTS: usize = 3;
const CONN_TIMEOUT: Duration = Duration::from_millis(1500);
const PING_TIMEOUT: Duration = Duration::from_millis(1000);
struct GatewayWithLatency<'a> {
gateway: &'a gateway::Node,
// The abstraction that some of these helpers use
pub trait ConnectableGateway {
fn identity(&self) -> &identity::PublicKey;
fn clients_address(&self) -> String;
fn is_wss(&self) -> bool;
}
impl ConnectableGateway for gateway::Node {
fn identity(&self) -> &identity::PublicKey {
self.identity()
}
fn clients_address(&self) -> String {
self.clients_address()
}
fn is_wss(&self) -> bool {
self.clients_wss_port.is_some()
}
}
struct GatewayWithLatency<'a, G: ConnectableGateway> {
gateway: &'a G,
latency: Duration,
}
impl<'a> GatewayWithLatency<'a> {
fn new(gateway: &'a gateway::Node, latency: Duration) -> Self {
impl<'a, G: ConnectableGateway> GatewayWithLatency<'a, G> {
fn new(gateway: &'a G, latency: Duration) -> Self {
GatewayWithLatency { gateway, latency }
}
}
@@ -130,11 +151,14 @@ async fn connect(endpoint: &str) -> Result<WsConn, ClientCoreError> {
JSWebsocket::new(endpoint).map_err(|_| ClientCoreError::GatewayJsConnectionFailure)
}
async fn measure_latency(gateway: &gateway::Node) -> Result<GatewayWithLatency, ClientCoreError> {
async fn measure_latency<G>(gateway: &G) -> Result<GatewayWithLatency<G>, ClientCoreError>
where
G: ConnectableGateway,
{
let addr = gateway.clients_address();
trace!(
"establishing connection to {} ({addr})...",
gateway.identity_key,
gateway.identity(),
);
let mut stream = connect(&addr).await?;
@@ -177,7 +201,7 @@ async fn measure_latency(gateway: &gateway::Node) -> Result<GatewayWithLatency,
let count = results.len() as u64;
if count == 0 {
return Err(ClientCoreError::NoGatewayMeasurements {
identity: gateway.identity_key.to_base58_string(),
identity: gateway.identity().to_base58_string(),
});
}
@@ -187,11 +211,11 @@ async fn measure_latency(gateway: &gateway::Node) -> Result<GatewayWithLatency,
Ok(GatewayWithLatency::new(gateway, avg))
}
pub async fn choose_gateway_by_latency<R: Rng>(
pub async fn choose_gateway_by_latency<'a, R: Rng, G: ConnectableGateway + Clone>(
rng: &mut R,
gateways: &[gateway::Node],
gateways: &[G],
must_use_tls: bool,
) -> Result<gateway::Node, ClientCoreError> {
) -> Result<G, ClientCoreError> {
let gateways = filter_by_tls(gateways, must_use_tls)?;
info!(
@@ -223,21 +247,19 @@ pub async fn choose_gateway_by_latency<R: Rng>(
info!(
"chose gateway {} with average latency of {:?}",
chosen.gateway.identity_key, chosen.latency
chosen.gateway.identity(),
chosen.latency
);
Ok(chosen.gateway.clone())
}
fn filter_by_tls(
gateways: &[gateway::Node],
fn filter_by_tls<G: ConnectableGateway>(
gateways: &[G],
must_use_tls: bool,
) -> Result<Vec<&gateway::Node>, ClientCoreError> {
) -> Result<Vec<&G>, ClientCoreError> {
if must_use_tls {
let filtered = gateways
.iter()
.filter(|g| g.clients_wss_port.is_some())
.collect::<Vec<_>>();
let filtered = gateways.iter().filter(|g| g.is_wss()).collect::<Vec<_>>();
if filtered.is_empty() {
return Err(ClientCoreError::NoWssGateways);
@@ -70,8 +70,8 @@ impl PacketRouter {
Ok(())
}
pub fn mark_as_success(&mut self) {
self.shutdown.mark_as_success();
pub fn disarm(&mut self) {
self.shutdown.disarm();
}
}
@@ -113,8 +113,8 @@ impl PartiallyDelegatedRouter {
let return_res = match ret {
Err(err) => self.stream_return.send(Err(err)),
Ok(_) => {
self.packet_router.mark_as_success();
task_client.mark_as_success();
self.packet_router.disarm();
task_client.disarm();
self.stream_return.send(Ok(split_stream))
}
};
@@ -1,7 +1,6 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nyxd::cosmwasm_client::types::ExecuteResult;
use crate::nyxd::error::NyxdError;
use cosmrs::abci::TxMsgData;
use cosmrs::cosmwasm::MsgExecuteContractResponse;
@@ -10,6 +9,7 @@ use log::error;
use prost::bytes::Bytes;
use tendermint_rpc::endpoint::broadcast;
use crate::nyxd::cosmwasm_client::types::ExecuteResult;
pub use cosmrs::abci::MsgResponse;
pub fn parse_msg_responses(data: Bytes) -> Vec<MsgResponse> {
@@ -21,8 +21,7 @@ pub struct Log {
/// Searches in logs for the first event of the given event type and in that event
/// for the first attribute with the given attribute key.
#[deprecated]
pub fn find_attribute_in_logs<'a>(
pub fn find_attribute<'a>(
logs: &'a [Log],
event_type: &str,
attribute_key: &str,
@@ -36,7 +35,6 @@ pub fn find_attribute_in_logs<'a>(
}
/// Search for the proposal id in the given log. It'll be in the LAST wasm event, with attribute key "proposal_id"
#[deprecated]
pub fn find_proposal_id(logs: &[Log]) -> Result<u64, NyxdError> {
let maybe_attributes = logs
.iter()
@@ -1,24 +1,12 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::nyxd::cosmwasm_client::logs::Log;
use crate::nyxd::TxResponse;
use cosmrs::tendermint::abci;
pub use abci::Event;
// Searches in events for an event of the given event type which contains an
// attribute for with the given key.
pub fn find_tx_attribute(tx: &TxResponse, event_type: &str, attribute_key: &str) -> Option<String> {
find_event_attribute(&tx.tx_result.events, event_type, attribute_key)
}
pub fn find_event_attribute(
events: &[Event],
event_type: &str,
attribute_key: &str,
) -> Option<String> {
let event = events.iter().find(|e| e.kind == event_type)?;
let event = tx.tx_result.events.iter().find(|e| e.kind == event_type)?;
let attribute = event.attributes.iter().find(|&attr| {
if let Ok(key_str) = attr.key_str() {
key_str == attribute_key
@@ -28,23 +16,3 @@ pub fn find_event_attribute(
})?;
Some(attribute.value_str().ok().map(|str| str.to_string())).flatten()
}
pub fn find_attribute_value_in_logs_or_events(
logs: &[Log],
events: &[Event],
event_type: &str,
attribute_key: &str,
) -> Option<String> {
// if logs are empty, i.e. we're using post 0.50 code, parse the events instead
if !logs.is_empty() {
#[allow(deprecated)]
return crate::nyxd::cosmwasm_client::logs::find_attribute_in_logs(
logs,
event_type,
attribute_key,
)
.map(|attr| attr.value.clone());
}
find_event_attribute(events, event_type, attribute_key)
}
+4 -5
View File
@@ -7,10 +7,9 @@ license.workspace = true
[dependencies]
anyhow = { workspace = true }
base64 = { workspace = true }
base64 = "0.13.0"
bip39 = { workspace = true }
bs58 = { workspace = true }
colored = { workspace = true }
comfy-table = { workspace = true }
cfg-if = { workspace = true }
clap = { workspace = true, features = ["derive"] }
@@ -22,13 +21,13 @@ humantime-serde = { workspace = true }
inquire = { workspace = true }
k256 = { workspace = true, features = ["ecdsa", "sha256"] }
log = { workspace = true }
rand = { workspace = true, features = ["std"] }
rand = {version = "0.6", features = ["std"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
time = { workspace = true, features = ["parsing", "formatting"] }
tokio = { workspace = true, features = ["sync"] }
toml = { workspace = true }
tokio = { workspace = true, features = ["sync"]}
toml = "0.5.6"
url = { workspace = true }
tap = { workspace = true }
zeroize = { workspace = true }
@@ -9,17 +9,9 @@ use nym_credential_storage::initialise_persistent_storage;
use nym_id::import_credential;
use std::fs;
use std::path::PathBuf;
use std::str::FromStr;
#[derive(Debug, Clone)]
pub struct CredentialDataWrapper(Vec<u8>);
impl FromStr for CredentialDataWrapper {
type Err = bs58::decode::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
bs58::decode(s).into_vec().map(CredentialDataWrapper)
}
fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> {
bs58::decode(raw).into_vec()
}
#[derive(Debug, Parser)]
@@ -30,8 +22,8 @@ pub struct Args {
pub(crate) client_config: PathBuf,
/// Explicitly provide the encoded credential data (as base58)
#[clap(long, group = "cred_data")]
pub(crate) credential_data: Option<CredentialDataWrapper>,
#[clap(long, group = "cred_data", value_parser = parse_encoded_credential_data)]
pub(crate) credential_data: Option<Vec<u8>>,
/// Specifies the path to file containing binary credential data
#[clap(long, group = "cred_data")]
@@ -60,7 +52,7 @@ pub async fn execute(args: Args) -> anyhow::Result<()> {
let credentials_store = initialise_persistent_storage(credentials_store).await;
let raw_credential = match args.credential_data {
Some(data) => data.0,
Some(data) => data,
None => {
// SAFETY: one of those arguments must have been set
fs::read(args.credential_path.unwrap())?
@@ -9,9 +9,6 @@ use nym_credential_storage::initialise_persistent_storage;
use nym_credential_utils::utils;
use nym_credentials_interface::TicketType;
use nym_crypto::asymmetric::identity;
use rand::rngs::OsRng;
use rand::RngCore;
use std::fs::create_dir_all;
use std::path::PathBuf;
#[derive(Debug, Parser)]
@@ -21,20 +18,12 @@ pub struct Args {
pub(crate) ticketbook_type: TicketType,
/// Config file of the client that is supposed to use the credential.
#[clap(long, group = "output")]
pub(crate) client_config: Option<PathBuf>,
/// Path to the dedicated credential storage database
#[clap(long, group = "output")]
pub(crate) credential_storage: Option<PathBuf>,
#[clap(long)]
pub(crate) client_config: PathBuf,
}
async fn issue_client_ticketbook(
cfg: PathBuf,
typ: TicketType,
client: SigningClient,
) -> anyhow::Result<()> {
let loaded = CommonConfigsWrapper::try_load(cfg)?;
pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> {
let loaded = CommonConfigsWrapper::try_load(args.client_config)?;
if let Ok(id) = loaded.try_get_id() {
println!("loaded config file for client '{id}'");
@@ -59,40 +48,9 @@ async fn issue_client_ticketbook(
&client,
&persistent_storage,
&private_id_key.to_bytes(),
typ,
args.ticketbook_type,
)
.await?;
Ok(())
}
async fn issue_standalone_ticketbook(
credentials_store: PathBuf,
typ: TicketType,
client: SigningClient,
) -> anyhow::Result<()> {
println!("attempting to issue a standalone ticketbook");
let mut rng = OsRng;
let mut random_seed = [0u8; 32];
rng.fill_bytes(&mut random_seed);
if let Some(parent) = credentials_store.parent() {
create_dir_all(parent)?;
}
let persistent_storage = initialise_persistent_storage(credentials_store).await;
utils::issue_credential(&client, &persistent_storage, &random_seed, typ).await?;
Ok(())
}
pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> {
match (args.client_config, args.credential_storage) {
(Some(cfg), None) => issue_client_ticketbook(cfg, args.ticketbook_type, client).await,
(None, Some(storage)) => {
issue_standalone_ticketbook(storage, args.ticketbook_type, client).await
}
_ => unreachable!("clap should have made this branch impossible to reach!"),
}
}
@@ -3,7 +3,6 @@
use clap::{Args, Subcommand};
pub mod generate_ticket;
pub mod import_ticket_book;
pub mod issue_ticket_book;
pub mod recover_ticket_book;
@@ -20,5 +19,4 @@ pub enum EcashCommands {
IssueTicketBook(issue_ticket_book::Args),
RecoverTicketBook(recover_ticket_book::Args),
ImportTicketBook(import_ticket_book::Args),
GenerateTicket(generate_ticket::Args),
}
@@ -1,178 +0,0 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::utils::CommonConfigsWrapper;
use anyhow::{anyhow, bail};
use clap::Parser;
use colored::Colorize;
use comfy_table::Table;
use nym_credential_storage::initialise_persistent_storage;
use nym_credential_storage::storage::Storage;
use nym_credentials::ecash::bandwidth::serialiser::VersionedSerialise;
use std::path::PathBuf;
#[derive(Debug, Parser)]
pub struct Args {
/// Specify the index of the ticket to retrieve from the ticketbook.
/// By default, the current unspent value is used.
#[clap(long, group = "output")]
pub(crate) ticket_index: Option<u64>,
/// Specify whether we should display payments for ALL available tickets
#[clap(long, group = "output")]
pub(crate) full: bool,
/// Base58-encoded identity of the provider (must be 32 bytes long)
#[clap(long)]
pub(crate) provider: String,
/// Config file of the client that is supposed to use the credential.
#[clap(long, group = "source")]
pub(crate) client_config: Option<PathBuf>,
/// Path to the dedicated credential storage database
#[clap(long, group = "source")]
pub(crate) credential_storage: Option<PathBuf>,
}
pub async fn execute(args: Args) -> anyhow::Result<()> {
let credentials_store = if let Some(explicit) = args.credential_storage {
explicit
} else {
// SAFETY: at least one of them MUST HAVE been specified
let cfg = args.client_config.unwrap();
let loaded = CommonConfigsWrapper::try_load(cfg)?;
if let Ok(id) = loaded.try_get_id() {
println!("loaded config file for client '{id}'");
}
let Ok(credentials_store) = loaded.try_get_credentials_store() else {
bail!("the loaded config does not have a credentials store information")
};
credentials_store
};
let decoded_provider = bs58::decode(&args.provider).into_vec()?;
if decoded_provider.len() != 32 {
bail!("the provided provider information is malformed")
}
let provider_arr: [u8; 32] = decoded_provider.try_into().unwrap();
let persistent_storage = initialise_persistent_storage(&credentials_store).await;
let Some(mut next_ticketbook) = persistent_storage
.get_next_unspent_usable_ticketbook(0)
.await?
else {
bail!(
"there are no valid ticketbooks in the storage at {}",
credentials_store.display()
)
};
let epoch_id = next_ticketbook.ticketbook.epoch_id();
let expiration_date = next_ticketbook.ticketbook.expiration_date();
let verification_key = persistent_storage
.get_master_verification_key(epoch_id)
.await?
.ok_or_else(|| {
anyhow!("ticketbook got incorrectly imported - the master verification key is missing")
})?;
let expiration_signatures = persistent_storage
.get_expiration_date_signatures(expiration_date)
.await?
.ok_or_else(|| {
anyhow!(
"ticketbook got incorrectly imported - the expiration date signatures are missing"
)
})?;
let coin_indices_signatures = persistent_storage
.get_coin_index_signatures(epoch_id)
.await?
.ok_or_else(|| {
anyhow!("ticketbook got incorrectly imported - the coin index signatures are missing")
})?;
let ticketbook_data = next_ticketbook.ticketbook.pack();
let next_ticket = args
.ticket_index
.unwrap_or(next_ticketbook.ticketbook.spent_tickets());
let pay_info = next_ticketbook.ticketbook.generate_pay_info(provider_arr);
println!("{}", "TICKETBOOK DATA:".bold());
println!("{}", bs58::encode(&ticketbook_data.data).into_string());
println!();
// display it only for a single ticket
if !args.full {
println!("attempting to generate payment for ticket {next_ticket}...");
println!();
next_ticketbook.ticketbook.update_spent_tickets(next_ticket);
let req = next_ticketbook.ticketbook.prepare_for_spending(
&verification_key,
pay_info.into(),
&coin_indices_signatures,
&expiration_signatures,
1,
)?;
let payment = req.payment;
println!("{}", format!("PAYMENT FOR TICKET {next_ticket}: ").bold());
println!("{}", bs58::encode(&payment.to_bytes()).into_string());
return Ok(());
}
println!(
"generating payment information for {} tickets. this might take a while!...",
next_ticketbook.ticketbook.params_total_tickets()
);
// otherwise generate all the payments
let last_spent = next_ticketbook.ticketbook.spent_tickets();
let mut table = Table::new();
table.set_header(vec!["index", "binary data", "spend status"]);
for i in 0..next_ticketbook.ticketbook.params_total_tickets() {
let status = if i < last_spent {
"SPENT".red()
} else {
"NOT SPENT".green()
};
next_ticketbook.ticketbook.update_spent_tickets(i);
let req = next_ticketbook.ticketbook.prepare_for_spending(
&verification_key,
pay_info.into(),
&coin_indices_signatures,
&expiration_signatures,
1,
)?;
let payment = req.payment;
let payment_bytes = payment.to_bytes();
let len = payment_bytes.len();
let display_size = 100;
let remaining = len - display_size;
table.add_row(vec![
i.to_string(),
format!(
"{}{remaining}bytes remaining",
bs58::encode(&payment_bytes[..display_size]).into_string()
),
status.to_string(),
]);
}
println!("{}", "AVAILABLE TICKETS".bold());
println!("{table}");
Ok(())
}
+1 -1
View File
@@ -1,7 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod coconut;
pub mod context;
pub mod ecash;
pub mod utils;
pub mod validator;
@@ -10,11 +10,7 @@ pub struct Args {
}
pub fn decode_mixnode_key(args: Args) {
use base64::{engine::general_purpose::STANDARD, Engine as _};
let b64_decoded = STANDARD
.decode(args.key)
.expect("failed to decode base64 string");
let b64_decoded = base64::decode(args.key).expect("failed to decode base64 string");
let b58_encoded = bs58::encode(&b64_decoded).into_string();
println!("{b58_encoded}")
+11 -5
View File
@@ -3,7 +3,9 @@
use crate::errors::{Error, Result};
use log::*;
use nym_bandwidth_controller::acquire::{get_ticket_book, query_and_persist_required_global_data};
use nym_bandwidth_controller::acquire::{
get_ticket_book, query_and_persist_required_global_signatures,
};
use nym_client_core::config::disk_persistence::CommonClientPaths;
use nym_config::DEFAULT_DATA_DIR;
use nym_credential_storage::persistent_storage::PersistentStorage;
@@ -43,10 +45,14 @@ where
let apis = all_ecash_api_clients(client, epoch_id).await?;
let ticketbook_expiration = ecash_default_expiration_date();
// make sure we have all required coin indices and expiration date signatures alongside the master verification key
// before attempting the deposit
query_and_persist_required_global_data(storage, epoch_id, ticketbook_expiration, apis.clone())
.await?;
// make sure we have all required coin indices and expiration date signatures before attempting the deposit
query_and_persist_required_global_signatures(
storage,
epoch_id,
ticketbook_expiration,
apis.clone(),
)
.await?;
let issuance_data = nym_bandwidth_controller::acquire::make_deposit(
client,
@@ -6,7 +6,7 @@ use crate::ecash::bandwidth::CredentialSpendingData;
use crate::ecash::utils::ecash_today;
use crate::error::Error;
use nym_credentials_interface::{
CoinIndexSignature, ExpirationDateSignature, NymPayInfo, PayInfo, SecretKeyUser, TicketType,
CoinIndexSignature, ExpirationDateSignature, PayInfo, SecretKeyUser, TicketType,
VerificationKeyAuth, Wallet, WalletSignatures,
};
use nym_ecash_time::EcashTime;
@@ -114,10 +114,6 @@ impl IssuedTicketBook {
&self.signatures_wallet
}
pub fn generate_pay_info(&self, provider_pk: [u8; 32]) -> NymPayInfo {
NymPayInfo::generate(provider_pk)
}
pub fn prepare_for_spending<BI, BE>(
&mut self,
verification_key: &VerificationKeyAuth,
+2 -5
View File
@@ -37,13 +37,10 @@ impl BandwidthManager {
}
/// Creates a new bandwidth entry for the particular client.
pub(crate) async fn insert_new_client_if_doesnt_exist(
&self,
client_id: i64,
) -> Result<(), sqlx::Error> {
pub(crate) async fn insert_new_client(&self, client_id: i64) -> Result<(), sqlx::Error> {
// FIXME: hack; we need to change api slightly
sqlx::query!(
"INSERT OR IGNORE INTO available_bandwidth(client_id, available, expiration) VALUES (?, 0, ?)",
"INSERT INTO available_bandwidth(client_id, available, expiration) VALUES (?, 0, ?)",
client_id,
OffsetDateTime::UNIX_EPOCH,
)
+1 -23
View File
@@ -35,13 +35,6 @@ pub trait Storage: Send + Sync {
client_address: DestinationAddressBytes,
) -> Result<i64, StorageError>;
/// Creates all relevant database entries for the newly registered client
async fn insert_new_client(
&self,
client_address: DestinationAddressBytes,
shared_keys: &SharedKeys,
) -> Result<i64, StorageError>;
/// Inserts provided derived shared keys into the database.
/// If keys previously existed for the provided client, they are overwritten with the new data.
///
@@ -329,19 +322,6 @@ impl Storage for PersistentStorage {
.await?)
}
async fn insert_new_client(
&self,
client_address: DestinationAddressBytes,
shared_keys: &SharedKeys,
) -> Result<i64, StorageError> {
let id = self.insert_shared_keys(client_address, shared_keys).await?;
self.bandwidth_manager
.insert_new_client_if_doesnt_exist(id)
.await?;
Ok(id)
}
async fn insert_shared_keys(
&self,
client_address: DestinationAddressBytes,
@@ -410,9 +390,7 @@ impl Storage for PersistentStorage {
}
async fn create_bandwidth_entry(&self, client_id: i64) -> Result<(), StorageError> {
self.bandwidth_manager
.insert_new_client_if_doesnt_exist(client_id)
.await?;
self.bandwidth_manager.insert_new_client(client_id).await?;
Ok(())
}
+1 -1
View File
@@ -57,7 +57,7 @@ impl PacketListener {
// cloning the arc as each accepted socket is handled in separate task
let connection_handler = Arc::clone(&self.connection_handler);
let mut handler_shutdown_listener = self.shutdown.clone();
handler_shutdown_listener.mark_as_success();
handler_shutdown_listener.disarm();
tokio::select! {
socket = listener.accept() => {
+1 -1
View File
@@ -245,7 +245,7 @@ impl VerlocMeasurer {
}
let mut shutdown_listener = self.shutdown_listener.clone().named("VerlocMeasurement");
shutdown_listener.mark_as_success();
shutdown_listener.disarm();
for chunk in nodes_to_test.chunks(self.config.tested_nodes_batch_size) {
let mut chunk_results = Vec::with_capacity(chunk.len());
+1 -1
View File
@@ -84,7 +84,7 @@ impl PacketSender {
tested_node: TestedNode,
) -> Result<VerlocMeasurement, RttError> {
let mut shutdown_listener = self.shutdown_listener.fork(tested_node.address.to_string());
shutdown_listener.mark_as_success();
shutdown_listener.disarm();
let mut conn = match tokio::time::timeout(
self.connection_timeout,
@@ -218,7 +218,7 @@ impl SocksClient {
packet_type: Option<PacketType>,
) -> Self {
// If this task fails and exits, we don't want to send shutdown signal
shutdown_listener.mark_as_success();
shutdown_listener.disarm();
let connection_id = Self::generate_random();
@@ -294,7 +294,7 @@ impl SocksClient {
.shutdown()
.await
.map_err(|source| SocksProxyError::SocketShutdownFailure { source })?;
self.shutdown_listener.mark_as_success();
self.shutdown_listener.disarm();
Ok(())
}
@@ -172,6 +172,6 @@ where
trace!("{} - inbound closed", connection_id);
shutdown_notify.notify_one();
shutdown_listener.mark_as_success();
shutdown_listener.disarm();
reader
}
@@ -148,7 +148,7 @@ where
}
pub fn into_inner(mut self) -> (TcpStream, ConnectionReceiver) {
self.shutdown_listener.mark_as_success();
self.shutdown_listener.disarm();
(
self.socket.take().unwrap(),
self.mix_receiver.take().unwrap(),
@@ -90,6 +90,6 @@ pub(super) async fn run_outbound(
trace!("{} - outbound closed", connection_id);
shutdown_notify.notify_one();
shutdown_listener.mark_as_success();
shutdown_listener.disarm();
(writer, mix_receiver)
}
+1 -5
View File
@@ -470,12 +470,8 @@ impl TaskClient {
// This listener should to *not* notify the ShutdownNotifier to shutdown when dropped. For
// example when we clone the listener for a task handling connections, we often want to drop
// without signal failure.
pub fn mark_as_success(&mut self) {
self.mode.set_should_not_signal_on_drop();
}
pub fn disarm(&mut self) {
self.mark_as_success();
self.mode.set_should_not_signal_on_drop();
}
pub fn send_we_stopped(&mut self, err: SentError) {
+1 -2
View File
@@ -12,7 +12,6 @@ license.workspace = true
[dependencies]
base64 = { workspace = true }
dashmap = { workspace = true }
log = { workspace = true }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
@@ -35,7 +34,7 @@ x25519-dalek = { workspace = true, features = ["static_secrets"] }
[dev-dependencies]
rand = "0.8.5"
nym-crypto = { path = "../crypto", features = ["rand"]}
nym-crypto = { path = "../crypto", features = ["rand"] }
[features]
+7
View File
@@ -6,10 +6,17 @@ pub mod error;
pub mod public_key;
pub mod registration;
use std::time::Duration;
pub use config::Config;
pub use error::Error;
pub use public_key::PeerPublicKey;
pub use registration::{ClientMac, ClientMessage, GatewayClient, InitMessage, Nonce};
// To avoid any problems, keep this stale check time bigger (>2x) then the bandwidth cap
// reset time (currently that one is 24h, at UTC midnight)
pub const DEFAULT_PEER_TIMEOUT: Duration = Duration::from_secs(60 * 60 * 24 * 3); // 3 days
pub const DEFAULT_PEER_TIMEOUT_CHECK: Duration = Duration::from_secs(5); // 5 seconds
#[cfg(feature = "verify")]
pub use registration::HmacSha256;
+3 -3
View File
@@ -4,8 +4,8 @@
use crate::error::Error;
use crate::PeerPublicKey;
use base64::{engine::general_purpose, Engine};
use dashmap::DashMap;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::net::IpAddr;
use std::time::SystemTime;
use std::{fmt, ops::Deref, str::FromStr};
@@ -17,8 +17,8 @@ use nym_crypto::asymmetric::encryption::PrivateKey;
#[cfg(feature = "verify")]
use sha2::Sha256;
pub type PendingRegistrations = DashMap<PeerPublicKey, RegistrationData>;
pub type PrivateIPs = DashMap<IpAddr, Taken>;
pub type PendingRegistrations = HashMap<PeerPublicKey, RegistrationData>;
pub type PrivateIPs = HashMap<IpAddr, Taken>;
#[cfg(feature = "verify")]
pub type HmacSha256 = Hmac<Sha256>;
+16 -15
View File
@@ -5,19 +5,15 @@ use chrono::{Timelike, Utc};
use defguard_wireguard_rs::{host::Peer, key::Key, WireguardInterfaceApi};
use nym_gateway_storage::Storage;
use nym_wireguard_types::registration::{RemainingBandwidthData, BANDWIDTH_CAP_PER_DAY};
use nym_wireguard_types::{DEFAULT_PEER_TIMEOUT, DEFAULT_PEER_TIMEOUT_CHECK};
use std::time::SystemTime;
use std::{collections::HashMap, sync::Arc, time::Duration};
use std::{collections::HashMap, sync::Arc};
use tokio::sync::mpsc;
use tokio_stream::{wrappers::IntervalStream, StreamExt};
use crate::error::Error;
use crate::WgApiWrapper;
// To avoid any problems, keep this stale check time bigger (>2x) then the bandwidth cap
// reset time (currently that one is 24h, at UTC midnight)
const DEFAULT_PEER_TIMEOUT: Duration = Duration::from_secs(60 * 60 * 24 * 3); // 3 days
const DEFAULT_PEER_TIMEOUT_CHECK: Duration = Duration::from_secs(60); // 1 minute
pub enum PeerControlRequest {
AddPeer(Peer),
RemovePeer(Key),
@@ -50,6 +46,7 @@ pub struct PeerController<St: Storage> {
active_peers: HashMap<Key, Peer>,
suspended_peers: HashMap<Key, Peer>,
last_seen_bandwidth: HashMap<Key, u64>,
timeout_count: u8,
}
impl<St: Storage> PeerController<St> {
@@ -64,19 +61,14 @@ impl<St: Storage> PeerController<St> {
let timeout_check_interval = tokio_stream::wrappers::IntervalStream::new(
tokio::time::interval(DEFAULT_PEER_TIMEOUT_CHECK),
);
let active_peers: HashMap<Key, Peer> = peers
let active_peers = peers
.into_iter()
.map(|peer| (peer.public_key.clone(), peer))
.collect();
let suspended_peers: HashMap<Key, Peer> = suspended_peers
let suspended_peers = suspended_peers
.into_iter()
.map(|peer| (peer.public_key.clone(), peer))
.collect();
let last_seen_bandwidth = active_peers
.iter()
.map(|(k, p)| (k.clone(), p.rx_bytes + p.tx_bytes))
.chain(suspended_peers.keys().map(|k| (k.clone(), 0)))
.collect();
PeerController {
storage,
@@ -86,7 +78,8 @@ impl<St: Storage> PeerController<St> {
timeout_check_interval,
active_peers,
suspended_peers,
last_seen_bandwidth,
last_seen_bandwidth: HashMap::new(),
timeout_count: 0,
}
}
@@ -149,6 +142,15 @@ impl<St: Storage> PeerController<St> {
.iter()
.map(|(key, peer)| (key.clone(), peer.rx_bytes + peer.tx_bytes))
.collect();
// Do in-memory updates of bandwidth every DEFAULT_PEER_TIMEOUT_CHECK
// and storage updates every 5 * DEFAULT_PEER_TIMEOUT_CHECK, because in-memory
// is more important for client query preciseness
self.timeout_count = self.timeout_count % 5 + 1;
if !reset && self.timeout_count < 5 {
return Ok(());
}
if reset {
self.active_peers = host.peers;
for peer in self.active_peers.values() {
@@ -197,7 +199,6 @@ impl<St: Storage> PeerController<St> {
log::error!("Could not configure peer: {:?}", e);
false
} else {
self.last_seen_bandwidth.insert(peer.public_key.clone(), peer.rx_bytes + peer.tx_bytes);
self.active_peers.insert(peer.public_key.clone(), peer);
true
};
+8
View File
@@ -108,3 +108,11 @@ copy-js = true # include Javascript code for search
[output.linkcheck]
warning-policy = "warn"
[output.html.redirect]
"/faq/general-faq.html" = "https://nymtech.net/developers/faq/integrations-faq.html"
"/tutorials/simple-service-provider/user-client.html" = "https://nymtech.net/developers/examples/custom-services.html"
"/quickstart/socks-proxy.html" = "https://nymtech.net/developers/clients/socks5/setup.html"
"/tutorials/matrix.html" = "https://nymtech.net/developers/archive/nym-connect.html#matrix-element-via-nymconnect"
"/tutorials/monero.html" = "https://nymtech.net/developers/archive/nym-connect.html#monero-wallet-via-nymconnect"
"/tutorials/telegram.html" = "https://nymtech.net/developers/archive/nym-connect.html#telegram-via-nymconnect"
+7 -2
View File
@@ -2,7 +2,7 @@
- [Introduction](introduction.md)
- [Clients Overview - Start Here!](clients-overview.md)
# SDKs
# SDKs
- [Rust SDK](sdk/rust/rust.md)
- [Message Types](sdk/rust/message-types.md)
- [Message Helpers](sdk/rust/message-helpers.md)
@@ -30,7 +30,7 @@
- [Using Your Client](clients/websocket/usage.md)
- [Examples](clients/websocket/examples.md)
- [Socks5 Client](clients/socks5-client.md)
- [Setup & Run](clients/socks5/setup.md)
- [Setup & Run](clients/socks5/setup.md)
- [Using Your Client](clients/socks5/usage.md)
- [Webassembly Client](clients/webassembly-client.md)
@@ -54,8 +54,13 @@
# User Manuals
- [NymVPN alpha](nymvpn/intro.md)
- [CLI](nymvpn/cli.md)
---
# Archive
- [NymConnect Setup](archive/nym-connect.md)
---
# Misc.
- [Code of Conduct](coc.md)
- [Licensing](licensing.md)
@@ -0,0 +1,85 @@
# Archive page: NymConnect Setup
```admonish warning
Since the beginning of 2024 NymConnect is no longer maintained. Nym is developing a new client called [NymVPN](https://nymvpn.com), an application routing all users traffic thorugh the mixnet.
If users want to route their traffic through socks5 we advice to use maintained [Nym Socks5 Client](../clients/socks5/setup.md).
```
In case you want to run deprecated NymConnect, follow these steps:
1. Navigate to our [Github repository](https://github.com/nymtech/nym/releases?q=nym-connect&expanded=true) and download NymConnect binary
2. On Linux and Mac, make executable by opening terminal in the same directory and run:
```sh
chmod +x ./nym-connect_<VERSION>.AppImage
```
1. Start the application
2. Click on `Connect` button to initialise the connection with the Mixnet
3. Anytime you'll need to setup Host and Port in your applications, click on `IP` and `Port` to copy the values to clipboard
4. In case you have problems such as `Gateway Issues`, try to reconnect or restart the application
## Connect Privacy Enhanced Applications (PEApps)
Here are some examples of applications which will work behind Socks5 proxy (`nym-socks5-client` or deprecated NymConnect), to enhance users privacy.
### Electrum Bitcoin wallet via NymConnect
To download Electrum visit the [official webpage](https://electrum.org/#download). To connect to the Mixnet follow these steps:
1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md))
2. Start your Electrum Bitcoin wallet
3. Go to: *Tools* -> *Network* -> *Proxy*
4. Set *Use proxy* to ✅, choose `SOCKS5` from the drop-down and add (copy-paste) the values from your NymConnect application
5. Now your Electrum Bitcoin wallet runs through the Mixnet and it will be connected only if your NymConnect or `nym-socks5-client` are connected.
![Electrum Bitcoin wallet setup](../images/electrum_tutorial/electrum.gif)
### Monero wallet via NymConnect
To download Monero wallet visit [getmonero.org](https://www.getmonero.org/downloads/). To connect to the Mixnet follow these steps:
1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md))
2. Start your Monero wallet
3. Go to: *Settings* -> *Interface* -> *Socks5 proxy* -> Add values: IP address `127.0.0.1`, Port `1080` (the values copied from NymConnect)
5. Now your Monero wallet runs through the Mixnet and it will be connected only if your NymConnect or `nym-socks5-client` are connected.
![Monero wallet setup](../images/monero_tutorial/monero-gui-NC.gif)
### Matrix (Element) via NymConnect
To download Element (chat client for Matrix) visit [element.io](https://element.io/download). To connect to the Mixnet follow these steps:
1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md))
2. Start `element-desktop` with `--proxy-server` argument:
**Linux**
```sh
element-desktop --proxy-server=socks5://127.0.0.1:1080
```
**Mac**
```sh
open -a Element --args --proxy-server=socks5://127.0.0.1:1080
```
To make the start of Element over NymConnect simplier, you can add this command to your key-binding shortcuts in your system settings.
### Telegram via NymConnect
1. Start and connect NymConnect (or [`nym-socks5-client`](../clients/socks5/setup.md))
2. Start your Telegram chat application
3. Open the Telegram proxy settings.
- Linux: *Settings* -> *Advanced* -> *Connection type* -> *Use custom proxy*
- MacOS: *Settings* -> *Advanced* -> *Data & Storage* -> *Connection Type* -> *Use custom Proxy*
- Windows: *Settings* -> *Data and Storage* -> *Use proxy*
4. Add a proxy with the *Add proxy button*.
5. Select *SOCKS5* and make sure the port details are the same as those generated by NymConnect. Alternatively, follow this link: [https://t.me/socks?server=127.0.0.1&port=1080](https://t.me/socks?server=127.0.0.1&port=1080)
6. *Save the proxy settings* in Telegram.
7. Telegram is now running through the Nym Mixnet and is privacy-enhanced! This allows you to connect from regions which blocked Telegram.
8. Note if you remain idle on Telegram for a while you might lose connectivity and your messages might not get through via SOCKS5 proxy. If that happens reconnect your NymConnect and reset the proxy again.
Follow this [video](https://youtu.be/quj8H2qeOwY?t=97) to see the steps on Telegram setup.
@@ -52,10 +52,10 @@ git checkout master # master branch has the latest release version: `develop` wi
cargo build --release # build your binaries with **mainnet** configuration
```
Quite a bit of stuff gets built. The key working parts for devs are the Client binaries and the CLI tool:
Quite a bit of stuff gets built. The key working parts for devs are the Client binaries and the CLI tool:
* [websocket client](../clients/websocket-client.md): `nym-client`
* [socks5 client](../clients/socks5-client.md): `nym-socks5-client`
* [nym-cli tool](https://nymtech.net/docs/tools/nym-cli.md): `nym-cli`
* [nym-cli tool](https://nymtech.net/docs/tools/nym-cli.html): `nym-cli`
> You cannot build from GitHub's .zip or .tar.gz archive files on the releases page - the Nym build scripts automatically include the current git commit hash in the built binary during compilation, so the build will fail if you use the archive code (which isn't a Git repository). Check the code out from github using `git clone` instead.
@@ -60,7 +60,7 @@ There are 2 pieces of software that work together to send SOCKS traffic through
The `nym-socks5-client` allows you to do the following from your local machine:
* Take a TCP data stream from a application that can send traffic via SOCKS5.
* Chop up the TCP stream into multiple Sphinx packets, assigning sequence numbers to them, while leaving the TCP connection open for more data
* Send the Sphinx packets through the mixnet to a [network requester](https://nymtech.net/operators/nodes/network-requester.md). Packets are shuffled and mixed as they transit the mixnet.
* Send the Sphinx packets through the Nym Network. Packets are shuffled and mixed as they transit the mixnet.
The `nym-network-requester` then reassembles the original TCP stream using the packets' sequence numbers, and make the intended request. It will then chop up the response into Sphinx packets and send them back through the mixnet to your `nym-socks5-client`. The application will then receive its data, without even noticing that it wasn't talking to a "normal" SOCKS5 proxy!
@@ -104,8 +104,6 @@ The `--use-reply-surbs` field denotes whether you wish to send [SURBs](https://n
The `--provider` field needs to be filled with the Nym address of a Network Requester that can make network requests on your behalf. If you don't want to [run your own](https://nymtech.net/operators/nodes/network-requester.md) you can select one from the [mixnet explorer](https://explorer.nymtech.net/network-components/service-providers) by copying its `Client ID` and using this as the value of the `--provider` flag. Alternatively, you could use [this list](https://harbourmaster.nymtech.net/).
Since the nodes on this list are the infrastructure for [Nymconnect](https://nymtech.net/developers/quickstart/nymconnect-gui.html) they will support all apps on the [default whitelist](https://nymtech.net/operators/nodes/network-requester.md#network-requester-whitelist): Keybase, Telegram, Electrum, Blockstream Green, and Helios.
#### Choosing a Gateway
By default - as in the example above - your client will choose a random gateway to connect to.
@@ -1,9 +1,14 @@
# Setup
# Setup
> `nym-socks5-client` now also supports SOCKS4 and SOCKS4A protocols as well as SOCKS5.
The Nym socks5 client allows you to proxy traffic from a desktop application through the mixnet, meaning you can send and receive information from remote application servers without leaking metadata which can be used to deanonymise you, even if you're using an encrypted application such as Signal.
```admonish info
Since the beginning of 2024 NymConnect is no longer maintained. Nym is developing a new client called [NymVPN](https://nymvpn.com), an application routing all users traffic thorugh the mixnet.
If users want to route their traffic through socks5 we advice to use this client. If you want to run deprecated NymConnect, visit [NymConnect archive page](../../archive/nym-connect.md) with setup and application examples.
```
## Setup and Run
### Download or compile socks5 client
@@ -38,5 +43,3 @@ Now your client is initialised, start it with the following:
```
./nym-socks5-client run --id <ID>
```
@@ -12,4 +12,6 @@ All of these code examples will do the following:
By varying the message content, you can easily build sophisticated service provider apps. For example, instead of printing the response received from the mixnet, your service provider might take some action on behalf of the user - perhaps initiating a network request, a blockchain transaction, or writing to a local data store.
<!-- THIS PAGE IS NOT WORKING AT THE MOMENT:
> You can find an example of building both frontend and service provider code with the websocket client in the [Simple Service Provider Tutorial](https://nymtech.net/developers/tutorials/simple-service-provider/simple-service-provider.html) in the Developer Portal.
-->
@@ -1,17 +1,17 @@
# Using Your Client
The Nym native client exposes a websocket interface that your code connects to. The **default** websocket port is `1977`, you can override that in the client config if you want.
Once you have a websocket connection, interacting with the client involves piping messages down the socket and listening for incoming messages.
Once you have a websocket connection, interacting with the client involves piping messages down the socket and listening for incoming messages.
# Message Requests
There are a number of message types that you can send up the websocket as defined [here](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/requests.rs):
# Message Requests
There are a number of message types that you can send up the websocket as defined [here](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/requests.rs):
```rust,noplayground
{{#include ../../../../../clients/native/websocket-requests/src/requests.rs:55:97}}
```
## Getting your own address
When you start your app, it is best practice to ask the native client to tell you what your own address is (from the generated configuration files - see [here](https://nymtech.net/docs/architecture/addressing-system.md) for more on Nym's addressing scheme). If you are running a service, you need to do this in order to know what address to give others. In a client-side piece of code you can also use this as a test to make sure your websocket connection is running smoothly. To do this, send:
When you start your app, it is best practice to ask the native client to tell you what your own address is (from the generated configuration files <!--add link -->. If you are running a service, you need to do this in order to know what address to give others. In a client-side piece of code you can also use this as a test to make sure your websocket connection is running smoothly. To do this, send:
```json
{
@@ -28,9 +28,9 @@ You'll receive a response of the format:
}
```
See [here](https://github.com/nymtech/nym/blob/93cc281abc2cc951023b51746fa6f2ead1f56c46/clients/native/examples/python-examples/websocket/textsend.py#L16C9-L16C9) for an example of this being used.
See [here](https://github.com/nymtech/nym/blob/93cc281abc2cc951023b51746fa6f2ead1f56c46/clients/native/examples/python-examples/websocket/textsend.py#L16C9-L16C9) for an example of this being used.
> Note that all the pieces of native client example code begin with printing the selfAddress. Examples exist for Rust, Go, Javascript, and Python.
> Note that all the pieces of native client example code begin with printing the selfAddress. Examples exist for Rust, Go, Javascript, and Python.
## Sending text
If you want to send text information through the mixnet, format a message like this one and poke it into the websocket:
@@ -58,33 +58,33 @@ In some applications, e.g. where people are chatting with friends who they know,
**If that fits your security model, good. However, will probably be the case that you want to send anonymous replies using Single Use Reply Blocks (SURBs)**.
You can read more about SURBs [here](https://nymtech.net/docs/architecture/traffic-flow.md#private-replies-using-surbs) but in short they are ways for the receiver of this message to anonymously reply to you - the sender - **without them having to know your client address**.
You can read more about SURBs [here](https://nymtech.net/docs/architecture/traffic-flow.html#private-replies-using-surbs) but in short they are ways for the receiver of this message to anonymously reply to you - the sender - **without them having to know your client address**.
Your client will send along a number of `replySurbs` to the recipient of the message. These are pre-addressed Sphinx packets that the recipient can write to the payload of (i.e. write response data to), but not view the final destination of. If the recipient is unable to fit the response data into the bucket of SURBs sent to it, it will use a SURB to request more SURBs be sent to it from your client.
```json
{
"type": "sendAnonymous",
"message": "something you want to keep secret",
"recipient": "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm",
"message": "something you want to keep secret",
"recipient": "71od3ZAupdCdxeFNg8sdonqfZTnZZy1E86WYKEjxD4kj@FWYoUrnKuXryysptnCZgUYRTauHq4FnEFu2QGn5LZWbm",
"replySurbs": 20 // however many reply SURBs to send along with your message
}
```
See ['Replying to SURB Messages'](#replying-to-surb-messages) below for an example of how to deal with incoming messages that have SURBs attached.
See ['Replying to SURB Messages'](#replying-to-surb-messages) below for an example of how to deal with incoming messages that have SURBs attached.
Deciding on the amount of SURBs to generate and send along with outgoing messages depends on the expected size of the reply. You might want to send a lot of SURBs in order to make sure you get your response as quickly as possible (but accept the minor additional latency when sending, as your client has to generate and encrypt the packets), or you might just send a few (e.g. 20) and then if your response requires more SURBs, send them along, accepting the additional latency in getting your response.
Deciding on the amount of SURBs to generate and send along with outgoing messages depends on the expected size of the reply. You might want to send a lot of SURBs in order to make sure you get your response as quickly as possible (but accept the minor additional latency when sending, as your client has to generate and encrypt the packets), or you might just send a few (e.g. 20) and then if your response requires more SURBs, send them along, accepting the additional latency in getting your response.
## Sending binary data
You can also send bytes instead of JSON. For that you have to send a binary websocket frame containing a binary encoded
Nym [`ClientRequest`](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/requests.rs#L25) containing the same information.
> As a response the `native-client` will send a `ServerResponse` to be decoded. See [Message Responses](#message-responses) below for more.
> As a response the `native-client` will send a `ServerResponse` to be decoded. See [Message Responses](#message-responses) below for more.
You can find examples of sending and receiving binary data in the [code examples](https://github.com/nymtech/nym/tree/master/clients/native/examples), and an example project from the Nym community [BTC-BC](https://github.com/sgeisler/btcbc-rs/): Bitcoin transaction transmission via Nym, a client and service provider written in Rust.
## Replying to SURB messages
Each bucket of `replySURBs`, when received as part of an incoming message, has a unique session identifier, which **only identifies the bucket of pre-addressed packets**. This is necessary to make sure that your app is replying to the correct people with the information meant for them in a situation where multiple clients are sending requests to a single service.
Each bucket of `replySURBs`, when received as part of an incoming message, has a unique session identifier, which **only identifies the bucket of pre-addressed packets**. This is necessary to make sure that your app is replying to the correct people with the information meant for them in a situation where multiple clients are sending requests to a single service.
Constructing a reply with SURBs looks something like this (where `senderTag` was parsed from the incoming message)
@@ -107,9 +107,9 @@ Errors from the app's client, or from the gateway, will be sent down the websock
```
## LaneQueueLength
This is currently only used in the [Socks Client](../socks5-client.md) to keep track of the number of Sphinx packets waiting to be sent to the mixnet via being slotted amongst cover traffic. As this value becomes larger, the client signals to the application it should slow down the speed with which it writes to the proxy. This is to stop situations arising whereby an app connected to the client appears as if it has sent (e.g.) a bunch of messages and is awaiting a reply, when they in fact have not been sent through the mixnet yet.
This is currently only used in the [Socks Client](../socks5-client.md) to keep track of the number of Sphinx packets waiting to be sent to the mixnet via being slotted amongst cover traffic. As this value becomes larger, the client signals to the application it should slow down the speed with which it writes to the proxy. This is to stop situations arising whereby an app connected to the client appears as if it has sent (e.g.) a bunch of messages and is awaiting a reply, when they in fact have not been sent through the mixnet yet.
# Message Responses
# Message Responses
Responses to your messages are defined [here](https://github.com/nymtech/nym/blob/develop/clients/native/websocket-requests/src/responses.rs):
```rust,noplayground
@@ -1,12 +1,12 @@
# Browser only
With the Typescript SDK you can run a Nym client in a webworker - meaning you can connect to the mixnet through the browser without having to worry about any other code than your web framework.
With the Typescript SDK you can run a Nym client in a webworker - meaning you can connect to the mixnet through the browser without having to worry about any other code than your web framework.
- Oreowallet have integrated `mixFetch` into their browser-extension wallet to run transactions through the mixnet.
- [Codebase](https://github.com/oreoslabs/oreowallet-extension/tree/mixFetch)
- Oreowallet have integrated `mixFetch` into their browser-extension wallet to run transactions through the mixnet.
- [Codebase](https://github.com/oreoslabs/oreowallet-extension/tree/mixFetch)
- [NoTrustVerify](https://notrustverify.ch/) have set up an example application using [`mixFetch`](https://sdk.nymtech.net/examples/mix-fetch) to fetch crypto prices from CoinGecko over the mixnet.
- [Website](https://notrustverify.github.io/mixfetch-examples/)
- [Codebase](https://github.com/notrustverify/mixfetch-examples)
- [NoTrustVerify](https://notrustverify.ch/) have set up an example application using [`mixFetch`](https://sdk.nymtech.net/examples/mix-fetch) to fetch crypto prices from CoinGecko over the mixnet.
- [Website](https://notrustverify.github.io/mixfetch-examples/)
- [Codebase](https://github.com/notrustverify/mixfetch-examples)
- There is a coconut-scheme based Credential Library playground [here](https://coco-demo.nymtech.net/). This is a WASM implementation of our Coconut libraries which generate raw Coconut credentials. Test it to create and re-randomize your own credentials. For more information on what is happening here check out the [Coconut docs](https://nymtech.net/docs/coconut.html).
@@ -1,17 +1,24 @@
# Apps Using Network Requesters
These applications utilise custom app logic in the user-facing apps in order to communicate using the mixnet as a transport layer, without having to rely on custom server-side logic. Instead, they utilise existing Nym infrastructure - [Network Requesters](https://nymtech.net/operators/nodes/network-requester-setup.html) - with a custom whitelist addition.
These applications utilise custom app logic in the user-facing apps in order to communicate using the mixnet as a transport layer, without having to rely on custom server-side logic. Instead, they utilise existing Nym infrastructure - Network Requesters - now embeded in `nym-node` running as `exit-gateway`.
If you are sending 'normal' application traffic, and/or don't require and custom logic to be happening on the 'other side' of the mixnet, this is most likely the best option to take as a developer who wishes to privacy-enhance their application.
> Nym will soon be switching from a whitelist-based approach to a blocklist-based approach to filtering traffic. As such, it will soon be even easier for developers to utilise the mixnet, as they will not have to run their own NRs or have to add their domains to the whitelist
If you are sending 'normal' application traffic, and/or don't require and custom logic to be happening on the 'other side' of the mixnet, this is most likely the best option to take as a developer who wishes to privacy-enhance their application.
> Nym will soon be switching from a whitelist-based approach to a blocklist-based approach to filtering traffic. As such, it will soon be even easier for developers to utilise the mixnet, as they will not have to run their own NRs or have to add their domains to the whitelist
<!-- I DON't THINK THIS WORKS NOW, NEED RESEARCH AND UPGRADE
- DarkFi over Nym leverages Nyms mixnet as a pluggable transport for DarkIRC, their p2p IRC variant. Users can anonymously connect to peers over the network, ensuring secure and private communication within the DarkFi ecosystem. Written in **Rust**.
- [Docs](https://darkrenaissance.github.io/darkfi/clients/nym_outbound.html?highlight=nym#3--run)
- [Github](https://github.com/darkrenaissance/darkfi/tree/master/doc)
-->
- MiniBolt is a complete guide to building a Bitcoin & Lightning full node on a personal computer. It has the capacity to run network traffic (transactions and syncing) over the mixnet, so you can privately sync your node and not expose your home IP to the wider world when interacting with the rest of the network!
- MiniBolt is a complete guide to building a Bitcoin & Lightning full node on a personal computer. It has the capacity to run network traffic (transactions and syncing) over the mixnet, so you can privately sync your node and not expose your home IP to the wider world when interacting with the rest of the network!
- [Docs](https://v2.minibolt.info/bonus-guides/system/nym-mixnet#proxying-bitcoin-core)
- [Codebase](https://github.com/minibolt-guide/minibolt)
- Email over Nym is a set of configuration options to set up a Network Requester to send and recieve emails over Nym, using something like Thunderbird.
- [Codebase](https://github.com/dial0ut/nymstr-email)
- Email over Nym is a set of configuration options to set up a Network Requester to send and recieve emails over Nym, using something like Thunderbird.
- [Codebase](https://github.com/dial0ut/nymstr-email)
+78 -17
View File
@@ -1,5 +1,9 @@
# NymVPN CLI Guide
```admonish tip title="web3summit testing"
**If you testing NymVPN CLI on Web3 Summit Berlin, visit our event page with all info tailored for the event: [nym-vpn-cli.sandbox.nymtech.net](https://nym-vpn-cli.sandbox.nymtech.net/).**
```
```admonish info
To download NymVPN desktop version, visit [nymvpn.com/en/download](https://nymvpn.com/en/download).
@@ -38,6 +42,32 @@ tar -xvf <BINARY>.tar.gz
# tar -xvf nym-vpn-cli_<!-- cmdrun ../../../scripts/cmdrun/nym_vpn_cli_version.sh -->_ubuntu-22.04_x86_64.tar.gz
```
### Building From Source
NymVPN CLI can be built from source. This process is recommended for more advanced users as the installation may require different dependencies based on the operating system used.
Start by installing [Go](https://go.dev/doc/install) and [Rust](https://rustup.rs/) languages on your system and then follow these steps:
1. Clone NymVPN repository:
```sh
git clone https://github.com/nymtech/nym-vpn-client.git
```
2. Move to `nym-vpn-client` directory and compile `wireguard`:
```sh
cd nym-vpn-client
make build-wireguard
```
3. Compile NymVPN CLI
```sh
make build-nym-vpn-core
```
Now your NymVPN CLI is installed. Navigate to `nym-vpn-core/target/release` and use the commands the section below to run the client.
## Running
If you are running Debian/Ubuntu/PopOS or any other distributio supporting debian packages and systemd, see the [relevant section below](#debian-package-for-debianubuntupopos).
@@ -125,7 +155,8 @@ To see all the possibilities run with `--help` flag:
```sh
./nym-vpn-cli --help
```
~~~admonish example collapsible=true title="Console output"
~~~admonish example collapsible=true title="nym-vpn-cli --help"
```sh
Usage: nym-vpn-cli [OPTIONS] <COMMAND>
@@ -142,25 +173,55 @@ Options:
```
~~~
Here is a list of the options and their descriptions. Some are essential, some are more technical and not needed to be adjusted by users.
You can also run any command with `--help` flag to see a list of all options associated witht that command, the most important may be `run` command, like in this example.
**Fundamental commands and arguments**
~~~admonish example collapsible=true title="nym-vpn-cli run --help"
```sh
Run the client
- `--entry-gateway-id`: paste one of the values labeled with a key `"identityKey"` (without `" "`)
- `--exit-gateway-id`: paste one of the values labeled with a key `"identityKey"` (without `" "`)
- `--exit-router-address`: paste one of the values labeled with a key `"address"` (without `" "`)
- `--enable-wireguard`: Enable the wireguard traffic between the client and the entry gateway. NymVPN uses Mullvad libraries for wrapping `wireguard-go` and to setup local routing rules to route all traffic to the TUN virtual network device
- `--wg-ip`: The address of the wireguard interface, you can get it [here](https://nymvpn.com/en/alpha)
- `--private-key`: get your private key for testing purposes [here](https://nymvpn.com/en/alpha)
- `--enable-two-hop` is a faster setup where the traffic is routed from the client to Entry Gateway and directly to Exit Gateway (default is 5-hops)
Usage: nym-vpn-cli run [OPTIONS]
**Advanced options**
Options:
--entry-gateway-id <ENTRY_GATEWAY_ID>
Mixnet public ID of the entry gateway
--entry-gateway-country <ENTRY_GATEWAY_COUNTRY>
Auto-select entry gateway by country ISO
--entry-gateway-low-latency
Auto-select entry gateway by latency
--exit-router-address <EXIT_ROUTER_ADDRESS>
Mixnet recipient address
--exit-gateway-id <EXIT_GATEWAY_ID>
Mixnet public ID of the exit gateway
--exit-gateway-country <EXIT_GATEWAY_COUNTRY>
Auto-select exit gateway by country ISO
--wireguard-mode
Enable the wireguard mode
--nym-ipv4 <NYM_IPV4>
The IPv4 address of the nym TUN device that wraps IP packets in sphinx packets
--nym-ipv6 <NYM_IPV6>
The IPv6 address of the nym TUN device that wraps IP packets in sphinx packets
--nym-mtu <NYM_MTU>
The MTU of the nym TUN device that wraps IP packets in sphinx packets
--dns <DNS>
The DNS server to use
--disable-routing
Disable routing all traffic through the nym TUN device. When the flag is set, the nym TUN device will be created, but to route traffic through it you will need to do it manually, e.g. ping -Itun0
--enable-two-hop
Enable two-hop mixnet traffic. This means that traffic jumps directly from entry gateway to exit gateway
--enable-poisson-rate
Enable Poisson process rate limiting of outbound traffic
--disable-background-cover-traffic
Disable constant rate background loop cover traffic
--enable-credentials-mode
Enable credentials mode
--min-mixnode-performance <MIN_MIXNODE_PERFORMANCE>
Set the minimum performance level for mixnodes
-h, --help
Print help
```
~~~
- `-c` is a path to an enviroment config, like [`sandbox.env`](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env)
- `--enable-poisson`: Enables process rate limiting of outbound traffic (disabled by default). It means that NymVPN client will send packets at a steady stream to the Entry Gateway. By default it's on average one sphinx packet per 20ms, but there is some randomness (poisson distribution). When there are no real data to fill the sphinx packets with, cover packets are generated instead.
- `--ip` is the IP address of the TUN device. That is the IP address of the local private network that is set up between local client and the Exit Gateway.
- `--mtu`: The MTU of the TUN device. That is the max IP packet size of the local private network that is set up between local client and the Exit Gateway.
- `--disable-routing`: Disable routing all traffic through the VPN TUN device.
## Testnet environment
@@ -171,7 +232,7 @@ If you want to run NymVPN CLI in Nym Sandbox environment, there are a few adjust
curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env
```
2. Check available Gateways at [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways)
2. Check available Gateways at [Sandbox API](https://sandbox-nym-api1.nymtech.net/api/v1/gateways) or [Sandbox Swagger page](https://sandbox-nym-api1.nymtech.net/api/swagger/index.html)
3. Run with a flag `-c`
```sh
@@ -2,6 +2,10 @@
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/897010658?h=1f55870fe6&amp;badge=0&amp;autopause=0&amp;player_id=0&amp;app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="NYMVPN alpha demo 37C3"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>
```admonish tip title="web3summit testing"
**If you testing NymVPN CLI on Web3 Summit Berlin, visit our event page with all info tailored for the event: [nym-vpn-cli.sandbox.nymtech.net](https://nym-vpn-cli.sandbox.nymtech.net/).**
```
**NymVPN alpha** is a client that uses [Nym Mixnet](https://nymtech.net) to anonymise all of a user's internet traffic through either a 5-hop mixnet (for a full network privacy) or the faster 2-hop decentralised VPN (with some extra features).
@@ -5,5 +5,4 @@ The following code shows how you can use the SDK to create and use a credential
{{#include ../../../../../../sdk/rust/nym-sdk/examples/bandwidth.rs}}
```
You can read more about Coconut credentials (also referred to as `zk-Nym`) [here](https://nymtech.net/docs/coconut.md).
You can read more about Coconut credentials (also referred to as `zk-Nym`) [here](https://nymtech.net/docs/coconut.html).
@@ -1,7 +1,7 @@
# Anonymous Replies with SURBs (Single Use Reply Blocks)
Both functions used to send messages through the mixnet (`send_message` and `send_plain_message`) send a pre-determined number of SURBs along with their messages by default.
You can read more about how SURBs function under the hood [here](https://nymtech.net/docs/architecture/traffic-flow.md#private-replies-using-surbs).
You can read more about how SURBs function under the hood [here](https://nymtech.net/docs/architecture/traffic-flow.html#private-replies-using-surbs).
In order to reply to an incoming message using SURBs, you can construct a `recipient` from the `sender_tag` sent along with the message you wish to reply to:
+14 -2
View File
@@ -18,8 +18,8 @@ pagetoc = true
sidebar-width = "280px"
content-max-width = "80%"
root-font-size = "70%"
# if you need to change anything in the index.hbs file you need to turn this to `false`, rebuild the book,
# probably remove the additional `comment` that gets appended to the header, and then change this back to `true`.
# if you need to change anything in the index.hbs file you need to turn this to `false`, rebuild the book,
# probably remove the additional `comment` that gets appended to the header, and then change this back to `true`.
# this is because of a bug in the `mdbook-theme` plugin
turn-off = true
@@ -103,3 +103,15 @@ copy-js = true # include Javascript code for search
[output.linkcheck]
warning-policy = "warn"
[output.html.redirect]
"/sdk/rust/examples/socks.html" = "https://nymtech.net/developers/sdk/rust/examples/socks.html"
"/clients/overview.html" = "https://nymtech.net/developers/clients-overview.html"
"/sdk/rust/rust.html" = "https://nymtech.net/developers/sdk/rust/rust.html"
"/clients/socks5-client.html" = "https://nymtech.net/developers/clients/socks5-client.html"
"/clients/webassembly-client.html" = "https://nymtech.net/developers/clients/webassembly-client.html"
"/sdk/typescript.html" = "https://sdk.nymtech.net"
"/clients/websocket-client.html" = "https://nymtech.net/developers/clients/websocket-client.html"
"/use-apps/blockstream-green" = "https://nymtech.net/developers/clients/socks5/usage.html"
"/use-apps/telegram" = "https://nymtech.net/developers/archive/nym-connect.html#telegram-via-nymconnect"
+9 -3
View File
@@ -31,9 +31,15 @@
- [RPC Nodes](nyx/rpc-node.md)
- [Ledger Live Support](nyx/ledger-live.md)
# Coconut
- [Coconut](coconut.md)
- [Bandwidth Credentials](bandwidth-credentials.md)
# zkNyms (prev. Coconut)
- [What are zk-nyms?](zknym/what-are-zknyms.md)
- [zk-nym Generation & Useage: Overview](zknym/zknym-overview.md)
- [Feature: Unlinkability](zknym/unlinkability.md)
- [Feature: Double Spend Protection](zknym/double-spend-prot.md)
- [Feature: Rerandomisation & Incremental Spend](zknym/rerandomise.md)
- [Archive](zknym/archive.md)
- [Coconut](zknym/coconut.md)
- [Bandwidth Credentials](zknym/bandwidth-credentials.md)
# Tools
- [NymCLI](tools/nym-cli.md)
@@ -4,11 +4,12 @@
Nym is the first system we're aware of which provides integrated protection on both the network and transaction level at once. This seamless approach gives the best possible privacy protections, ensuring that nothing falls through the cracks between systems.
The diagram and brief explainer texts below give a high level overview of the difference between Nym and other comparable systems.
The diagram and brief explainer texts below give a high level overview of the difference between Nym and other comparable systems.
> If you want to dig more deeply into the way traffic is packetised and moved through the mixnet, check out the [Mixnet Traffic Flow](https://nymtech.net/docs/architecture/traffic-flow.html) page of the docs.
<img src="../images/nym-vs-animation.gif"/>
> If you want to dig more deeply into the way traffic is packetised and moved through the mixnet, check out the [Mixnet Traffic Flow](https://nymtech.net/docs/architecture/traffic-flow.html) page of the docs.
<!-- IMG DOES NOT EXIST
![](../images/nym-vs-animation.gif)
-->
### Nym vs VPNs
@@ -56,9 +56,9 @@ Quite a bit of stuff gets built. The key working parts are:
* [Nym Node](https://nymtech.net/operators/nodes/nym-node.html): `nym-node`
* [Validator](https://nymtech.net/operators/nodes/validator-setup.html)
* [websocket client](https://nymtech.net/docs/clients/websocket-client.html): `nym-client`
* [socks5 client](https://nymtech.net/docs/clients/socks5-client.html): `nym-socks5-client`
* [webassembly client](https://nymtech.net/docs/clients/webassembly-client.html): `webassembly-client`
* [websocket client](https://nymtech.net/developers/clients/websocket-client.html): `nym-client`
* [socks5 client](https://nymtech.net/developers/clients/socks5-client.html): `nym-socks5-client`
* [webassembly client](https://nymtech.net/developers/clients/webassembly-client.html): `webassembly-client`
* [nym-cli tool](https://nymtech.net/docs/tools/nym-cli.html): `nym-cli`
* [nym-api](https://nymtech.net/operators/nodes/nym-api.html): `nym-api`
* [nymvisor](https://nymtech.net/operators/nodes/nymvisor-upgrade.html): `nymvisor`
Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

+3
View File
@@ -0,0 +1,3 @@
# Archive
You can find the previously published Coconut scheme pages in this archive. This has since been superceded by the zk-nyms scheme, which combines elements of the [Coconut Credential](./coconut.md) and [Offline Ecash](https://arxiv.org/pdf/2303.08221) schemes.
@@ -1,8 +1,13 @@
# Bandwidth Credentials
```admonish caution
This page is now archived.
For up-to-date example interaction with zk-nyms navigate to the [zk-nym unlinkability](./unlinkability.md) page.
```
You can now try using Nym Bandwidth Credentials in our [Sandbox testnet environment](https://sandbox-explorer.nymtech.net).
Create a `sandbox.env` file with the following details:
Create a `sandbox.env` file with the following details:
```
CONFIGURED=true
@@ -32,17 +37,17 @@ NYXD="https://rpc.sandbox.nymtech.net"
NYM_API="https://sandbox-validator1-api.nymtech.net/api"
```
Create an account on Sandbox using the nym-cli:
Create an account on Sandbox using the nym-cli:
```./nym-cli --config-env-file <path-to>sandbox.env account create```
You will need `nymt` funds sent to this account. Get in touch via Nym [Telegram](https://t.me/nymchan) or [Discord](https://nymtech.net/go/discord) and we can send them to you.
You will need `nymt` funds sent to this account. Get in touch via Nym [Telegram](https://t.me/nymchan) or [Discord](https://nymtech.net/go/discord) and we can send them to you.
Next, you init the nym-client with the enabled credentials mode set to true:
Next, you init the nym-client with the enabled credentials mode set to true:
```./nym-client --config-env-file <path-to>sandbox.env init --id <ID> --enabled-credentials-mode true```
Using the new credentials binary, purchase some credentials for the client. The recovery directory is a directory where the credentials will be temporarily stored in case the request fails.
Using the new credentials binary, purchase some credentials for the client. The recovery directory is a directory where the credentials will be temporarily stored in case the request fails.
```./credential --config-env-file <path-to>sandbox.env run --client-home-directory <path-to-the-client-config> --nyxd-url https://rpc.sandbox.nymtech.net --mnemonic "<mnemonic of the account created above>" --amount 50 --recovery-dir <a-path> ```
@@ -56,11 +61,11 @@ Run the network requester which can be downloaded [here](https://github.com/nymt
> You need to run this version for now, as the `nym-client` functionality was recently integrated into the `network-requester` binary but for the moment cannot support coconut credentials natively.
Now time to init the socks5 client:
Now time to init the socks5 client:
`./nym-socks5-client --config-env-file <path-to>sandbox.env init --id <ID> --provider <insert provider address which was returned when init-ing the nym-client> --enabled-credentials-mode true`
Purchase credentials for this now too:
Purchase credentials for this now too:
`./credential --config-env-file <path-to>sandbox.env run --client-home-directory <path-to-socks5-config> --nyxd-url https://rpc.sandbox.nymtech.net --mnemonic "<any valid sandbox mnemonic>" --amount 100 --recovery-dir <a-path>`
@@ -68,13 +73,13 @@ Run the socks5 client:
`./nym-socks5-client --config-env-file <path-to>sandbox.env run --id <ID> --enabled-credentials-mode true`
NOTE
NOTE
You can check to see if credentials have been correctly purchased by installing sqlite, and proceeding to do the following:
```
sqlite3 ~/.nym/socks5-clients/<ID>/data/credentials_database.db
sqlite3 ~/.nym/socks5-clients/<ID>/data/credentials_database.db
select * from coconut_credentials;
```
Keep in mind 1GB = 1NYM
Keep in mind 1GB = 1NYM
@@ -1,6 +1,10 @@
# Coconut
> Coconut is in active development - stay tuned for code and integration examples
```admonish caution
This page is now archived: the current anonymous credential scheme - zk-nyms - is partially based on Coconut, but this page is really just retained for posterity.
For up-to-date information on anonymous mixnet access, navigate to the [zk-nym overview](./what-are-zknyms.md).
```
Coconut is a cryptographic signature scheme that produces privacy-enhanced credentials. It lets application programmers who are concerned with resource access control to think and code in a new way.
@@ -0,0 +1,39 @@
# Double Spend Protection
Double spend protection in the context of zk-nym is a balancing act between speed, reliability, and UX. There are two possible modes for protecting against attempted double spending of zk-nyms:
- Online: The online approach mandates that ingress Gateways instantly deposit zk-nyms received from clients to the NymAPI Quorum for verification. Once verified by the Quroum, the ingress Gateway is paid proprtional to the amount of bandwidth 'spent' with the zk-nym, and proceeds to grant the client access to the network.
- Offline: In contrast, the offline approach involves the periodic submission of collected zk-nyms by ingress Gateways to the Quorum, instead of an instant check. Subsequently, the Quorum nodes perform checks to detect any instances of double-spending and identify the public key associated with such occurrences, whereas the ingress Gateways only do a simple check to check that _that particular_ zk-nym had not been spent with itself before.
> The zk-nym system takes the **offline** approach.
## Offline Approach: Pros & Cons
The advantages of the offline approach are manifold:
- Immediate access to the Nym network upon zk-nym submission, eliminating any delays in service provisioning until payments are deposited and verified as would occur in the online approach.
- Alleviates performance strain on ingress Gateways and Quorum members, serving as a more efficient method compared to the online counterpart. By moving computationally intense work to the Quorum, this means that Gateway nodes are able to be run on less powerful machines, meaning more operators can more easily run them (and cover their costs) and thus increase the overall number and spread of Gateways around the globe.
- Moreover, the offline approach can circumvent the potential issue of overwhelming the blockchain with the serial numbers of spent coins.
However, the offline approach introduces certain limitations.
- Ingress Gateways accept zk-nyms without preemptively checking for instances of double spending thus making them susceptible to unknowingly accepting double-spent credentials.
- Any potential repercussions against double spenders can only be implemented once the user requests a new credential for their zk-nym Generator (aka they have to 'top up' and buy more bandwidth allowance), assuming they haven't altered their identifier (the Bech32 address).
An exploitable scenario arises from these limitations:
- A malicious user purchases bandwidth and aggregates a valid zk-nym credential in the standard way, worth $10 of crypto/fiat. Subsequently, the malicious user proceeds to sell the credential to 100 users for $1 each, allowing each user to generate zk-nym credits of 100MB from this **valid** credential. Under the offline approach, entry nodes forego double-spending checks; so long as the clients all used different ingress Gateways, all 100 users could access the network without obtaining a subscription. As bandwidth consumption is tracked locally between client and ingress node, and each zk-nym credit is rerandomised, there is no way that ingress Gateways would know that the zk-credential used by the client has been shared with other parties. This loophole highlights the need for stringent measures to counter such potential abuses within the system, without creating either speed bottlenecks (in the case of the Online model) or impacting the anonymity of the system. We can, however, mitigate this problem without doing either of these things.
## Solution to Offline Double Spending
To efficiently prevent the fraudulent use of tickets within the Nym network, a two-tiered solution is in place that combines (1) the immediate detection of double-spending attempts at the level of individuals ingress Gateways and (2) subsequent identification and blacklisting of offending clients at the Quorum level.
### Entry Node Implementation: Real-Time Ticket Unspending Validation
Each spent zk-nym credit contains as an attribute a unique serial number, which is revealed in plaintext to the respective ingress Gateway. Each Gateway has a copy of a [Bloom Filter](https://www.geeksforgeeks.org/bloom-filters-introduction-and-python-implementation/) - on receiving a credit, it will check against its copy of a local database to check whether this serial number has already been seen. If so, it rejects the credit as being double-spent and the client's connection request is rejected. If not, it will add the serial number to its local DB.
> Since each time a zk-nym credential is rerandomised its serial number is changed, the serial number being shared in no way identifies a client or user.
Each Gateway will periodically share their serial numbers with the Quorum and refresh their copy of the Bloom Filters from the Quorum, in order to refresh the global list shared by all ingress Gateways and the Quorum. See the step below for more on this.
> Crucially, ingress Gateways refrain from extensive computations to identify the original ticket owner, and avoids broadcasting information about the double-spending attempt to other ingress Gateways. The entry node is also not involved in any global blacklisting process of the clients. The sole purpose of this check is to swiftly identify any attempts at double-spending and add the seen ticket's serial number to the local DB cache.
### Nym-API Implementation: Blacklisting and Penalties for Double-Spenders
All Gateways periodically forward the collected credits to the Quorum, enabling them to pinpoint and blacklist any clients who double spend. Upon receiving the credits, the Quorum appends all the incoming serial numbers to the global list of spend zk-nym serial numbers and proceed with the identification process for any malicious users engaging in double-spending.
This identification phase involves looking for instances of double spending, identifying the id of the double-spending client, and blacklisting this client by its id. Subsequently, when this client requests a new credential, their plaintext public identifier is included in the request. The Quorum then checks if this identifier is blacklisted. If it is, a new credential is not issued. Furthermore, since the PSCs are only attainable after depositing NYM as payment, the Quorum has the authority to withhold the deposited NYMs as a punitive measure for any detected instances of double-spending.
<!-- extract parts of large diagram & upload as PNG to server + link -->
@@ -0,0 +1,48 @@
# Rerandomisation & Incremental Spend
Each zk-nym credit will not be valid for the entire amount of data that the credential aggregated from the PSCs is; if the aggregated credential is worth (e.g.) 10GB of Mixnet data, each credit will be worth far less (e.g. 100MB). This amount will be globally uniform in order to avoid situations where differently sized credits allow for patterns to emerge.
```admonish info
The functionality included in the following code block examples were added to the [nym-cli tool](../tools/nym-cli.md) for illustrative purposes only: this is not necessarily how credentials will be accessed in the future.
**Furthermore, the `nym-cli` uses the words 'tickets' in place of 'credits' and 'ticketbook' in place of 'aggregated credential': this is wording that we are moving away from now in place of the simpler credential/credit.** This will be updated in the `nym-cli` tool in a future release.
The numbers used in this high level overview are for illustration purposes only. The figures used in production will potentially vary. Note that individual zkNym sizes will be uniform across the Network.
```
## Why not spend the entire credential at once?
This is to account for the need for a client to change their ingress Gateway, either because the Gateway itself has gone down / is not offering the required bandwidth, or because a user might simply want to split their traffic across multiple Gateways for extra privacy.
This means that clients are not tied to particular Gateways they have 'spent' their entire subscription amount with; if the ingress Gateway goes down, or the client simply wishes to use another ingress Gateway, the user has multiple other zk-nym credits they can use that account for their remaining purchased bandwidth.
Going back to the `nym-cli` tool to illustrate this; we can generate multiple unlinkable credits ('tickets' on this command output) from a single aggregated credential ('ticketbook' below):
```
./nym-cli ecash generate-ticket --credential-storage storage.db --provider 6qidVK21zpHD298jdDa1RRpbRozP29ENVyqcSbm6hQrG --full
TICKETBOOK DATA:
4Ys9pzUf9MPxX4s5RASyrRoY9fPk1a1kFuPBP2jm2L5PyUy535yPEfjHAfpUTC1Lf2d155TmjukvcDycQYfBSDfhEUJM4J3qPNfG3B5aQEEkefESZp3CM5AEnAu1AEyhpepbYw6BuXokiNcmaYtq3yJQbA4KicKP8FowoRzKHmXpJoUqY8wYQughGfdtXgr3rVaZmK21X51P1NL2UW1aCE512WWfy6P1LJHByWywT3qVw28Z83
generating payment information for 50 tickets. this might take a while!...
AVAILABLE TICKETS
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
| index | binary data | spend status |
+============================================================================================================================================================================================+
| 0 | 4kgKyJLq1zQuk9r9AbEFHPqD8mDuxsLSjgo9XW4Lf7EqGSbgfNsWSEcTbRPEMFLzpstbX5azsA3opFh851h4g5qCG2qE3Luwqua4GG2ebJhk91rvEc5JPctbVQxL62fkfQ6svdcNp…1057bytes remaining | NOT SPENT |
|-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------|
| 1 | 4kefQqViRZd5YezMHH1FTcgUGPK2E2ivfmwgf59exvsnR8tsb5aJtGVwpA7wAJT6icPeo8jtDwDZ3WMPJxL3VRLiakAQr79zh7ixM89gowg3ChHEy6ewmHcT7T6RFkZFsMCMj1CNd…1057bytes remaining | NOT SPENT |
|-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------|
| 2 | 4kxaKdBxyFzJ8gxSZCh1v3wBfN7JvnCJuoJ4MWqkkMHtt2XgRKbDmHCv5ZxtA57Qk8LC3NDMBmqjADvY34mAPdT3tLBL4uxse9ASa227Ji96dwgxvfbpvLXSSr5o4vuPRV9K7UfpJ…1057bytes remaining | NOT SPENT |
|-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------|
| 3 | 4kdYwUJwXyxZBLQXextd4GsU2MATjzArVq5Ec459fTXyrm6q3vxurWULzBMpV5UjcmjJtnw1zFqt7f8Ydu5gyxwAVXP3Nwpn83ouguv2n4YrUewZCvFAqQYXgahhhaQGp6RxK2Arh…1057bytes remaining | NOT SPENT |
|-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------|
...
| 46 | 4kg8bfQ7kGgq5TkkqXagpAEu95gmGT4i7NKbaxJtp2gRgWRrQZM1rxaDAzAxfghoM6PFNbYgKsnLD4MF8HtXW3p92CnPBjswzJ1EbtsMGpgDER3CYFt2ivAhMAVXFziF5UjVJXhpa…1057bytes remaining | NOT SPENT |
|-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------|
| 47 | 4kipbH5Fqt5E9hFMynm9vzFh5FkxKRdHrSEiiJWDwmg3mASctR61sXoFD5u5ZMBwGdvz9sWsRfrpR4MX2NNfRhC85aUxqtkAv3hXZiCLtE1pUC54Cq7YXHyv2XTNKpvuFZs2GmwYg…1057bytes remaining | NOT SPENT |
|-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------|
| 48 | 4kxYZ26HXvxVhh4quHXeCUyQokydeF5wkwUi8fMx6P3uoMvuiPaNP1SJTbYnaQEFFtF6U4dGop6QckUYvbtwQFoGJTJesHFHTDtHbshj5Dg8DwbyaHuAR86zGwYMUPved4XKUTMLa…1057bytes remaining | NOT SPENT |
|-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------|
| 49 | 4kb6zmPebRxjKLVicctq2whvANjWJMoohiPBMr21cT4xj78nvXmJEK8EB4PpqQVFo6ddU9uzuer5ggQZNZgETX2VXBzymBYNzXBuXjLJi1WRdAiASqWz5Hv5im1TJh4XBE4mxKo8Q…1057bytes remaining | NOT SPENT |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------+
```
@@ -0,0 +1,36 @@
# Unlinkability
Each time a credential is requested by an ingress Gateway to prove that a client has purchased data to send through the Mixnet, instead of sending that credential, the Requester's device will produce a zk-nym credit. This is a rereandomised value that is able to be verified as being legitimate (in that it was created by a valid root credential) but **not linked to any other credits**, either previously generated or to be generated in the future. This feature also allows for a credential to be split across multiple ingress Gateways / connections and [incrementally spent](./rerandomise.md) over time.
```admonish info
The functionality included in the following code block examples were added to the [nym-cli tool](../tools/nym-cli.md) for illustrative purposes only: this is not necessarily how credentials will be accessed in the future.
**Furthermore, the `nym-cli` uses the words 'tickets' in place of 'credits' and 'ticketbook' in place of 'aggregated credential': this is wording that we are moving away from now in place of the simpler credential/credit.** This will be updated in the `nym-cli` tool in a future release.
The numbers used in this high level overview are for illustration purposes only. The figures used in production will potentially vary. Note that individual zkNym sizes will be uniform across the Network.
```
```
./nym-cli ecash generate-ticket --credential-storage storage.db --provider 6qidVK21zpHD298jdDa1RRpbRozP29ENVyqcSbm6hQrG --ticket-index=3
TICKETBOOK DATA:
4Ys9pzUf9MPxX4s5RASyrRoY9fPk1a1kFuPBP2jm2L5PyUy535yPEfjHAfpUTC1Lf2d155TmjukvcDycQYfBSDfhEUJM4J3qPNfG3B5aQEEkefESZp3CM5AEnAu1AEyhpepbYw6BuXokiNcmaYtq3yJQbA4KicKP8FowoRzKHmXpJoUqY8wYQughGfdtXgr3rVaZmK21X51P1NL2UW1aCE512WWfy6P1LJHByWywT3qVw28Z83
attempting to generate payment for ticket 3...
PAYMENT FOR TICKET 3:
VfZAuVRRHekQYMvFevNAZmPPuwMAfEhTBY8TXatBysbrNXAg8euEGPpJvdbhNfQSznBb9nRSeBUSVoNTToSA6Uj5dXmJ7oE2rCB439DarLMWHWYfQNhw6yhWJhcg6bt7ebBYTs3vVeQgSB5kYuifzJF4QQmK6uJyTNPvpV1J6V8M32PBkGT3JpVB3GUGZiksETf7TaF9wAhMo2QAMxw5ZvaQVve5ea7Mane6cfb2Gx69SRff5zDfEQvKqKnyyZje4SGZgWUeHWVLhRjg4KMTJ3JcsHxEqj2k5qeGeyBbgzcuEtCpYvaytsz7nuZGJsT4Z87gB5Zq4NGuDmekuN977eRJvua2dASNWeHiAzVyvnS7ARN5cdUjjYKYiWgHaYrHGsv26WTDeiu4U3sdJMrLHGFY5ihX7f8sTZqD6Wx5AWjQNbEtKaVHymDogfLcwGCC42gQ2yhKfPUaWJ8H4yMB65YBDXGjATaUzcDmJcZKx8g31j2uTVNSFUesd5CRNEEcTNW7cSFFCishCD3T4eV9SuyZyEXAZ48pazPzc1BysBNHEXQNUEtEAZTKmpghC2pihhfDub6LnMJPo9DDdhCULCbcWbGAPc1vPekPaWvk7wrUTGwp5xoNUhQLW3MeJzMvrMSsqLdursCKB4h4Tk272WCStCPQwAKMYoxjWvMzxoUTTWCkhLKHruMtsehRnai4vhu13jbui6ji1F389gfazm4ctth2s4Yw3H3SaPtRETBfZNvZ7n5UV1MD6Q3qin92gT65iqXEi4zRN3woYcK6ZehiSvgUksdEFAUSxNMgNXKtHEYDS6kA37tn5JdBa2Ex2jLudFfhg6JBM226ZKyj65o6feYPgbJAR3jMCmQRHe6DSFb4aH895EowNMjfGUhwhmnbYB1djp7iFXxPP7575NAerhxEQ1WFnxTfoX7pu1Vc9YZb5priCAVbATCaDkECJsdedM45Vx96Jc6E5NWqD98RhMsPimVJkSfYJmRxH9qugica6WonFFb2YLvXYyhoBA1VHBcRqZJ5KHitS5AegYSoYprUfubMzcYo2hGVEQkGKAsFq6jZgCsbJoGLXt3No317vcowB5f3hqT9FjASHAzW2j8uJ9RRzX7XtrPhArwx4EyPgYzrvgG7xcenoSgQt8poa7aYky56eZTKHVUZgUEt6St32MjcivMvmNdWiAHHDc2ZxzTJHgeuCckX7n19vQ3XNLuXv9oGKNNCi8kHnT4tUnnGXNAWXWuyBgZKWUL8u3y41iW6dLYK3Pw5zfpKZTrq3q3bTLJRN5LnnUuFVnWsC3SNqa6VAAvhTGR9PzxLk8C6HeLP2AsYPpqeQwbaL3Ks6tvPdob3tQPWRBGL4uiKtNZ23tRYZGZLYFWZK7psRSZg5AETejKxztVzAuYovpVUiDq71o331tjqWWV1SzWT13Rd1uwz6nHtsjgao2863YaizKARcYr1j9MKtNfDs483yho6i7tbCRR9M4CPLqdiKEaRyVC1FP4F3sejA6nZTuAA35JWUzX6BBj7wgdypMLdMmmtcCZm3bRrF3GvJJs67U8JWRc6dnoGUDaD7rUu
```
Now lets generate another credit to spend either topping up once the previous one's data allowance has been used, or with another Gateway. Notice that the `ticket-index` is the same: this is generated from the same aggregated credential as the one above!
```
./nym-cli ecash generate-ticket --credential-storage storage.db --provider 6qidVK21zpHD298jdDa1RRpbRozP29ENVyqcSbm6hQrG --ticket-index=3
TICKETBOOK DATA:
4Ys9pzUf9MPxX4s5RASyrRoY9fPk1a1kFuPBP2jm2L5PyUy535yPEfjHAfpUTC1Lf2d155TmjukvcDycQYfBSDfhEUJM4J3qPNfG3B5aQEEkefESZp3CM5AEnAu1AEyhpepbYw6BuXokiNcmaYtq3yJQbA4KicKP8FowoRzKHmXpJoUqY8wYQughGfdtXgr3rVaZmK21X51P1NL2UW1aCE512WWfy6P1LJHByWywT3qVw28Z83
attempting to generate payment for ticket 3...
PAYMENT FOR TICKET 3:
Vev3SmwWtH5vbnejX5Zzc1EcxXAgveqHpKNN8arxXaWLhFcEpdcZ6n7qr3NrQUNURWsK2AsUiX8aSiGSjMPEY3iDE3aDYnjYERVow8RKUmQiYSKvz7v9cEJxt97JAHBfu9WYNHXTnLFSJwWuFtBdzY5dzPdzGckFenGCysa1ZBHGADHChDVXKoPHXxpn5qyJxmi48coUQDptR64QgkCeQ8RRZ396Lxw2NKFSjqavCMMDVm3g1rW7cYyPanBhkoAUzPU9KXX1rtmhD6F9gV89mGZ8fm7ByDuKuYU28seLQ7GkVKkhNeRW9XxbjSiyscTnMUzJ24R5VbSdr141BaquUHezdUTzmA2EjAtcyyiVrCMV13cc96CRbMXENP2soUzckFnh1qPnrfKCvX4JYkztq7UgPT2mZEnSTDW4C6Z2NVCNBPNLqUSYrU4id8Jzcp1mBxqJjdYcQ7P5fWJbT5Q9NAq44PCgfXpsUkNoj35QVQvKXKLb5oNGqnua5YC1WBPcENcpS7ZPWpk2hwe8VK4gNgnwQtWH2RPmWbvBREAV97vS1vKNHJyry9sD2PiMJGSmBnb1bKsGxR9UQN3YvRsdGHzyJHzAMTzxbFJBqMPmxjSHJR4UdwzhB81Ludu1RAffTvecWFxmWH5bNymCQjw3wey7Uequcxgyy8KAWYDzvHGwCZQbHQXghsYREiqquZWaa8hX3iTNBFUtEk8PRVT78MoFNdeBWNjsLr8zyZ5EGnf4kqmw3a91g5p5vywf6e3LgMu19VHjPSNtKMNXiatkPEVjsCuCppmV4sB7FsdKKWcMUSWLsdmrDBg9PStHr7NaJRzLL5E91gvysmB36Nob9cHeHSZj3wM4NVVjFfZeRqQf4bi7ahfXjeeBetgDpqx7JcbU6tTN4JpcGUpp7fp4MhTq7MeVQMLweGUVLqewKgAGzCvEmrK6dzLd3U1P9vkAAVZ3cCAKUywnHGxoxDeEfexP1g1EqJLtKNZVKPf7hSMWqGhoQ36K7y5GnyZ5YhQ7jcDME9orm5w4StoxoDdCPcjbakKG7UaTHuhd7tU1mUffXcEvVerkXoQK9SEaKvGks21RBhW86aHUzJWVbkiDzdaqjJWbmzLV8FKvNxNyzucoH2rq8LiHRMZfV1H3SkVSa4j2Ktw7ZGoQfdj8DgekxXSR2nHPfhybzKYXTBqFo2ACisxkjR4rXr9Xo6eYywQhQ1MP6aYgYCAXFGHPoFf7kx7Jns5sWvHRBdaMF65zeFF2m5NDuMWETtLgFfsyNgR84vfSqTfzj2gsUykRei7q9N4LKmiDwBALTAEcTvZpLtXBjc8JaB9PUeBw7DoSiSK376sGrQ9F6ZGTngXACNz1TbvYhtau4bDa6KC2Qn7wmoyrphpn7TtM1jdwGBxLcaEEWZKQHvWVfTyL2itjqnrcAZkxYdCj56oQYwpWfKQk3zJEUA6SYHqyJjaLNVK6u25j7969EWjdpTsJ8qSsZgXi3T7dQqiwintZbUUUKRq7egN1SGVnA6Wup91uKrYUWEWMqVu4g8ipmRsLD9iXHHr3yA21Cka7pqk1FxR9BFTAnkk1
```
These are both generated by the _same_ underlying credential and used in a way that they cannot be tied to each other. An ingress Gateway might (for instance) get 100 connection requests from 100 Nym clients, each validated with a zk-nym credi t. It has no way of knowing whether these are all from the same single subscription, or 100 different ones.
@@ -0,0 +1,45 @@
# What are zk-nyms?
The zk-nym scheme enables the creation and use of unlinkable, rerandomisable anonymous access credentials that are 'spent' with Gateways in order to anonymously prove that someone has paid for Mixnet access. This implementation incorporates elements of both the [Coconut Credential](./coconut.md) and [Offline Ecash](https://arxiv.org/pdf/2303.08221) schemes.
As outlined in the [overview](./zknym-overview.md) on the next page, zk-nyms allow for users to pay for Mixnet access in a manner that is **unlinkable to their payment account**; even with pseudonymous cryptocurrencies or fiat. This solves one of the fundamental privacy problems with the majority of VPNs and dVPNs in production today: the linkability of a user's session with their payment information, which can in the majority of cases be easily used to deanonymise them, either at the behest of an authority or by the service operators themselves.
> The current zk-nym scheme is non-generic in that it is only used for gating Mixnet access. A generic scheme based on zk-nyms is being actively researched in order to facilitate more generic and customisable anonymous credentials for other applications and services.
## Motivations
Most of the time, when we build system security, we think of _who_ questions:
- Has Alice identified herself (authentication)?
- Is Alice allowed to take a specific action (authorisation)?
However, _who_ is not necessarily a question we want to be asking when designing a system with anonymous access control. This scheme allows us to instead consider questions of _rights_, namely:
- Does the entity taking this action have a right to do _X_?
This allows a different kind of security. Many of the computer systems we talk to every day don't need to know _who we are_, they only need to know if the entity kicking off a request has the _right to use_ the system.
The zk-nym scheme allows for this move to take place. Credentials are generated cooperatively by decentralised, trustless systems, and once the credentials are generated, they can be _re-randomized_; entirely new credentials, which no one has ever seen before, can be presented to the ingress point of the Nym Network, and validated without being linkable back to the signatures produced by the Quorum of credential signers used to generate them, or any credentials previously used by an entity wanting access. These properties allow zk-nyms to act as something like cryptographic bearer tokens generated by decentralised systems. The tokens can be mutated so that they are not traceable, but still verified with the original permissions intact.
> TL;DR: Users present cryptographic claims encoded inside the credentials to get secure access to resources despite the systems verifying credential usage not being able to know who they are.
### Re-randomisation vs pseudonymity
We stand on the shoulders of giants. Ten years ago, Bitcoin showed the way forward by allowing people to control resource access without recourse to _who_ questions. Rather, in Bitcoin and succeeding blockchains, a private key proves a _right to use_.
But as we can now see, private keys in blockchain systems act only as a minor barrier to finding out _who_ is accessing resources. A Bitcoin or Ethereum private key is effectively a long-lived pseudonym which is easily traceable through successive transactions.
**zk-nyms allows us to build truly private systems rather than pseudonymous ones.**
## Features
Specifically, zk-nym is an implementation of a blinded, re-randomizable, selective disclosure threshold credential signature scheme.
Let's say you have a `message` with the content `This credential controls X` in hand. In addition to the normal `sign(message, secretKey)` and `verify(message, publicKey)` functions present in other signature schemes like RSA, the zk-nym credential scheme adds the following:
1. _[Blind signatures](https://en.wikipedia.org/wiki/Blind_signature)_ - disguises message content so that the signer can't see what they're signing. This defends users against signers: the entity that signed can't identify the user who created a given credential, since they've never seen the message they're signing before it's been _blinded_ (turned into seemingly random binary data). The scheme uses zero-knowledge proofs so that the signer can sign confidently without seeing the unblinded content of the message.
2. _Re-randomizable signatures_ - take a signature, and generate a brand new signature that is valid for the same underlying message `This credential controls X`. The new bitstring in the re-randomized signature is equivalent to the original signature but not linkable to it. So a user can generate multiple zk-nyms from a single credential source, unlinkable to any previous "shown" zk-nym. But the underlying content of the re-randomized credential is the same (including for things like double-spend protection). This once again protects the user against the signer, because the signer can't trace the signed message that they gave back to the user when it is presented. It also protects the user against the relying party that accepts the signed credential. The user can generate multiple re-randomized credentials repeatedly, and although the underlying message is the same in all cases, there's no way of tracking them by watching the user present the same credential multiple times.
3. _Selective disclosure of attributes_ - allows someone with the public key to verify some, but not all, parts of a message. So you could for instance selectively reveal parts of a signed message to some people, but not to others. This is a very powerful property of the scheme which is to be explored more in future work, potentially leading to diverse applications: voting systems, anonymous currency, privacy-friendly KYC systems, etc.
4. _[Threshold issuance](https://en.wikipedia.org/wiki/Threshold_cryptosystem)_ - allows signature generation to be split up across multiple nodes and decentralized, so that either all signers need to sign (_n of n_ where _n_ is the number of signers) or only a threshold number of signers need to sign a message (_t of n_ where _t_ is the threshold value).
Taken together, these properties provide privacy for applications when it comes to generating and using signatures for cryptographic claims. If you compare it to existing tech, you might think of it as a sort of supercharged decentralized privacy-friendly [JWT](https://jwt.io/).
@@ -0,0 +1,58 @@
# Generating and using zk-nym anonymous credentials
```admonish info
The first use-case of zk-nyms is for anonymously proving the right to use the Nym mixnet for privacy.
The Nym mixnet is - at the time of publication - free for everyone. However, soon™ it will be required for each connecting client to present a valid credential - a zk-nym - to their ingress Gateway to access the Mixnet.
Accessing zk-nym credentials will vary depending on use:
- Individual developers building on the mixnet will be able to get zk-nym credentials via something like a faucet.
- Larger application integrations will have their own 'under the hood' credential generation and distribution scheme to generate access credentials on behalf of their users automatically.
- NymVPN users will have a variety of payment methods avaliable to them. The vast majority, if not all of the steps outlined on this page, will happen under the hood from their perspective. _More on this soon_.
```
Generation of zk-nyms involves the following actors / pieces of infrastructure:
- **Requester needing a zk-nym** for example a single user using the NymVPN app, or a company purchasing zk-nyms to distribute to their app users, in the instance of an app integrating a Mixnet client via one of the SDKs. The Requester is represented by a Bech32 address on the Nyx blockchain.
- [NymAPI](https://nymtech.net/operators/nodes/nym-api.html) instances working together on signature generation and spent credential validation, referred to as the **NymAPI Quorum**. Members of the Quorum are a subset of the Nyx chain Validator set (other tasks they perform include a multisig used for triggering reward payouts to the Network Infrastructure Node Operators and maintaining the global Bloom Filter for double-spend protection).
- **OrderAPI**: an API creating crypto/fiat <> NYM swaps and then depositing the NYM tokens in a smart contract managed by the NymAPI Quroum for payment verification. Implementation details of the API will be released in the coming months.
Generation happens in 3 distinct stages:
- Key Generation & payment
- Issue credential
- Generate unlinkable zk-nyms for Nym Network access
From the perspective of the Requester most of this happens under the hood, but results in the creation and usage of an **unlinkable, rerandomisable anonymous proof-of-payment credential** - a zk-nym - with which to access the Mixnet without fear of doxxing themselves via linking app usage and payment information. The user experience is further enhanced by the fact that a single credential can be split into multiple small zk-nyms, meaning that a Requester may buy a large chunk of bandwidth but 'spend' this in the form of multiple zk-nyms with different ingress Gateways. Whilst this happens under the hood, what it affords the Requester is an ease of experience in that they have to 'top up' their bandwidth less and are able to chop and change ingress points to the Nym Network as they see fit, akin to the UX of most modern day VPNs and dVPNs.
## Key Generation & Payment
- First, a Cosmos [Bech32 address](https://docs.cosmos.network/main/build/spec/addresses/bech32) is created for the Requester. This is used to identify themselves when interacting with the OrderAPI via signed authentication tokens. This is the only identity that the OrderAPI is able to see, and is not able to link this to the zk-nyms that will be generated. This identity never leaves the Requesters device and there is no email or any personal details needed for signup. If a Requester is simply 'topping up' their subscription, the creation of the address is skipped as it already exists.
- The Requester also generates an ed25519 keypair: this is used to identify and authenticate them in the case of using zk-nyms across several devices as an individual user. However, this is never used in the clear: these keys are used as private attribute values within generated credentials which are verified via zero-knowledge.
- The Requester can then interact with various payment backends to pay for their zk-nyms with crypto, fiat options, or natively with NYM tokens.
- Payment options will trigger the OrderAPI. This will:
- Create a swap for <PAYMENT_AMOUNT> <> NYM tokens.
- Deposit these tokens with the NymAPI Quorum via a CosmWasm smart contract deployed on the Nyx blockchain.
- The Requester sends a request to each member of the Quorum requesting a zk-nym credential. This request is signed with their private key and includes the transaction hash of the NYM deposit into the deposit contract, performed either by themselves or the OrderAPI.
<!-- diagram that shows clearly how on the one hand, the Bech32 address is used to identify user towards the OrderAPI for payments, and on the other hand shows how the ed25519 keypair is for identification and authentication for using zk-nym creds -->
## Issue zk-nym
At this point, NYM tokens have been deposited into the smart contract controlled by the Quorum's multisig and a zk-nym credential has been requested. Next, each member of the Quorum who responds to the Requester's request for a zk-nym checks the validity and returns a PSC signed with part of the master key (since this is a threshold cryptsystem, not all members of the Quroum must respond to create a zk-nym, only enough to pass the threshold). The process looks like this:
- Members of the Quroum performs several checks to verify the request is valid:
- They verify the signature sent as part of the request is valid and that the request was made in the last 48 hours.
- They verify that the amount requested matches the amount deposited in the transation, the hash of which was signed by the Requester's ed25519 key and sent as part of the request.
- Members then create a partial blinded signature - a 'partial signed credential' ('PSC') - from their fragment of the master key generated and split amongst them at the beginning of the Quroum in the initial DKG ceremony.
- The member also creates a `key:value` entry in their local cache with the transaction hash as the key, and the PSC + encrypted signature as the value. This is used later for zk-nym validation and is cleaned after a predefined timeout.
- These PSCs are given back to the Requester after setting up a secure channel via DH key exchange, with each replying Quorum member also sending their public key for verification that the returned PSC was signed by them.
Once the Requester has received > threshold number of PSCs they can assemble them into a credential signed by the master key. The Requester never learns this master key (it is a private attribute) but the credential can be verified by the Quroum as being valid by checking for a proof that the credential's private attribute - the value of the master key - is valid.
![steps1-2](../images/zknym/deposit-generate.png)
## Spend zk-nym to Access Mixnet
- Once the credential has been aggregated from the PSCs returned from > threshold of Quorum members, smaller 'zk-nym credits' can be generated from it, accounting for smaller chunks of bandwidth which can be 'spent' with ingress Gateways. This occurs entirely offline, on the device of the zk-nym Requester. See pages on the scheme's [unlinkability](unlinkability.md) and [rerandomisation and incremental spending](./rerandomise.md) features for further information on this.
- This zk-nym credit is later presented to the Quorum by the Gateway that collected it, which is used to calculate reward percentages given to Nym Network infrastructure operators by the Quorum, with payouts triggered by their multisig wallet. Both ingress Gateways and the Quorum use spent zk-nym credits when engaging in [double spending protection](./double-spend-prot.md).
![step3](../images/zknym/use-zknym.png)
@@ -23,7 +23,7 @@ Make sure you do the preparation listed in the [preliminary steps page](initial-
## Gateway setup
Now that you have built the codebase, set up your wallet, and have a VPS with the `nym-gateway` binary, you can set up your gateway with the instructions below.
Now that you have built the codebase, set up your wallet, and have a VPS with the `nym-gateway` binary, you can set up your gateway with the instructions below.
To begin, move to `/target/release` directory from which you run the node commands:
@@ -47,10 +47,10 @@ You can also check the various arguments required for individual commands with:
## Initialising your Gateway
As Nym developers build towards [Exit Gateway](../../legal/exit-gateway.md) functionality, operators can now run their `nym-gateway` binary with inbuilt Network Requester and include the our new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt). Considering the plan to [*smoosh*](../faq/smoosh-faq.md) all the nodes into one binary and have wide opened Exit Gateways, we recommend this setup, instead of operating two separate binaries.
As Nym developers build towards [Exit Gateway](../../legal/exit-gateway.md) functionality, operators can now run their `nym-gateway` binary with inbuilt Network Requester and include the our new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt). Considering the plan to [*smoosh*](../faq/smoosh-faq.md) all the nodes into one binary and have wide opened Exit Gateways, we recommend this setup, instead of operating two separate binaries.
```admonish warning
Before you start an Exit Gateway, read our [Operators Legal Forum](../legal/exit-gateway.md) page and [*Project Smoosh FAQ*](../faq/smoosh-faq.md).
Before you start an Exit Gateway, read our [Operators Legal Forum](../../legal/exit-gateway.md) page and [*Project Smoosh FAQ*](../faq/smoosh-faq.md).
```
```admonish info
@@ -68,9 +68,9 @@ An operator can initialise the Exit Gateway functionality by adding Network Requ
```
You can see that the printed information besides *identity* and *sphinx keys* also includes a long string called *address*. This is the address to be provided to your local [socks5 client](https://nymtech.net/docs/clients/socks5-client.html) as a `--provider` if you wish to connect to your own Exit Gateway.
You can see that the printed information besides *identity* and *sphinx keys* also includes a long string called *address*. This is the address to be provided to your local [socks5 client](https://nymtech.net/docs/clients/socks5-client.html) as a `--provider` if you wish to connect to your own Exit Gateway.
Additionally
Additionally
#### Add Network Requester to an existing Gateway
@@ -83,10 +83,10 @@ See the options:
```
To setup Exit Gateway functionality with our new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) add a flag `--with-exit-policy true`.
To setup Exit Gateway functionality with our new [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) add a flag `--with-exit-policy true`.
```
./nym-gateway setup-network-requester --enabled true --with-exit-policy true --id <ID>
./nym-gateway setup-network-requester --enabled true --with-exit-policy true --id <ID>
```
Say we have a Gateway with `<ID>` as `new-gateway`, originally initialised and ran without the Exit Gateway functionality. To change the setup, run:
@@ -156,7 +156,7 @@ The `run` command starts the Gateway:
## Bonding your Gateway
```admonish info
Before you bond your Gateway, please make sure the [firewall configuration](./maintenance.md#configure-your-firewall) is setup so your Gateway can be reached from the outside. You can also setup WSS and automate your Gateway to simplify the operation overhead. We highly recommend to run any of these steps before bonding to prevent disruption of your Gateway's routing score later on.
Before you bond your Gateway, please make sure the [firewall configuration](../../nodes/maintenance.md#configure-your-firewall) is setup so your Gateway can be reached from the outside. You can also setup WSS and automate your Gateway to simplify the operation overhead. We highly recommend to run any of these steps before bonding to prevent disruption of your Gateway's routing score later on.
```
### Via the Desktop wallet (recommended)
@@ -167,7 +167,7 @@ You can bond your Gateway via the Desktop wallet. **Make sure your Gateway is ru
2. Enter the `Amount`, `Operating cost` and press `Next`.
3. You will be asked to run a the `sign` command with your `gateway` - copy and paste the long signature `<PAYLOAD_GENERATED_BY_THE_WALLET>` and paste it as a value of `--contract-msg` in the following command:
3. You will be asked to run a the `sign` command with your `gateway` - copy and paste the long signature `<PAYLOAD_GENERATED_BY_THE_WALLET>` and paste it as a value of `--contract-msg` in the following command:
```
./nym-gateway sign --id <YOUR_ID> --contract-msg <PAYLOAD_GENERATED_BY_THE_WALLET>
@@ -186,7 +186,7 @@ It will look something like this (as `<YOUR_ID>` we used `supergateway`):
|_| |_|\__, |_| |_| |_|
|___/
(nym-gateway - version v1.1.<XX>)
(nym-gateway - version v1.1.<XX>)
>>> attempting to sign 2Mf8xYytgEeyJke9LA7TjhHoGQWNBEfgHZtTyy2krFJfGHSiqy7FLgTnauSkQepCZTqKN5Yfi34JQCuog9k6FGA2EjsdpNGAWHZiuUGDipyJ6UksNKRxnFKhYW7ri4MRduyZwbR98y5fQMLAwHne1Tjm9cXYCn8McfigNt77WAYwBk5bRRKmC34BJMmWcAxphcLES2v9RdSR68tkHSpy2C8STfdmAQs3tZg8bJS5Qa8pQdqx14TnfQAPLk3QYCynfUJvgcQTrg29aqCasceGRpKdQ3Tbn81MLXAGAs7JLBbiMEAhCezAr2kEN8kET1q54zXtKz6znTPgeTZoSbP8rzf4k2JKHZYWrHYF9JriXepuZTnyxAKAxvGFPBk8Z6KAQi33NRQkwd7MPyttatHna6kG9x7knffV6ebGzgRBf7NV27LurH8x4L1uUXwm1v1UYCA1WSBQ9Pp2JW69k5v5v7G9gBy8RUcZnMbeL26Qqb8WkuGcmuHhaFfoqSfV7PRHPpPT4M8uRqUyR4bjUtSJJM1yh6QSeZk9BEazzoJqPeYeGoiFDZ3LMj2jesbJweQR4caaYuRczK92UGSSqu9zBKmE45a
@@ -206,7 +206,7 @@ It will look something like this (as `<YOUR_ID>` we used `supergateway`):
* And paste it into the wallet nodal, press `Next` and confirm the transaction.
![Paste Signature](../../images/wallet-screenshots/wallet-gateway-sign.png)
![Paste Signature](../../images/wallet-screenshots/wallet-gateway-sign.png)
*This image is just an example, copy-paste your own base58-encoded signature.*
* Your Gateway is now bonded.
@@ -220,4 +220,3 @@ If you want to bond your Gateway via the CLI, then check out the [relevant secti
## Maintenance
For Gateway upgrade, firewall setup, port configuration, API endpoints, VPS suggestions, automation, WSS setup and more, see the [maintenance page](../../nodes/maintenance.md)
@@ -56,9 +56,9 @@ Quite a bit of stuff gets built. The key working parts are:
* [Nym Node](../nodes/nym-node.md): `nym-node`
* [Validator](../nodes/validator-setup.md)
* [websocket client](https://nymtech.net/docs/clients/websocket-client.html): `nym-client`
* [socks5 client](https://nymtech.net/docs/clients/socks5-client.html): `nym-socks5-client`
* [webassembly client](https://nymtech.net/docs/clients/webassembly-client.html): `webassembly-client`
* [websocket client](https://nymtech.net/developers/clients/websocket-client.html): `nym-client`
* [socks5 client](https://nymtech.net/developers/clients/socks5-client.html): `nym-socks5-client`
* [webassembly client](https://nymtech.net/developers/clients/webassembly-client.html): `webassembly-client`
* [nym-cli tool](https://nymtech.net/docs/tools/nym-cli.html): `nym-cli`
* [nym-api](../nodes/nym-api.md): `nym-api`
* [nymvisor](../nodes/nymvisor-upgrade.md): `nymvisor`
+298
View File
@@ -2,6 +2,304 @@
This page displays a full list of all the changes during our release cycle from [`v2024.3-eclipse`](https://github.com/nymtech/nym/blob/nym-binaries-v2024.3-eclipse/CHANGELOG.md) onwards. Operators can find here the newest updates together with links to relevant documentation. The list is sorted so that the newest changes appear first.
## `v2024.9-topdeck`
- [Release binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2024.9-topdeck)
- [Release CHANGELOG.md](https://github.com/nymtech/nym/blob/nym-binaries-v2024.9-topdeck/CHANGELOG.md)
- [`nym-node`](nodes/nym-node.md) version `1.1.6`
~~~admonish example collapsible=true title='CHANGELOG.md'
- chore: fix 1.80 lint issues ([#4731])
- Handle clients with different versions in IPR ([#4723])
- Add 1GB/day/user bandwidth cap ([#4717])
- Feature/merge back ([#4710])
- removed mixnode/gateway config migration code and disabled cli without explicit flag ([#4706])
[#4731]: https://github.com/nymtech/nym/pull/4731
[#4723]: https://github.com/nymtech/nym/pull/4723
[#4717]: https://github.com/nymtech/nym/pull/4717
[#4710]: https://github.com/nymtech/nym/pull/4710
[#4706]: https://github.com/nymtech/nym/pull/4706
~~~
### Features
* [Removed `nym-mixnode` and `nym-gateway` config migration code and disabled CLI without explicit flag](https://github.com/nymtech/nym/pull/4706): Gateway and Mixnode commands now won't do anything without explicit `--force-run` to bypass the deprecation, instead it will tell an operator to run a `nym-node`. The next step, in say a month or so, is to completely remove all `cli` related things.
~~~admonish example collapsible=true title='Testing steps performed'
- Verify that the `nym-gateway` binary and `nym-mixnode` binary commands return the `_error message_` stating to *update to `nym-node`*
- Check that when adding the `--force-run` flag, it still allows the command to be run (aside from `init` which has been removed) and the message stating to update to `nym-node` is a `_warning_` now
- Check `nym-node` is not affected
- Review the changes in the PR
~~~
* [Add 1GB/day/user bandwidth cap](https://github.com/nymtech/nym/pull/4717)
~~~admonish example collapsible=true title='Testing steps performed - Scenario 1: Bandwidth Decreasing Continuously'
1. Start the client and noted the initial bandwidth (e.g., 1GB).
2. Us the client and track bandwidth usage over time (e.g., decrease by 100MB every hour).
3. Restart the client after some usage.
4. Verify the bandwidth continued from the last recorded value, not reset.
**Notes:**
The bandwidth continued decreasing without resetting upon restart. Logs and reports correctly reflected the decreasing bandwidth.
~~~
~~~admonish example collapsible=true title='Testing steps performed - Scenario 2: Bandwidth Reset Next Day'
1. Use the client normally until the end of the day.
2. Suspend some clients and kept others active.
3. Check bandwidth at midnight.
4. Verify that bandwidth reset to 1GB for both suspended and active clients.
**Notes:**
Bandwidth reset to 1GB for all clients at midnight. Logs and reports correctly showed the reset.
~~~
~~~admonish example collapsible=true title='Testing steps performed - Scenario 3: Bandwidth Reset at a Different Time (e.g., Midday)'
1. Configure the system to reset bandwidth at midday.
2. Use the client and monitored bandwidth until midday.
3. Keep the client connected during the reset time.
4. Verify that bandwidth reset to 1GB live at midday.
**Notes:**
Bandwidth reset to 1GB at midday while the client was connected. Logs and reports correctly reflected the reset.
~~~
* [Handle clients with different versions in IPR](https://github.com/nymtech/nym/pull/4723): Allow the IPR to handle clients connecting both using `v6` and `v7`, independently. The motivation is that we want to be able to roll out an API version change gradually for NymVPN clients without breaking backwards compatibility. The main feature on the new `v7` format that is not yet used, is that it adds signatures for connect/disconnect.
~~~admonish example collapsible=true title='Testing steps performed'
Run the same command (using same gateways deployed from this PR) on different versions of the `nym-vpn-cli`.
Example:
```sh
sudo -E ./nym-vpn-cli -c ../qa.env run --entry-gateway-id $entry_gateway --exit-gateway-id $exit_gateway --enable-two-hop
sudo -E ./nym-vpn-cli -c ../qa.env run --entry-gateway-id $entry_gateway --exit-gateway-id $exit_gateway --enable-two-hop
```
~~~
### Bugfix
* [Feature/merge back](https://github.com/nymtech/nym/pull/4710): Merge back from the release branch the changes that fix the `nym-node` upgrades.
* [Fix version `1.x.x` not having template correspondent initially](https://github.com/nymtech/nym/pull/4733): This should fix the problem of config deserialisation when operators upgrade nodes and skip over multiple versions.
~~~admonish example collapsible=true title='Testing steps performed'
- Tested updating an old nym-node version and ensuring it did not throw any errors.
~~~
* [chore: fix 1.80 lint issues](https://github.com/nymtech/nym/pull/4731):
~~~admonish example collapsible=true title='Testing steps performed'
- Building all binaries is ok
- Running `cargo fmt` returns no issues
~~~
### Operators Guide updates
* [WireGuard tunnel configuration guide](nodes/configuration.md#routing-configuration) for `nym-node` (currently Gateways functionalities). For simplicity we made a detailed step by step guide to upgrade an existing `nym-node` to the latest version and configure your VPS routing for WireGuard. Open by clicking on the example block below.
~~~admonish example collapsible=true title='Upgrading `nym-node` with WG'
**Prerequisites**
- **Nym Node Version:** You must be running the `2024.9-topdeck` release branch, which operates as `nym-node` version `1.1.6`. You can find the release here: [Nym 2024.9-topdeck Release](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2024.9-topdeck).
- **Important:** Before proceeding, make sure to [back up](nodes/maintenance.md#backup-a-node) your current `nym-node` configuration to avoid any potential data loss or issues.
- **Download Nym Node:**
- You can download the `nym-node` binary directly using the following command:
```bash
curl -L https://github.com/nymtech/nym/releases/download/nym-binaries-v2024.9-topdeck/nym-node -o nym-node && chmod u+x nym-node
```
**Step 1: Update UFW Firewall Rules**
- **Warning:** Enabling the firewall with UFW without allowing SSH port 22 first will lead to losing access over SSH. Make sure port 22 is allowed before proceeding with any UFW configurations.
Run the following as root or with `sudo` prefix:
1. Check the current status of UFW (Uncomplicated Firewall):
```bash
ufw status
```
2. Ensure that the following ports are allowed on your machine before adding the WireGuard port:
```bash
ufw allow 22/tcp # SSH - you're in control of these ports
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw allow 1789/tcp # Nym specific
ufw allow 1790/tcp # Nym specific
ufw allow 8080/tcp # Nym specific - nym-node-api
ufw allow 9000/tcp # Nym Specific - clients port
ufw allow 9001/tcp # Nym specific - wss port
ufw allow 51822/udp # WireGuard
```
3. Confirm that the UFW rules have been updated:
```bash
ufw status
```
**Step 2: Download and Prepare the Network Tunnel Manager Script**
1. Download the [`network_tunnel_manager.sh`](https://gist.github.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77) script:
```bash
curl -L -o network_tunnel_manager.sh https://gist.githubusercontent.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77/raw/3c0a38c1416f8fdf22906c013299dd08d1497183/network_tunnel_manager.sh
```
2. Make the script executable:
```bash
chmod u+x network_tunnel_manager.sh
```
3. Apply the WireGuard IPTables rules:
```bash
./network_tunnel_manager.sh apply_iptables_rules_wg
```
**Step 3: Update the Nym Node Service File**
1. Modify your [`nym-node` service file](nodes/configuration.md#systemd) to enable WireGuard. Open the file (usually located at `/etc/systemd/system/nym-node.service`) and update the `[Service]` section as follows:
```ini
[Service]
User=<YOUR_USER_NAME>
Type=simple
#Environment=RUST_LOG=debug
# CAHNGE PATH IF YOU DON'T RUN IT FROM ROOT HOME DIRECTORY
ExecStart=/root/nym-node run --mode exit-gateway --id <YOUR_NODE_LOCAL_ID> --accept-operator-terms-and-conditions --wireguard-enabled true
Restart=on-failure
RestartSec=30
StartLimitInterval=350
StartLimitBurst=10
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
# ADD OR TWEAK ANY CUSTOM SETTINGS
```
2. Reload the systemd daemon to apply the changes:
```bash
systemctl daemon-reload
```
3. Restart the `nym-node service`:
```bash
systemctl restart nym-node.service
```
4. Optionally, you can check if the node is running correctly by monitoring the service logs:
```bash
journalctl -u nym-node.service -f -n 100
```
**Step 4: Run the Network Tunnel Manager Script**
Finally, run the following command to initiate our favorite routing test - run the joke through the WireGuard tunnel:
```bash
./network_tunnel_manager.sh joke_through_wg_tunnel
```
- **Note:** Wireguard will return only IPv4 joke, not IPv6. WG IPv6 is under development. Running IPR joke through the mixnet with `./network_tunnel_manager.sh joke_through_the_mixnet` should work with both IPv4 and IPv6!
~~~
* [Change `--wireguard-enabled` flag to `true`](nodes/setup.md#-initialise--run): With a proper [routing configuration](nodes/configuration.md#routing-configuration) `nym-nodes` running as Gateways can now enable WG. See the example below:
~~~admonish example collapsible=true title='Syntax to run `nym-node` with WG enabled'
For Exit Gateway:
```sh
./nym-node run --id <ID> --mode exit-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <COUNTRY_FULL_NAME> --accept-operator-terms-and-conditions --wireguard-enabled true
# <YOUR_DOMAIN> is in format without 'https://' prefix
# <COUNTRY_FULL_NAME> is format like 'Jamaica', or two-letter alpha2 (e.g. 'JM'), three-letter alpha3 (e.g. 'JAM') or three-digit numeric-3 (e.g. '388') can be provided.
# wireguard can be enabled from version 1.1.6 onwards
```
For Entry Gateway:
```sh
./nym-node run --id <ID> --mode entry-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --accept-operator-terms-and-conditions --wireguard-enabled true
# <YOUR_DOMAIN> is in format without 'https://' prefix
# <COUNTRY_FULL_NAME> is format like 'Jamaica', or two-letter alpha2 (e.g. 'JM'), three-letter alpha3 (e.g. 'JAM') or three-digit numeric-3 (e.g. '388') can be provided.
# wireguard can be enabled from version 1.1.6 onwards
```
~~~
* [Update Nym exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt): Based on the survey, AMA and following discussions we added several ports to Nym exit policy. The ports voted upon in the [forum governance](https://forum.nymtech.net/t/poll-a-new-nym-exit-policy-for-exit-gateways-and-the-nym-mixnet-is-inbound/464) have not been added yet due to the concerns raised. These ports were unrestricted:
~~~admonish example collapsible=true title='Newly opened ports in Nym exit policy'
```
22 # SSH
123 # NTP
445 # SMB file share Windows
465 # URD for SSM
587 # SMTP
853 # DNS over TLS
1433 # databases
1521 # databases
2049 # NFS
3074 # Xbox Live
3306 # databases
5000-5005 # RTP / VoIP
5432 # databases
6543 # databases
8080 # HTTP Proxies
8767 # TeamSpeak
8883 # Secure MQ Telemetry Transport - MQTT over SSL
9053 # Tari
9339 # gaming
9443 # alternative HTTPS
9735 # Lightning
25565 # Minecraft
27000-27050 # Steam and game servers
60000-61000 # MOSH
```
~~~
* [Create a NymConnect archive page](https://nymtech.net/developers/archive/nym-connect.html), PR [\#4750](https://github.com/nymtech/nym/commit/5096c1e60e203dcf8be934823946e24fda16a9a3): Archive deprecated NymConnect for backward compatibility, show PEApps examples for both NC and maintained `nym-socks5-client`.
* Fix broken URLs and correct redirection. PRs: [\#4745](https://github.com/nymtech/nym/commit/7e36595d8fa7706876880b42df1c998a4b8c1478), [\#4752](https://github.com/nymtech/nym/commit/1db61f800c6884e284c5ab21e7abce3bc6d91d99) [\#4755](https://github.com/nymtech/nym/commit/aaf3dca5b999ad7f19d2ff170078b43c9c4476c2), [\#4737](https://github.com/nymtech/nym/commit/6f669866e92e637772726ad05caa5c5501a830f3)
~~~admonish example collapsible=true title='Testing steps performed'
- Use [deadlinkchecker.com](https://www.deadlinkchecker.com/website-dead-link-checker.asp) to go over `nymtech.net` and correct all docs URLs
- Go over search engines and old medium articles and check that all dead URLs re-directing correctly
~~~
* [Clarify syntax on `nym-nodes` ports on VPS setup page](https://nymtech.net/operators/nodes/vps-setup.html#configure-your-firewall), PR [\#4734](https://github.com/nymtech/nym/commit/5e6417f83788f30b2a84e4dd73d6dd9619a2bb16): Make crystal clear that the addresses and ports in operators `config.toml` must be opened using [`ufw`](https://nymtech.net/operators/nodes/vps-setup.html#configure-your-firewall) and set up as in the example below:
~~~admonish example collapsible=true title='snap of binding addresses and ports in `config.toml`'
```toml
[host]
public_ips = [
'<YOUR_PUBLIC_IPv4>'
]
[mixnet]
bind_address = '0.0.0.0:1789'
[http]
bind_address = '0.0.0.0:8080'
[mixnode]
[mixnode.verloc]
bind_address = '0.0.0.0:1790'
[entry_gateway]
bind_address = '0.0.0.0:9000'
```
~~~
### Tooling
* [Nym Harbourmaster](https://https://harbourmaster.nymtech.net/) has now several new functionalities:
- Tab for Mixnodes
- Tab with Charts
- New columns with: *Moniker (node description)*, *DP delegatee*, *Accepted T&Cs* - also part of a new category 🐼😀
* Nym has a new [Token page](https://nymtech.net/about/token)
---
## `v2024.8-wispa`
- [Release binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2024.8-wispa)
@@ -6,7 +6,8 @@ The entire content of this page is under [Creative Commons Attribution 4.0 Inter
This page is a part of Nym Community Legal Forum and its content is composed by shared advices in [Node Operators Legal Forum](https://matrix.to/#/!YfoUFsJjsXbWmijbPG:nymtech.chat?via=nymtech.chat&via=matrix.org) (Matrix chat) as well as though pull requests done by the node operators directly to our [repository](https://github.com/nymtech/nym/tree/develop/documentation/operators/src), reviewed by Nym DevRels.
This document presents an initiative to further support Nyms mission of allowing privacy for everyone everywhere. This would be achieved with the support of Nym node operators operating Gateways and opening these to any online service. Such setup needs a **clear policy**, one which will remain the **same for all operators** running Nym nodes. The [proposed **Exit policy**](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) is a combination of two existing safeguards: [Tor Null deny list](https://tornull.org/) and [Tor reduced policy](https://tornull.org/tor-reduced-reduced-exit-policy.php).
This document presents an initiative to further support Nyms mission of allowing privacy for everyone everywhere. This would be achieved with the support of Nym node operators operating Gateways and opening these to any online service. Such setup needs a **clear policy**, one which will remain the **same for all operators** running Nym nodes. [**Nym exit policy**](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) is a combination of safeguards like (nowadays deprecated) `Tor Null deny list` and `Tor reduced policy` together with changes decided by Nym operators community through the governance (like in this [vote](https://forum.nymtech.net/t/poll-a-new-nym-exit-policy-for-exit-gateways-and-the-nym-mixnet-is-inbound/464)). This policy aims to find a healthy compromise between protecting the operators and NymVPN users against attacks while allowing for as wide experience when accessing the internet through Nym Network.
All the technical changes on the side of Nym nodes - ***Project Smoosh*** - are described in the [FAQ section](../archive/faq/smoosh-faq.md).
@@ -17,13 +18,13 @@ Nym core team cannot provide comprehensive legal advice across all jurisdictions
## Summary
* This document outlines a plan to change Nym Gateways from operating with an allow to a deny list to enable broader uptake and usage of the Nym Mixnet. It provides operators with an overview of the plan, pros and cons, legal as well as technical advice.
* This document outlines a plan to change Nym Gateways from operating with an allow to a deny list to enable broader uptake and usage of the Nym Mixnet. It provides operators with an overview of the plan, pros and cons, legal as well as technical advice.
* Nym is committed to ensuring privacy for all users, regardless of their location and for the broadest possible range of online services. In order to achieve this aim, the Nym Mixnet needs to increase its usability across a broad range of apps and services.
* Currently, Nym Gateway nodes only enable access to apps and services that are on an allow list that is maintained by the core team.
* Currently, Nym Gateway nodes only enable access to apps and services that are on an allow list that is maintained by the core team.
* To decentralise and enable privacy for a broader range of services, this initiative will have to transition from the current allow list to a deny list - [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt). In accordance with the [Tor Null 'deny' list](https://tornull.org/) and [Tor reduced policy](https://tornull.org/tor-reduced-reduced-exit-policy.php), which are two established safeguards.
* To decentralise and enable privacy for a broader range of services, this initiative will have to transition from the current allow list to a deny list - [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt). In accordance with the (nowadays deprecated) `Tor Null deny list` and `Tor reduced policy` together with changes decided by Nym operators community through the governance (like in this [vote](https://forum.nymtech.net/t/poll-a-new-nym-exit-policy-for-exit-gateways-and-the-nym-mixnet-is-inbound/464))
* This will enhance the usage and appeal of Nym products for end users. As a result, increased usage will ultimately lead to higher revenues for Nym operators.
@@ -52,7 +53,7 @@ Previous setup: Running nodes supporting strict SOCKS5 app-based traffic
| Technical | - No changes required in technical setup | |
| Operational | - No impact on operators operations (e.g., relationships with VPS providers)<br>- Low overhead<br>- Can be run as an individual | |
| Legal | - Limited legal risks for operators | |
| Financial | | - Low revenues for operators due to limited product traction |
| Financial | | - Low revenues for operators due to limited product traction |
The new setup: Running nodes supporting traffic of any online service (with safeguards in the form of a denylist)
@@ -66,13 +67,13 @@ The new setup: Running nodes supporting traffic of any online service (with safe
## Exit Gateways: New setup
In our previous technical setup, Network Requesters acted as a proxy, and only made requests that match an allow list. That was a default IP based list of allowed domains stored at Nym page in a centralised fashion possibly re-defined by any Network Requester operator.
In our previous technical setup, Network Requesters acted as a proxy, and only made requests that match an allow list. That was a default IP based list of allowed domains stored at Nym page in a centralised fashion possibly re-defined by any Network Requester operator.
This restricts the hosts that the NymConnect app can connect to and has the effect of selectively supporting messaging services (e.g. Telegram, Matrix) or crypto wallets (e.g. Electrum or Monero). Operators of Network Requesters can have confidence that the infrastructure they run only connects to a limited set of public internet hosts.
The principal change in the new configuration is to make this short allow list more permissive. Nym's [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) will restrict the hosts to which Nym Mixnet and Nym VPN users are permitted to connect. This will be done in an effort to protect the operators, as Gateways will act both as SOCKS5 Network Requesters, and exit nodes for IP traffic from Nym Mixnet VPN and VPN clients (both wrapped in the same app).
The principal change in the new configuration is to make this short allow list more permissive. Nym's [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) will restrict the hosts to which Nym Mixnet and Nym VPN users are permitted to connect. This will be done in an effort to protect the operators, as Gateways will act both as SOCKS5 Network Requesters, and exit nodes for IP traffic from Nym Mixnet VPN and VPN clients (both wrapped in the same app).
As of now we the Gateways will be defaulted to a combination of [Tor Null deny list](https://tornull.org/) (note: Not affiliated with Tor) - reproduction permitted under Creative Commons Attribution 3.0 United States License which is IP-based, e.g., `ExitPolicy reject 5.188.10.0/23:*` and [Tor reduced policy](https://tornull.org/tor-reduced-reduced-exit-policy.php). Whether we will stick with this list, do modifications or compile another one is still a subject of discussion. In all cases, this policy will remain the same for all the nodes, without any option to modify it by Nym node operators to secure stable and reliable service for the end users.
As of now we the Gateways will be defaulted to a combination of (nowadays deprecated) `Tor Null deny list` (note: Tornull is not affiliated with Tor Project) - reproduction permitted under Creative Commons Attribution 3.0 United States License which is IP-based, e.g., `ExitPolicy reject 5.188.10.0/23:*` and `Tor reduced policy` together with changes decided by Nym operators community through the governance (like in this [vote](https://forum.nymtech.net/t/poll-a-new-nym-exit-policy-for-exit-gateways-and-the-nym-mixnet-is-inbound/464)). This policy will remain the same for all the nodes, without any option to modify it by Nym node operators individually, to secure stable and reliable service for the end users.
For exit relays on ports 80 and 443, the Gateways will exhibit an HTML page resembling the one proposed by [Tor](https://gitlab.torproject.org/tpo/core/tor/-/raw/HEAD/contrib/operator-tools/tor-exit-notice.html). By doing so, the operator will be able to disclose details regarding their Gateway, including the currently configured exit policy, all without the need for direct correspondence with regulatory or law enforcement agencies. It also makes the behavior of Exit Gateways transparent and even computable (a possible feature would be to offer a machine readable form of the notice in JSON or YAML).
@@ -82,14 +83,14 @@ We also recommend operators to check the technical advice from [Tor](https://com
Giving the legal similarity between Nym Exit Gateways and Tor Exit Relays, it is helpful to have a look in [Tor community Exit Guidelines](https://community.torproject.org/relay/community-resources/tor-exit-guidelines/). This chapter is an exert of tor page.
Note that Tor states:
Note that Tor states:
> This FAQ is for informational purposes only and does not constitute legal advice.
*Check legal advice prior to running an exit relay*
*Check legal advice prior to running an exit relay*
* Understand the risks associated with running an exit relay; E.g., know legal paragraphs relevant in the country of operations:
- US [DMCA 512](https://www.law.cornell.edu/uscode/text/17/512); see [EFF's Legal FAQ for Tor Operators](https://community.torproject.org/relay/community-resources/eff-tor-legal-faq) (a very good and relevant read for other countries as well)
- Germanys [TeleMedienGesetz 8](http://www.gesetze-im-internet.de/tmg/__8.html) and [15](http://www.gesetze-im-internet.de/tmg/__15.html)
- Germanys [TeleMedienGesetz 8](https://www.gesetze-im-internet.de/tmg/__8.html) and 15](https://www.gesetze-im-internet.de/tmg/__15.html)
- Netherlands: [Artikel 6:196c BW](http://wetten.overheid.nl/BWBR0005289/Boek6/Titel3/Afdeling4A/Artikel196c/)
- Austria: [E-Commerce-Gesetz 13](http://www.ris.bka.gv.at/Dokument.wxe?Abfrage=Bundesnormen&Dokumentnummer=NOR40025809)
- Sweden: [16-19 2002:562](https://lagen.nu/2002:562#P16S1)
@@ -100,9 +101,9 @@ Note that Tor states:
* Consult a lawyer / local digital rights association / the EFF prior to operating an exit relay, especially in a place where exit relay operators have been harassed or not operating before. Note that Tor DOES NOT provide legal advice for specific countries. It only provides general advice (itself or in partnership), eventually skewed towards [US audiences](https://www.eff.org/pages/legal-faq-tor-relay-operators).
*Run an exit relay within an entity*
*Run an exit relay within an entity*
As an organisation - it might help from a liability perspective
As an organisation - it might help from a liability perspective
* Within your university
* With a node operators association (e.g., a Torservers.net partner)
* Within a company
@@ -114,7 +115,7 @@ As an organisation - it might help from a liability perspective
* Note that Tor states: *“We are not aware of any case that made it near a court, and we will do everything in our power to support you if it does.”*
* Document experience with ISPs at [community.torproject.org/relay/community-resources/good-bad-isps](https://community.torproject.org/relay/community-resources/good-bad-isps/)
Useful links:
Useful links:
* Tor abuse templates:
- [community.torproject.org/relay/community-resources/tor-abuse-templates/](https://community.torproject.org/relay/community-resources/tor-abuse-templates/)
@@ -140,7 +140,7 @@ Basically, you want the full `/<PATH>/<TO>/nym-mixnode run --id <WHATEVER-YOUR-N
#### Following steps for Nym nodes running as `systemd` service
Once your init file is save follow these steps:
Once your `init` file is saved follow these steps:
1. Reload systemctl to pickup the new unit file
```sh
@@ -189,20 +189,30 @@ This lets your operating system know it's ok to reload the service configuration
During our ongoing testing events [Fast and Furious](https://nymtech.net/events/fast-and-furious) we found out, that after introducing IP Packet Router (IPR) and [Nym exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) on embedded Network Requester (NR) by default, only a fragment of Gateways routes correctly through IPv4 and IPv6. We built a useful monitor to check out your Gateway (`nym-node --mode exit-gateway`) at [harbourmaster.nymtech.net](https://harbourmaster.nymtech.net/).
IPv6 routing is not only a case for gateways. Imagine a rare occassion when you run a `mixnode` without IPv6 enabled and a client will sent IPv6 packets through the Mixnet through such route:
IPv6 routing is not only a case for gateways. Imagine a rare occasion when you run a `mixnode` without IPv6 enabled and a client will sent IPv6 packets through the Mixnet through such route:
```ascii
[client] -> [entry-gateway] -> [mixnode layer 1] -> [your mixnode] -> [IPv6 mixnode layer3] -> [exit-gateway]
```
In this (unusual) case your `mixnode` will not be able to route the packets. The node will drop the packets and its performance would go down. For that reason it's beneficial to have IPv6 enabled when running a `mixnode` functionality.
### Quick IPv6 Check
```admonish info
We recommend operators to configure their `nym-node` with the full routing configuration.
```admonish caution
Make sure to keep your IPv4 address enabled while setting up IPv6, as the majority of routing goes through that one!
However, most of the time the packets sent through the Mixnet are IPv4 based. The IPv6 packets are still pretty rare and therefore it's not mandatory from operational point of view to have this configuration implemented if you running only `mixnode` mode.
If you preparing to run a `nym-node` with all modes enabled in the future, this setup is required.
```
```admonish tip title="Delegation Program"
For everyone participating in Delegation Program or Service Grant program, this setup is a requirement!
```
### Quick IPv6 Check
You can always check IPv6 address and connectivity by using some of these methods:
~~~admonish example collapsible=true
```sh
# locally listed IPv6 addresses
ip -6 addr
@@ -221,55 +231,69 @@ curl -6 https://ipv6.icanhazip.com
# using telnet
telnet -6 ipv6.telnetmyip.com
```
~~~
### IPv6 Configuration
```admonish caution
Make sure to keep your IPv4 address enabled while setting up IPv6, as the majority of routing goes through that one!
```
While we're working on Rust implementation to have these settings as a part of the binary build, we wrote a script to solve these connectivity requirements in the meantime we wrote a script [`network_tunnel_manager.sh`](https://gist.github.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77) to support the operators to configure their servers and address all the connectivity requirements.
### Routing Configuration
While we're working on Rust implementation to have these settings as a part of the binary build, to solve these connectivity requirements in the meantime we wrote a script [`network_tunnel_manager.sh`](https://gist.github.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77) to support the operators to configure their servers and address all the connectivity requirements.
Networking configuration across different ISPs and various operation systems does not have a generic solution. If the provided configuration setup doesn't solve your problem check out [IPv6 troubleshooting](../troubleshooting/vps-isp.md#ipv6-troubleshooting) page. Be aware that you may have to do more research and customised adjustments.
#### Mode: `exit-gateway`
The `nymtun0` interface is dynamically managed by the `exit-gateway` service. When the service is stopped, `nymtun0` disappears, and when started, `nymtun0` is recreated.
The script should be used in a context where `nym-node --mode exit-gateway` is running to fully utilise its capabilities, particularly for fetching IPv6 addresses or applying network rules that depend on the `nymtun0` interface.
The script should be used in a context where `nym-node`is running to fully utilise its capabilities, particularly for fetching IPv6 addresses or applying network rules that depend on the `nymtun0` interface and to establish a WireGuard tunnel.
Before starting with the following, make sure you have the [latest `nym-node` binary](https://github.com/nymtech/nym/releases/) installed and your [VPS setup](vps-setup.md) finished properly!
1. Download `network_tunnel_manager.sh`, make executable and run:
```sh
curl -o network_tunnel_manager.sh -L https://gist.githubusercontent.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77/raw/9d785d6ee3aa2970553633eccbd89a827f49fab5/network_tunnel_manager.sh && chmod +x network_tunnel_manager.sh && ./network_tunnel_manager.sh
curl -L -o network_tunnel_manager.sh https://gist.githubusercontent.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77/raw/3c0a38c1416f8fdf22906c013299dd08d1497183/network_tunnel_manager.sh && \
chmod +x network_tunnel_manager.sh && \
./network_tunnel_manager.sh
```
Here is a quick command explanation, for more details on the `network_tunnel_manager.sh` script, refer to the [overview](https://gist.github.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77) under the code block.
2. Make sure your `nym-node` service is up and running
- **If you setting up a new node and not upgrading an existing one, keep it running and [bond](bonding.md) your node now**. Then come back here and follow the rest of the configuration.
~~~admonish example collapsible=true title="A summarized usage of `network_tunnel_manager.sh`"
```admonish tip title=""
Run the following steps as root or with `sudo` prefix!
```
3. Display IPv6:
- At this point you should see a `global ipv6` address.
```sh
summary:
This is a comprehensive script for configuring network packet forwarding and iptables rules,
aimed at ensuring smooth operation of a tunnel interface.
It includes functionality for both setup and tear-down of nymtun network configurations,
alongside diagnostics for verifying system settings and network connectivity.
* fetch_ipv6_address_nym_tun - Fetches the IPv6 address assigned to the 'nymtun0'.
* fetch_and_display_ipv6 - Displays the IPv6 address on the default network device.
* apply_iptables_rules - Applies necessary IPv4 and IPv6 iptables rules.
* remove_iptables_rules - Removes applied IPv4 and IPv6 iptables rules.
* check_ipv6_ipv4_forwarding - Checks if IPv4 and IPv6 forwarding are enabled.
* check_nymtun_iptables - Check nymtun0 device
* perform_ipv4_ipv6_pings - Perform ipv4 and ipv6 pings to google
* check_ip6_ipv4_routing - Check ipv6 and ipv4 routing
* joke_through_the_mixnet - Run a joke through the mixnet via ipv4 and ipv6
./network_tunnel_manager.sh fetch_and_display_ipv6
```
~~~admonish example collapsible=true title="Correct `./network_tunnel_manager.sh fetch_and_display_ipv6` output:"
```sh
iptables-persistent is already installed.
Using IPv6 address: 2001:db8:a160::1/112 #the address will be different for you
operation fetch_ipv6_address_nym_tun completed successfully.
```
~~~
- To run the script next time, just enter `./network_tunnel_manager <ARG>`
2. Make sure your `nym-node --mode exit-gateway` service is up running
3. Check Nymtun IP tables:
4. Apply the rules for IPv4 and IPv6:
```sh
sudo ./network_tunnel_manager.sh check_nymtun_iptables
./network_tunnel_manager.sh apply_iptables_rules
```
- The process may prompt you if you want to save current IPv4 and IPv6 rules, choose yes.
![](../images/ip_table_prompt.png)
5. Check Nymtun IP tables:
- If there's no process running it wouldn't return anything.
- In case you see `nymtun0` but not active, this is probably because you are setting up a new (never bonded) node and not upgrading an existing one.
```sh
./network_tunnel_manager.sh check_nymtun_iptables
```
~~~admonish example collapsible=true title="Correct `./network_tunnel_manager.sh check_nymtun_iptables` output:"
@@ -303,40 +327,19 @@ operation check_nymtun_iptables completed successfully.
```
~~~
- If there's no process running it wouldn't return anything.
- In case you see `nymtun0` but not active, this is probably because you are setting up a new (never bonded) node and not upgrading an exisitng one. In that case you need to [bond](bonding.md) your node now.
6. Apply the rules for WG routing:
4. Display IPv6:
```sh
sudo ./network_tunnel_manager.sh fetch_and_display_ipv6
```
- if you have a `global ipv6` address this is good
~~~admonish example collapsible=true title="Correct `./network_tunnel_manager.sh fetch_and_display_ipv6` output:"
```sh
iptables-persistent is already installed.
Using IPv6 address: 2001:db8:a160::1/112 #the address will be different for you
operation fetch_ipv6_address_nym_tun completed successfully.
```
~~~
5. Apply the rules:
```sh
sudo ./network_tunnel_manager.sh apply_iptables_rules
./network_tunnel_manager.sh apply_iptables_rules_wg
```
- The process may prompt you if you want to save current IPv4 and IPv6 rules, choose yes.
7. At this point your node needs to be [bonded](bonding.md) to the API for `nymtun0` to interact with the network. After bonding please follow up with the remaining steps below to ensure that your node is routing properly.
![](../images/ip_table_prompt.png)
- check IPv6 again like in point 3
6. At this point your node needs to be [bonded](bonding.md) to the API for `nymtun0` to interact with the network. After bonding please follow up with the remaining streps below to ensure that your Exit Gateway is routing properly.
7. Check `nymtun0` interface:
8. Check `nymtun0` interface:
```sh
ip addr show nymtun0
```
~~~admonish example collapsible=true title="Correct `ip addr show nymtun0` output:"
```sh
# your addresses will be different
@@ -351,82 +354,30 @@ ip addr show nymtun0
```
~~~
8. Validate your IPv6 and IPv4 networking by running a joke via Mixnet:
9. Validate your IPv6 and IPv4 networking by running a joke test via Mixnet:
```sh
sudo ./network_tunnel_manager.sh joke_through_the_mixnet
./network_tunnel_manager.sh joke_through_the_mixnet
```
Make sure that you get the validation of IPv4 and IPv6 connectivity. If there are still any problems, please refer to [troubleshooting section](../troubleshooting/vps-isp.md#incorrect-gateway-network-check).
#### Mode: `mixnode`
```admonish caution title=""
Most of the time the packets sent through the Mixnet are IPv4 based. The IPv6 packets are still pretty rare and therefore it's not mandatory from operational point of view. If you preparing to run a `nym-node` with all modes enabled once this option is implemented, then the IPv6 setup on your VPS is required.
```
1. Download `network_tunnel_manager.sh`, make executable and run:
10. Validate your tunneling by running a joke test via WG:
```sh
curl -o network_tunnel_manager.sh -L https://gist.githubusercontent.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77/raw/9d785d6ee3aa2970553633eccbd89a827f49fab5/network_tunnel_manager.sh && chmod +x network_tunnel_manager.sh && ./network_tunnel_manager.sh
./network_tunnel_manager.sh joke_through_wg_tunnel
```
Here is a quick command explanation, for more details on the `network_tunnel_manager.sh` script, refer to the [overview](https://gist.github.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77) under the code block. Mind that for `mixnode` VPS setup we will use only a few of the commands.
- **Note:** WireGuard will return only IPv4 joke, not IPv6. WG IPv6 is under development. Running IPR joke through the mixnet with `./network_tunnel_manager.sh joke_through_the_mixnet` should work with both IPv4 and IPv6!
~~~admonish example collapsible=true title="A summarized usage of `network_tunnel_manager.sh`"
11. Now you can run your node with the `--wireguard-enabled true` flag or add it to your [systemd service config](#systemd). Restart your `nym-node` or [systemd](#following-steps-for-nym-nodes-running-as-systemd-service) service (recommended):
```sh
summary:
This is a comprehensive script for configuring network packet forwarding and iptables rules,
aimed at ensuring smooth operation of a tunnel interface.
It includes functionality for both setup and tear-down of nymtun network configurations,
alongside diagnostics for verifying system settings and network connectivity.
* fetch_ipv6_address_nym_tun - Fetches the IPv6 address assigned to the 'nymtun0'.
* fetch_and_display_ipv6 - Displays the IPv6 address on the default network device.
* apply_iptables_rules - Applies necessary IPv4 and IPv6 iptables rules.
* remove_iptables_rules - Removes applied IPv4 and IPv6 iptables rules.
* check_ipv6_ipv4_forwarding - Checks if IPv4 and IPv6 forwarding are enabled.
* check_nymtun_iptables - Check nymtun0 device
* perform_ipv4_ipv6_pings - Perform ipv4 and ipv6 pings to google
* check_ip6_ipv4_routing - Check ipv6 and ipv4 routing
* joke_through_the_mixnet - Run a joke through the mixnet via ipv4 and ipv6
systemctl daemon-reload && systemctl restart nym-node.service
```
~~~
- To run the script next time, just enter `./network_tunnel_manager <ARG>`
2. Display IPv6:
- Optionally, you can check if the node is running correctly by monitoring the service logs:
```sh
sudo ./network_tunnel_manager.sh fetch_and_display_ipv6
```
- if you have a `global ipv6` address this is good
~~~admonish example collapsible=true title="Correct `./network_tunnel_manager.sh fetch_and_display_ipv6` output:"
```sh
iptables-persistent is already installed.
Using IPv6 address: 2001:db8:a160::1/112 #the address will be different for you
operation fetch_ipv6_address_nym_tun completed successfully.
```
~~~
3. Apply the rules:
```sh
sudo ./network_tunnel_manager.sh apply_iptables_rules
journalctl -u nym-node.service -f -n 100
```
- The process may prompt you if you want to save current IPv4 and IPv6 rules, choose yes.
Make sure that you get the validation of all connectivity. If there are still any problems, please refer to [troubleshooting section](../troubleshooting/vps-isp.md#incorrect-gateway-network-check).
![](../images/ip_table_prompt.png)
- check IPv6 again like in point 2
4. Check connectivity
```sh
telnet -6 ipv6.telnetmyip.com
```
Make sure that you get the validation of IPv4 and IPv6 connectivity. If there are still any problems, please refer to [troubleshooting section](../troubleshooting/vps-isp.md#incorrect-gateway-network-check).
## Next Steps
There are a few more good suggestions for `nym-node` VPS configuration, especially to be considered for `exit-gateway` functionality, like Web Secure Socket or Reversed Proxy setup. Visit [Proxy configuration](proxy-configuration.md) page to see the guides.
There are a few more good suggestions for `nym-node` configuration, like Web Secure Socket or Reversed Proxy setup. These are optional and you can skip them if you want. Visit [Proxy configuration](proxy-configuration.md) page to see the guides.
@@ -344,22 +344,18 @@ less ~/.nym/nym-nodes/default-nym-node/config/config.toml
## Ports
All `<NODE>`-specific port configuration can be found in `$HOME/.nym/<NODE>/<YOUR_ID>/config/config.toml`. If you do edit any port configs, remember to restart your client and node processes.
### Nym Node: Mixnode mode port reference
### Nym Node Port Reference
| Default port | Use |
| ------------ | ------------------------- |
| `1789` | Listen for Mixnet traffic |
| `1790` | Listen for VerLoc traffic |
| `8080` | Metrics http API endpoint |
### Nym Node: Gateway modes port reference
| Default port | Use |
|--------------|---------------------------|
| `1789` | Listen for Mixnet traffic |
| `9000` | Listen for Client traffic |
| `9001` | WSS |
| `51822/udp` | WireGuard |
### Validator port reference
### Validator Port Reference
All validator-specific port configuration can be found in `$HOME/.nymd/config/config.toml`. If you do edit any port configs, remember to restart your validator.
| Default port | Use |
+14 -8
View File
@@ -6,21 +6,25 @@ If you are a `nym-mixnode` or `nym-gateway` operator and you are not familiar wi
NYM NODE is a tool for running a node within the Nym network. Nym Nodes containing functionality such as `mixnode`, `entry-gateway` and `exit-gateway` are fundamental components of Nym Mixnet architecture. Nym Nodes are ran by decentralised node operators.
To setup any type of Nym Node, start with either building [Nym's platform](../binaries/building-nym.md) from source or download [pre-compiled binaries](../binaries/pre-built-binaries.md) on the [configured server (VPS)](vps-setup.md) where you want to run the node. Nym Node will need to be bond to [Nym's wallet](wallet-preparation.md). Follow [preliminary steps](preliminary-steps.md) page before you initialise and run a node.
To setup any type of Nym Node, start with either building [Nym's platform](../binaries/building-nym.md) from source or download [pre-compiled binaries](../binaries/pre-built-binaries.md) on the [configured server (VPS)](vps-setup.md) where you want to run the node. Your Nym Node will need to be bonded before it can be run. We recommend most users use the [Nym desktop wallet](wallet-preparation.md) for this.
```admonish info
**Migrating an existing node to a new `nym-node` is simple. The steps are documented on the [next page](setup.md#migrate)**
```
**Follow [preliminary steps](preliminary-steps.md) page before you configure and run a `nym-node`!**
## Steps for Nym Node Operators
Once VPS and Nym wallet are configured, binaries ready, the operators of `nym-node` need to:
Once [VPS and Nym wallet are configured](preliminary-steps.md), binaries ready, the operators of `nym-node` need to:
1. **[Setup & Run](setup.md) the node**
1. **[Setup](setup.md) the node**
2. **[Configure](configuration.md) the node** (and optionally WSS, reversed proxy, automation)
2. **[Configure](configuration.md) the node and optionally automation, Wireguard, WSS, reversed proxy ...**
3. **[Bond](bonding.md) the node to the Nym API, using Nym wallet**
3. **[Run](setup.md#initialise--run) the node or [the service](configuration.md#following-steps-for-nym-nodes-running-as-systemd-service)**
4. **[Bond](bonding.md) the node to the Nym API, using Nym wallet**
Make sure to follow the steps thoroughly, in case you find any point difficult don't hesitate to ask in our [Operators channel](https://matrix.to/#/#operators:nymtech.chat).
<!-- COMMENTING OUT
## Quick `nym-node --mode exit-gateway` Setup
@@ -98,3 +102,5 @@ ip addr show nymtun0
```sh
sudo ./network_tunnel_manager.sh joke_through_the_mixnet
```
-->
+16 -9
View File
@@ -82,10 +82,8 @@ To list all available flags for each command, run `./nym-node <COMMAND> --help`
```
~~~
```admonish bug
The Wireguard flags currently have limited functionality. This feature is under development and testing.
**Keep Wireguard disabled for the time being!**
```admonish warning
The Wireguard flags currently have limited functionality. From version `1.1.6` ([`v2024.9-topdeck`](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2024.9-topdeck)) wireguard is available and recommended to be switched on for nodes running as Gateways. Keep in mind that this option needs a bit of a special [configuration](configuration.md#wireguard-setup).
```
#### Flags Summary
@@ -170,11 +168,11 @@ To prevent over-flooding of our documentation we cannot provide with every singl
./nym-node run --mode exit-gateway
# with other options
./nym-node run --id <ID> --mode exit-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <COUNTRY_FULL_NAME> --accept-operator-terms-and-conditions --wireguard-enabled false
./nym-node run --id <ID> --mode exit-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <COUNTRY_FULL_NAME> --accept-operator-terms-and-conditions --wireguard-enabled true
# <YOUR_DOMAIN> is in format without 'https://' prefix
# <COUNTRY_FULL_NAME> is format like 'Jamaica', or two-letter alpha2 (e.g. 'JM'), three-letter alpha3 (e.g. 'JAM') or three-digit numeric-3 (e.g. '388') can be provided.
# keep wireguard disabled
# wireguard can be enabled from version 1.1.6 onwards
```
**Initialise only** without running the node with `--init-only` command :
@@ -184,11 +182,11 @@ To prevent over-flooding of our documentation we cannot provide with every singl
./nym-node run --init-only --mode exit-gateway
# with a custom `--id` and other options
./nym-node run --id <ID> --init-only --mode exit-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <COUNTRY_FULL_NAME> --accept-operator-terms-and-conditions --wireguard-enabled false
./nym-node run --id <ID> --init-only --mode exit-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --location <COUNTRY_FULL_NAME> --accept-operator-terms-and-conditions --wireguard-enabled true
# <YOUR_DOMAIN> is in format without 'https://' prefix
# <COUNTRY_FULL_NAME> is format like 'Jamaica', or two-letter alpha2 (e.g. 'JM'), three-letter alpha3 (e.g. 'JAM') or three-digit numeric-3 (e.g. '388') can be provided.
# keep wireguard disabled
# wireguard can be enabled from version 1.1.6 onwards
```
Run the node with custom `--id` without initialising, using `--deny-init` command
@@ -203,7 +201,16 @@ Run the node with custom `--id` without initialising, using `--deny-init` comman
./nym-node run --mode entry-gateway
```
Initialise only with a custom `--id` and `--init-only` command:
Initialise & run with all options
```sh
./nym-node run --id <ID> --mode entry-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --accept-operator-terms-and-conditions --wireguard-enabled true
# <YOUR_DOMAIN> is in format without 'https://' prefix
# <COUNTRY_FULL_NAME> is format like 'Jamaica', or two-letter alpha2 (e.g. 'JM'), three-letter alpha3 (e.g. 'JAM') or three-digit numeric-3 (e.g. '388') can be provided.
# wireguard can be enabled from version 1.1.6 onwards
```
Initialise only, with an `--init-only` command (a custom `--id` used):
```sh
./nym-node run --id <ID> --init-only --mode entry-gateway --public-ips "$(curl -4 https://ifconfig.me)" --hostname "<YOUR_DOMAIN>" --http-bind-address 0.0.0.0:8080 --mixnet-bind-address 0.0.0.0:1789 --accept-operator-terms-and-conditions
```
+18 -9
View File
@@ -97,18 +97,26 @@ ufw enable
ufw status
```
2. Open all needed ports to have your firewall working correctly:
2. Open all needed ports to have your firewall for `nym-node` working correctly:
```sh
# for nym-node
ufw allow 1789,1790,8080,9000,9001,22/tcp
ufw allow 22/tcp # SSH - you're in control of these ports
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw allow 1789/tcp # Nym specific
ufw allow 1790/tcp # Nym specific
ufw allow 8080/tcp # Nym specific - nym-node-api
ufw allow 9000/tcp # Nym Specific - clients port
ufw allow 9001/tcp # Nym specific - wss port
ufw allow 51822/udp # WireGuard
```
# in case of planning to setup a WSS (for Gateway functionality)
ufw allow 9001/tcp
- In case of reverse proxy setup add:
```sh
ufw allow 443/tcp
```
# in case of reverse proxy for the swagger page (for Gateway optionality)
ufw allow 80,443/tcp
# for validator
- For validator setup open these ports:
```sh
ufw allow 1317,26656,26660,22,80,443/tcp
```
@@ -237,6 +245,7 @@ All node-specific port configuration can be found in `$HOME/.nym/<NODE>/<YOUR_ID
| `9000` | Listen for Client traffic |
| `9001` | WSS |
| `8080, 80, 443` | Reversed Proxy & Swagger page |
|`51822/udp` | WireGuard |
#### Embedded Network Requester functionality ports
+1 -1
View File
@@ -40,7 +40,7 @@ curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/env
![](images/sandbox.png)
~~~admonish tip
1. If you [built Nym from source](building-nym.md), you already have `sandbox.env` as a part of the monorepo (`nym/envs/sandbox.env`). Giving that you are likely to run `nym-node` from `nym/target/release`, the flag will look like this `--config-env-file ../../envs/sandbox.env`
1. If you [built Nym from source](../binaries/building-nym.md), you already have `sandbox.env` as a part of the monorepo (`nym/envs/sandbox.env`). Giving that you are likely to run `nym-node` from `nym/target/release`, the flag will look like this `--config-env-file ../../envs/sandbox.env`
2. You can export the path to `sandbox.env` to your enviromental variables:
```sh
@@ -2,8 +2,8 @@
Nym Node operators running Gateway functionality are already familiar with the monitoring tool [Harbourmaster.nymtech.net](https://harbourmaster.nymtech.net). Under the hood of Nym Harbourmaster runs iterations of `nym-gateway-probe` doing various checks and displaying the results on the interface. Operators don't have to rely on the probe ran by Nym and wait for the data to refresh. With `nym-gateway-probe` everyone can check any Gateway's networking status from their own computer at any time. In one command the client queries data from:
- [`nym-api`](https://validator.nymtech.net/api/)
- [`explorer-api`](https://explorer.nymtech.net/api/)
- [`nym-api`](https://validator.nymtech.net/api/v1/gateways)
- [`explorer-api`](https://explorer.nymtech.net/api/v1/gateways)
- [`harbour-master`](https://harbourmaster.nymtech.net/)
@@ -4,7 +4,7 @@ Nym Mixnet has been running on mainnet for quite some time. There is still work
As developers we need to be constantly improving the software. Operators have as much important role, keep their nodes up to date, monitor their performance and share their feedback with the rest of the community and core developers.
Therefore [monitoring](#monitoring) and [testing](#testing) are essential pieces of our common work. We call out all Nym operators to join the efforts!
Therefore [monitoring](#monitoring) and [testing](#testing) are essential pieces of our common work. We call out all Nym operators to join the efforts!
## Monitoring
@@ -24,10 +24,10 @@ A list of different scripts, templates and guides for easier navigation:
For the purpose of the performance testing Nym core developers plan to run instances of Prometheus and Grafana connected to Node explorer in the house. The network overall key insights we seek from these tests are primarily internal. We're focused on pinpointing bottlenecks, capacity loads, and monitoring cpu usage on the nodes' machines.
## Testing
## Testing
```admonish info
For the moment we paused Fast and Furious `perf` environment. Nym Mainnet environment will be used for future tests, please wait for further instructions.
For the moment we paused Fast and Furious `perf` environment. Nym Mainnet environment will be used for future tests, please wait for further instructions.
```
Nym asks its decentralised community of operators to join a series of performance testing events in order to **increase the overall quality of the Mixnet**. The main takeaways of such event are:
@@ -43,9 +43,10 @@ Nym asks its decentralised community of operators to join a series of performanc
Visit [Fast and Furious web page]({{performance_testing_webpage}}) and [Nym Harbour Master](https://harbourmaster.nymtech.net/) Gateways monitoring page to read more about the performance testing and the results of it.
<!--- THIS NEEDS A REDO:
## Performance Testing Work Flow
* Nym runs a paralel network environment [validator.performance.nymte.ch]({{performance_validator}}) with a chain ID `perf`
* Nym runs a paralel network environment with a chain ID `perf`
* Operators of Nym Nodes join by following easy steps on [performance testing web page]({{performance_testing_webpage}}), including simplified node authentication signature (while keep running their nodes on the mainnet)
* Once signed in, operators will be asked to swap their binary for the modified version with metrics endpoint to be able to connect their own [monitoring system](#monitoring)
* Core node data will be fed to a unique mixnet contract for the `perf` side chain
@@ -53,9 +54,5 @@ Visit [Fast and Furious web page]({{performance_testing_webpage}}) and [Nym Harb
* Nym tracks packet flow using Prometheus and Grafana
* Nym creates a large number of clients to the [performance validator network]({{performance_validator}}), intensifying the packet traffic
* Observe and record the metrics - this will probably put more strain on mainnet as well as many nodes spec is minimal
## More Information
* What happens after the test or what operators get for participating is shared up to date on the [performance testing web page]({{performance_testing_webpage}})
--->
@@ -1,6 +1,6 @@
# Prometheus & Grafana
The combination of Prometheus and Grafana is a common stack used by Nym team for internal monitoring as well as by core community operators like [ExploreNym](https://github.com/ExploreNYM/vps-monitor) or [No Trust Verify](https://status.notrustverify.ch/d/CW3L7dVVk/nym-mixnet?orgId=1).
The combination of Prometheus and Grafana is a common stack used by Nym team for internal monitoring as well as by core community operators like [ExploreNym](https://github.com/ExploreNYM/self-hosted-monitor) or [No Trust Verify](https://status.notrustverify.ch/d/CW3L7dVVk/nym-mixnet?orgId=1).
@@ -33,4 +33,4 @@ There are various ways how to setup this stack. You can chose based on your pref
* [Prometheus documentation](https://prometheus.io/docs/introduction/overview/)
* Installation [guide to install Prometheus](https://www.cherryservers.com/blog/install-prometheus-ubuntu) on Ubuntu by cherryservers
* [Grafana installation guide](https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/)
* Nym's script [`prom_targets.py`](https://github.com/nymtech/nym/blob/promethus-is-our-friend/scripts/prom_targets.py) - a python program to request data from API and can be plugged to this stack
* Nym's script [`prom_targets.py`](https://github.com/nymtech/nym/blob/develop/scripts/prom_targets.py) - a python program to request data from API and can be plugged to this stack
@@ -64,7 +64,7 @@ Be extra careful editing this file since you may lock yourself out of the server
Once finished, save the file and reboot the server. Now, running `ip a` command should return correct IPv4 and IPv6 addresses.
Finally re-run `network_tunnel_manager.sh` script, following the steps in node [IPv6 configuration chapter](https://github.com/nymtech/nym/nodes/configuration.md#ipv6-configuration).
Finally re-run `network_tunnel_manager.sh` script, following the steps in node [IPv6 configuration chapter](../nodes/configuration.md#ipv6-configuration).
## Other VPS troubleshooting
+5 -4
View File
@@ -13,10 +13,11 @@ DENOMS_EXPONENT=6
REWARDING_VALIDATOR_ADDRESS=n1pefc2utwpy5w78p2kqdsfmpjxfwmn9d39k5mqa
MIXNET_CONTRACT_ADDRESS=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav
VESTING_CONTRACT_ADDRESS=n1unyuj8qnmygvzuex3dwmg9yzt9alhvyeat0uu0jedg2wj33efl5qackslz
GROUP_CONTRACT_ADDRESS=n1ewmwz97xm0h8rdk8sw7h9mwn866qkx9hl9zlmagqfkhuzvwk5hhq844ue9
MULTISIG_CONTRACT_ADDRESS=n1tz0setr8vkh9udp8xyxgpqc89ns27k4d0jx2h942hr0ax63yjhmqz6xct8
COCONUT_DKG_CONTRACT_ADDRESS=n1v3n2ly2dp3a9ng3ff6rh26yfkn0pc5hed7w2shc5u9ca5c865utqj5elvh
ECASH_CONTRACT_ADDRESS=n1v3vydvs2ued84yv3khqwtgldmgwn0elljsdh08dr5s2j9x4rc5fs9jlwz9
ECASH_CONTRACT_ADDRESS=n1ljlwey4xdj0zs7zueepc48nkr033fca6fjgvurfvttqegm8dvsrswsul70
GROUP_CONTRACT_ADDRESS=n10v3rjnq4cjyccfykyams68ztce337gksuu6f0lvtl4meuwvkewaqru4uav
MULTISIG_CONTRACT_ADDRESS=n1cemnu8as0ls45v3caunpesl8jlsfw2ff9rlwnltlecp7zrxct4dsqc2y42
COCONUT_DKG_CONTRACT_ADDRESS=n1zx96qgd88vqlzcxkpwzks7kqs5ctrx36xtzfc58p7q6c4ng9anlqzc4nh8
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0"
EXPLORER_API=https://sandbox-explorer.nymtech.net/api
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "explorer-api"
version = "1.1.39"
version = "1.1.38"
edition = "2021"
license.workspace = true
+4 -25
View File
@@ -10,7 +10,7 @@ use nym_config::{
must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate,
DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR,
};
use nym_network_defaults::{mainnet, DEFAULT_NYM_NODE_HTTP_PORT, TICKETBOOK_VALIDITY_DAYS};
use nym_network_defaults::{mainnet, DEFAULT_NYM_NODE_HTTP_PORT};
use serde::{Deserialize, Serialize};
use std::io;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
@@ -501,7 +501,7 @@ pub struct ZkNymTicketHandlerDebug {
pub minimum_redemption_tickets: usize,
/// Specifies the maximum time between two subsequent tickets redemptions.
/// That's required as nym-apis will purge all ticket information for tickets older than maximum validity.
/// That's required as nym-apis will purge all ticket information for tickets older than 30 days.
#[serde(with = "humantime_serde")]
pub maximum_time_between_redemption: Duration,
}
@@ -511,28 +511,7 @@ impl ZkNymTicketHandlerDebug {
pub const DEFAULT_PENDING_POLLER: Duration = Duration::from_secs(300);
pub const DEFAULT_MINIMUM_API_QUORUM: f32 = 0.8;
pub const DEFAULT_MINIMUM_REDEMPTION_TICKETS: usize = 100;
// use min(4/5 of max validity, validity - 1), but making sure it's no greater than 1 day
// ASSUMPTION: our validity period is AT LEAST 2 days
//
// this could have been a constant, but it's more readable as a function
pub const fn default_maximum_time_between_redemption() -> Duration {
let desired_secs = TICKETBOOK_VALIDITY_DAYS * (86400 * 4) / 5;
let desired_secs_alt = (TICKETBOOK_VALIDITY_DAYS - 1) * 86400;
// can't use `min` in const context
let target_secs = if desired_secs < desired_secs_alt {
desired_secs
} else {
desired_secs_alt
};
assert!(
target_secs > 86400,
"the maximum time between redemption can't be lower than 1 day!"
);
Duration::from_secs(target_secs as u64)
}
pub const DEFAULT_MAXIMUM_TIME_BETWEEN_REDEMPTION: Duration = Duration::from_secs(86400 * 25);
}
impl Default for ZkNymTicketHandlerDebug {
@@ -542,7 +521,7 @@ impl Default for ZkNymTicketHandlerDebug {
pending_poller: Self::DEFAULT_PENDING_POLLER,
minimum_api_quorum: Self::DEFAULT_MINIMUM_API_QUORUM,
minimum_redemption_tickets: Self::DEFAULT_MINIMUM_REDEMPTION_TICKETS,
maximum_time_between_redemption: Self::default_maximum_time_between_redemption(),
maximum_time_between_redemption: Self::DEFAULT_MAXIMUM_TIME_BETWEEN_REDEMPTION,
}
}
}
@@ -122,7 +122,7 @@ pub(crate) struct CredentialHandlerConfig {
pub(crate) minimum_redemption_tickets: usize,
/// Specifies the maximum time between two subsequent tickets redemptions.
/// That's required as nym-apis will purge all ticket information for tickets older than maximum validity.
/// That's required as nym-apis will purge all ticket information for tickets older than 30 days.
pub(crate) maximum_time_between_redemption: Duration,
}
@@ -26,7 +26,6 @@ use std::time::Duration;
use thiserror::Error;
use tokio::io::{AsyncRead, AsyncWrite};
use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError};
use tracing::field::debug;
use tracing::*;
use crate::node::client_handling::websocket::common_state::CommonHandlerState;
@@ -299,7 +298,6 @@ where
///
/// * `client_address`: address of the client that is going to receive the messages.
/// * `shared_keys`: shared keys derived between the client and the gateway used to encrypt and tag the messages.
#[instrument(skip_all)]
async fn push_stored_messages_to_client(
&mut self,
client_address: DestinationAddressBytes,
@@ -308,7 +306,6 @@ where
where
S: AsyncRead + AsyncWrite + Unpin,
{
debug!("attempting to push stored messages to client");
let mut start_next_after = None;
loop {
// retrieve some messages
@@ -524,7 +521,6 @@ where
/// * `client_address`: address of the client wishing to authenticate.
/// * `encrypted_address`: ciphertext of the address of the client wishing to authenticate.
/// * `iv`: fresh IV received with the request.
#[instrument(skip_all)]
async fn handle_authenticate(
&mut self,
client_protocol_version: Option<u8>,
@@ -535,7 +531,6 @@ where
where
S: AsyncRead + AsyncWrite + Unpin,
{
debug("handling client authentication");
let negotiated_protocol = self.negotiate_client_protocol(client_protocol_version)?;
// populate the negotiated protocol for future uses
self.negotiated_protocol = Some(negotiated_protocol);
@@ -615,9 +610,23 @@ where
let client_id = self
.shared_state
.storage
.insert_new_client(client_address, client_shared_keys)
.insert_shared_keys(client_address, client_shared_keys)
.await?;
// see if we have bandwidth entry for the client already, if not, create one with zero value
if self
.shared_state
.storage
.get_available_bandwidth(client_id)
.await?
.is_none()
{
self.shared_state
.storage
.create_bandwidth_entry(client_id)
.await?;
}
self.push_stored_messages_to_client(client_address, client_shared_keys)
.await?;
@@ -630,7 +639,6 @@ where
/// # Arguments
///
/// * `init_data`: init payload of the registration handshake.
#[instrument(skip_all)]
async fn handle_register(
&mut self,
client_protocol_version: Option<u8>,
@@ -639,7 +647,6 @@ where
where
S: AsyncRead + AsyncWrite + Unpin + Send,
{
debug!("handling client registration");
let negotiated_protocol = self.negotiate_client_protocol(client_protocol_version)?;
// populate the negotiated protocol for future uses
self.negotiated_protocol = Some(negotiated_protocol);
@@ -652,9 +659,7 @@ where
}
let shared_keys = self.perform_registration_handshake(init_data).await?;
debug!("managed to derived shared keys");
let client_id = self.register_client(remote_address, &shared_keys).await?;
event!(Level::DEBUG, client_id, protocol = negotiated_protocol);
let client_details = ClientDetails::new(client_id, remote_address, shared_keys);
@@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::config::Config;
use fresh::InitialAuthenticationError;
use nym_credentials_interface::AvailableBandwidth;
use nym_gateway_requests::registration::handshake::SharedKeys;
use nym_gateway_requests::ServerResponse;
@@ -96,7 +95,7 @@ pub(crate) async fn handle_connection<R, S, St>(
St: Storage + Clone + 'static,
{
// If the connection handler abruptly stops, we shouldn't signal global shutdown
shutdown.mark_as_success();
shutdown.disarm();
match shutdown
.run_future(handle.perform_websocket_handshake())
@@ -123,12 +122,6 @@ pub(crate) async fn handle_connection<R, S, St>(
trace!("received shutdown signal while performing initial authentication");
return;
}
// For storage error, we want to print the extended storage error, but without
// including it in the error that's returned to the clients
Some(Err(InitialAuthenticationError::StorageError(err))) => {
warn!("authentication has failed: {err}");
return;
}
Some(Err(err)) => {
warn!("authentication has failed: {err}");
return;
@@ -203,7 +203,7 @@ impl<St: Storage> ConnectionHandler<St> {
mut shutdown: TaskClient,
) {
debug!("Starting connection handler for {:?}", remote);
shutdown.mark_as_success();
shutdown.disarm();
let mut framed_conn = Framed::new(conn, NymCodec);
while !shutdown.is_shutdown() {
tokio::select! {
@@ -81,7 +81,7 @@ impl ConnectionHandler {
mut shutdown: TaskClient,
) {
debug!("Starting connection handler for {:?}", remote);
shutdown.mark_as_success();
shutdown.disarm();
let mut framed_conn = Framed::new(conn, NymCodec);
while !shutdown.is_shutdown() {
tokio::select! {
+1 -1
View File
@@ -4,7 +4,7 @@
[package]
name = "nym-api"
license = "GPL-3.0"
version = "1.1.43"
version = "1.1.42"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
+10 -11
View File
@@ -16,9 +16,8 @@ use nym_coconut_dkg_common::types::{
use nym_coconut_dkg_common::verification_key::{ContractVKShare, VerificationKeyShare};
use nym_contracts_common::IdentityKey;
use nym_dkg::Threshold;
use nym_validator_client::nyxd::cosmwasm_client::logs::NODE_INDEX;
use nym_validator_client::nyxd::cosmwasm_client::logs::{find_attribute, NODE_INDEX};
use nym_validator_client::nyxd::cosmwasm_client::types::ExecuteResult;
use nym_validator_client::nyxd::helpers::find_attribute_value_in_logs_or_events;
use nym_validator_client::nyxd::AccountId;
pub(crate) struct DkgClient {
@@ -169,15 +168,15 @@ impl DkgClient {
.inner
.register_dealer(bte_key, identity_key, announce_address, resharing)
.await?;
let node_index =
find_attribute_value_in_logs_or_events(&res.logs, &res.events, "wasm", NODE_INDEX)
.ok_or(EcashError::NodeIndexRecoveryError {
reason: String::from("node index not found"),
})?
.parse::<NodeIndex>()
.map_err(|_| EcashError::NodeIndexRecoveryError {
reason: String::from("node index could not be parsed"),
})?;
let node_index = find_attribute(&res.logs, "wasm", NODE_INDEX)
.ok_or(EcashError::NodeIndexRecoveryError {
reason: String::from("node index not found"),
})?
.value
.parse::<NodeIndex>()
.map_err(|_| EcashError::NodeIndexRecoveryError {
reason: String::from("node index could not be parsed"),
})?;
Ok(node_index)
}
+14 -15
View File
@@ -18,9 +18,8 @@ use nym_dkg::{
bte::{self, decrypt_share},
combine_shares, try_recover_verification_keys, Dealing,
};
use nym_validator_client::nyxd::cosmwasm_client::logs::Log;
use nym_validator_client::nyxd::helpers::find_attribute_value_in_logs_or_events;
use nym_validator_client::nyxd::{Event, Hash};
use nym_validator_client::nyxd::cosmwasm_client::logs::{find_attribute, Log};
use nym_validator_client::nyxd::Hash;
use rand::{CryptoRng, RngCore};
use std::collections::{BTreeMap, HashMap};
use std::ops::Deref;
@@ -454,25 +453,25 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
key: &VerificationKeyAuth,
resharing: bool,
) -> Result<u64, KeyDerivationError> {
fn extract_proposal_id(
fn extract_proposal_id_from_logs(
logs: &[Log],
events: &[Event],
tx_hash: Hash,
) -> Result<u64, KeyDerivationError> {
let event_type = "wasm";
let attribute_key = DKG_PROPOSAL_ID;
let proposal_value =
find_attribute_value_in_logs_or_events(logs, events, event_type, attribute_key)
.ok_or(KeyDerivationError::MissingProposalIdAttribute {
tx_hash,
event_type: event_type.to_string(),
attribute_key: attribute_key.to_string(),
})?;
let proposal_attribute = find_attribute(logs, event_type, attribute_key).ok_or(
KeyDerivationError::MissingProposalIdAttribute {
tx_hash,
event_type: event_type.to_string(),
attribute_key: attribute_key.to_string(),
},
)?;
proposal_value
proposal_attribute
.value
.parse()
.map_err(|_| KeyDerivationError::UnparsableProposalId {
raw: proposal_value.clone(),
raw: proposal_attribute.value.clone(),
})
}
@@ -482,7 +481,7 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
.submit_verification_key_share(key.to_bs58(), resharing)
.await?;
let hash = res.transaction_hash;
let proposal_id = extract_proposal_id(&res.logs, &res.events, hash)?;
let proposal_id = extract_proposal_id_from_logs(&res.logs, hash)?;
debug!("Submitted own verification key share, proposal id {proposal_id} is attached to it. tx hash: {hash}");
Ok(proposal_id)
+1 -1
View File
@@ -56,7 +56,7 @@ pub(crate) async fn prepare_partial_bloomfilter_builder(
.try_load_partial_bloomfilter_bitmap(date, params_id)
.await?
else {
log::warn!("missing double spending bloomfilter bitmap for {date} (if this API hasn't been running for at least {days} day(s) since 'ecash'-based zk-nyms were introduced this is expected)");
log::warn!("missing double spending bloomfilter bitmap for {date} (if this API hasn't been running for at least 30 days since 'ecash'-based zk-nyms were introduced this is expected)");
continue;
};
if !filter_builder.add_bytes(&bitmap) {
+1 -1
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-node"
version = "1.1.7"
version = "1.1.6"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
+4 -25
View File
@@ -5,7 +5,7 @@ use crate::config::helpers::ephemeral_gateway_config;
use crate::config::persistence::EntryGatewayPaths;
use crate::config::Config;
use crate::error::EntryGatewayError;
use nym_config::defaults::{DEFAULT_CLIENT_LISTENING_PORT, TICKETBOOK_VALIDITY_DAYS};
use nym_config::defaults::DEFAULT_CLIENT_LISTENING_PORT;
use nym_config::helpers::inaddr_any;
use nym_config::serde_helpers::de_maybe_port;
use nym_gateway::node::LocalAuthenticatorOpts;
@@ -90,7 +90,7 @@ pub struct ZkNymTicketHandlerDebug {
pub minimum_redemption_tickets: usize,
/// Specifies the maximum time between two subsequent tickets redemptions.
/// That's required as nym-apis will purge all ticket information for tickets older than maximum validity.
/// That's required as nym-apis will purge all ticket information for tickets older than 30 days.
#[serde(with = "humantime_serde")]
pub maximum_time_between_redemption: Duration,
}
@@ -100,28 +100,7 @@ impl ZkNymTicketHandlerDebug {
pub const DEFAULT_PENDING_POLLER: Duration = Duration::from_secs(300);
pub const DEFAULT_MINIMUM_API_QUORUM: f32 = 0.8;
pub const DEFAULT_MINIMUM_REDEMPTION_TICKETS: usize = 100;
// use min(4/5 of max validity, validity - 1), but making sure it's no greater than 1 day
// ASSUMPTION: our validity period is AT LEAST 2 days
//
// this could have been a constant, but it's more readable as a function
pub const fn default_maximum_time_between_redemption() -> Duration {
let desired_secs = TICKETBOOK_VALIDITY_DAYS * (86400 * 4) / 5;
let desired_secs_alt = (TICKETBOOK_VALIDITY_DAYS - 1) * 86400;
// can't use `min` in const context
let target_secs = if desired_secs < desired_secs_alt {
desired_secs
} else {
desired_secs_alt
};
assert!(
target_secs > 86400,
"the maximum time between redemption can't be lower than 1 day!"
);
Duration::from_secs(target_secs as u64)
}
pub const DEFAULT_MAXIMUM_TIME_BETWEEN_REDEMPTION: Duration = Duration::from_secs(86400 * 25);
}
impl Default for ZkNymTicketHandlerDebug {
@@ -131,7 +110,7 @@ impl Default for ZkNymTicketHandlerDebug {
pending_poller: Self::DEFAULT_PENDING_POLLER,
minimum_api_quorum: Self::DEFAULT_MINIMUM_API_QUORUM,
minimum_redemption_tickets: Self::DEFAULT_MINIMUM_REDEMPTION_TICKETS,
maximum_time_between_redemption: Self::default_maximum_time_between_redemption(),
maximum_time_between_redemption: Self::DEFAULT_MAXIMUM_TIME_BETWEEN_REDEMPTION,
}
}
}
+3 -4
View File
@@ -7,7 +7,6 @@ use nym_credential_utils::utils::issue_credential;
use nym_credentials_interface::TicketType;
use nym_network_defaults::NymNetworkDetails;
use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient};
use std::ops::Deref;
use zeroize::Zeroizing;
/// Represents a client that can be used to acquire bandwidth. You typically create one when you
@@ -18,7 +17,7 @@ use zeroize::Zeroizing;
pub struct BandwidthAcquireClient<'a, St: Storage> {
client: DirectSigningHttpRpcNyxdClient,
storage: &'a St,
client_id: Zeroizing<Vec<u8>>,
client_id: Zeroizing<String>,
ticketbook_type: TicketType,
}
@@ -31,7 +30,7 @@ where
network_details: NymNetworkDetails,
mnemonic: String,
storage: &'a St,
client_id: Vec<u8>,
client_id: String,
ticketbook_type: TicketType,
) -> Result<Self> {
let nyxd_url = network_details.endpoints[0].nyxd_url.as_str();
@@ -54,7 +53,7 @@ where
issue_credential(
&self.client,
self.storage,
self.client_id.deref(),
self.client_id.as_bytes(),
self.ticketbook_type,
)
.await?;
+11 -15
View File
@@ -40,7 +40,6 @@ use std::net::IpAddr;
use std::path::Path;
use std::path::PathBuf;
use url::Url;
use zeroize::Zeroizing;
// The number of surbs to include in a message by default
const DEFAULT_NUMBER_OF_SURBS: u32 = 10;
@@ -561,20 +560,17 @@ where
if !self.config.enabled_credentials_mode {
return Err(Error::DisabledCredentialsMode);
}
let client_id_array = Zeroizing::new(
self.storage
.key_store()
.load_keys()
.await
.map_err(|e| Error::KeyStorageError {
source: Box::new(e),
})?
.identity_keypair()
.private_key()
.to_bytes(),
);
let client_id = client_id_array.to_vec();
let client_id = self
.storage
.key_store()
.load_keys()
.await
.map_err(|e| Error::KeyStorageError {
source: Box::new(e),
})?
.identity_keypair()
.private_key()
.to_base58_string();
BandwidthAcquireClient::new(
self.config.network_details.clone(),
mnemonic,
@@ -24,7 +24,7 @@ use nym_wireguard_types::{
GatewayClient, InitMessage, PeerPublicKey,
};
use rand::{prelude::IteratorRandom, thread_rng};
use tokio::sync::mpsc::UnboundedReceiver;
use tokio::sync::{mpsc::UnboundedReceiver, RwLock};
use tokio_stream::wrappers::IntervalStream;
use crate::{config::Config, error::*};
@@ -32,6 +32,20 @@ use crate::{config::Config, error::*};
type AuthenticatorHandleResult = Result<AuthenticatorResponse>;
const DEFAULT_REGISTRATION_TIMEOUT_CHECK: Duration = Duration::from_secs(60); // 1 minute
pub(crate) struct RegistredAndFree {
registration_in_progres: PendingRegistrations,
free_private_network_ips: PrivateIPs,
}
impl RegistredAndFree {
pub(crate) fn new(free_private_network_ips: PrivateIPs) -> Self {
RegistredAndFree {
registration_in_progres: Default::default(),
free_private_network_ips,
}
}
}
pub(crate) struct MixnetListener {
// The configuration for the mixnet listener
pub(crate) config: Config,
@@ -43,12 +57,10 @@ pub(crate) struct MixnetListener {
pub(crate) task_handle: TaskHandle,
// Registrations awaiting confirmation
pub(crate) registration_in_progres: Arc<PendingRegistrations>,
pub(crate) registred_and_free: RwLock<RegistredAndFree>,
pub(crate) peer_manager: PeerManager,
pub(crate) free_private_network_ips: Arc<PrivateIPs>,
pub(crate) timeout_check_interval: IntervalStream,
}
@@ -63,15 +75,13 @@ impl MixnetListener {
) -> Self {
let timeout_check_interval =
IntervalStream::new(tokio::time::interval(DEFAULT_REGISTRATION_TIMEOUT_CHECK));
let free_private_network_ips = private_ip_network.iter().map(|ip| (ip, None)).collect();
MixnetListener {
config,
mixnet_client,
task_handle,
registration_in_progres: Default::default(),
registred_and_free: RwLock::new(RegistredAndFree::new(free_private_network_ips)),
peer_manager: PeerManager::new(wireguard_gateway_data, response_rx),
free_private_network_ips: Arc::new(
private_ip_network.iter().map(|ip| (ip, None)).collect(),
),
timeout_check_interval,
}
}
@@ -80,9 +90,15 @@ impl MixnetListener {
self.peer_manager.wireguard_gateway_data.keypair()
}
fn remove_stale_registrations(&self) -> Result<()> {
for reg in self.registration_in_progres.iter().map(|reg| reg.clone()) {
let mut ip = self
async fn remove_stale_registrations(&self) -> Result<()> {
let mut registred_and_free = self.registred_and_free.write().await;
let registred_values: Vec<_> = registred_and_free
.registration_in_progres
.values()
.cloned()
.collect();
for reg in registred_values {
let ip = registred_and_free
.free_private_network_ips
.get_mut(&reg.gateway_data.private_ip)
.ok_or(AuthenticatorError::InternalDataCorruption(format!(
@@ -90,10 +106,9 @@ impl MixnetListener {
reg.gateway_data.private_ip
)))?;
let timestamp = ip.ok_or(AuthenticatorError::InternalDataCorruption(format!(
"timestamp should be set for IP {}",
ip.key()
)))?;
let timestamp = ip.ok_or(AuthenticatorError::InternalDataCorruption(
"timestamp should be set".to_string(),
))?;
let duration = SystemTime::now().duration_since(timestamp).map_err(|_| {
AuthenticatorError::InternalDataCorruption(
"set timestamp shouldn't have been set in the future".to_string(),
@@ -101,7 +116,8 @@ impl MixnetListener {
})?;
if duration > DEFAULT_REGISTRATION_TIMEOUT_CHECK {
*ip = None;
self.registration_in_progres
registred_and_free
.registration_in_progres
.remove(&reg.gateway_data.pub_key());
log::debug!(
"Removed stale registration of {}",
@@ -120,9 +136,15 @@ impl MixnetListener {
) -> AuthenticatorHandleResult {
let remote_public = init_message.pub_key();
let nonce: u64 = fastrand::u64(..);
if let Some(registration_data) = self.registration_in_progres.get(&remote_public) {
if let Some(registration_data) = self
.registred_and_free
.read()
.await
.registration_in_progres
.get(&remote_public)
{
return Ok(AuthenticatorResponse::new_pending_registration_success(
registration_data.value().clone(),
registration_data.clone(),
request_id,
reply_to,
));
@@ -145,18 +167,19 @@ impl MixnetListener {
request_id,
));
}
let mut private_ip_ref = self
let mut registred_and_free = self.registred_and_free.write().await;
let private_ip_ref = registred_and_free
.free_private_network_ips
.iter_mut()
.filter(|r| r.is_none())
.filter(|r| r.1.is_none())
.choose(&mut thread_rng())
.ok_or(AuthenticatorError::NoFreeIp)?;
// mark it as used, even though it's not final
*private_ip_ref = Some(SystemTime::now());
*private_ip_ref.1 = Some(SystemTime::now());
let gateway_data = GatewayClient::new(
self.keypair().private_key(),
remote_public.inner(),
*private_ip_ref.key(),
*private_ip_ref.0,
nonce,
);
let registration_data = RegistrationData {
@@ -164,7 +187,8 @@ impl MixnetListener {
gateway_data,
wg_port: self.config.authenticator.announced_port,
};
self.registration_in_progres
registred_and_free
.registration_in_progres
.insert(remote_public, registration_data.clone());
Ok(AuthenticatorResponse::new_pending_registration_success(
@@ -180,11 +204,11 @@ impl MixnetListener {
request_id: u64,
reply_to: Recipient,
) -> AuthenticatorHandleResult {
let registration_data = self
let mut registred_and_free = self.registred_and_free.write().await;
let registration_data = registred_and_free
.registration_in_progres
.get(&gateway_client.pub_key())
.ok_or(AuthenticatorError::RegistrationNotInProgress)?
.value()
.clone();
if gateway_client
@@ -192,7 +216,8 @@ impl MixnetListener {
.is_ok()
{
self.peer_manager.add_peer(&gateway_client).await?;
self.registration_in_progres
registred_and_free
.registration_in_progres
.remove(&gateway_client.pub_key());
Ok(AuthenticatorResponse::new_registered(
@@ -294,7 +319,7 @@ impl MixnetListener {
log::debug!("Authenticator [main loop]: received shutdown");
},
_ = self.timeout_check_interval.next() => {
if let Err(e) = self.remove_stale_registrations() {
if let Err(e) = self.remove_stale_registrations().await {
log::error!("Could not clear stale registrations. The registration process might get jammed soon - {:?}", e);
}
}
@@ -4,7 +4,7 @@
[package]
name = "nym-network-requester"
license = "GPL-3.0"
version = "1.1.41"
version = "1.1.40"
authors.workspace = true
edition.workspace = true
rust-version = "1.70"
@@ -495,7 +495,7 @@ impl NRServiceProvider {
.send(error_msg)
.await
.expect("InputMessageReceiver has stopped receiving!");
shutdown.mark_as_success();
shutdown.disarm();
return;
}

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