Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6e215646c3 | |||
| a8dc703399 | |||
| e09986e505 | |||
| bb3c015633 | |||
| b21346064e | |||
| fa81b96951 | |||
| 8cccc9ab24 | |||
| b567ac22d3 | |||
| b43a1b8c94 | |||
| d7da6ed1ab | |||
| 4d62dc9c74 | |||
| 2d39f3c722 | |||
| 3d122f45b4 | |||
| cb375f15c2 | |||
| 7406fdd677 | |||
| d7d4c9f09a | |||
| 94d83648c2 | |||
| aa51af7023 | |||
| f45ed78806 | |||
| c0337ec1d4 | |||
| 6fe049d1a2 | |||
| 63ed99d4d6 | |||
| 2061629d1d | |||
| 9b99a19ba0 | |||
| 6a3afb50b8 | |||
| bea64b926f | |||
| 3b83c30558 | |||
| ceeccbba07 | |||
| be55bb61cb | |||
| f2af35fc2e | |||
| b874fc9314 | |||
| 914c586e68 | |||
| 10ba3c2ab9 | |||
| 7e32787ab2 | |||
| 7062f69e45 | |||
| 5e98c14a98 | |||
| f04d1fea56 | |||
| 836e237116 | |||
| 0f9bd648a1 | |||
| 0c2c0bdc54 | |||
| 991cc3fa01 | |||
| 3510ee8df6 | |||
| 6774158e7a | |||
| f98698a121 | |||
| 8e99c17f49 | |||
| ab4cc9b282 | |||
| dbe6a5de7d | |||
| 1948fd8e67 | |||
| c8f38ae785 | |||
| f32ea17de5 | |||
| 4ac25aef4d | |||
| 3ad6a31e1f | |||
| 6cacc53e5a | |||
| 387933a975 | |||
| f6c24412c0 | |||
| 5c753c0794 | |||
| 67132161f4 | |||
| 643f54024b | |||
| 16aaf7b5df | |||
| 17c6b79735 | |||
| 8bd758ad0e | |||
| a51fc0cb9e | |||
| ae602ae771 | |||
| d6d36364b0 | |||
| accb42cad9 | |||
| dd43c5d2d2 | |||
| e42d46100a | |||
| ed8b1841dc | |||
| dd15a9454a |
@@ -4,18 +4,18 @@ on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'clients/**'
|
||||
- 'common/**'
|
||||
- 'explorer-api/**'
|
||||
- 'gateway/**'
|
||||
- 'integrations/**'
|
||||
- 'mixnode/**'
|
||||
- 'sdk/rust/nym-sdk/**'
|
||||
- 'service-providers/**'
|
||||
- 'nym-api/**'
|
||||
- 'nym-outfox/**'
|
||||
- 'tools/nym-cli/**'
|
||||
- 'tools/ts-rs-cli/**'
|
||||
- "clients/**"
|
||||
- "common/**"
|
||||
- "explorer-api/**"
|
||||
- "gateway/**"
|
||||
- "integrations/**"
|
||||
- "mixnode/**"
|
||||
- "sdk/rust/nym-sdk/**"
|
||||
- "service-providers/**"
|
||||
- "nym-api/**"
|
||||
- "nym-outfox/**"
|
||||
- "tools/nym-cli/**"
|
||||
- "tools/ts-rs-cli/**"
|
||||
|
||||
jobs:
|
||||
publish-nym:
|
||||
@@ -53,6 +53,16 @@ jobs:
|
||||
command: build
|
||||
args: --workspace --release
|
||||
|
||||
- name: Install cargo-deb
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: install
|
||||
args: cargo-deb
|
||||
|
||||
- name: Build deb packages
|
||||
shell: bash
|
||||
run: make deb
|
||||
|
||||
- name: Prepare build output
|
||||
shell: bash
|
||||
env:
|
||||
@@ -67,6 +77,7 @@ jobs:
|
||||
cp target/release/nym-network-statistics $OUTPUT_DIR
|
||||
cp target/release/nym-cli $OUTPUT_DIR
|
||||
cp target/release/explorer-api $OUTPUT_DIR
|
||||
cp target/debian/*.deb $OUTPUT_DIR
|
||||
|
||||
- name: Deploy branch to CI www
|
||||
continue-on-error: true
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
name: ci-cargo-deny
|
||||
on: [workflow_dispatch]
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
cargo-deny:
|
||||
runs-on: ubuntu-22.04
|
||||
@@ -7,10 +10,7 @@ jobs:
|
||||
matrix:
|
||||
checks:
|
||||
# - advisories
|
||||
- licenses
|
||||
- bans sources
|
||||
|
||||
continue-on-error: ${{ matrix.checks == 'licenses' }}
|
||||
- licenses bans sources
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: install yarn in root
|
||||
run: cd ../.. yarn install
|
||||
run: cd ../.. && yarn install
|
||||
|
||||
- name: Install npm
|
||||
run: npm install
|
||||
|
||||
@@ -187,6 +187,16 @@ dependencies = [
|
||||
"syn 2.0.38",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr"
|
||||
version = "0.15.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a93b8a41dbe230ad5087cc721f8d41611de654542180586b315d9f4cf6b72bef"
|
||||
dependencies = [
|
||||
"psl",
|
||||
"psl-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.21.0"
|
||||
@@ -1559,6 +1569,12 @@ version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
|
||||
|
||||
[[package]]
|
||||
name = "const-str"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aca749d3d3f5b87a0d6100509879f9cf486ab510803a4a4e1001da1ff61c2bd6"
|
||||
|
||||
[[package]]
|
||||
name = "const_format"
|
||||
version = "0.2.32"
|
||||
@@ -1604,9 +1620,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.17.0"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24"
|
||||
checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
"time",
|
||||
@@ -3981,6 +3997,16 @@ dependencies = [
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
@@ -6047,6 +6073,7 @@ dependencies = [
|
||||
"clap 4.4.7",
|
||||
"clap_complete",
|
||||
"clap_complete_fig",
|
||||
"const-str",
|
||||
"log",
|
||||
"opentelemetry",
|
||||
"opentelemetry-jaeger",
|
||||
@@ -6219,6 +6246,7 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.8",
|
||||
"si-scale",
|
||||
"sqlx",
|
||||
"tap",
|
||||
"tempfile",
|
||||
@@ -6645,21 +6673,27 @@ name = "nym-ip-packet-router"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bs58 0.4.0",
|
||||
"bytes",
|
||||
"clap 4.4.7",
|
||||
"etherparse",
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"nym-bin-common",
|
||||
"nym-client-core",
|
||||
"nym-config",
|
||||
"nym-crypto",
|
||||
"nym-exit-policy",
|
||||
"nym-ip-packet-requests",
|
||||
"nym-network-defaults",
|
||||
"nym-network-requester",
|
||||
"nym-sdk",
|
||||
"nym-service-providers-common",
|
||||
"nym-sphinx",
|
||||
"nym-task",
|
||||
"nym-tun",
|
||||
"nym-types",
|
||||
"nym-wireguard",
|
||||
"nym-wireguard-types",
|
||||
"rand 0.8.5",
|
||||
@@ -6818,6 +6852,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"dotenvy",
|
||||
"hex-literal",
|
||||
"log",
|
||||
"once_cell",
|
||||
"schemars",
|
||||
"serde",
|
||||
@@ -6829,6 +6864,7 @@ dependencies = [
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.32"
|
||||
dependencies = [
|
||||
"addr",
|
||||
"anyhow",
|
||||
"async-file-watcher",
|
||||
"async-trait",
|
||||
@@ -7725,9 +7761,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "okapi"
|
||||
version = "0.7.0-rc.1"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce66b6366e049880a35c378123fddb630b1a1a3c37fa1ca70caaf4a09f6e2893"
|
||||
checksum = "9a64853d7ab065474e87696f7601cee817d200e86c42e04004e005cb3e20c3c5"
|
||||
dependencies = [
|
||||
"log",
|
||||
"schemars",
|
||||
@@ -8056,7 +8092,7 @@ checksum = "61a386cd715229d399604b50d1361683fe687066f42d56f54be995bc6868f71c"
|
||||
dependencies = [
|
||||
"inlinable_string",
|
||||
"pear_codegen",
|
||||
"yansi 1.0.0-rc.1",
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8433,7 +8469,7 @@ dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.38",
|
||||
"version_check",
|
||||
"yansi 1.0.0-rc.1",
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8558,14 +8594,28 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "publicsuffix"
|
||||
version = "1.5.6"
|
||||
name = "psl"
|
||||
version = "2.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95b4ce31ff0a27d93c8de1849cf58162283752f065a90d508f1105fa6c9a213f"
|
||||
checksum = "383703acfc34f7a00724846c14dc5ea4407c59e5aedcbbb18a1c0c1a23fe5013"
|
||||
dependencies = [
|
||||
"idna 0.2.3",
|
||||
"native-tls",
|
||||
"url",
|
||||
"psl-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psl-types"
|
||||
version = "2.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
|
||||
|
||||
[[package]]
|
||||
name = "publicsuffix"
|
||||
version = "2.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457"
|
||||
dependencies = [
|
||||
"idna 0.3.0",
|
||||
"psl-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -9168,9 +9218,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rocket"
|
||||
version = "0.5.0-rc.3"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58734f7401ae5cfd129685b48f61182331745b357b96f2367f01aebaf1cc9cc9"
|
||||
checksum = "9e7bb57ccb26670d73b6a47396c83139447b9e7878cab627fdfe9ea8da489150"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
@@ -9180,8 +9230,7 @@ dependencies = [
|
||||
"either",
|
||||
"figment",
|
||||
"futures",
|
||||
"indexmap 1.9.3",
|
||||
"is-terminal",
|
||||
"indexmap 2.0.2",
|
||||
"log",
|
||||
"memchr",
|
||||
"multer",
|
||||
@@ -9202,30 +9251,33 @@ dependencies = [
|
||||
"tokio-util",
|
||||
"ubyte",
|
||||
"version_check",
|
||||
"yansi 0.5.1",
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rocket_codegen"
|
||||
version = "0.5.0-rc.3"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7093353f14228c744982e409259fb54878ba9563d08214f2d880d59ff2fc508b"
|
||||
checksum = "a2238066abf75f21be6cd7dc1a09d5414a671f4246e384e49fe3f8a4936bd04c"
|
||||
dependencies = [
|
||||
"devise",
|
||||
"glob",
|
||||
"indexmap 1.9.3",
|
||||
"indexmap 2.0.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rocket_http",
|
||||
"syn 2.0.38",
|
||||
"unicode-xid",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rocket_cors"
|
||||
version = "0.5.2"
|
||||
source = "git+https://github.com/lawliet89/rocket_cors?rev=dfd3662c49e2f6fc37df35091cb94d82f7fb5915#dfd3662c49e2f6fc37df35091cb94d82f7fb5915"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfac3a1df83f8d4fc96aa41dba3b86c786417b7fc0f52ec76295df2ba781aa69"
|
||||
dependencies = [
|
||||
"http",
|
||||
"log",
|
||||
"regex",
|
||||
"rocket",
|
||||
@@ -9238,16 +9290,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rocket_http"
|
||||
version = "0.5.0-rc.3"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "936012c99162a03a67f37f9836d5f938f662e26f2717809761a9ac46432090f4"
|
||||
checksum = "37a1663694d059fe5f943ea5481363e48050acedd241d46deb2e27f71110389e"
|
||||
dependencies = [
|
||||
"cookie 0.17.0",
|
||||
"cookie 0.18.0",
|
||||
"either",
|
||||
"futures",
|
||||
"http",
|
||||
"hyper",
|
||||
"indexmap 1.9.3",
|
||||
"indexmap 2.0.2",
|
||||
"log",
|
||||
"memchr",
|
||||
"pear",
|
||||
@@ -9265,11 +9317,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rocket_okapi"
|
||||
version = "0.8.0-rc.3"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "742098674565c8f0c35c77444f90344aafedebb71cfee9cdbf0185acc6b9cdb7"
|
||||
checksum = "e059407ecef9ee2f071fc971e10444fcf942149deb028879d6d8ca61a7ce9edc"
|
||||
dependencies = [
|
||||
"either",
|
||||
"log",
|
||||
"okapi",
|
||||
"rocket",
|
||||
@@ -9281,9 +9332,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rocket_okapi_codegen"
|
||||
version = "0.8.0-rc.3"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c43f8edc57d88750a220b0ec1870a36c1106204ec99cc35131b49de3b954a4a"
|
||||
checksum = "cfb96114e69e5d7f80bfa0948cbc0120016e9b460954abe9eed37e9a2ad3f999"
|
||||
dependencies = [
|
||||
"darling 0.13.4",
|
||||
"proc-macro2",
|
||||
@@ -9599,9 +9650,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "0.8.15"
|
||||
version = "0.8.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c"
|
||||
checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29"
|
||||
dependencies = [
|
||||
"dyn-clone",
|
||||
"indexmap 1.9.3",
|
||||
@@ -9612,9 +9663,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "schemars_derive"
|
||||
version = "0.8.15"
|
||||
version = "0.8.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c"
|
||||
checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -10012,6 +10063,12 @@ dependencies = [
|
||||
"dirs 4.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "si-scale"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44beb68bf488343b13ddbd74d1d5d5e6559a58b6dfaee74eb8d5ed4f7ed7666f"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
@@ -10371,9 +10428,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "state"
|
||||
version = "0.5.3"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b"
|
||||
checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8"
|
||||
dependencies = [
|
||||
"loom",
|
||||
]
|
||||
@@ -12625,17 +12682,14 @@ dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "1.0.0-rc.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1367295b8f788d371ce2dbc842c7b709c73ee1364d30351dd300ec2203b12377"
|
||||
dependencies = [
|
||||
"is-terminal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yasna"
|
||||
|
||||
@@ -128,7 +128,7 @@ default-members = [
|
||||
"nym-validator-rewarder",
|
||||
]
|
||||
|
||||
exclude = ["explorer", "contracts", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop", "nym-vpn/ui/src-tauri", "cpu-cycles"]
|
||||
exclude = ["explorer", "contracts", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop", "nym-vpn/ui/src-tauri", "cpu-cycles", "sdk/ffi/cpp"]
|
||||
|
||||
[workspace.package]
|
||||
authors = ["Nym Technologies SA"]
|
||||
|
||||
@@ -12,6 +12,7 @@ help:
|
||||
@echo " clippy: run clippy for all workspaces"
|
||||
@echo " test: run clippy, unit tests, and formatting."
|
||||
@echo " test-all: like test, but also includes the expensive tests"
|
||||
@echo " deb: build debian packages
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Meta targets
|
||||
@@ -157,6 +158,12 @@ build-explorer-api:
|
||||
build-nym-cli:
|
||||
cargo build -p nym-cli --release
|
||||
|
||||
build-nym-gateway:
|
||||
cargo build -p nym-gateway --release
|
||||
|
||||
build-nym-mixnode:
|
||||
cargo build -p nym-mixnode --release
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Misc
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -169,6 +176,13 @@ run-api-tests:
|
||||
cd nym-api/tests/functional_test && yarn test:qa
|
||||
|
||||
# Build debian package, and update PPA
|
||||
# Requires base64 encode GPG key to be set up in environment PPA_SIGNING_KEY
|
||||
deb:
|
||||
scripts/ppa.sh
|
||||
deb-mixnode: build-nym-mixnode
|
||||
cargo deb -p nym-mixnode
|
||||
|
||||
deb-gateway: build-nym-gateway
|
||||
cargo deb -p nym-gateway
|
||||
|
||||
deb-cli: build-nym-cli
|
||||
cargo deb -p nym-cli
|
||||
|
||||
deb: deb-mixnode deb-gateway deb-cli
|
||||
@@ -51,7 +51,7 @@ impl InitialisableClient for NativeClientInit {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Args, Clone)]
|
||||
#[derive(Args, Clone, Debug)]
|
||||
pub(crate) struct Init {
|
||||
#[command(flatten)]
|
||||
common_args: CommonClientInitArgs,
|
||||
|
||||
@@ -51,7 +51,7 @@ impl InitialisableClient for Socks5ClientInit {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Args, Clone)]
|
||||
#[derive(Args, Clone, Debug)]
|
||||
pub(crate) struct Init {
|
||||
#[command(flatten)]
|
||||
common_args: CommonClientInitArgs,
|
||||
|
||||
@@ -9,6 +9,7 @@ repository = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
atty = "0.2"
|
||||
const-str = "0.5.6"
|
||||
clap = { workspace = true, features = ["derive"] }
|
||||
clap_complete = "4.0"
|
||||
clap_complete_fig = "4.0"
|
||||
|
||||
@@ -42,12 +42,20 @@ pub struct BinaryBuildInformation {
|
||||
|
||||
// VERGEN_CARGO_DEBUG
|
||||
/// Provides the cargo debug mode that was used for the build.
|
||||
pub cargo_debug: &'static str,
|
||||
// NOTE: keep the old name cargo_profile instead of cargo_debug for backwards compatibility
|
||||
pub cargo_profile: &'static str,
|
||||
}
|
||||
|
||||
impl BinaryBuildInformation {
|
||||
// explicitly require the build_version to be passed as it's binary specific
|
||||
pub const fn new(binary_name: &'static str, build_version: &'static str) -> Self {
|
||||
let cargo_debug = env!("VERGEN_CARGO_DEBUG");
|
||||
let cargo_profile = if const_str::equal!(cargo_debug, "true") {
|
||||
"debug"
|
||||
} else {
|
||||
"release"
|
||||
};
|
||||
|
||||
BinaryBuildInformation {
|
||||
binary_name,
|
||||
build_timestamp: env!("VERGEN_BUILD_TIMESTAMP"),
|
||||
@@ -57,7 +65,7 @@ impl BinaryBuildInformation {
|
||||
commit_branch: env!("VERGEN_GIT_BRANCH"),
|
||||
rustc_version: env!("VERGEN_RUSTC_SEMVER"),
|
||||
rustc_channel: env!("VERGEN_RUSTC_CHANNEL"),
|
||||
cargo_debug: env!("VERGEN_CARGO_DEBUG"),
|
||||
cargo_profile,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +79,7 @@ impl BinaryBuildInformation {
|
||||
commit_branch: self.commit_branch.to_owned(),
|
||||
rustc_version: self.rustc_version.to_owned(),
|
||||
rustc_channel: self.rustc_channel.to_owned(),
|
||||
cargo_debug: self.cargo_debug.to_owned(),
|
||||
cargo_profile: self.cargo_profile.to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +125,8 @@ pub struct BinaryBuildInformationOwned {
|
||||
|
||||
// VERGEN_CARGO_DEBUG
|
||||
/// Provides the cargo debug mode that was used for the build.
|
||||
pub cargo_debug: String,
|
||||
// NOTE: keep the old name cargo_profile instead of cargo_debug for backwards compatibility
|
||||
pub cargo_profile: String,
|
||||
}
|
||||
|
||||
impl Display for BinaryBuildInformationOwned {
|
||||
@@ -151,8 +160,8 @@ impl Display for BinaryBuildInformationOwned {
|
||||
self.rustc_version,
|
||||
"rustc Channel:",
|
||||
self.rustc_channel,
|
||||
"cargo Debug:",
|
||||
self.cargo_debug,
|
||||
"cargo Profile:",
|
||||
self.cargo_profile,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ nym-validator-client = { path = "../client-libs/validator-client", default-featu
|
||||
nym-task = { path = "../task" }
|
||||
nym-credential-storage = { path = "../credential-storage" }
|
||||
nym-network-defaults = { path = "../network-defaults" }
|
||||
si-scale = "0.2.2"
|
||||
|
||||
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream]
|
||||
version = "0.1.11"
|
||||
|
||||
@@ -109,6 +109,8 @@ pub async fn initialise_client<C>(
|
||||
) -> Result<InitResultsWithConfig<C::Config>, C::Error>
|
||||
where
|
||||
C: InitialisableClient,
|
||||
<C as InitialisableClient>::Config: std::fmt::Debug,
|
||||
<C as InitialisableClient>::InitArgs: std::fmt::Debug,
|
||||
{
|
||||
info!("initialising {} client", C::NAME);
|
||||
|
||||
@@ -140,17 +142,32 @@ where
|
||||
|
||||
// Attempt to use a user-provided gateway, if possible
|
||||
let user_chosen_gateway_id = common_args.gateway;
|
||||
log::debug!("User chosen gateway id: {user_chosen_gateway_id:?}");
|
||||
|
||||
let selection_spec = GatewaySelectionSpecification::new(
|
||||
user_chosen_gateway_id.map(|id| id.to_base58_string()),
|
||||
Some(common_args.latency_based_selection),
|
||||
false,
|
||||
);
|
||||
log::debug!("Gateway selection specification: {selection_spec:?}");
|
||||
|
||||
// Load and potentially override config
|
||||
log::debug!("Init arguments: {init_args:#?}");
|
||||
let config = C::construct_config(&init_args);
|
||||
log::debug!("Constructed config: {config:#?}");
|
||||
let paths = config.common_paths();
|
||||
let core = config.core_config();
|
||||
|
||||
log::info!(
|
||||
"Using nym-api: {}",
|
||||
core.client
|
||||
.nym_api_urls
|
||||
.iter()
|
||||
.map(|url| url.as_str())
|
||||
.collect::<Vec<&str>>()
|
||||
.join(",")
|
||||
);
|
||||
|
||||
// Setup gateway by either registering a new one, or creating a new config from the selected
|
||||
// one but with keys kept, or reusing the gateway configuration.
|
||||
let key_store = OnDiskKeys::new(paths.keys.clone());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::packet_statistics_control::PacketStatisticsReporter;
|
||||
use super::received_buffer::ReceivedBufferMessage;
|
||||
use super::topology_control::geo_aware_provider::GeoAwareTopologyProvider;
|
||||
use crate::client::base_client::storage::gateway_details::GatewayDetailsStore;
|
||||
@@ -10,6 +11,7 @@ use crate::client::inbound_messages::{InputMessage, InputMessageReceiver, InputM
|
||||
use crate::client::key_manager::persistence::KeyStore;
|
||||
use crate::client::mix_traffic::transceiver::{GatewayReceiver, GatewayTransceiver, RemoteGateway};
|
||||
use crate::client::mix_traffic::{BatchMixMessageSender, MixTrafficController};
|
||||
use crate::client::packet_statistics_control::PacketStatisticsControl;
|
||||
use crate::client::real_messages_control;
|
||||
use crate::client::real_messages_control::RealMessagesController;
|
||||
use crate::client::received_buffer::{
|
||||
@@ -254,6 +256,7 @@ where
|
||||
self_address: Recipient,
|
||||
topology_accessor: TopologyAccessor,
|
||||
mix_tx: BatchMixMessageSender,
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
shutdown: TaskClient,
|
||||
) {
|
||||
info!("Starting loop cover traffic stream...");
|
||||
@@ -266,6 +269,7 @@ where
|
||||
topology_accessor,
|
||||
debug_config.traffic,
|
||||
debug_config.cover_traffic,
|
||||
stats_tx,
|
||||
);
|
||||
|
||||
stream.start_with_shutdown(shutdown);
|
||||
@@ -285,6 +289,7 @@ where
|
||||
client_connection_rx: ConnectionCommandReceiver,
|
||||
shutdown: TaskClient,
|
||||
packet_type: PacketType,
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
) {
|
||||
info!("Starting real traffic stream...");
|
||||
|
||||
@@ -299,6 +304,7 @@ where
|
||||
reply_controller_receiver,
|
||||
lane_queue_lengths,
|
||||
client_connection_rx,
|
||||
stats_tx,
|
||||
)
|
||||
.start_with_shutdown(shutdown, packet_type);
|
||||
}
|
||||
@@ -312,6 +318,7 @@ where
|
||||
reply_key_storage: SentReplyKeys,
|
||||
reply_controller_sender: ReplyControllerSender,
|
||||
shutdown: TaskClient,
|
||||
packet_statistics_control: PacketStatisticsReporter,
|
||||
) {
|
||||
info!("Starting received messages buffer controller...");
|
||||
let controller: ReceivedMessagesBufferController<SphinxMessageReceiver> =
|
||||
@@ -321,6 +328,7 @@ where
|
||||
mixnet_receiver,
|
||||
reply_key_storage,
|
||||
reply_controller_sender,
|
||||
packet_statistics_control,
|
||||
);
|
||||
controller.start_with_shutdown(shutdown)
|
||||
}
|
||||
@@ -506,6 +514,13 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start_packet_statistics_control(shutdown: TaskClient) -> PacketStatisticsReporter {
|
||||
info!("Starting packet statistics control...");
|
||||
let (packet_statistics_control, packet_stats_reporter) = PacketStatisticsControl::new();
|
||||
packet_statistics_control.start_with_shutdown(shutdown);
|
||||
packet_stats_reporter
|
||||
}
|
||||
|
||||
fn start_mix_traffic_controller(
|
||||
gateway_transceiver: Box<dyn GatewayTransceiver + Send>,
|
||||
shutdown: TaskClient,
|
||||
@@ -633,6 +648,9 @@ where
|
||||
)
|
||||
.await?;
|
||||
|
||||
let packet_stats_reporter =
|
||||
Self::start_packet_statistics_control(shutdown.fork("packet_statistics_control"));
|
||||
|
||||
let gateway_packet_router = PacketRouter::new(
|
||||
ack_sender,
|
||||
mixnet_messages_sender,
|
||||
@@ -662,6 +680,7 @@ where
|
||||
reply_storage.key_storage(),
|
||||
reply_controller_sender.clone(),
|
||||
shutdown.fork("received_messages_buffer"),
|
||||
packet_stats_reporter.clone(),
|
||||
);
|
||||
|
||||
// The message_sender is the transmitter for any component generating sphinx packets
|
||||
@@ -700,6 +719,7 @@ where
|
||||
client_connection_rx,
|
||||
shutdown.fork("real_traffic_controller"),
|
||||
self.config.debug.traffic.packet_type,
|
||||
packet_stats_reporter.clone(),
|
||||
);
|
||||
|
||||
if !self
|
||||
@@ -714,6 +734,7 @@ where
|
||||
self_address,
|
||||
shared_topology_accessor.clone(),
|
||||
message_sender,
|
||||
packet_stats_reporter,
|
||||
shutdown.fork("cover_traffic_stream"),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::client::mix_traffic::BatchMixMessageSender;
|
||||
use crate::client::packet_statistics_control::{PacketStatisticsEvent, PacketStatisticsReporter};
|
||||
use crate::client::topology_control::TopologyAccessor;
|
||||
use crate::{config, spawn_future};
|
||||
use futures::task::{Context, Poll};
|
||||
@@ -61,6 +62,8 @@ where
|
||||
secondary_packet_size: Option<PacketSize>,
|
||||
|
||||
packet_type: PacketType,
|
||||
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
}
|
||||
|
||||
impl<R> Stream for LoopCoverTrafficStream<R>
|
||||
@@ -97,7 +100,8 @@ where
|
||||
// obviously when we finally make shared rng that is on 'higher' level, this should become
|
||||
// generic `R`
|
||||
impl LoopCoverTrafficStream<OsRng> {
|
||||
pub fn new(
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn new(
|
||||
ack_key: Arc<AckKey>,
|
||||
average_ack_delay: Duration,
|
||||
mix_tx: BatchMixMessageSender,
|
||||
@@ -105,6 +109,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
||||
topology_access: TopologyAccessor,
|
||||
traffic_config: config::Traffic,
|
||||
cover_config: config::CoverTraffic,
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
) -> Self {
|
||||
let rng = OsRng;
|
||||
|
||||
@@ -122,6 +127,7 @@ impl LoopCoverTrafficStream<OsRng> {
|
||||
primary_packet_size: traffic_config.primary_packet_size,
|
||||
secondary_packet_size: traffic_config.secondary_packet_size,
|
||||
packet_type: traffic_config.packet_type,
|
||||
stats_tx,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,6 +197,10 @@ impl LoopCoverTrafficStream<OsRng> {
|
||||
log::warn!("Failed to send cover message - channel closed");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.stats_tx.report(PacketStatisticsEvent::CoverPacketSent(
|
||||
cover_traffic_packet_size.size(),
|
||||
));
|
||||
}
|
||||
|
||||
// TODO: I'm not entirely sure whether this is really required, because I'm not 100%
|
||||
|
||||
@@ -7,6 +7,7 @@ pub(crate) mod helpers;
|
||||
pub mod inbound_messages;
|
||||
pub mod key_manager;
|
||||
pub mod mix_traffic;
|
||||
pub(crate) mod packet_statistics_control;
|
||||
pub mod real_messages_control;
|
||||
pub mod received_buffer;
|
||||
pub mod replies;
|
||||
|
||||
@@ -0,0 +1,498 @@
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use si_scale::helpers::bibytes2;
|
||||
|
||||
use crate::spawn_future;
|
||||
|
||||
// Time interval between reporting packet statistics
|
||||
const PACKET_REPORT_INTERVAL_SECS: u64 = 2;
|
||||
// Interval for taking snapshots of the packet statistics
|
||||
const SNAPSHOT_INTERVAL_MS: u64 = 500;
|
||||
// When computing rates, we include snapshots that are up to this old. We set it to some odd number
|
||||
// a tad larger than an integer number of snapshot intervals, so that we don't have to worry about
|
||||
// threshold effects.
|
||||
// Also, set it larger than the packet report interval so that we don't miss notable singular events
|
||||
const RECORDING_WINDOW_MS: u64 = 2300;
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
struct PacketStatistics {
|
||||
// Sent
|
||||
real_packets_sent: u64,
|
||||
real_packets_sent_size: usize,
|
||||
cover_packets_sent: u64,
|
||||
cover_packets_sent_size: usize,
|
||||
|
||||
// Received
|
||||
real_packets_received: u64,
|
||||
real_packets_received_size: usize,
|
||||
cover_packets_received: u64,
|
||||
cover_packets_received_size: usize,
|
||||
|
||||
// Acks
|
||||
total_acks_received: u64,
|
||||
total_acks_received_size: usize,
|
||||
real_acks_received: u64,
|
||||
real_acks_received_size: usize,
|
||||
cover_acks_received: u64,
|
||||
cover_acks_received_size: usize,
|
||||
|
||||
// Types of packets queued
|
||||
// TODO: track the type sent instead
|
||||
real_packets_queued: u64,
|
||||
retransmissions_queued: u64,
|
||||
reply_surbs_queued: u64,
|
||||
additional_reply_surbs_queued: u64,
|
||||
}
|
||||
|
||||
impl PacketStatistics {
|
||||
fn handle_event(&mut self, event: PacketStatisticsEvent) {
|
||||
match event {
|
||||
PacketStatisticsEvent::RealPacketSent(packet_size) => {
|
||||
self.real_packets_sent += 1;
|
||||
self.real_packets_sent_size += packet_size;
|
||||
}
|
||||
PacketStatisticsEvent::CoverPacketSent(packet_size) => {
|
||||
self.cover_packets_sent += 1;
|
||||
self.cover_packets_sent_size += packet_size;
|
||||
}
|
||||
PacketStatisticsEvent::RealPacketReceived(packet_size) => {
|
||||
self.real_packets_received += 1;
|
||||
self.real_packets_received_size += packet_size;
|
||||
}
|
||||
PacketStatisticsEvent::CoverPacketReceived(packet_size) => {
|
||||
self.cover_packets_received += 1;
|
||||
self.cover_packets_received_size += packet_size;
|
||||
}
|
||||
PacketStatisticsEvent::AckReceived(packet_size) => {
|
||||
self.total_acks_received += 1;
|
||||
self.total_acks_received_size += packet_size;
|
||||
}
|
||||
PacketStatisticsEvent::RealAckReceived(packet_size) => {
|
||||
self.real_acks_received += 1;
|
||||
self.real_acks_received_size += packet_size;
|
||||
}
|
||||
PacketStatisticsEvent::CoverAckReceived(packet_size) => {
|
||||
self.cover_acks_received += 1;
|
||||
self.cover_acks_received_size += packet_size;
|
||||
}
|
||||
PacketStatisticsEvent::RealPacketQueued => {
|
||||
self.real_packets_queued += 1;
|
||||
}
|
||||
PacketStatisticsEvent::RetransmissionQueued => {
|
||||
self.retransmissions_queued += 1;
|
||||
}
|
||||
PacketStatisticsEvent::ReplySurbRequestQueued => {
|
||||
self.reply_surbs_queued += 1;
|
||||
}
|
||||
PacketStatisticsEvent::AdditionalReplySurbRequestQueued => {
|
||||
self.additional_reply_surbs_queued += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn summary(&self) -> (String, String) {
|
||||
(
|
||||
format!(
|
||||
"packets sent: {} (real: {}, cover: {}, retransmissions: {})",
|
||||
self.real_packets_sent + self.cover_packets_sent,
|
||||
self.real_packets_sent,
|
||||
self.cover_packets_sent,
|
||||
self.retransmissions_queued,
|
||||
),
|
||||
format!(
|
||||
"packets received: {}, (real: {}, cover: {}, acks: {}, acks for cover: {})",
|
||||
self.real_packets_received + self.cover_packets_received,
|
||||
self.real_packets_received,
|
||||
self.cover_packets_received,
|
||||
self.real_acks_received,
|
||||
self.cover_acks_received,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Sub for PacketStatistics {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
real_packets_sent: self.real_packets_sent - rhs.real_packets_sent,
|
||||
real_packets_sent_size: self.real_packets_sent_size - rhs.real_packets_sent_size,
|
||||
cover_packets_sent: self.cover_packets_sent - rhs.cover_packets_sent,
|
||||
cover_packets_sent_size: self.cover_packets_sent_size - rhs.cover_packets_sent_size,
|
||||
|
||||
real_packets_received: self.real_packets_received - rhs.real_packets_received,
|
||||
real_packets_received_size: self.real_packets_received_size
|
||||
- rhs.real_packets_received_size,
|
||||
cover_packets_received: self.cover_packets_received - rhs.cover_packets_received,
|
||||
cover_packets_received_size: self.cover_packets_received_size
|
||||
- rhs.cover_packets_received_size,
|
||||
|
||||
total_acks_received: self.total_acks_received - rhs.total_acks_received,
|
||||
total_acks_received_size: self.total_acks_received_size - rhs.total_acks_received_size,
|
||||
real_acks_received: self.real_acks_received - rhs.real_acks_received,
|
||||
real_acks_received_size: self.real_acks_received_size - rhs.real_acks_received_size,
|
||||
cover_acks_received: self.cover_acks_received - rhs.cover_acks_received,
|
||||
cover_acks_received_size: self.cover_acks_received_size - rhs.cover_acks_received_size,
|
||||
|
||||
real_packets_queued: self.real_packets_queued - rhs.real_packets_queued,
|
||||
retransmissions_queued: self.retransmissions_queued - rhs.retransmissions_queued,
|
||||
reply_surbs_queued: self.reply_surbs_queued - rhs.reply_surbs_queued,
|
||||
additional_reply_surbs_queued: self.additional_reply_surbs_queued
|
||||
- rhs.additional_reply_surbs_queued,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct PacketRates {
|
||||
real_packets_sent: f64,
|
||||
real_packets_sent_size: f64,
|
||||
cover_packets_sent: f64,
|
||||
cover_packets_sent_size: f64,
|
||||
|
||||
real_packets_received: f64,
|
||||
real_packets_received_size: f64,
|
||||
cover_packets_received: f64,
|
||||
cover_packets_received_size: f64,
|
||||
|
||||
total_acks_received: f64,
|
||||
total_acks_received_size: f64,
|
||||
real_acks_received: f64,
|
||||
real_acks_received_size: f64,
|
||||
cover_acks_received: f64,
|
||||
cover_acks_received_size: f64,
|
||||
|
||||
real_packets_queued: f64,
|
||||
retransmissions_queued: f64,
|
||||
reply_surbs_queued: f64,
|
||||
additional_reply_surbs_queued: f64,
|
||||
}
|
||||
|
||||
impl From<PacketStatistics> for PacketRates {
|
||||
fn from(stats: PacketStatistics) -> Self {
|
||||
Self {
|
||||
real_packets_sent: stats.real_packets_sent as f64,
|
||||
real_packets_sent_size: stats.real_packets_sent_size as f64,
|
||||
cover_packets_sent: stats.cover_packets_sent as f64,
|
||||
cover_packets_sent_size: stats.cover_packets_sent_size as f64,
|
||||
|
||||
real_packets_received: stats.real_packets_received as f64,
|
||||
real_packets_received_size: stats.real_packets_received_size as f64,
|
||||
cover_packets_received: stats.cover_packets_received as f64,
|
||||
cover_packets_received_size: stats.cover_packets_received_size as f64,
|
||||
|
||||
total_acks_received: stats.total_acks_received as f64,
|
||||
total_acks_received_size: stats.total_acks_received_size as f64,
|
||||
real_acks_received: stats.real_acks_received as f64,
|
||||
real_acks_received_size: stats.real_acks_received_size as f64,
|
||||
cover_acks_received: stats.cover_acks_received as f64,
|
||||
cover_acks_received_size: stats.cover_acks_received_size as f64,
|
||||
|
||||
real_packets_queued: stats.real_packets_queued as f64,
|
||||
retransmissions_queued: stats.retransmissions_queued as f64,
|
||||
reply_surbs_queued: stats.reply_surbs_queued as f64,
|
||||
additional_reply_surbs_queued: stats.additional_reply_surbs_queued as f64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Sub for PacketRates {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
real_packets_sent: self.real_packets_sent - rhs.real_packets_sent,
|
||||
real_packets_sent_size: self.real_packets_sent_size - rhs.real_packets_sent_size,
|
||||
cover_packets_sent: self.cover_packets_sent - rhs.cover_packets_sent,
|
||||
cover_packets_sent_size: self.cover_packets_sent_size - rhs.cover_packets_sent_size,
|
||||
|
||||
real_packets_received: self.real_packets_received - rhs.real_packets_received,
|
||||
real_packets_received_size: self.real_packets_received_size
|
||||
- rhs.real_packets_received_size,
|
||||
cover_packets_received: self.cover_packets_received - rhs.cover_packets_received,
|
||||
cover_packets_received_size: self.cover_packets_received_size
|
||||
- rhs.cover_packets_received_size,
|
||||
|
||||
total_acks_received: self.total_acks_received - rhs.total_acks_received,
|
||||
total_acks_received_size: self.total_acks_received_size - rhs.total_acks_received_size,
|
||||
real_acks_received: self.real_acks_received - rhs.real_acks_received,
|
||||
real_acks_received_size: self.real_acks_received_size - rhs.real_acks_received_size,
|
||||
cover_acks_received: self.cover_acks_received - rhs.cover_acks_received,
|
||||
cover_acks_received_size: self.cover_acks_received_size - rhs.cover_acks_received_size,
|
||||
|
||||
real_packets_queued: self.real_packets_queued - rhs.real_packets_queued,
|
||||
retransmissions_queued: self.retransmissions_queued - rhs.retransmissions_queued,
|
||||
reply_surbs_queued: self.reply_surbs_queued - rhs.reply_surbs_queued,
|
||||
additional_reply_surbs_queued: self.additional_reply_surbs_queued
|
||||
- rhs.additional_reply_surbs_queued,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Div<f64> for PacketRates {
|
||||
type Output = Self;
|
||||
|
||||
fn div(self, rhs: f64) -> Self::Output {
|
||||
Self {
|
||||
real_packets_sent: self.real_packets_sent / rhs,
|
||||
real_packets_sent_size: self.real_packets_sent_size / rhs,
|
||||
cover_packets_sent: self.cover_packets_sent / rhs,
|
||||
cover_packets_sent_size: self.cover_packets_sent_size / rhs,
|
||||
|
||||
real_packets_received: self.real_packets_received / rhs,
|
||||
real_packets_received_size: self.real_packets_received_size / rhs,
|
||||
cover_packets_received: self.cover_packets_received / rhs,
|
||||
cover_packets_received_size: self.cover_packets_received_size / rhs,
|
||||
|
||||
total_acks_received: self.total_acks_received / rhs,
|
||||
total_acks_received_size: self.total_acks_received_size / rhs,
|
||||
real_acks_received: self.real_acks_received / rhs,
|
||||
real_acks_received_size: self.real_acks_received_size / rhs,
|
||||
cover_acks_received: self.cover_acks_received / rhs,
|
||||
cover_acks_received_size: self.cover_acks_received_size / rhs,
|
||||
|
||||
real_packets_queued: self.real_packets_queued / rhs,
|
||||
retransmissions_queued: self.retransmissions_queued / rhs,
|
||||
reply_surbs_queued: self.reply_surbs_queued / rhs,
|
||||
additional_reply_surbs_queued: self.additional_reply_surbs_queued / rhs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketRates {
|
||||
fn summary(&self) -> String {
|
||||
format!(
|
||||
"rx: {}/s (real: {}/s), tx: {}/s (real: {}/s)",
|
||||
bibytes2(self.real_packets_received_size + self.cover_packets_received_size),
|
||||
bibytes2(self.real_packets_received_size),
|
||||
bibytes2(self.real_packets_sent_size + self.cover_packets_sent_size),
|
||||
bibytes2(self.real_packets_sent_size),
|
||||
)
|
||||
}
|
||||
|
||||
fn detailed_summary(&self) -> String {
|
||||
format!(
|
||||
"RX: {:.1} mixpkt/s, {}/s (real: {}/s, acks: {}/s), TX: {:.1} mixpkt/s, {}/s (real: {}/s)",
|
||||
self.real_packets_received + self.cover_packets_received,
|
||||
bibytes2(self.real_packets_received_size + self.cover_packets_received_size),
|
||||
bibytes2(self.real_packets_received_size),
|
||||
bibytes2(self.total_acks_received_size),
|
||||
self.real_packets_sent + self.cover_packets_sent,
|
||||
bibytes2(self.real_packets_sent_size + self.cover_packets_sent_size),
|
||||
bibytes2(self.real_packets_sent_size),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) enum PacketStatisticsEvent {
|
||||
// The real packets sent. Recall that acks are sent by the gateway, so it's not included here.
|
||||
RealPacketSent(usize),
|
||||
// The cover packets sent
|
||||
CoverPacketSent(usize),
|
||||
|
||||
// Real packets received
|
||||
RealPacketReceived(usize),
|
||||
// Cover packets received
|
||||
CoverPacketReceived(usize),
|
||||
|
||||
// Ack of any type received. This is mostly used as a consistency check, and should be the sum
|
||||
// of real and cover acks received.
|
||||
AckReceived(usize),
|
||||
// Out of the total acks received, this is the subset of those that were real
|
||||
RealAckReceived(usize),
|
||||
// Out of the total acks received, this is the subset of those that were for cover traffic
|
||||
CoverAckReceived(usize),
|
||||
|
||||
// Types of packets queued
|
||||
RealPacketQueued,
|
||||
RetransmissionQueued,
|
||||
ReplySurbRequestQueued,
|
||||
AdditionalReplySurbRequestQueued,
|
||||
}
|
||||
|
||||
type PacketStatisticsReceiver = tokio::sync::mpsc::UnboundedReceiver<PacketStatisticsEvent>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct PacketStatisticsReporter {
|
||||
stats_tx: tokio::sync::mpsc::UnboundedSender<PacketStatisticsEvent>,
|
||||
}
|
||||
|
||||
impl PacketStatisticsReporter {
|
||||
pub(crate) fn new(stats_tx: tokio::sync::mpsc::UnboundedSender<PacketStatisticsEvent>) -> Self {
|
||||
Self { stats_tx }
|
||||
}
|
||||
|
||||
pub(crate) fn report(&self, event: PacketStatisticsEvent) {
|
||||
self.stats_tx.send(event).unwrap_or_else(|err| {
|
||||
log::error!("Failed to report packet stat: {:?}", err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct PacketStatisticsControl {
|
||||
// Incoming packet stats events from other tasks
|
||||
stats_rx: PacketStatisticsReceiver,
|
||||
|
||||
// Keep track of packet statistics over time
|
||||
stats: PacketStatistics,
|
||||
|
||||
// We keep snapshots of the statistics over time so we can compute rates, and also keeping the
|
||||
// full history allows for some more fancy averaging if we want to do that.
|
||||
history: VecDeque<(Instant, PacketStatistics)>,
|
||||
|
||||
// Keep previous rates so that we can detect notable events
|
||||
rates: VecDeque<(Instant, PacketRates)>,
|
||||
}
|
||||
|
||||
impl PacketStatisticsControl {
|
||||
pub(crate) fn new() -> (Self, PacketStatisticsReporter) {
|
||||
let (stats_tx, stats_rx) = tokio::sync::mpsc::unbounded_channel();
|
||||
|
||||
(
|
||||
Self {
|
||||
stats_rx,
|
||||
stats: PacketStatistics::default(),
|
||||
history: VecDeque::new(),
|
||||
rates: VecDeque::new(),
|
||||
},
|
||||
PacketStatisticsReporter::new(stats_tx),
|
||||
)
|
||||
}
|
||||
|
||||
// Add the current stats to the history, and remove old ones.
|
||||
fn update_history(&mut self) {
|
||||
// Update latest
|
||||
self.history.push_back((Instant::now(), self.stats.clone()));
|
||||
|
||||
// Filter out old ones
|
||||
let recording_window = Instant::now() - Duration::from_millis(RECORDING_WINDOW_MS);
|
||||
while self
|
||||
.history
|
||||
.front()
|
||||
.map_or(false, |&(t, _)| t < recording_window)
|
||||
{
|
||||
self.history.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
fn compute_rates(&self) -> Option<PacketRates> {
|
||||
// NOTE: consider changing this to compute rates over the history instead of using current
|
||||
// stats. Currently it should not make much of a difference since we call this just after
|
||||
// updating the history, but it seems like it could be more internally consistent to do it
|
||||
// that way.
|
||||
|
||||
// Do basic averaging over the entire history, which just uses the first and last
|
||||
if let Some((start, start_stats)) = self.history.front() {
|
||||
let duration_secs = Instant::now().duration_since(*start).as_secs_f64();
|
||||
let delta = self.stats.clone() - start_stats.clone();
|
||||
let rates = PacketRates::from(delta) / duration_secs;
|
||||
Some(rates)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn update_rates(&mut self) {
|
||||
// Update latest
|
||||
if let Some(rates) = self.compute_rates() {
|
||||
self.rates.push_back((Instant::now(), rates));
|
||||
}
|
||||
|
||||
// Filter out old ones
|
||||
let recording_window = Instant::now() - Duration::from_millis(RECORDING_WINDOW_MS);
|
||||
while self
|
||||
.rates
|
||||
.front()
|
||||
.map_or(false, |&(t, _)| t < recording_window)
|
||||
{
|
||||
self.rates.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
fn report_rates(&self) {
|
||||
if let Some((_, rates)) = self.rates.back() {
|
||||
log::info!("{}", rates.summary());
|
||||
log::debug!("{}", rates.detailed_summary());
|
||||
}
|
||||
}
|
||||
|
||||
fn report_counters(&self) {
|
||||
log::trace!("packet statistics: {:?}", &self.stats);
|
||||
let (summary_sent, summary_recv) = self.stats.summary();
|
||||
log::debug!("{}", summary_sent);
|
||||
log::debug!("{}", summary_recv);
|
||||
}
|
||||
|
||||
fn check_for_notable_events(&self) {
|
||||
let Some((_, latest_rates)) = self.rates.back() else {
|
||||
return;
|
||||
};
|
||||
|
||||
// If we get a burst of retransmissions
|
||||
// TODO: consider making this the number of retransmissions since last report instead.
|
||||
if latest_rates.retransmissions_queued > 0.0 {
|
||||
log::debug!(
|
||||
"retransmissions: {:.2} pkt/s",
|
||||
latest_rates.retransmissions_queued
|
||||
);
|
||||
|
||||
// Check what the number of retransmissions was during the recording window
|
||||
if let Some((_, start_stats)) = self.history.front() {
|
||||
let delta = self.stats.clone() - start_stats.clone();
|
||||
log::info!("retransmissions: {}", delta.retransmissions_queued,);
|
||||
} else {
|
||||
log::warn!("Unable to check retransmissions during recording window");
|
||||
}
|
||||
}
|
||||
|
||||
// IDEA: if there is a burst of acks, that could indicate tokio task starvation.
|
||||
}
|
||||
|
||||
pub(crate) async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) {
|
||||
log::debug!("Started PacketStatisticsControl with graceful shutdown support");
|
||||
|
||||
let report_interval = Duration::from_secs(PACKET_REPORT_INTERVAL_SECS);
|
||||
let mut report_interval = tokio::time::interval(report_interval);
|
||||
let snapshot_interval = Duration::from_millis(SNAPSHOT_INTERVAL_MS);
|
||||
let mut snapshot_interval = tokio::time::interval(snapshot_interval);
|
||||
|
||||
loop {
|
||||
tokio::select! {
|
||||
stats_event = self.stats_rx.recv() => match stats_event {
|
||||
Some(stats_event) => {
|
||||
log::trace!("PacketStatisticsControl: Received stats event");
|
||||
self.stats.handle_event(stats_event);
|
||||
},
|
||||
None => {
|
||||
log::trace!("PacketStatisticsControl: stopping since stats channel was closed");
|
||||
break;
|
||||
}
|
||||
},
|
||||
_ = snapshot_interval.tick() => {
|
||||
self.update_history();
|
||||
self.update_rates();
|
||||
}
|
||||
_ = report_interval.tick() => {
|
||||
self.report_rates();
|
||||
self.check_for_notable_events();
|
||||
self.report_counters();
|
||||
}
|
||||
_ = shutdown.recv_with_delay() => {
|
||||
log::trace!("PacketStatisticsControl: Received shutdown");
|
||||
break;
|
||||
},
|
||||
}
|
||||
}
|
||||
log::debug!("PacketStatisticsControl: Exiting");
|
||||
}
|
||||
|
||||
pub(crate) fn start_with_shutdown(mut self, task_client: nym_task::TaskClient) {
|
||||
spawn_future(async move {
|
||||
self.run_with_shutdown(task_client).await;
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::client::packet_statistics_control::{PacketStatisticsEvent, PacketStatisticsReporter};
|
||||
|
||||
use super::action_controller::{AckActionSender, Action};
|
||||
use futures::StreamExt;
|
||||
use log::*;
|
||||
@@ -17,6 +19,7 @@ pub(super) struct AcknowledgementListener {
|
||||
ack_key: Arc<AckKey>,
|
||||
ack_receiver: AcknowledgementReceiver,
|
||||
action_sender: AckActionSender,
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
}
|
||||
|
||||
impl AcknowledgementListener {
|
||||
@@ -24,16 +27,21 @@ impl AcknowledgementListener {
|
||||
ack_key: Arc<AckKey>,
|
||||
ack_receiver: AcknowledgementReceiver,
|
||||
action_sender: AckActionSender,
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
) -> Self {
|
||||
AcknowledgementListener {
|
||||
ack_key,
|
||||
ack_receiver,
|
||||
action_sender,
|
||||
stats_tx,
|
||||
}
|
||||
}
|
||||
|
||||
async fn on_ack(&mut self, ack_content: Vec<u8>) {
|
||||
trace!("Received an ack");
|
||||
self.stats_tx
|
||||
.report(PacketStatisticsEvent::AckReceived(ack_content.len()));
|
||||
|
||||
let frag_id = match recover_identifier(&self.ack_key, &ack_content)
|
||||
.map(FragmentIdentifier::try_from_bytes)
|
||||
{
|
||||
@@ -48,11 +56,14 @@ impl AcknowledgementListener {
|
||||
// because nothing was inserted in the first place
|
||||
if frag_id == COVER_FRAG_ID {
|
||||
trace!("Received an ack for a cover message - no need to do anything");
|
||||
self.stats_tx
|
||||
.report(PacketStatisticsEvent::CoverAckReceived(ack_content.len()));
|
||||
return;
|
||||
}
|
||||
|
||||
trace!("Received {} from the mix network", frag_id);
|
||||
|
||||
self.stats_tx
|
||||
.report(PacketStatisticsEvent::RealAckReceived(ack_content.len()));
|
||||
self.action_sender
|
||||
.unbounded_send(Action::new_remove(frag_id))
|
||||
.unwrap();
|
||||
|
||||
@@ -8,6 +8,7 @@ use self::{
|
||||
sent_notification_listener::SentNotificationListener,
|
||||
};
|
||||
use crate::client::inbound_messages::InputMessageReceiver;
|
||||
use crate::client::packet_statistics_control::PacketStatisticsReporter;
|
||||
use crate::client::real_messages_control::message_handler::MessageHandler;
|
||||
use crate::client::replies::reply_controller::ReplyControllerSender;
|
||||
use crate::spawn_future;
|
||||
@@ -208,6 +209,7 @@ where
|
||||
connectors: AcknowledgementControllerConnectors,
|
||||
message_handler: MessageHandler<R>,
|
||||
reply_controller_sender: ReplyControllerSender,
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
) -> Self {
|
||||
let (retransmission_tx, retransmission_rx) = mpsc::unbounded();
|
||||
|
||||
@@ -224,6 +226,7 @@ where
|
||||
Arc::clone(&ack_key),
|
||||
connectors.ack_receiver,
|
||||
connectors.ack_action_sender.clone(),
|
||||
stats_tx,
|
||||
);
|
||||
|
||||
// will listen for any new messages from the client
|
||||
|
||||
@@ -35,6 +35,8 @@ use crate::client::replies::reply_controller;
|
||||
use crate::config;
|
||||
pub(crate) use acknowledgement_control::{AckActionSender, Action};
|
||||
|
||||
use super::packet_statistics_control::PacketStatisticsReporter;
|
||||
|
||||
pub(crate) mod acknowledgement_control;
|
||||
pub(crate) mod message_handler;
|
||||
pub(crate) mod real_traffic_stream;
|
||||
@@ -143,6 +145,7 @@ impl RealMessagesController<OsRng> {
|
||||
reply_controller_receiver: ReplyControllerReceiver,
|
||||
lane_queue_lengths: LaneQueueLengths,
|
||||
client_connection_rx: ConnectionCommandReceiver,
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
) -> Self {
|
||||
let rng = OsRng;
|
||||
|
||||
@@ -181,6 +184,7 @@ impl RealMessagesController<OsRng> {
|
||||
ack_controller_connectors,
|
||||
message_handler.clone(),
|
||||
reply_controller_sender,
|
||||
stats_tx.clone(),
|
||||
);
|
||||
|
||||
let reply_control = ReplyController::new(
|
||||
@@ -199,6 +203,7 @@ impl RealMessagesController<OsRng> {
|
||||
topology_access,
|
||||
lane_queue_lengths,
|
||||
client_connection_rx,
|
||||
stats_tx,
|
||||
);
|
||||
|
||||
RealMessagesController {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
use self::sending_delay_controller::SendingDelayController;
|
||||
use crate::client::mix_traffic::BatchMixMessageSender;
|
||||
use crate::client::packet_statistics_control::{PacketStatisticsEvent, PacketStatisticsReporter};
|
||||
use crate::client::real_messages_control::acknowledgement_control::SentPacketNotificationSender;
|
||||
use crate::client::topology_control::TopologyAccessor;
|
||||
use crate::client::transmission_buffer::TransmissionBuffer;
|
||||
@@ -113,6 +114,9 @@ where
|
||||
|
||||
/// Report queue lengths so that upstream can backoff sending data, and keep connections open.
|
||||
lane_queue_lengths: LaneQueueLengths,
|
||||
|
||||
/// Channel used for sending statistics events to `PacketStatisticsControl`.
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -171,6 +175,7 @@ where
|
||||
topology_access: TopologyAccessor,
|
||||
lane_queue_lengths: LaneQueueLengths,
|
||||
client_connection_rx: ConnectionCommandReceiver,
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
) -> Self {
|
||||
OutQueueControl {
|
||||
config,
|
||||
@@ -184,6 +189,7 @@ where
|
||||
transmission_buffer: TransmissionBuffer::new(),
|
||||
client_connection_rx,
|
||||
lane_queue_lengths,
|
||||
stats_tx,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +220,7 @@ where
|
||||
async fn on_message(&mut self, next_message: StreamMessage) {
|
||||
trace!("created new message");
|
||||
|
||||
let (next_message, fragment_id) = match next_message {
|
||||
let (next_message, fragment_id, packet_size) = match next_message {
|
||||
StreamMessage::Cover => {
|
||||
let cover_traffic_packet_size = self.loop_cover_message_size();
|
||||
trace!("the next loop cover message will be put in a {cover_traffic_packet_size} packet");
|
||||
@@ -250,15 +256,28 @@ where
|
||||
"Somehow failed to generate a loop cover message with a valid topology",
|
||||
),
|
||||
None,
|
||||
cover_traffic_packet_size.size(),
|
||||
)
|
||||
}
|
||||
StreamMessage::Real(real_message) => {
|
||||
(real_message.mix_packet, real_message.fragment_id)
|
||||
let packet_size = real_message.packet_size();
|
||||
(
|
||||
real_message.mix_packet,
|
||||
real_message.fragment_id,
|
||||
packet_size,
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(err) = self.mix_tx.send(vec![next_message]).await {
|
||||
log::error!("Failed to send: {err}");
|
||||
} else {
|
||||
let event = if fragment_id.is_some() {
|
||||
PacketStatisticsEvent::RealPacketSent(packet_size)
|
||||
} else {
|
||||
PacketStatisticsEvent::CoverPacketSent(packet_size)
|
||||
};
|
||||
self.stats_tx.report(event);
|
||||
}
|
||||
|
||||
// notify ack controller about sending our message only after we actually managed to push it
|
||||
@@ -340,6 +359,28 @@ where
|
||||
let lane_length = self.transmission_buffer.lane_length(&lane);
|
||||
self.lane_queue_lengths.set(&lane, lane_length);
|
||||
|
||||
// This is the last step in the pipeline where we know the type of the message, so
|
||||
// lets count the number of retransmissions and reply surb messages sent here.
|
||||
let stat_event = match lane {
|
||||
TransmissionLane::General => None,
|
||||
TransmissionLane::ConnectionId(_) => None,
|
||||
TransmissionLane::ReplySurbRequest => {
|
||||
Some(PacketStatisticsEvent::ReplySurbRequestQueued)
|
||||
}
|
||||
TransmissionLane::AdditionalReplySurbs => {
|
||||
Some(PacketStatisticsEvent::AdditionalReplySurbRequestQueued)
|
||||
}
|
||||
TransmissionLane::Retransmission => Some(PacketStatisticsEvent::RetransmissionQueued),
|
||||
};
|
||||
if let Some(stat_event) = stat_event {
|
||||
self.stats_tx.report(stat_event);
|
||||
}
|
||||
// To avoid comparing apples to oranges when presenting the fraction of packets that are
|
||||
// retransmissions, we also need to keep track to the total number of real messages queued,
|
||||
// even though we also track the actual number of messages sent later in the pipeline.
|
||||
self.stats_tx
|
||||
.report(PacketStatisticsEvent::RealPacketQueued);
|
||||
|
||||
Some(real_next)
|
||||
}
|
||||
|
||||
@@ -433,6 +474,13 @@ where
|
||||
Poll::Ready(Some((real_messages, conn_id))) => {
|
||||
log::trace!("handling real_messages: size: {}", real_messages.len());
|
||||
|
||||
// This is the last step in the pipeline where we know the type of the message, so
|
||||
// lets count the number of retransmissions here.
|
||||
if conn_id == TransmissionLane::Retransmission {
|
||||
self.stats_tx
|
||||
.report(PacketStatisticsEvent::RetransmissionQueued);
|
||||
}
|
||||
|
||||
// First store what we got for the given connection id
|
||||
self.transmission_buffer.store(&conn_id, real_messages);
|
||||
let real_next = self.pop_next_message().expect("we just added one");
|
||||
@@ -471,10 +519,10 @@ where
|
||||
let mult = self.sending_delay_controller.current_multiplier();
|
||||
let delay = self.current_average_message_sending_delay().as_millis();
|
||||
let status_str = if self.config.traffic.disable_main_poisson_packet_distribution {
|
||||
format!("Status: {lanes} lanes, backlog: {backlog:.2} kiB ({packets}), no delay")
|
||||
format!("Packet backlog: {backlog:.2} kiB ({packets}), {lanes} lanes, no delay")
|
||||
} else {
|
||||
format!(
|
||||
"Status: {lanes} lanes, backlog: {backlog:.2} kiB ({packets}), avg delay: {delay}ms ({mult})"
|
||||
"Packet backlog: {backlog:.2} kiB ({packets}), {lanes} lanes, avg delay: {delay}ms ({mult})"
|
||||
)
|
||||
};
|
||||
if packets > 1000 {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::client::replies::reply_controller::ReplyControllerSender;
|
||||
use crate::client::replies::reply_storage::SentReplyKeys;
|
||||
use crate::client::{
|
||||
packet_statistics_control::{PacketStatisticsEvent, PacketStatisticsReporter},
|
||||
replies::{reply_controller::ReplyControllerSender, reply_storage::SentReplyKeys},
|
||||
};
|
||||
use crate::spawn_future;
|
||||
use futures::channel::mpsc;
|
||||
use futures::lock::Mutex;
|
||||
@@ -43,15 +45,33 @@ struct ReceivedMessagesBufferInner<R: MessageReceiver> {
|
||||
// but perhaps it should be changed to include timestamps of when the message was reconstructed
|
||||
// and every now and then remove ids older than X
|
||||
recently_reconstructed: HashSet<i32>,
|
||||
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
}
|
||||
|
||||
impl<R: MessageReceiver> ReceivedMessagesBufferInner<R> {
|
||||
fn recover_from_fragment(&mut self, fragment_data: &[u8]) -> Option<NymMessage> {
|
||||
fn recover_from_fragment(
|
||||
&mut self,
|
||||
fragment_data: &[u8],
|
||||
fragment_data_size: usize,
|
||||
) -> Option<NymMessage> {
|
||||
if nym_sphinx::cover::is_cover(fragment_data) {
|
||||
trace!("The message was a loop cover message! Skipping it");
|
||||
// NOTE: it's important to note that there is quite a bit of difference in size of
|
||||
// received and sent packets due to the sphinx layers being removed by the exit gateway
|
||||
// before it reaches the mixnet client.
|
||||
self.stats_tx
|
||||
.report(PacketStatisticsEvent::CoverPacketReceived(
|
||||
fragment_data_size,
|
||||
));
|
||||
return None;
|
||||
}
|
||||
|
||||
self.stats_tx
|
||||
.report(PacketStatisticsEvent::RealPacketReceived(
|
||||
fragment_data_size,
|
||||
));
|
||||
|
||||
let fragment = match self.message_receiver.recover_fragment(fragment_data) {
|
||||
Err(err) => {
|
||||
warn!("failed to recover fragment from raw data: {err}. The whole underlying message might be corrupted and unrecoverable!");
|
||||
@@ -103,15 +123,17 @@ impl<R: MessageReceiver> ReceivedMessagesBufferInner<R> {
|
||||
reply_ciphertext: &mut [u8],
|
||||
reply_key: SurbEncryptionKey,
|
||||
) -> Result<Option<NymMessage>, MessageRecoveryError> {
|
||||
let reply_ciphertext_size = reply_ciphertext.len();
|
||||
// note: this performs decryption IN PLACE without extra allocation
|
||||
self.message_receiver
|
||||
.recover_plaintext_from_reply(reply_ciphertext, reply_key)?;
|
||||
let fragment_data = reply_ciphertext;
|
||||
|
||||
Ok(self.recover_from_fragment(fragment_data))
|
||||
Ok(self.recover_from_fragment(fragment_data, reply_ciphertext_size))
|
||||
}
|
||||
|
||||
fn process_received_regular_packet(&mut self, mut raw_fragment: Vec<u8>) -> Option<NymMessage> {
|
||||
let raw_fragment_size = raw_fragment.len();
|
||||
let fragment_data = match self.message_receiver.recover_plaintext_from_regular_packet(
|
||||
self.local_encryption_keypair.private_key(),
|
||||
&mut raw_fragment,
|
||||
@@ -123,7 +145,7 @@ impl<R: MessageReceiver> ReceivedMessagesBufferInner<R> {
|
||||
Ok(frag_data) => frag_data,
|
||||
};
|
||||
|
||||
self.recover_from_fragment(fragment_data)
|
||||
self.recover_from_fragment(fragment_data, raw_fragment_size)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +163,7 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
|
||||
local_encryption_keypair: Arc<encryption::KeyPair>,
|
||||
reply_key_storage: SentReplyKeys,
|
||||
reply_controller_sender: ReplyControllerSender,
|
||||
stats_tx: PacketStatisticsReporter,
|
||||
) -> Self {
|
||||
ReceivedMessagesBuffer {
|
||||
inner: Arc::new(Mutex::new(ReceivedMessagesBufferInner {
|
||||
@@ -149,6 +172,7 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
|
||||
message_receiver: R::new(),
|
||||
message_sender: None,
|
||||
recently_reconstructed: HashSet::new(),
|
||||
stats_tx,
|
||||
})),
|
||||
reply_key_storage,
|
||||
reply_controller_sender,
|
||||
@@ -353,7 +377,7 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
|
||||
};
|
||||
|
||||
if let Some(completed) = completed_message {
|
||||
info!("received {completed}");
|
||||
debug!("received {completed}");
|
||||
completed_messages.push(completed)
|
||||
}
|
||||
}
|
||||
@@ -480,11 +504,13 @@ impl<R: MessageReceiver + Clone + Send + 'static> ReceivedMessagesBufferControll
|
||||
mixnet_packet_receiver: MixnetMessageReceiver,
|
||||
reply_key_storage: SentReplyKeys,
|
||||
reply_controller_sender: ReplyControllerSender,
|
||||
packet_statistics_reporter: PacketStatisticsReporter,
|
||||
) -> Self {
|
||||
let received_buffer = ReceivedMessagesBuffer::new(
|
||||
local_encryption_keypair,
|
||||
reply_key_storage,
|
||||
reply_controller_sender,
|
||||
packet_statistics_reporter,
|
||||
);
|
||||
|
||||
ReceivedMessagesBufferController {
|
||||
|
||||
@@ -65,7 +65,7 @@ pub async fn current_gateways<R: Rng>(
|
||||
.ok_or(ClientCoreError::ListOfNymApisIsEmpty)?;
|
||||
let client = nym_validator_client::client::NymApiClient::new(nym_api.clone());
|
||||
|
||||
log::trace!("Fetching list of gateways from: {nym_api}");
|
||||
log::debug!("Fetching list of gateways from: {nym_api}");
|
||||
|
||||
let gateways = client.get_cached_described_gateways().await?;
|
||||
log::debug!("Found {} gateways", gateways.len());
|
||||
|
||||
@@ -178,7 +178,7 @@ impl<T> From<PersistedGatewayDetails<T>> for GatewayDetails<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum GatewaySelectionSpecification<T = EmptyCustomDetails> {
|
||||
/// Uniformly choose a random remote gateway.
|
||||
UniformRemote { must_use_tls: bool },
|
||||
|
||||
@@ -226,4 +226,8 @@ impl EpochState {
|
||||
pub fn is_final(&self) -> bool {
|
||||
*self == EpochState::InProgress
|
||||
}
|
||||
|
||||
pub fn is_in_progress(&self) -> bool {
|
||||
matches!(self, EpochState::InProgress)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ repository.workspace = true
|
||||
cfg-if = { workspace = true }
|
||||
dotenvy = { workspace = true }
|
||||
hex-literal = "0.3.3"
|
||||
log = { workspace = true }
|
||||
once_cell = { workspace = true }
|
||||
schemars = { workspace = true, features = ["preserve_order"] }
|
||||
serde = { workspace = true, features = ["derive"]}
|
||||
|
||||
@@ -400,11 +400,25 @@ fn fix_deprecated_environmental_variables() {
|
||||
}
|
||||
}
|
||||
|
||||
// Read the variables from the file and log what the corresponding values in the environment are.
|
||||
fn print_env_vars_with_keys_in_file<P: AsRef<Path> + Copy>(config_env_file: P) {
|
||||
let items = dotenvy::from_path_iter(config_env_file)
|
||||
.expect("Invalid path to environment configuration file");
|
||||
for item in items {
|
||||
let (key, val) = item.expect("Invalid item in environment configuration file");
|
||||
log::debug!("{}: {}", key, val);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup_env<P: AsRef<Path>>(config_env_file: Option<P>) {
|
||||
match std::env::var(var_names::CONFIGURED) {
|
||||
// if the configuration is not already set in the env vars
|
||||
Err(std::env::VarError::NotPresent) => {
|
||||
if let Some(config_env_file) = config_env_file {
|
||||
if let Some(config_env_file) = &config_env_file {
|
||||
log::debug!(
|
||||
"Loading environment variables from {:?}",
|
||||
config_env_file.as_ref()
|
||||
);
|
||||
dotenvy::from_path(config_env_file)
|
||||
.expect("Invalid path to environment configuration file");
|
||||
fix_deprecated_environmental_variables();
|
||||
@@ -412,17 +426,25 @@ pub fn setup_env<P: AsRef<Path>>(config_env_file: Option<P>) {
|
||||
// if nothing is set, the use mainnet defaults
|
||||
// if the user has not set `CONFIGURED`, then even if they set any of the env variables,
|
||||
// overwrite them
|
||||
log::debug!("Loading mainnet defaults");
|
||||
crate::mainnet::export_to_env();
|
||||
}
|
||||
}
|
||||
Err(_) => crate::mainnet::export_to_env(),
|
||||
Err(_) => {
|
||||
log::debug!("Environment variables already set. Using them");
|
||||
crate::mainnet::export_to_env()
|
||||
}
|
||||
_ => {
|
||||
fix_deprecated_environmental_variables();
|
||||
}
|
||||
}
|
||||
|
||||
// if we haven't explicitly defined any of the constants, fallback to defaults
|
||||
crate::mainnet::export_to_env_if_not_set()
|
||||
crate::mainnet::export_to_env_if_not_set();
|
||||
|
||||
if let Some(config_env_file) = &config_env_file {
|
||||
print_env_vars_with_keys_in_file(config_env_file);
|
||||
}
|
||||
}
|
||||
|
||||
// Name of the event triggered by the eth contract. If the event name is changed,
|
||||
|
||||
@@ -239,8 +239,15 @@ impl NymMessage {
|
||||
let (packets_used, space_left) =
|
||||
chunking::number_of_required_fragments(total_required_bytes, plaintext_per_packet);
|
||||
|
||||
let wasted_space = space_left as f32 / (bytes.len() + 1 + space_left) as f32;
|
||||
log::trace!("Padding {self_display}: {} of raw plaintext bytes are required. They're going to be put into {packets_used} sphinx packets with {space_left} bytes of leftover space. {wasted_space}% of packet capacity is going to be wasted.", bytes.len() + 1);
|
||||
let wasted_space_percentage =
|
||||
(space_left as f32 / (bytes.len() + 1 + space_left) as f32) * 100.0;
|
||||
log::trace!(
|
||||
"Padding {self_display}: {} of raw plaintext bytes are required. \
|
||||
They're going to be put into {packets_used} sphinx packets with {space_left} bytes \
|
||||
of leftover space. {wasted_space_percentage:.1}% of packet capacity is going to \
|
||||
be wasted.",
|
||||
bytes.len() + 1
|
||||
);
|
||||
|
||||
bytes
|
||||
.into_iter()
|
||||
|
||||
@@ -4,9 +4,10 @@ version = "0.1.0"
|
||||
edition = "2021"
|
||||
build = "build.rs"
|
||||
links = "cpucycles"
|
||||
license = "LicenseRef-PD-hp OR CC0-1.0 OR 0BSD OR MIT-0 OR MIT"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.140"
|
||||
|
||||
[build-dependencies]
|
||||
cfg-if = "1"
|
||||
cfg-if = "1"
|
||||
|
||||
@@ -114,6 +114,7 @@ allow = [
|
||||
"CC0-1.0",
|
||||
"Unicode-DFS-2016",
|
||||
"OpenSSL",
|
||||
"Zlib",
|
||||
]
|
||||
# List of explicitly disallowed licenses
|
||||
# See https://spdx.org/licenses/ for list of possible licenses
|
||||
|
||||
@@ -51,6 +51,10 @@ assets_version = "3.0.0" # do not edit: managed by `mdbook-admonish install`
|
||||
minimum_rust_version = "1.66"
|
||||
wallet_release_version = "1.2.8"
|
||||
|
||||
# nym-vpn related variables
|
||||
nym_vpn_latest_binary_url = "https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.3"
|
||||
nym_vpn_form_url = "https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2"
|
||||
|
||||
[preprocessor.last-changed]
|
||||
command = "mdbook-last-changed"
|
||||
renderer = ["html"]
|
||||
|
||||
@@ -18,6 +18,16 @@
|
||||
|
||||
# User Manuals
|
||||
|
||||
- [NymVPN alpha](nymvpn/intro.md)
|
||||
- [GUI](nymvpn/gui.md)
|
||||
- [Linux](nymvpn/gui-linux.md)
|
||||
- [MacOS](nymvpn/gui-mac.md)
|
||||
- [CLI](nymvpn/cli.md)
|
||||
- [Linux](nymvpn/cli-linux.md)
|
||||
- [MacOS](nymvpn/cli-mac.md)
|
||||
- [Testing](nymvpn/testing.md)
|
||||
- [Troubleshooting](nymvpn/troubleshooting.md)
|
||||
- [NymVPN FAQ](nymvpn/faq.md)
|
||||
- [NymConnect X Monero](tutorials/monero.md)
|
||||
- [NymConnect X Matrix](tutorials/matrix.md)
|
||||
- [NymConnect X Telegram](tutorials/telegram.md)
|
||||
@@ -68,12 +78,6 @@
|
||||
|
||||
# Events
|
||||
|
||||
- [CryptoTalk](events/cryptotalk/nym-vpn.md)
|
||||
- [NymVPN Linux Guide](events/cryptotalk/nym-vpn-linux.md)
|
||||
- [NymVPN MacOS Guide](events/cryptotalk/nym-vpn-mac.md)
|
||||
- [NymVPN Testing](events/cryptotalk/nym-vpn-testing.md)
|
||||
- [NymVPN Troubleshooting](events/cryptotalk/nym-vpn-troubleshooting.md)
|
||||
- [NymVPN FAQ](events/cryptotalk/nym-vpn-faq.md)
|
||||
- [Web3Privacy Now](./events/web3-privacy.md)
|
||||
- [HCPP23-serinko](./events/hcpp23-serinko.md)
|
||||
- [HCPP23-max](./events/hcpp23-max.md)
|
||||
|
||||
@@ -1,198 +0,0 @@
|
||||
# NymVPN alpha: Guide for GNU/Linux
|
||||
|
||||
```admonish warning
|
||||
NymVPN is an experimental software and it's for [testing](./nym-vpn-testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the event), and follow the steps listed in the form [*NymVPN User research*](https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2).
|
||||
```
|
||||
|
||||
## Preparation
|
||||
|
||||
> Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||
|
||||
You can use our automated script of follow the steps below to download, verify, install and run NymVPN client.
|
||||
|
||||
|
||||
### Automated Script CLI Installation
|
||||
|
||||
Open a terminal and follow these steps:
|
||||
|
||||
* Download the script
|
||||
```sh
|
||||
curl -o nym-vpn-cli-executor.sh -L https://gist.githubusercontent.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af/raw/99cea8f4d80f2d002802ed1cbedba288bfca4488/execute-nym-vpn-cli-binary.sh
|
||||
```
|
||||
* Make the script executable
|
||||
```sh
|
||||
chmod u+x nym-vpn-cli-executor.sh
|
||||
```
|
||||
* Run the script
|
||||
```sh
|
||||
./nym-vpn-cli-executor.sh
|
||||
```
|
||||
* When prompted to verify `sha256sum` paste one from the [release page](https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.2) including the binary name (all as one input with a space in between), for example:
|
||||
```sh
|
||||
61a08de46881411e140f66cdb4940041150adb573c10e3f510a58a86a32f08fb nym-vpn-cli-ubuntu-22.04.zip
|
||||
```
|
||||
|
||||
The script will automatically start the client. Follow the instructions:
|
||||
|
||||
* The script will print a JSON view of existing Gateways and prompt you to:
|
||||
- ***(Make sure to use two different Gateways for entry and exit!)***
|
||||
- `enter a gateway ID:` paste one of the values labeled with a key `"identityKey"` printed above (without `" "`)
|
||||
- `enter an exit address:` paste one of the values labeled with a key `"address"` printed above (without `" "`)
|
||||
- `do you want five hop or two hop?`: type `five` or `two`
|
||||
|
||||
### Manual CLI and GUI Installation
|
||||
|
||||
* Visit the [releases page](https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.2) to download the binary for Debian based Linux
|
||||
* Open terminal in the same directory and check the the `sha256sum` by running:
|
||||
```sh
|
||||
# for CLI
|
||||
sha256sum ./nym-vpn-cli_0.1.0_ubuntu-22.04_amd64.zip
|
||||
|
||||
# for GUI
|
||||
sha256sum ./nym-vpn-ui_0.0.2_ubuntu-22.04_amd64.zip
|
||||
```
|
||||
* Compare the result with the sha256 hash shared on the [release page](https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.2)
|
||||
* Extract files with `unzip` command or manually as you are used to
|
||||
* If you prefer to run `.AppImage` make executable by running:
|
||||
```sh
|
||||
# for CLI
|
||||
chmod +x ./nym-vpn-cli
|
||||
|
||||
# for GUI
|
||||
chmod +x ./appimage/nym-vpn_0.0.2_amd64.AppImage
|
||||
# make sure your path to package is correct and the package name as well
|
||||
```
|
||||
* If you prefer to use the `.deb` version for installation (Linux only), open terminal in the same directory and run:
|
||||
```sh
|
||||
cd deb
|
||||
|
||||
sudo dpkg -i ./nym-vpn_0.0.2_amd64.deb
|
||||
|
||||
# or
|
||||
sudo apt-get install -f ./nym-vpn_0.0.2_amd64.deb
|
||||
|
||||
```
|
||||
* **For CLI**: Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries. In case of GUI setup, see the steps below.
|
||||
|
||||
### GUI configuration
|
||||
|
||||
* Create a NymVPN config directory called `nym-vpn` in your `~/.config`, either manually or by a command:
|
||||
```sh
|
||||
# for Linux
|
||||
mkdir $HOME/.config/nym-vpn/
|
||||
```
|
||||
* Create the network config by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the directory `nym-vpn` you just created
|
||||
* Create the main config file called `config.toml` in the same directory with this content:
|
||||
```toml
|
||||
# change <USER> to your username
|
||||
env_config_file = "/home/<USER>/.config/nym-vpn/sandbox.env"
|
||||
entry_node_location = "DE" # two letters country code
|
||||
```
|
||||
|
||||
## Run NymVPN
|
||||
|
||||
* **For NymVPN to work, all other VPNs must be switched off!**
|
||||
* At this alpha stage of NymVPN, network connection (wifi) must be re-connected after or in-between NymVPN testing rounds.
|
||||
|
||||
### Run CLI
|
||||
|
||||
Make sure your terminal is open in the same directory as your `nym-vpn-cli` binary.
|
||||
|
||||
* Find the entire command with all the needed arguments' values and your wireguard private key for testing purposes at [nymvpn.com/en/alpha](https://nymvpn.com/en/alpha)
|
||||
* Run it with `sudo` as root, the command will look like this with specified arguments:
|
||||
```sh
|
||||
sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id <ENTRY_GATEWAY_ID> --exit-router-address <EXIT_ROUTER_ADDRESS> --enable-wireguard --private-key <PRIVATE_KEY> --wg-ip <WG_IP>
|
||||
```
|
||||
* To chose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways)
|
||||
* To see all possibilities see [command explanation](#cli-commands-and-options) below
|
||||
|
||||
### Run GUI
|
||||
|
||||
In case you used `.deb` package and installed the client, you may be able to have a NymVPN application icon in your app menu. However this may not work as the application needs root permission.
|
||||
|
||||
Make sure you went through the GUI configuration in the [preparation section](#gui-configuration). Then open terminal in the same directory where you [installed](#preparation) the binary and run:
|
||||
|
||||
```sh
|
||||
# .AppImage must be run from the same directory
|
||||
sudo -E ./nym-vpn_0.0.2_amd64.AppImage
|
||||
|
||||
# .deb installation shall be executable from anywhere as
|
||||
sudo -E nym-vpn
|
||||
```
|
||||
|
||||
In case of errors, see [troubleshooting section](./nym-vpn-troubleshooting.md).
|
||||
|
||||
### CLI Commands and Options
|
||||
|
||||
The basic syntax of `nym-vpn-cli` is:
|
||||
```sh
|
||||
sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id <ENTRY_GATEWAY_ID> --exit-router-address <EXIT_ROUTER_ADDRESS> --enable-wireguard --private-key <PRIVATE_KEY> --wg-ip <WG_IP>
|
||||
```
|
||||
* To chose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways)
|
||||
* To see all possibilities run with `--help` flag:
|
||||
```sh
|
||||
./nym-vpn-cli --help
|
||||
```
|
||||
|
||||
~~~admonish example collapsible=true title="Console output"
|
||||
```
|
||||
Usage: nym-vpn-cli [OPTIONS]
|
||||
|
||||
Options:
|
||||
-c, --config-env-file <CONFIG_ENV_FILE>
|
||||
Path pointing to an env file describing the network
|
||||
--mixnet-client-path <MIXNET_CLIENT_PATH>
|
||||
Path to the data directory of a previously initialised mixnet client, where the keys reside
|
||||
--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
|
||||
--exit-router-address <EXIT_ROUTER_ADDRESS>
|
||||
Mixnet recipient address
|
||||
--exit-gateway-id <EXIT_GATEWAY_ID>
|
||||
|
||||
--exit-router-country <EXIT_ROUTER_COUNTRY>
|
||||
Mixnet recipient address
|
||||
--enable-wireguard
|
||||
Enable the wireguard traffic between the client and the entry gateway
|
||||
--private-key <PRIVATE_KEY>
|
||||
Associated private key
|
||||
--wg-ip <WG_IP>
|
||||
The IP address of the wireguard interface
|
||||
--ip <IP>
|
||||
The IP address of the TUN device
|
||||
--mtu <MTU>
|
||||
The MTU of the TUN device
|
||||
--disable-routing
|
||||
Disable routing all traffic through the VPN TUN device
|
||||
--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
|
||||
-h, --help
|
||||
Print help
|
||||
-V, --version
|
||||
Print version
|
||||
|
||||
|
||||
```
|
||||
~~~
|
||||
|
||||
**Fundamental commands and arguments**
|
||||
|
||||
Here is a list of the options and their descriptions. Some are essential, some are more technical and not needed to adjusted by users:
|
||||
|
||||
- `-c` is a path to the [Sandbox config](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) file saved as `sandbox.env`
|
||||
- `--entry-gateway-id`: paste one of the values labeled with a key `"identityKey"` (without `" "`) from [here](https://nymvpn.com/en/alpha/api/gateways)
|
||||
- `--exit-router-address`: paste one of the values labeled with a key `"address"` (without `" "`) from here [here](https://nymvpn.com/en/alpha/api/gateways)
|
||||
- `--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)
|
||||
|
||||
**Advanced options**
|
||||
|
||||
- `--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.
|
||||
@@ -1,191 +0,0 @@
|
||||
# NymVPN alpha: Guide for Mac OS
|
||||
|
||||
```admonish warning
|
||||
NymVPN is an experimental software and it's for [testing](./nym-vpn-testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the event), and follow the steps listed in the form [*NymVPN User research*](https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2).
|
||||
```
|
||||
|
||||
## Preparation
|
||||
|
||||
> Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||
|
||||
### CLI Installation
|
||||
|
||||
You can use our automated script of follow the steps below to download, verify, install and run NymVPN client.
|
||||
|
||||
#### Automated Script CLI Installation
|
||||
|
||||
Open a terminal and follow these steps:
|
||||
|
||||
* Download the script
|
||||
```sh
|
||||
curl -o nym-vpn-client-executor.sh -L https://gist.githubusercontent.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af/raw/99cea8f4d80f2d002802ed1cbedba288bfca4488/execute-nym-vpn-cli-binary.sh
|
||||
```
|
||||
* Make the script executable
|
||||
```sh
|
||||
chmod u+x nym-vpn-client-executor.sh
|
||||
```
|
||||
* Run the script
|
||||
```sh
|
||||
./nym-vpn-client-executor.sh
|
||||
```
|
||||
* When prompted to verify `sha256sum` paste one from the [release page](https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.2) including the binary name (all as one input with a space in between), for example:
|
||||
```sh
|
||||
96623ccc69bc4cc0e4e3e18528b6dae6be69f645d0a592d926a3158ce2d0c269 nym-vpn-cli_0.1.0_macos_x86_64.zip
|
||||
```
|
||||
|
||||
The script will automatically start the client. Follow the instructions:
|
||||
|
||||
* The script will print a JSON view of existing Gateways and prompt you to:
|
||||
- ***(Make sure to use two different Gateways for entry and exit!)***
|
||||
- `enter a gateway ID:` paste one of the values labeled with a key `"identityKey"` printed above (without `" "`)
|
||||
- `enter an exit address:` paste one of the values labeled with a key `"address"` printed above (without `" "`)
|
||||
- `do you want five hop or two hop?`: type `five` or `two`
|
||||
|
||||
#### Manual CLI Installation
|
||||
|
||||
* Visit the [releases page](https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.2) to download the binary for Debian based Linux
|
||||
* Open terminal in the same directory and check the the `sha256sum` by running:
|
||||
```sh
|
||||
# x86_64
|
||||
sha256sum ./nym-vpn-cli_0.1.0_macos_x86_64.zip
|
||||
|
||||
# aarch64
|
||||
sha256sum ./nym-vpn-cli_0.1.0_macos_aarch64.zip
|
||||
```
|
||||
* Compare the result with the sha256 hash shared on the [release page](https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.2)
|
||||
* Extract files with `unzip` command or manually as you are used to
|
||||
```sh
|
||||
# for CLI
|
||||
chmod +x ./nym-vpn-cli
|
||||
```
|
||||
|
||||
* Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries. In case of GUI setup, see the steps below.
|
||||
|
||||
### GUI Installation
|
||||
|
||||
We created a [script](https://gist.github.com/tommyv1987/7d210d4daa8f7abc61f9a696d0321f19) which does download, extraction, installation and configuration for MacOS users automatically following the steps below:
|
||||
|
||||
* To download the script, open a terminal in a directory where you want to download the script and run:
|
||||
```sh
|
||||
curl -o nym-vpn-client-executor.sh - L https://gist.githubusercontent.com/tommyv1987/7d210d4daa8f7abc61f9a696d0321f19/raw/4397365b4cf74594c7f99c1ef5d690b2f5b41192/nym-vpn-client-macos-executor.sh
|
||||
```
|
||||
* Make executable
|
||||
```sh
|
||||
chmod u+x nym-vpn-client-macos-executor.sh
|
||||
```
|
||||
* Run
|
||||
```sh
|
||||
./nym-vpn-client-macos-executor.sh
|
||||
```
|
||||
* When prompted to verify `sha256sum` paste one from the [release page](https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.2) including the binary name (all as one input with a space in between), for example:
|
||||
```sh
|
||||
06c7c82f032f230187da1002a9a9a88242d3bbf6c5c09dc961a71df151d768d0 nym-vpn-ui_0.0.2_macos_x86_64.zip
|
||||
```
|
||||
* The script will run the application and it will prompt you for a country code to exit, chose one of the offered options
|
||||
|
||||
In case of errors check out the [troubleshooting](./nym-vpn-troubleshooting.html#installing-gui-on-macos-not-working) section.
|
||||
|
||||
## Run NymVPN
|
||||
|
||||
* **For NymVPN to work, all other VPNs must be switched off!**
|
||||
* At this alpha stage of NymVPN, network connection (wifi) must be re-connected after or in-between NymVPN testing rounds.
|
||||
|
||||
### Run CLI
|
||||
|
||||
Make sure your terminal is open in the same directory as your `nym-vpn-cli` binary.
|
||||
|
||||
* Find the entire command with all the needed arguments' values and your wireguard private key for testing purposes at [nymvpn.com/en/alpha](https://nymvpn.com/en/alpha)
|
||||
* Run it with `sudo` as root, the command will look like this with specified arguments:
|
||||
```sh
|
||||
sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id <ENTRY_GATEWAY_ID> --exit-router-address <EXIT_ROUTER_ADDRESS> --enable-wireguard --private-key <PRIVATE_KEY> --wg-ip <WG_IP>
|
||||
```
|
||||
* To chose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways)
|
||||
* To see all possibilities see [command explanation](#cli-commands-and-options) below
|
||||
|
||||
### Run GUI
|
||||
|
||||
Make sure you went through the GUI configuration in the [preparation section](#gui-installation).
|
||||
|
||||
You may be able to have a NymVPN application icon in your app menu. However this may not work as the application needs root permission.
|
||||
|
||||
* Run GUI from terminal:
|
||||
```sh
|
||||
sudo $nym_vpn_dir/nym-vpn
|
||||
```
|
||||
|
||||
In case of errors, see [troubleshooting section](./nym-vpn-troubleshooting.md#macos-alert-on-nymvpn-ui-startup).
|
||||
|
||||
### CLI Commands and Options
|
||||
|
||||
The basic syntax of `nym-vpn-cli` is:
|
||||
```sh
|
||||
sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id <ENTRY_GATEWAY_ID> --exit-router-address <EXIT_ROUTER_ADDRESS> --enable-wireguard --private-key <PRIVATE_KEY> --wg-ip <WG_IP>
|
||||
```
|
||||
* To chose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways)
|
||||
* To see all possibilities run with `--help` flag:
|
||||
```sh
|
||||
./nym-vpn-cli --help
|
||||
```
|
||||
|
||||
~~~admonish example collapsible=true title="Console output"
|
||||
```
|
||||
Usage: nym-vpn-cli [OPTIONS]
|
||||
|
||||
Options:
|
||||
-c, --config-env-file <CONFIG_ENV_FILE>
|
||||
Path pointing to an env file describing the network
|
||||
--mixnet-client-path <MIXNET_CLIENT_PATH>
|
||||
Path to the data directory of a previously initialised mixnet client, where the keys reside
|
||||
--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
|
||||
--exit-router-address <EXIT_ROUTER_ADDRESS>
|
||||
Mixnet recipient address
|
||||
--exit-gateway-id <EXIT_GATEWAY_ID>
|
||||
|
||||
--exit-router-country <EXIT_ROUTER_COUNTRY>
|
||||
Mixnet recipient address
|
||||
--enable-wireguard
|
||||
Enable the wireguard traffic between the client and the entry gateway
|
||||
--private-key <PRIVATE_KEY>
|
||||
Associated private key
|
||||
--wg-ip <WG_IP>
|
||||
The IP address of the wireguard interface
|
||||
--ip <IP>
|
||||
The IP address of the TUN device
|
||||
--mtu <MTU>
|
||||
The MTU of the TUN device
|
||||
--disable-routing
|
||||
Disable routing all traffic through the VPN TUN device
|
||||
--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
|
||||
-h, --help
|
||||
Print help
|
||||
-V, --version
|
||||
Print version
|
||||
|
||||
|
||||
```
|
||||
~~~
|
||||
|
||||
**Fundamental commands and arguments**
|
||||
|
||||
Here is a list of the options and their descriptions. Some are essential, some are more technical and not needed to adjusted by users:
|
||||
|
||||
- `-c` is a path to the [Sandbox config](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) file saved as `sandbox.env`
|
||||
- `--entry-gateway-id`: paste one of the values labeled with a key `"identityKey"` (without `" "`) from [here](https://nymvpn.com/en/alpha/api/gateways)
|
||||
- `--exit-router-address`: paste one of the values labeled with a key `"address"` (without `" "`) from here [here](https://nymvpn.com/en/alpha/api/gateways)
|
||||
- `--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)
|
||||
|
||||
**Advanced options**
|
||||
|
||||
- `--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.
|
||||
@@ -1,100 +0,0 @@
|
||||
# Troubleshooting
|
||||
|
||||
Below are listed some points which may need to be addressed when testing NymVPN alpha. If you crashed into any errors which are not listed, please contact us at the event.
|
||||
|
||||
#### Problems with the newest version `nym-vpn-alpha-0.0.2 demo`
|
||||
|
||||
Try the previous version `nym-vpn-alpha-0.0.1 demo` which was tested multiple times by downloading the client from this [release page(https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.1) and doing all the steps with the name of your downloaded binary.
|
||||
|
||||
#### Installing GUI on MacOS not working
|
||||
|
||||
In case there was a problem running the script, try a manual configuration:
|
||||
|
||||
* Visit the [releases page](https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.1) to download the binary for Debian based Linux
|
||||
* Open terminal in the same directory and check the the `sha256sum` by running:
|
||||
```sh
|
||||
# for MacOS GUI
|
||||
sha256sum ./nym-vpn-ui-macos-latest.zip
|
||||
```
|
||||
* Compare the result with the sha256 hash shared on the [release page](https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.1)
|
||||
* Extract files with `unzip` command or manually as you are used toi
|
||||
* Create a NymVPN config directory called `nym-vpn` in your `~/.config`, either manually or by a command:
|
||||
```sh
|
||||
mkdir $HOME/Library/Application Support/nym-vpn/
|
||||
```
|
||||
* Create the network config by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the config directory `nym-vpn` you just created
|
||||
* Create the main config file called `config.toml` in the same directory with this content:
|
||||
```toml
|
||||
env_config_file = "$HOME/Library/Application Support/nym-vpn/"
|
||||
entry_node_location = "DE" # two letters country code
|
||||
```
|
||||
|
||||
**Note:** Some users had a problem to access their home config folder on macOS, in that case save the configuration files in the same directory where you downloaded your `nym-vpn` binary as following:
|
||||
|
||||
* Create the network config by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `.env` (yes just like that) in the same directory like `nym-vpn` binaries.
|
||||
* Create the main config file called `config.toml` in the very same directory with this content:
|
||||
```toml
|
||||
env_config_file = "$HOME/Library/Application Support/nym-vpn/"
|
||||
entry_node_location = "DE" # two letters country code
|
||||
```
|
||||
|
||||
#### Thread `main` panicked
|
||||
|
||||
If you see a message like:
|
||||
```sh
|
||||
thread 'main' panicked at /Users/runner/.cargo/git/checkouts/mullvadvpn-app-a575cf705b5dfd76/ccfbaa2/talpid-routing/src/unix.rs:301:30:
|
||||
```
|
||||
Restart your wifi connection and start again.
|
||||
|
||||
#### macOS alert on NymVPN UI startup
|
||||
|
||||
If you are running NymVPN on mac OS for the first time, you may see this alert message:
|
||||
|
||||

|
||||
|
||||
1. Head to System Settings -> Privacy & Security and click `Allow anyway`
|
||||
|
||||

|
||||
|
||||
2. Confirm with your password or TouchID
|
||||
|
||||
3. Possibly you may have to confirm again upon running the application
|
||||
|
||||
#### Missing `jq` error
|
||||
|
||||
In case of missing `jq` on Linux (Debian) install it with:
|
||||
```sh
|
||||
# Linux (Debian)
|
||||
sudo apt-get install jq
|
||||
# macOS
|
||||
brew install jq
|
||||
```
|
||||
On some Linux distributions however the [script](./nym-vpn.md#testssh) returns `jq` error even if your system claims that `jq is already the newest version`.
|
||||
In that case, comment the `jq` check in the script as follows:
|
||||
```sh
|
||||
#if ! command -v jq &>/dev/null; then
|
||||
# echo "jq is not installed. Please install jq to proceed."
|
||||
# exit 1
|
||||
#fi
|
||||
```
|
||||
|
||||
#### Error current_time: not found
|
||||
|
||||
When running `sudo sh ./test.sh` you may see an error like: `93: current_time: not found`. This has something to do with the `current_time` setup of your system and on itself shall not have a negative impact on the test. It has nothing to do with the client at all as it only relates to the code in our testing script.
|
||||
|
||||
#### Not connecting to the endpoint
|
||||
|
||||
In case the automatic download of all the Gateways fail (and it shouldn't), you do an easy manual work around:
|
||||
|
||||
1. Open the list of Gateways created by API [here](https://nymvpn.com/en/ccc/api/gateways)
|
||||
2. On top click on `JSON` option (shall be default view) and `Save`
|
||||
3. Save it as `data.json` to the `nym-vpn-tests` folder
|
||||
4. Replace line 3 in the [script `tests.sh`](./nym-vpn.md#testssh) with:
|
||||
```sh
|
||||
NEW_ENDPOINT="http://localhost:8000/data.json"
|
||||
```
|
||||
5. In a new terminal window run:
|
||||
```sh
|
||||
python3 -m http.server 8000
|
||||
```
|
||||
6. Continue with the steps listed in [testing section](./nym-vpn.md#testing)
|
||||
@@ -1,51 +0,0 @@
|
||||
# NymVPN alpha
|
||||
|
||||
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/897010658?h=1f55870fe6&badge=0&autopause=0&player_id=0&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>
|
||||
|
||||
We are honored to present NymVPN, 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). At this event we have the unique opportunity to be part of the initial alpha testing. The following pages provide a how-to guide, explaining steps to install and run NymVPN CLI and GUI on our testing environment Nym Sandbox.
|
||||
|
||||
## NymVPN
|
||||
|
||||
The following overview provides an easy introduction to the NymVPN alpha client. We recommend interested developers to begin with [Nym network overview](https://nymtech.net/docs/architecture/network-overview.html) and the [Mixnet traffic flow](https://nymtech.net/docs/architecture/traffic-flow.html) pages.
|
||||
|
||||
The default is to run in 5-hop mode:
|
||||
|
||||
```
|
||||
┌─►mix──┐ mix mix
|
||||
│ │
|
||||
Entry │ │ Exit
|
||||
client ───► Gateway ──┘ mix │ mix ┌─►mix ───► Gateway ───► internet
|
||||
│ │
|
||||
│ │
|
||||
mix └─►mix──┘ mix
|
||||
```
|
||||
|
||||
Users can switch to 2-hop only mode, which is a faster but less private option. In this mode traffic is only sent between the two Gateways, and is not passed between Mix Nodes.
|
||||
|
||||
The client can optionally do the first hop (local client to Entry Gateway) using Wireguard. NymVPN uses Mullvad libraries for wrapping `wireguard-go` and to setup local routing rules to route all traffic to the TUN virtual network device.
|
||||
|
||||
## NymVPN Guide & FAQ pages
|
||||
|
||||
To download, install and test NymVPN alpha, visit pages listed below:
|
||||
|
||||
* [GNU/Linux](nym-vpn-linux.md)
|
||||
* [Mac OS](nym-vpn-mac.md)
|
||||
* [Testing scripts](nym-vpn-testing.md)
|
||||
* [Troubleshooting](nym-vpn-troubleshooting.md)
|
||||
* [NymVPN FAQ](nym-vpn-faq.md)
|
||||
|
||||
## Goals of testing
|
||||
|
||||
This alpha testing will help:
|
||||
|
||||
* Stabilise NymVPN client
|
||||
* Understand NymVPN client behavior in various setups (OS, connectivity, etc.)
|
||||
* Stabilize the VPN infrastructure and improve its reliability / speed / features (e.g. IPv6 support)
|
||||
* Load test the network in Sandbox environment and identify / anticipate potential weaknesses
|
||||
|
||||
|
||||
```admonish info
|
||||
Our alpha testing round is done live with some participants at the event. This guide will not work for everyone, as the NymVPN binaries aren't publicly accessible yet. Note that this setup of Nym testnet Sandbox environment is limited event and some of the configurations will not work in the future.
|
||||
|
||||
**If you commit to test NymVPN alpha, please start with the [user research form](https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2) where all the steps will be provided**.
|
||||
```
|
||||
@@ -0,0 +1,116 @@
|
||||
# NymVPN alpha CLI: Guide for GNU/Linux
|
||||
|
||||
```admonish info
|
||||
NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results.
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
> Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||
|
||||
1. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for Debian based Linux
|
||||
2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example:
|
||||
```sh
|
||||
echo "<SHA_STRING>" | shasum -a 256 -c
|
||||
|
||||
# choose a correct one according to your binary, this is just an example
|
||||
echo "0e4abb461e86b2c168577e0294112a3bacd3a24bf8565b49783bfebd9b530e23 nym-vpn-cli_0.1.0_ubuntu-22.04_amd64.zip" | shasum -a 256 -c
|
||||
```
|
||||
3. Extract files with `unzip` command or manually as you are used to
|
||||
4. Make executable by running:
|
||||
```sh
|
||||
chmod u+x ./nym-vpn-cli
|
||||
```
|
||||
5. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries by running:
|
||||
```sh
|
||||
curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env
|
||||
```
|
||||
|
||||
## Run NymVPN
|
||||
|
||||
**For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds.
|
||||
|
||||
Make sure your terminal is open in the same directory as your `nym-vpn-cli` binary.
|
||||
|
||||
1. Go to [nymvpn.com/en/alpha](https://nymvpn.com/en/alpha) to get the entire command with all the needed arguments' values and your wireguard private key for testing purposes
|
||||
2. Run it as root with `sudo` - the command will look like this with specified arguments:
|
||||
```sh
|
||||
sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id <ENTRY_GATEWAY_ID> --exit-router-address <EXIT_ROUTER_ADDRESS> --enable-wireguard --private-key <PRIVATE_KEY> --wg-ip <WIREGUARD_IP>
|
||||
```
|
||||
3. To choose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways) and pick one
|
||||
4. See all possibilities in [command explanation](#cli-commands-and-options) section below
|
||||
|
||||
In case of errors, see [troubleshooting section](troubleshooting.md).
|
||||
|
||||
### CLI Commands and Options
|
||||
|
||||
The basic syntax of `nym-vpn-cli` is:
|
||||
```sh
|
||||
sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id <ENTRY_GATEWAY_ID> --exit-router-address <EXIT_ROUTER_ADDRESS> --enable-wireguard --private-key <PRIVATE_KEY> --wg-ip <WG_IP>
|
||||
```
|
||||
* To choose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways)
|
||||
* To see all possibilities run with `--help` flag:
|
||||
```sh
|
||||
./nym-vpn-cli --help
|
||||
```
|
||||
~~~admonish example collapsible=true title="Console output"
|
||||
```
|
||||
Usage: nym-vpn-cli [OPTIONS]
|
||||
|
||||
Options:
|
||||
-c, --config-env-file <CONFIG_ENV_FILE>
|
||||
Path pointing to an env file describing the network
|
||||
--mixnet-client-path <MIXNET_CLIENT_PATH>
|
||||
Path to the data directory of a previously initialised mixnet client, where the keys reside
|
||||
--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
|
||||
--exit-router-address <EXIT_ROUTER_ADDRESS>
|
||||
Mixnet recipient address
|
||||
--exit-gateway-id <EXIT_GATEWAY_ID>
|
||||
|
||||
--exit-router-country <EXIT_ROUTER_COUNTRY>
|
||||
Mixnet recipient address
|
||||
--enable-wireguard
|
||||
Enable the wireguard traffic between the client and the entry gateway
|
||||
--private-key <PRIVATE_KEY>
|
||||
Associated private key
|
||||
--wg-ip <WG_IP>
|
||||
The IP address of the wireguard interface used for the first hop to the entry gateway
|
||||
--nym-ip <NYM_IP>
|
||||
The IP 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
|
||||
--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
|
||||
-h, --help
|
||||
Print help
|
||||
-V, --version
|
||||
Print version
|
||||
|
||||
```
|
||||
~~~
|
||||
|
||||
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.
|
||||
|
||||
**Fundamental commands and arguments**
|
||||
|
||||
- `-c` is a path to the [Sandbox config](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) file saved as `sandbox.env`
|
||||
- `--entry-gateway-id`: paste one of the values labeled with a key `"identityKey"` (without `" "`) from [here](https://nymvpn.com/en/alpha/api/gateways)
|
||||
- `--exit-router-address`: paste one of the values labeled with a key `"address"` (without `" "`) from here [here](https://nymvpn.com/en/alpha/api/gateways)
|
||||
- `--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)
|
||||
|
||||
**Advanced options**
|
||||
|
||||
- `--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.
|
||||
@@ -0,0 +1,117 @@
|
||||
# NymVPN alpha CLI: Guide for MacOS
|
||||
|
||||
```admonish info
|
||||
NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results.
|
||||
```
|
||||
|
||||
## Preparation
|
||||
|
||||
> Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||
|
||||
1. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for MacOS
|
||||
2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example:
|
||||
```sh
|
||||
echo "<SHA_STRING>" | shasum -a 256 -c
|
||||
|
||||
# choose a correct one according to your binary, this is just an example
|
||||
echo "96623ccc69bc4cc0e4e3e18528b6dae6be69f645d0a592d926a3158ce2d0c269 nym-vpn-cli_0.1.0_macos_x86_64.zip" | shasum -a 256 -c
|
||||
```
|
||||
5. Extract files with `unzip` command or manually as you are used to
|
||||
6. Make executable by running:
|
||||
```sh
|
||||
chmod u+x ./nym-vpn-cli
|
||||
```
|
||||
7. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries by running:
|
||||
```sh
|
||||
curl -L "https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env" -o sandbox.env
|
||||
```
|
||||
|
||||
## Run NymVPN
|
||||
|
||||
**For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds.
|
||||
|
||||
Make sure your terminal is open in the same directory as your `nym-vpn-cli` binary.
|
||||
|
||||
|
||||
1. Go to [nymvpn.com/en/alpha](https://nymvpn.com/en/alpha) to get the entire command with all the needed arguments' values and your wireguard private key for testing purposes
|
||||
2. Run it as root with `sudo` - the command will look like this with specified arguments:
|
||||
```sh
|
||||
sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id <ENTRY_GATEWAY_ID> --exit-router-address <EXIT_ROUTER_ADDRESS> --enable-wireguard --private-key <PRIVATE_KEY> --wg-ip <WIREGUARD_IP>
|
||||
```
|
||||
3. To choose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways) and pick one
|
||||
4. See all possibilities in [command explanation](#cli-commands-and-options) section below
|
||||
|
||||
In case of errors, see [troubleshooting section](troubleshooting.md).
|
||||
|
||||
### CLI Commands and Options
|
||||
|
||||
The basic syntax of `nym-vpn-cli` is:
|
||||
```sh
|
||||
sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id <ENTRY_GATEWAY_ID> --exit-router-address <EXIT_ROUTER_ADDRESS> --enable-wireguard --private-key <PRIVATE_KEY> --wg-ip <WG_IP>
|
||||
```
|
||||
* To choose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways)
|
||||
* To see all possibilities run with `--help` flag:
|
||||
```sh
|
||||
./nym-vpn-cli --help
|
||||
```
|
||||
~~~admonish example collapsible=true title="Console output"
|
||||
```
|
||||
Usage: nym-vpn-cli [OPTIONS]
|
||||
|
||||
Options:
|
||||
-c, --config-env-file <CONFIG_ENV_FILE>
|
||||
Path pointing to an env file describing the network
|
||||
--mixnet-client-path <MIXNET_CLIENT_PATH>
|
||||
Path to the data directory of a previously initialised mixnet client, where the keys reside
|
||||
--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
|
||||
--exit-router-address <EXIT_ROUTER_ADDRESS>
|
||||
Mixnet recipient address
|
||||
--exit-gateway-id <EXIT_GATEWAY_ID>
|
||||
|
||||
--exit-router-country <EXIT_ROUTER_COUNTRY>
|
||||
Mixnet recipient address
|
||||
--enable-wireguard
|
||||
Enable the wireguard traffic between the client and the entry gateway
|
||||
--private-key <PRIVATE_KEY>
|
||||
Associated private key
|
||||
--wg-ip <WG_IP>
|
||||
The IP address of the wireguard interface used for the first hop to the entry gateway
|
||||
--nym-ip <NYM_IP>
|
||||
The IP 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
|
||||
--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
|
||||
-h, --help
|
||||
Print help
|
||||
-V, --version
|
||||
Print version
|
||||
|
||||
```
|
||||
~~~
|
||||
|
||||
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.
|
||||
|
||||
**Fundamental commands and arguments**
|
||||
|
||||
- `-c` is a path to the [Sandbox config](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) file saved as `sandbox.env`
|
||||
- `--entry-gateway-id`: paste one of the values labeled with a key `"identityKey"` (without `" "`) from [here](https://nymvpn.com/en/alpha/api/gateways)
|
||||
- `--exit-router-address`: paste one of the values labeled with a key `"address"` (without `" "`) from here [here](https://nymvpn.com/en/alpha/api/gateways)
|
||||
- `--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)
|
||||
|
||||
**Advanced options**
|
||||
|
||||
- `--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.
|
||||
@@ -0,0 +1,46 @@
|
||||
# NymVPN Command Line Interface (CLI)
|
||||
|
||||
```admonish info
|
||||
Our alpha testing round is done with participants at live workshop events. This guide will not work for everyone, as the NymVPN source code is not yet publicly accessible. The alpha testing is done on Nym testnet Sandbox environment, this configuration is limited and will not work in the future.
|
||||
|
||||
**If you commit to test NymVPN alpha, please start with the [user research form]({{nym_vpn_form_url}}) where all the steps will be provided**. If you disagree with any of the conditions listed, please leave this page.
|
||||
```
|
||||
|
||||
NymVPN CLI is a fundamental way to run the client for different purposes, currently it is a must for users who want to run the [testing scripts](testing.md).
|
||||
|
||||
Follow the simple [automated script](#automated-script-for-cli-installation) below to install and run NymVPN CLI. If you prefer to do a manual setup follow the steps in the guide for [Linux](cli-linux.md) or [MacOS](cli-mac.md).
|
||||
|
||||
## Automated Script for CLI Installation
|
||||
|
||||
We wrote a [script](https://gist.github.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af) which does download of the CLI, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically following the steps below:
|
||||
|
||||
1. Open a terminal window in a directory where you want the script and NymVPN CLI binary be downloaded and run
|
||||
```sh
|
||||
curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af/raw/2a8b703655549f2e515ef1960b5f6dc54adc02fa/execute-nym-vpn-cli-binary.sh
|
||||
```
|
||||
|
||||
2. Make the script executable
|
||||
```sh
|
||||
chmod u+x execute-nym-vpn-cli-binary.sh
|
||||
```
|
||||
|
||||
3. Start the script as root, turn off any VPN and run
|
||||
```sh
|
||||
sudo ./execute-nym-vpn-cli-binary.sh
|
||||
```
|
||||
|
||||
4. Follow the prompts in the program
|
||||
|
||||
5. The script will automatically start the client. Make sure to **turn off any other VPNs** and follow the prompts:
|
||||
|
||||
* It prints a JSON view of existing Gateways and prompt you to:
|
||||
- *Make sure to use two different Gateways for entry and exit!*
|
||||
- `enter a gateway ID:` paste one of the values labeled with a key `"identityKey"` printed above (without `" "`)
|
||||
- `enter an exit address:` paste one of the values labeled with a key `"address"` printed above (without `" "`)
|
||||
- `do you want five hop or two hop?`: type `five` or `two`
|
||||
- `enable WireGuard? (yes/no):` if you chose yes, find your private key and wireguard IP [here](https://nymvpn.com/en/alpha)
|
||||
|
||||
To run `nym-vpn-cli` again, reconnect your wifi, move to the directory of your CLI binary `cd ~/nym-vpn-cli-dir` and follow the guide for [Linux](cli-linux.md#run-nymvpn) or [MacOS](cli-mac.md#run-nymvpn). If you find it too difficult, just run this script again - like in step \#3 above.
|
||||
|
||||
In case of errors check out the [troubleshooting](troubleshooting.md) section.
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
# Frequently Asked Questions
|
||||
|
||||
This is a FAQ page tailored for this event. If you interested to read more about Nym platform, you can have a look at [Nym general FAQ](https://nymtech.net/developers/faq/general-faq.html) and read through Nym's technical [documentation](https://nymtech.net/docs), [Developer Portal](https://nymtech.net/developers) and [Operators Guide](https://nymtech.net/operators).
|
||||
**NymVPN [*Support & FAQ page*](https://nymvpn.com/en/support)** contains all essential FAQs regarding the client. This page (below) is a source of additional information often seeked by users, operators and developers testing NymVPN.
|
||||
|
||||
If you interested to read more about Nym platform, you can have a look at [Nym general FAQ](https://nymtech.net/developers/faq/general-faq.html) and read through Nym's technical [documentation](https://nymtech.net/docs), [Developer Portal](https://nymtech.net/developers) and [Operators Guide](https://nymtech.net/operators).
|
||||
|
||||
## NymVPN
|
||||
|
||||
If this your first time hearing about NymVPN, make sure you visit [NymVPN webpage](https://nymvpn.com/en), the official NymVPN [support & FAQ page](https://nymvpn.com/en/support) and the proceed to the introduction and guide on how to [install, run and test](./nym-vpn.md) the client.
|
||||
If this your first time hearing about NymVPN, make sure you visit [NymVPN webpage](https://nymvpn.com/en), the official NymVPN [support & FAQ page](https://nymvpn.com/en/support) and the proceed to the introduction and guide on how to [install, run and test](intro.md#nymvpn-guides) the client.
|
||||
|
||||
Below are some extra FAQs which came out during the initial alpha testing round.
|
||||
Below are some extra FAQs which came out during the previous alpha testing rounds.
|
||||
|
||||
### What's the difference between 2-hops and 5-hops
|
||||
|
||||
@@ -54,11 +56,11 @@ Project Smoosh is a code name for a process in which different components of Nym
|
||||
|
||||
## Exit Gateway
|
||||
|
||||
Part of the the transition under code name [Project Smoosh](./nym-vpn-faq.md#project-smoosh) is a creation of [Nym Exit Gateway](https://nymtech.net/operators/legal/exit-gateway.html) functionality. The operators running Gateways would have to “open” their nodes to a wider range of online services, in a similar fashion to Tor exit relays. The main change will be to expand the original short [allowed.list](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) to a more permissive setup. An [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) will constrain the hosts that the users of the Nym VPN and Mixnet can connect to. 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 VPN and Mixnet clients.
|
||||
Part of the the transition under code name [Project Smoosh](#project-smoosh) is a creation of [Nym Exit Gateway](https://nymtech.net/operators/legal/exit-gateway.html) functionality. The operators running Gateways would have to “open” their nodes to a wider range of online services, in a similar fashion to Tor exit relays. The main change will be to expand the original short [allowed.list](https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt) to a more permissive setup. An [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) will constrain the hosts that the users of the Nym VPN and Mixnet can connect to. 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 VPN and Mixnet clients.
|
||||
|
||||
* Read more how the exit policy gets implemented [here](https://nymtech.net/operators/faq/smoosh-faq.html#how-will-the-exit-policy-be-implemented)
|
||||
* Check out [Nym Operators Legal Forum](https://nymtech.net/operators/legal/exit-gateway.html)
|
||||
* Do reach out to us during 37c3 with any experiences you may have running Tor Exit relays or legal findings and suggestions for Nym Exit Gateway operators
|
||||
* Do reach out to us with any experiences you may have running Tor Exit relays or legal findings and suggestions for Nym Exit Gateway operators
|
||||
|
||||
## Nym Integrations and SDKs
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
# NymVPN alpha GUI: Guide for GNU/Linux
|
||||
|
||||
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/908221306?h=404b2bbdc8" style="position:absolute;top:0;left:0;width:100%;height:100%;" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>
|
||||
|
||||
```admonish info
|
||||
NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results.
|
||||
```
|
||||
|
||||
## Preparation
|
||||
|
||||
> Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||
|
||||
### Installation
|
||||
|
||||
1. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for Debian based Linux
|
||||
2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example:
|
||||
```sh
|
||||
echo "<SHA_STRING>" | shasum -a 256 -c
|
||||
|
||||
# choose a correct one according to your binary, this is just an example
|
||||
echo "a5f91f20d587975e30b6a75d3a9e195234cf1269eac278139a5b9c39b039e807 nym-vpn-desktop_0.0.3_ubuntu-22.04_x86_64.zip" | shasum -a 256 -c
|
||||
```
|
||||
3. Extract files with `unzip` command or manually as you are used to
|
||||
4. If you prefer to run `.AppImage` make executable by running:
|
||||
```sh
|
||||
chmod u+x ./appimage/nym-vpn_0.0.2_amd64.AppImage
|
||||
```
|
||||
5. If you prefer to use the `.deb` version for installation (works on Debian based Linux only), open terminal in the same directory and run:
|
||||
```sh
|
||||
cd deb
|
||||
|
||||
sudo dpkg -i ./nym-vpn_0.0.3_amd64.deb
|
||||
# or
|
||||
sudo apt-get install -f ./nym-vpn_0.0.3_amd64.deb
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
6. Create a NymVPN config directory called `nym-vpn` in your `~/.config`, either manually or by a command:
|
||||
```sh
|
||||
mkdir $HOME/.config/nym-vpn/
|
||||
```
|
||||
7. Create the network config by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the directory `~/.config/nym-vpn/` you just created by running:
|
||||
```sh
|
||||
curl -o $HOME/.config/nym-vpn/sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env
|
||||
```
|
||||
|
||||
8. Create NymVPN main config file called `config.toml` in the same directory `~/.config/nym-vpn/` with this content:
|
||||
```toml
|
||||
# change <USER> to your username
|
||||
env_config_file = "/home/<USER>/.config/nym-vpn/sandbox.env"
|
||||
entry_node_location = "DE" # two letters country code
|
||||
# You can choose different entry by entering one of the following two letter country codes:
|
||||
# DE, UK, FR, IE
|
||||
```
|
||||
|
||||
## Run NymVPN
|
||||
|
||||
**For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds.
|
||||
|
||||
In case you used `.deb` package and installed the client, you may be able to have a NymVPN application icon in your app menu. However this may not work as the application needs root permission.
|
||||
|
||||
Open terminal and run:
|
||||
|
||||
```sh
|
||||
# .AppImage must be run from the same directory as the binary
|
||||
sudo -E ./nym-vpn_0.0.2_amd64.AppImage
|
||||
|
||||
# .deb installation shall be executable from anywhere as
|
||||
sudo -E nym-vpn
|
||||
```
|
||||
|
||||
In case of errors, see [troubleshooting section](troubleshooting.md).
|
||||
@@ -0,0 +1,59 @@
|
||||
# NymVPN alpha GUI: Guide for Mac OS
|
||||
|
||||
```admonish info
|
||||
NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results.
|
||||
```
|
||||
|
||||
## Preparation
|
||||
|
||||
> Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||
|
||||
### Installation
|
||||
|
||||
1. Create a directory `~/nym-vpn-latest`
|
||||
```sh
|
||||
mkdir -p "$HOME/nym-vpn-latest"
|
||||
```
|
||||
2. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for MacOS
|
||||
3. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example:
|
||||
```sh
|
||||
echo "<SHA_STRING>" | shasum -a 256 -c
|
||||
|
||||
# choose a correct one according to your binary, this is just an example
|
||||
echo "da4c0bf8e8b52658312d341fa3581954cfcb6efd516d9a448c76d042a454b5df nym-vpn-desktop_0.0.3_macos_x86_64.zip" | shasum -a 256 -c
|
||||
```
|
||||
4. Extract files with `unzip` command or manually as you are used to
|
||||
5. Move to the application directory and make executable
|
||||
```sh
|
||||
cd "macos/nym-vpn.app/Contents/MacOS"
|
||||
|
||||
chmod u+x nym-vpn
|
||||
```
|
||||
6. Move `nym-vpn` to your `~/nym-vpn-latest` directory
|
||||
```sh
|
||||
mv nym-vpn "$HOME/nym-vpn-latest"
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
7. Create the configuration file by opening a text editor and saving the lines below as `config.toml` in the same directory `~/nym-vpn-latest`
|
||||
```toml
|
||||
env_config_file = ".env"
|
||||
entry_node_location = "DE" # two letters country code
|
||||
# You can choose different entry by entering one of the following two letter country codes:
|
||||
# DE, UK, FR, IE
|
||||
```
|
||||
8. Create testnet configuration file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `.env` in the same directory `~/nym-vpn-latest`
|
||||
```sh
|
||||
curl -L "https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env" -o "$HOME/nym-vpn-latest/.env"
|
||||
```
|
||||
## Run NymVPN
|
||||
|
||||
**For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds.
|
||||
|
||||
Open terminal in your `~/nym-vpn-latest` directory and run:
|
||||
```sh
|
||||
sudo ./nym-vpn
|
||||
```
|
||||
|
||||
In case of errors check out the [troubleshooting](troubleshooting.html#installing-gui-on-macos-not-working) section.
|
||||
@@ -0,0 +1,43 @@
|
||||
# NymVPN Application (GUI)
|
||||
|
||||
```admonish info
|
||||
Our alpha testing round is done with participants at live workshop events. This guide will not work for everyone, as the NymVPN source code is not yet publicly accessible. The alpha testing is done on Nym testnet Sandbox environment, this configuration is limited and will not work in the future.
|
||||
|
||||
**If you commit to test NymVPN alpha, please start with the [user research form]({{nym_vpn_form_url}}) where all the steps will be provided**. If you disagree with any of the conditions listed, please leave this page.
|
||||
```
|
||||
|
||||
This is the alpha version of NymVPN application - the GUI. A demo of how the client will look like for majority of day-to-day users. For qualitative testing the [CLI](cli.md) is a necessity but to run the GUI holds the same importance as it provides the user with an experience of the actual app and the developers with a valuable feedback from the users.
|
||||
|
||||
Follow the simple [automated script](#automated-script-for-gui-installation) below to install and run NymVPN GUI. If you prefer to do a manual setup follow the steps in the guide for [Linux](gui-linux.md) or [MacOS](gui-mac.md).
|
||||
|
||||
## Automated Script for GUI Installation
|
||||
|
||||
We wrote a [script](https://gist.github.com/serinko/e0a9f7ff3d79e974ec6f6783caa1137e) which does download of dependencies and the application, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically following the steps below:
|
||||
|
||||
1. Open a terminal window in a directory where you want the script and NymVPN binary be downloaded and run
|
||||
```sh
|
||||
curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/serinko/e0a9f7ff3d79e974ec6f6783caa1137e/raw/064c0d42af6a187b4f62998a0c2e6a84c319eeef/nym-vpn-desktop-install-run.sh
|
||||
```
|
||||
|
||||
2. Make the script executable
|
||||
```sh
|
||||
chmod u+x nym-vpn-desktop-install-run.sh
|
||||
```
|
||||
|
||||
3. Start the script as root, turn off any VPN and run
|
||||
```sh
|
||||
sudo -E ./nym-vpn-desktop-install-run.sh
|
||||
```
|
||||
|
||||
4. Follow the prompts in the program
|
||||
|
||||
To start the application again, reconnect your wifi and run
|
||||
```sh
|
||||
# Linux
|
||||
sudo -E ~/nym-vpn-latest/nym-vpn_0.0.3_amd64.AppImage
|
||||
|
||||
# MacOS
|
||||
sudo $nym_vpn_dir/nym-vpn
|
||||
```
|
||||
|
||||
In case of errors check out the [troubleshooting](troubleshooting.md#installing-gui-on-macos-not-working) section.
|
||||
|
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
@@ -0,0 +1,54 @@
|
||||
# NymVPN alpha
|
||||
|
||||
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/897010658?h=1f55870fe6&badge=0&autopause=0&player_id=0&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>
|
||||
|
||||
**Nym proudly presents NymVPN alpha** - 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).
|
||||
|
||||
|
||||
**You are invited to take part in the alpha testing** of this new application. The following pages provide a how-to guide, explaining steps to install and run NymVPN [CLI](cli.md) and [GUI](gui.md) on the Sandbox testnet environment as well as provide some scripts for [qualitative testing](testing.md).
|
||||
|
||||
**Here is how**
|
||||
|
||||
1. Go to the NymVPN [testers form]({{nym_vpn_form_url}})
|
||||
2. Please consent to the GDPR so we can use the results
|
||||
3. To test the GUI, [go here](gui.md)
|
||||
4. To test the CLI, [go here](cli.md)
|
||||
5. Run [qualitative testing script](testing.md)
|
||||
6. Fill and submit the [form!]({{nym_vpn_form_url}})
|
||||
7. Join the [NymVPN matrix channel](https://matrix.to/#/#NymVPN:nymtech.chat) if you have any questions, comments or blockers
|
||||
|
||||
***NymVPN alpha testing will last from 15th of January - 15th of February.***
|
||||
|
||||
*NOTE: NymVPN alpha is experimental software for [testing purposes](testing.md) only.*
|
||||
|
||||
|
||||
## NymVPN Overview
|
||||
|
||||
To understand what's under the hood of NymVPN and the mixnet, we recommend interested developers to begin with [Nym network overview](https://nymtech.net/docs/architecture/network-overview.html) and the [Mixnet traffic flow](https://nymtech.net/docs/architecture/traffic-flow.html) pages.
|
||||
|
||||
The default setup of NymVPN is to run in 5-hop mode (mixnet):
|
||||
|
||||
```
|
||||
┌─►mix──┐ mix mix
|
||||
│ │
|
||||
Entry │ │ Exit
|
||||
client ───► Gateway ──┘ mix │ mix ┌─►mix ───► Gateway ───► internet
|
||||
│ │
|
||||
│ │
|
||||
mix └─►mix──┘ mix
|
||||
```
|
||||
|
||||
Users can switch to 2-hop only mode, which is a faster but less private option. In this mode traffic is only sent between the two Gateways, and is not passed between Mix Nodes.
|
||||
|
||||
The client can optionally do the first hop (local client to Entry Gateway) using Wireguard. NymVPN uses Mullvad libraries for wrapping `wireguard-go` and to setup local routing rules to route all traffic to the TUN virtual network device.
|
||||
|
||||
## NymVPN Resources & Guides
|
||||
|
||||
* [NymVPN webpage](https://nymvpn.com)
|
||||
* [Alpha release page]({{nym_vpn_latest_binary_url}})
|
||||
* [NymVPN application (GUI) guide](gui.md)
|
||||
* [NymVPN Command Line Interface (CLI) guide](cli.md)
|
||||
* [Testing scripts](testing.md)
|
||||
* [Troubleshooting](troubleshooting.md)
|
||||
* [NymVPN FAQ](faq.md)
|
||||
* [NymVPN matrix channel](https://matrix.to/#/#NymVPN:nymtech.chat)
|
||||
@@ -1,6 +1,12 @@
|
||||
# Testing NymVPN alpha
|
||||
|
||||
> Before you get into testing NymVPN, make sure to go through the preparation steps for [Linux](nym-vpn-linux.md) or [MacOS](nym-vpn-mac.md).
|
||||
<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/908640440?h=0f7f6dfa53" style="position:absolute;top:0;left:0;width:100%;height:100%;" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>
|
||||
|
||||
```admonish info
|
||||
NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results.
|
||||
```
|
||||
|
||||
> Before you get into testing NymVPN, make sure to go through the preparation steps for NymVPN [CLI](cli.md).
|
||||
|
||||
One of the main aims of NymVPN alpha release is testing; your results will help us to make NymVPN robust and stabilise both the client and the network through provided measurements.
|
||||
|
||||
@@ -8,14 +14,20 @@ One of the main aims of NymVPN alpha release is testing; your results will help
|
||||
|
||||
> Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||
|
||||
1. Create a directory called `nym-vpn-tests` and copy your `nym-vpn-cli` binary and [`sandbox.env`](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) to that directory
|
||||
1. Create a directory called `nym-vpn-tests` and copy your `nym-vpn-cli` binary ([download here]({{nym_vpn_latest_binary_url}})) and [`sandbox.env`](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) to that directory
|
||||
2. Copy the [block below](#testssh) and save it as `tests.sh` to the same folder
|
||||
3. Open terminal in the same directory
|
||||
4. Turn off any existing VPN's (including the NymVPN instances), reconnect your wifi and make the script executable by running `chmod +x ./tests.sh`
|
||||
5. Run the tests: `sudo ./tests.sh`
|
||||
6. In case of errors, see the [troubleshooting section](./nym-vpn-troubleshooting.md#missing-jq-error) below
|
||||
4. Turn off any existing VPN's (including the NymVPN instances), reconnect your wifi and make the script executable by running
|
||||
```sh
|
||||
chmod u+x ./tests.sh
|
||||
```
|
||||
5. Run the `tests.sh` script:
|
||||
```sh
|
||||
sudo ./tests.sh
|
||||
````
|
||||
6. In case of errors, see the [troubleshooting section](troubleshooting.md#missing-jq-error)
|
||||
7. The script will print a JSON view of existing Gateways and prompt you to:
|
||||
- ***(Make sure to use two different Gateways for entry and exit!)***
|
||||
- *Make sure to use two different Gateways for entry and exit!*
|
||||
- `enter a gateway ID:` paste one of the values labeled with a key `"identityKey"` printed above (without `" "`)
|
||||
- `enter an exit address:` paste one of the values labeled with a key `"address"` printed above (without `" "`)
|
||||
- `enable WireGuard? (yes/no):` if you chose yes, find your private key and wireguard IP [here](https://nymvpn.com/en/alpha)
|
||||
@@ -34,9 +46,8 @@ nym-vpn-tests
|
||||
├── timeout
|
||||
└── two_hop_perf_test_results.log
|
||||
```
|
||||
10. In case of errors, see [troubleshooting section](./nym-vpn-troubleshooting.md#missing-jq-error) below
|
||||
11. When the tests are finished, remove the `nym-vpn-cli` binary from the folder and compress the entire folder as `nym-vpn-tests.zip`
|
||||
12. Upload this compressed file to the [questionnaire](https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2) upload field when prompted
|
||||
10. When the tests are finished, remove the `nym-vpn-cli` binary from the folder and compress the entire folder as `nym-vpn-tests.zip`
|
||||
11. Upload this compressed file to the [form]({{nym_vpn_form_url}}) upload field when prompted
|
||||
|
||||
#### tests.sh
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
# Troubleshooting
|
||||
|
||||
Below are listed some points which may need to be addressed when testing NymVPN alpha. If you crashed into any errors which are not listed, please contact us at the testing workshop or in the NymVPN [Matrix channel](https://matrix.to/#/#NymVPN:nymtech.chat).
|
||||
|
||||
#### Problems with the newest version `nym-vpn-alpha-0.0.X demo`
|
||||
|
||||
Try the previous version which was tested multiple times by downloading the client from the [release page](https://github.com/nymtech/nym/releases). Then follow all the setup steps the name of your downloaded binary.
|
||||
|
||||
#### Installing GUI on MacOS not working
|
||||
|
||||
In case there was a problem running the script, try the [manual setup](gui-mac.md) for MacOS.
|
||||
|
||||
#### Thread `main` panicked
|
||||
|
||||
If you see a message like:
|
||||
```sh
|
||||
thread 'main' panicked at /Users/runner/.cargo/git/checkouts/mullvadvpn-app-a575cf705b5dfd76/ccfbaa2/talpid-routing/src/unix.rs:301:30:
|
||||
```
|
||||
Restart your wifi connection and start again.
|
||||
|
||||
#### MacOS alert on NymVPN UI startup
|
||||
|
||||
If you are running NymVPN on mac OS for the first time, you may see this alert message:
|
||||
|
||||

|
||||
|
||||
1. Head to System Settings -> Privacy & Security and click `Allow anyway`
|
||||
|
||||

|
||||
|
||||
2. Confirm with your password or TouchID
|
||||
|
||||
3. Possibly you may have to confirm again upon running the application
|
||||
|
||||
#### Missing `jq` error
|
||||
|
||||
In case of missing `jq` on Linux (Debian) install it with:
|
||||
```sh
|
||||
# Linux (Debian)
|
||||
sudo apt-get install jq
|
||||
# macOS
|
||||
brew install jq
|
||||
```
|
||||
On some Linux distributions however the [script](testing.md#testssh) returns `jq` error even if your system claims that `jq is already the newest version`.
|
||||
In that case, comment the `jq` check in the script as follows:
|
||||
```sh
|
||||
#if ! command -v jq &>/dev/null; then
|
||||
# echo "jq is not installed. Please install jq to proceed."
|
||||
# exit 1
|
||||
#fi
|
||||
```
|
||||
|
||||
#### Error current_time: not found
|
||||
|
||||
When running `sudo sh ./test.sh` you may see an error like: `93: current_time: not found`. This has something to do with the `current_time` setup of your system and on itself shall not have a negative impact on the test. It has nothing to do with the client at all as it only relates to the code in our testing script.
|
||||
|
||||
#### Not connecting to the endpoint
|
||||
|
||||
In case the automatic download of all the Gateways fail (and it shouldn't), you do an easy manual work around:
|
||||
|
||||
1. Open the list of Gateways created by API [here](https://nymvpn.com/en/alpha/api/gateways)
|
||||
2. On top click on `JSON` option (shall be default view) and `Save`
|
||||
3. Save it as `data.json` to the `nym-vpn-tests` folder
|
||||
4. Replace line 3 in the [script `tests.sh`](testing.md#testssh) with:
|
||||
```sh
|
||||
NEW_ENDPOINT="http://localhost:8000/data.json"
|
||||
```
|
||||
5. In a new terminal window run:
|
||||
```sh
|
||||
python3 -m http.server 8000
|
||||
```
|
||||
6. Continue with the steps listed in [testing section](testing.md)
|
||||
@@ -32,10 +32,14 @@
|
||||
# Legal Forum
|
||||
|
||||
- [Exit Gateway](legal/exit-gateway.md)
|
||||
- [Switzerland](legal/swiss.md)
|
||||
- [United States](legal/united-states.md)
|
||||
- [Community Counsel](legal/community-counsel.md)
|
||||
- [Jurisdictions](legal/jurisdictions.md)
|
||||
- [Switzerland](legal/swiss.md)
|
||||
- [United States](legal/united-states.md)
|
||||
- [Landing Pages](legal/landing-pages.md)
|
||||
- [How to Add Info](legal/add-content.md)
|
||||
|
||||
---
|
||||
---
|
||||
# Misc.
|
||||
- [Code of Conduct](coc.md)
|
||||
- [Licensing](licensing.md)
|
||||
|
||||
@@ -1,22 +1,51 @@
|
||||
# Frequently Asked Questions
|
||||
|
||||
## Nym Nodes
|
||||
## Nym Mixnet
|
||||
|
||||
To see different stats about Nym Mixnet live, we recommend you to visit [status.notrustverify.ch](https://status.notrustverify.ch/d/CW3L7dVVk/nym-mixnet?orgId=1) built by [No Trust Verify](https://notrustverify.ch/) crew, one of the squads within Nym core community.
|
||||
|
||||
<iframe src="https://status.notrustverify.ch/d-solo/CW3L7dVVk/nym-mixnet?orgId=1&from=1702215592419&to=1704807592419&panelId=12" width="800" height="400" frameborder="0"></iframe>
|
||||
|
||||
|
||||
### Is there an explorer for Nym Mixnet?
|
||||
|
||||
Yes, there are several places, some are built by Nym core community:
|
||||
|
||||
* [Nym Explorer](https://explorer.nymtech.net/)
|
||||
* [Guru Explorer](https://mixnet.explorers.guru/)
|
||||
* [ExploreNYM](https://explorenym.net/)
|
||||
|
||||
### What determines the rewards when running a Mix Node?
|
||||
|
||||
The stake required for a Mix Node to achieve maximum rewards is called Mix Node saturation point. This is calculated from the staking supply (all circulating supply + part of unlocked tokens). The target level of staking is to have 50% of the staking supply locked in Mix Nodes.
|
||||
The stake required for a Mix Node to achieve maximum rewards is called Mix Node saturation point. This is calculated from the staking supply (all circulating supply + part of unlocked tokens). The target level of staking is to have 40% of the staking supply locked in Mix Nodes.
|
||||
|
||||
The node stake saturation point, which we denote by Nsat, is given by the stake supply, target level of staking divided by the number of rewarded (active) nodes.
|
||||
The node stake saturation point, which we denote by Nsat, is given by the stake supply, target level of staking divided between the rewarded nodes.
|
||||
|
||||
This design ensures the nodes aim to have a same size of stake (reputation) which can be done by delegation staking, as well as it secures a whale prevention and decentralization of staking, as any higher level of delegated $NYM than Nsat per node results in worsening reward ratio. On the contrary, the more Mix Nodes are active, the lower is Nsat. The equilibrium is reached when the staked tokens are delegated equally across the active Mix nodes and that's our basis for this incentive system.
|
||||
|
||||
<iframe src="https://status.notrustverify.ch/d-solo/CW3L7dVVk/nym-mixnet?orgId=1&from=1703074760986&to=1705666760986&panelId=5" width="800" height="400" frameborder="0"></iframe>
|
||||
|
||||
|
||||
The rewarded nodes are the nodes which will receive some rewards by the end of the given epoch. These can be separated further separated into:
|
||||
|
||||
1. Active: Top *N* nodes of the rewarded set (currently all of them but this can change), these are nodes which are used by the clients and mix packets.
|
||||
|
||||
2. Standby: Bottom *N* nodes of the rewarded set, they don't mix data from the clients but are used for testing. Their reward is smaller.
|
||||
|
||||
This design ensures the nodes aim to have a same size of stake (reputation) which can be done by delegation staking, as well as it ensures that there is a decentralization of staking as any higher level of staked tokens per node results in worse rewards. On the contrary, the more Mix Nodes are active, the lower is Nsat. The equilibrium is reached when the staked tokens are delegated equally across the active mix-nodes and that's our basis for this incentive system.
|
||||
|
||||
For more detailed calculation, read our blog post [Nym Token Economics update](https://blog.nymtech.net/nym-token-economics-update-fedff0ed5267). More info on staking can be found [here](https://blog.nymtech.net/staking-in-nym-introducing-mainnet-mixmining-f9bb1cbc7c36). And [here](https://blog.nymtech.net/want-to-stake-in-nym-here-is-how-to-choose-a-mix-node-to-delegate-nym-to-c3b862add165) is more info on how to choose a Mix Node for delegation. And finally an [update](https://blog.nymtech.net/quarterly-token-economic-parameter-update-b2862948710f) on token economics from July 2023.
|
||||
|
||||
<iframe src="https://status.notrustverify.ch/d-solo/CW3L7dVVk/nym-mixnet?orgId=1&from=1703074829887&to=1705666829887&panelId=31" width="850" height="400" frameborder="0"></iframe>
|
||||
|
||||
*More graphs and stats at [stats.notrustverify.ch](https://status.notrustverify.ch/d/CW3L7dVVk/nym-mixnet?orgId=1&from=1703074861988&to=1705666862004).*
|
||||
|
||||
### Which VPS providers would you recommend?
|
||||
|
||||
Consider in which jurisdiction you reside and where do you want to run a Mix Node. Do you want to pay by crypto or not and what are the other important particularities for your case? We always recommend operators to try to choose smaller and decentralised VPS providers over the most known ones controlling a majority of the internet. We receive some good feedback on these: Linode, Ghandi, Flokinet and Exoscale. Do your own research and share with the community.
|
||||
|
||||
<!---### Why is a mix node setup on a self-hosted machine so tricky?--->
|
||||
### Why is a mix node setup on a self-hosted machine so tricky?
|
||||
|
||||
We don't recommend this setup because it's really difficult to get a static IP and route IPv6 traffic.
|
||||
|
||||
### What's the Sphinx packet size?
|
||||
|
||||
@@ -28,7 +57,7 @@ Because of the way the smart contract works we keep it one-node one-address at t
|
||||
|
||||
### Which nodes are the most needed to be setup to strengthen Nym infrastructure and which ones bring rewards?
|
||||
|
||||
Right now only Mix Nodes are rewarded. We're working on Gateway and service payments. Gateways are the weak link right now due mostly to lack of incentivisation. Services like Network Requesters are obviously the most necessary for people to start using the platform, and we're working on smart contracts to allow for people to start advertising them the same way they do Mix Nodes.
|
||||
Ath this point the most crutial component needed are [Exit Gateways](../legal/exit-gateway.md).
|
||||
|
||||
### Are Mix Nodes whitelisted?
|
||||
|
||||
@@ -60,7 +89,6 @@ We are currently working towards building up a closed set of reputable validator
|
||||
|
||||
We understand that the early days of the Nyx blockchain will face possible vulnerabilities in terms of size - easy to disrupt or halt the chain if a malicious party entered with a large portion of stake. Besides that, there are some legal issues we need to address before we can distribute the validator set in a fully permissions fashion.
|
||||
|
||||
### Why does Nym do many airdrops?
|
||||
### Why does Nym do airdrops?
|
||||
|
||||
It is part of ensuring decentralisation - we need to avoid a handful of people having too much control over the token and market. Of course ideally people will stake the tokens and contribute to the project at this stage. We run surveys to better understand what people are doing with their tokens and what usability issues there are for staking. Any feedback is appreciated as it helps us improve all aspects of using the token and participating in the ecosystem.
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
# Adding Content to Legal Forum
|
||||
|
||||
Our aim is to establish a strong community network, sharing legal findings and other suggestions with each other. We would like to encourage all of the current and future operators to do research about the situation in the jurisdiction they operate in, to share solutions to the challenges they encountered when running Exit Gateway, and create a pull request (PR).
|
||||
|
||||
First of all, please join our [Node Operators Legal Forum](https://matrix.to/#/!YfoUFsJjsXbWmijbPG:nymtech.chat?via=nymtech.chat&via=matrix.org) (Matrix chat) and post any information or questions there.
|
||||
|
||||
To add your information to this book, you can create a PR directly to our [repository](https://github.com/nymtech/nym/tree/develop/documentation/operators/src/legal).
|
||||
|
||||
**Steps to make a pull request:**
|
||||
|
||||
1. Write down your legal findings, suggestions, communication templates, FAQ in a text editor
|
||||
|
||||
2. Clone `nymtech/nym` repository or pull in case you already have it and switch to `develop` branch
|
||||
|
||||
```sh
|
||||
# clone the repository
|
||||
git clone https://github.com/nymtech/nym
|
||||
|
||||
# go to the directory nym
|
||||
cd nym
|
||||
|
||||
# switch to branch develop
|
||||
git checkout develop
|
||||
|
||||
# update the repository
|
||||
git pull origin develop
|
||||
```
|
||||
|
||||
3. Make your own branch based off `develop` and switch to it
|
||||
|
||||
```sh
|
||||
# choose a descriptive and consise name without using <>
|
||||
git checkout -b operators/legal-forum/<MY_BRANCH_NAME>
|
||||
|
||||
# example: git checkout -b operators/legal-forum/alice-vps-faq-template
|
||||
|
||||
# you can double check that you are on the right branch
|
||||
git branch
|
||||
```
|
||||
|
||||
4. Save your legal findings as `<JURISDICTION_NAME>.md` to `/nym/documentation/operators/src/legal` or add info to an existing page
|
||||
|
||||
5. **Don't change anything in `SUMMARY.md`**, the admins will do it when merging
|
||||
|
||||
6. Add, commit and push your changes
|
||||
|
||||
```sh
|
||||
cd documentation/operators/src/legal
|
||||
git add <FILE_NAME>.md
|
||||
git commit -am "<DESCRIBE YOUR CHANGES>"
|
||||
git push origin operators/legal-forum/<MY_BRANCH_NAME>
|
||||
```
|
||||
7. Open the git generated link in your browser, fill the description and click on `Create a Pull Request` button
|
||||
```sh
|
||||
# the url will look like this
|
||||
https://github.com/nymtech/nym/pull/new/operators/legal-forum/<MY_BRANCH_NAME>
|
||||
```
|
||||
8. Notify others in the [Node Operators Legal Forum](https://matrix.to/#/!YfoUFsJjsXbWmijbPG:nymtech.chat?via=nymtech.chat&via=matrix.org) (Matrix chat) about the PR.
|
||||
@@ -0,0 +1,11 @@
|
||||
# Community Counsel
|
||||
|
||||
```admonish info
|
||||
The entire content of this page is under [Creative Commons Attribution 4.0 International Public License](https://creativecommons.org/licenses/by/4.0/).
|
||||
```
|
||||
|
||||
Running an Exit Gateway is a commitment and as such is exposed to various challenges. Besides different legal regulations typical difficulties may be dealing with VPS or ISP providers. Our strength lies in decentralised community of squads and individuals supporting each other. Sharing examples of [landing pages](landing-pages.md), templates for communication and FAQs is a great way to empower other operators sharing the mission of liberating internet. Below is a simple way how to create a pull request directly to Nym Operator Guide book.
|
||||
|
||||
## How to add content
|
||||
|
||||
Our aim is to establish a strong community network, sharing legal findings and other suggestions with each other. We would like to encourage all of the current and future operators to do research about the situation in the jurisdiction they operate in as well as solutions to any challenges when running an Exit Gateway and add those through a pull request (PR). Please check out the [steps to make a pull request](add-content.md).
|
||||
@@ -127,67 +127,14 @@ Useful links:
|
||||
- [github.com/coldhakca/abuse-templates/blob/master/dmca.template](https://github.com/coldhakca/abuse-templates/blob/master/dmca.template)
|
||||
|
||||
|
||||
## Legal environment - Findings from our legal team
|
||||
## Legal environment of Nym Exit Gateway
|
||||
|
||||
The Node Operators Legal Forum pages are divided into pages according the region:
|
||||
The Node Operators Legal Forum pages are divided according [jurisdictions](jurisdictions.md). Read below to learn [how to add](add-content.md) findings about your jurisdiction or edit existing info.
|
||||
|
||||
- [Switzerland](./swiss.md)
|
||||
- [United States](./united-states.md)
|
||||
## Community Counsel
|
||||
|
||||
See the next chapter to learn how to edit information or add findings about your jurisdiction.
|
||||
|
||||
## How to edit or add legal information
|
||||
|
||||
Our aim is to establish a strong community network, sharing legal findings with each other. We would like to encourage all the current and future operators to do research about the situation in the jurisdiction they operate and update this page.
|
||||
|
||||
First of all, please join our [Node Operators Legal Forum](https://matrix.to/#/!YfoUFsJjsXbWmijbPG:nymtech.chat?via=nymtech.chat&via=matrix.org) (Matrix chat) and post any information or questions there.
|
||||
|
||||
To add your information to this book, you can create a pull request directly to our [repository](https://github.com/nymtech/nym/tree/develop/documentation/operators/src), than ping the admins in the [Legal Forum chat](https://matrix.to/#/!YfoUFsJjsXbWmijbPG:nymtech.chat?via=nymtech.chat&via=matrix.org) and we will review it as fast as possible.
|
||||
|
||||
To do so, follow the steps below:
|
||||
|
||||
1. Write your legal findings down in a text editor (Soon we will share a template)
|
||||
2. Clone `nymtech/nym` repository and switch to develop branch
|
||||
|
||||
```sh
|
||||
# Clone the repository
|
||||
git clone https://github.com/nymtech/nym
|
||||
|
||||
# Go to the directory nym
|
||||
cd nym
|
||||
|
||||
# Switch to branch develop
|
||||
git checkout develop
|
||||
|
||||
# Update the repository
|
||||
git pull origin develop
|
||||
```
|
||||
|
||||
3. Make your own branch based off `develop` and switch to it
|
||||
|
||||
```sh
|
||||
git branch operators/legal-forum/<MY_BRANCH_NAME> # choose a descriptive and consiose name without using <>
|
||||
git checkout operators/legal-forum/<MY_BRANCH_NAME>
|
||||
|
||||
# you can double check that you are on the right branch
|
||||
git branch
|
||||
```
|
||||
|
||||
4. Save your legal findings as `<FILE_NAME>.md` to `/nym/documentation/operators/src/legal`
|
||||
5. Don't change anything in `SUMMARY.md`, the admins will do it when merging
|
||||
6. Add, commit and push your changes
|
||||
|
||||
```sh
|
||||
cd documentation/operators/src/legal
|
||||
git add <FILE_NAME>.md
|
||||
git commit -am "<describe your changes>"
|
||||
git push origin operators/legal-forum/<MY_BRANCH_NAME>
|
||||
```
|
||||
7. Open the git generated link in your browser, fill the description and click on `Create a Pull Request` button
|
||||
```sh
|
||||
# The link will look like this
|
||||
https://github.com/nymtech/nym/pull/new/<MY_BRANCH_NAME>
|
||||
```
|
||||
8. Notify others in the [Node Operators Legal Forum](https://matrix.to/#/!YfoUFsJjsXbWmijbPG:nymtech.chat?via=nymtech.chat&via=matrix.org) (Matrix chat)
|
||||
Nym Node operators are invited to add their legal findings or helpful suggestions directly through [pull requests](add-content.md). This can be done as a new legal information (or entire new country) to the list of [jurisdictions](jurisdictions.md) or in a form of an advice to [Community counsel pages](community-counsel.md), sharing examples of Exit Gateway [landing pages](landing-pages.md), templates etcetra.
|
||||
|
||||
## How to add content
|
||||
|
||||
Our aim is to establish a strong community network, sharing legal findings and other suggestions with each other. We would like to encourage all of the current and future operators to do research about the situation in the jurisdiction they operate in as well as solutions to any challenges when running an Exit Gateway and add those through a pull request (PR). Please check out the [steps to make a pull request](add-content.md).
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# Exit Gateway - Jurisdictions
|
||||
|
||||
```admonish info
|
||||
The entire content of this page is under [Creative Commons Attribution 4.0 International Public License](https://creativecommons.org/licenses/by/4.0/).
|
||||
```
|
||||
|
||||
```admonish warning
|
||||
The following part is for informational purposes only. Nym core team cannot provide comprehensive legal advice across all jurisdictions. Knowledge and experience with the legalities are being built up with the help of our counsel and with you, the community of Nym node operators. We encourage Nym node operators to join the [Node Operator](https://matrix.to/#/#operators:nymtech.chat) and [Operators Legal Forum](https://matrix.to/#/!YfoUFsJjsXbWmijbPG:nymtech.chat?via=nymtech.chat&via=matrix.org) channels on Element to share best practices and experiences.
|
||||
```
|
||||
|
||||
There is no one silver bullet covering the entire globe. Every jurisdiction has different set of laws and practices regarding internet traffic routing. Therefore the Node Operators Legal Forum pages are divided per region.
|
||||
|
||||
These are some findings from our legal team as an example:
|
||||
|
||||
- [Switzerland](swiss.md)
|
||||
- [United States](united-states.md)
|
||||
|
||||
> Nym Node operators are invited to add their legal findings directly through [pull requests](add-content.md).
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# Landing Pages
|
||||
|
||||
```admonish info
|
||||
The entire content of this page is under [Creative Commons Attribution 4.0 International Public License](https://creativecommons.org/licenses/by/4.0/).
|
||||
```
|
||||
|
||||
> Nym Node operators are invited to add their legal findings and suggestions directly through [pull requests](add-content.md).
|
||||
|
||||
Exit Gateway landing page is a great and transparent way to prevent possible troubles by providing people with basic facts, links to laws and regulations on a given topic as well as operator's contact info. To inspire each other we share some examples how Nym community handled this issue below.
|
||||
@@ -132,7 +132,7 @@ Save, exit and restart your Gateway. Now you are an operator of post-smooshed Ex
|
||||
|
||||
In case you already added Network Requester functionality to your Gateway as described above but haven't enabled the [exit policy](https://nymtech.net/.wellknown/network-requester/exit-policy.txt) there is an easy tweak to do so and turn your node into [Nym Exit Gateway](../faq/smoosh-faq.md#what-are-the-changes).
|
||||
|
||||
Open the config file stored at `.nym/gateways/<ID>/config/network_requester_config.tom` and set:
|
||||
Open the config file stored at `.nym/gateways/<ID>/config/network_requester_config.toml` and set:
|
||||
```sh
|
||||
use_deprecated_allow_list = false
|
||||
```
|
||||
|
||||
@@ -726,6 +726,7 @@ server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name "<nym-api.nyx.yourdomain.tld>";
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8000;
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
[//]: # (> The nym-api binary was built in the [building nym](../binaries/building-nym.md) section. If you haven't yet built Nym and want to run the code, go there first. You can build just the API with `cargo build --release --bin nym-api`.)
|
||||
|
||||
> The `nym-api` binary will be released in the immediate future - we're releasing this document beforehand so that Validators have information as soon as possible and get an idea of what to expect. This doc will be expanded over time as we release the API binary itself as well as start enabling functionality.
|
||||
>
|
||||
> The `nym-api` binary will be released in the immediate future - we're releasing this document beforehand so that validators have information as soon as possible and get an idea of what to expect. This doc will be expanded over time as we release the API binary itself as well as start enabling functionality.
|
||||
>
|
||||
> You can build the API with `cargo build --release --bin nym-api`.
|
||||
|
||||
> Any syntax in `<>` brackets is a user's unique variable. Exchange with a corresponding name without the `<>` brackets.
|
||||
@@ -18,7 +18,7 @@ This is important for both the proper decentralisation of the network uptime cal
|
||||
The process of enabling these different aspects of the system will take time. At the moment, Nym API operators will only have to run the binary in a minimal 'caching' mode in order to get used to maintaining an additional process running alongside a full node.
|
||||
|
||||
```admonish warning
|
||||
It is highly recommended to run `nym-api` alongside a full node since you will be exposing HTTP port(s) to the Internet. We also observed degradation in p2p and block signing operations when `nym-api` was run alongside a signing validator.
|
||||
It is highly recommended to run `nym-api` alongside a full node and NOT a validator node, since you will be exposing HTTP port(s) to the Internet. We also observed degradation in p2p and block signing operations when `nym-api` was run alongside a signing validator.
|
||||
```
|
||||
|
||||
### Rewards
|
||||
@@ -26,23 +26,75 @@ Operators of Nym API will be rewarded for performing the extra work of taking pa
|
||||
|
||||
Rewards for credential signing will be calculated hourly, with API operators receiving a proportional amount of the reward pool (333NYM per hour / 237,600 NYM per month), proportional to the percentage of credentials they have signed.
|
||||
|
||||
### (Coming Soon) Machine Specs
|
||||
We are working on load testing currently in order to get good specs for a full node + Nym API setup. Bear in mind that credential signing is primarily CPU-bound.
|
||||
|
||||
### Hardware Requirements
|
||||
|
||||
The specification mentioned below is for running a full node alongside the nym-api. It is recommended to run `nym-api` and a full Nyx node on the same machine for optimum performance.
|
||||
|
||||
Bear in mind that credential signing is primarily CPU-bound, so choose the fastest CPU available to you.
|
||||
|
||||
#### Minimum Requirements
|
||||
|
||||
| Hardware | Minimum Specification |
|
||||
|----------|--------------------------------------------|
|
||||
| CPU | 8-cores, 2.8GHz base clock speed or higher |
|
||||
| RAM | 16GB DDR4+ |
|
||||
| Disk | 500 GiB+ NVMe SSD |
|
||||
|
||||
#### Recommended Requirements
|
||||
|
||||
| Hardware | Minimum Specification |
|
||||
|----------|---------------------------------------------|
|
||||
| CPU | 16-cores, 2.8GHz base clock speed or higher |
|
||||
| RAM | 32GB DDR4+ |
|
||||
| Disk | 1 TiB+ NVMe SSD |
|
||||
|
||||
### Full node configuration
|
||||
|
||||
To install a full node from scratch, refer to the [validator setup guide](./validator-setup.md) and follow the steps outlined there.
|
||||
Additionally, to ensure `nym-api` works as expected, ensure the configuration is as below:
|
||||
|
||||
#### Ensure transaction index is turned on in your `config.toml`:
|
||||
|
||||
```
|
||||
[tx_index]
|
||||
|
||||
# Ensure that this is not set to "null". You're free to use any indexer
|
||||
|
||||
indexer = "kv"
|
||||
```
|
||||
|
||||
#### Ensure pruning settings are manually configured
|
||||
|
||||
`nym-api` needs to check validity of user-submitted transactions (in the past) while issuing credentials and as part of double-spend check. Hence, aggressively pruning data will lead to errors with your `nym-api`
|
||||
|
||||
Make sure your pruning settings are configured as below in `app.toml`:
|
||||
|
||||
```
|
||||
pruning = "custom"
|
||||
|
||||
# This number is likely to be updated once zk-nym signing goes live
|
||||
pruning-keep-recent = "750000"
|
||||
pruning-interval = "100"
|
||||
```
|
||||
|
||||
The example value of `100` for `pruning-interval` can be customised as per your requirement.
|
||||
|
||||
|
||||
### (Coming Soon) Credential Generation
|
||||
Validators that take part in the DKG ceremony will become part of the 'quorum' generating and verifying zk-Nym credentials. These will initially be used for private proof of payment for NymVPN (see our blogposts [here](https://blog.nymtech.net/nymvpn-an-invitation-for-privacy-experts-and-enthusiasts-63644139d09d) and [here](https://blog.nymtech.net/zk-nyms-are-here-a-major-milestone-towards-a-market-ready-mixnet-a3470c9ab10a) for more on this), and in the future will be expanded into more general usecases such as [offline ecash](https://arxiv.org/abs/2303.08221).
|
||||
Validators that take part in the DKG ceremony will become part of the 'quorum' generating and verifying zk-Nym credentials. These will initially be used for private proof of payment for NymVPN (see our blogposts [here](https://blog.nymtech.net/nymvpn-an-invitation-for-privacy-experts-and-enthusiasts-63644139d09d) and [here](https://blog.nymtech.net/zk-nyms-are-here-a-major-milestone-towards-a-market-ready-mixnet-a3470c9ab10a) for more on this), and in the future will be expanded into more general usecases such as [offline ecash](https://arxiv.org/abs/2303.08221).
|
||||
|
||||
The DKG ceremony will be used to create a subset of existing validators - referred to as the quorum. As outlined above, they will be the ones taking part in the generation and verification of zk-Nym credentials. The size of the 'minimum viable quorum' is 10 - we are aiming for a larger number than this for the initial quorum in order to have some redundancy in the case of a Validator dropping or going offline.
|
||||
The DKG ceremony will be used to create a subset of existing validators - referred to as the quorum. As outlined above, they will be the ones taking part in the generation and verification of zk-Nym credentials. The size of the 'minimum viable quorum' is 10 - we are aiming for a larger number than this for the initial quorum in order to have some redundancy in the case of a Validator dropping or going offline.
|
||||
|
||||
We will be releasing more detailed step-by-step documentation for involved validators nearer to the ceremony itself, but at a high level it will involve:
|
||||
* the deployment and initialisation of [`group`](https://github.com/nymtech/nym/tree/develop/contracts/multisig/cw4-group) and [`multisig`](https://github.com/nymtech/nym/tree/develop/contracts/multisig) contracts by Nym. Validators that are members of the `group` contract are the only ones that will be able to take part in the ceremony.
|
||||
* the deployment and initialisation of an instance of the [DKG contract](https://github.com/nymtech/nym/tree/develop/contracts/coconut-dkg) by Nym.
|
||||
* the deployment and initialisation of [`group`](https://github.com/nymtech/nym/tree/develop/contracts/multisig/cw4-group) and [`multisig`](https://github.com/nymtech/nym/tree/develop/contracts/multisig) contracts by Nym. Validators that are members of the `group` contract are the only ones that will be able to take part in the ceremony.
|
||||
* the deployment and initialisation of an instance of the [DKG contract](https://github.com/nymtech/nym/tree/develop/contracts/coconut-dkg) by Nym.
|
||||
* Validators will update their `nym-api` configs with the address of the deployed contracts. They will also stop running their API instance in caching only mode, instead switching over run with the `--enabled-credentials-mode`.
|
||||
* From the perspective of operators, this is all they have to do. Under the hood, each `nym-api` instance will then take part in several rounds of key submission, verification, and derivation. This will continue until quorum is acheived. More information on this will be released closer to the time of the ceremony.
|
||||
* From the perspective of operators, this is all they have to do. Under the hood, each `nym-api` instance will then take part in several rounds of key submission, verification, and derivation. This will continue until quorum is acheived. More information on this will be released closer to the time of the ceremony.
|
||||
|
||||
**We will be communicating individually with members of the existing Validator set who have expressed interest in joining the quorum concerning the timing and specifics of the ceremony**.
|
||||
**We will be communicating individually with members of the existing Validator set who have expressed interest in joining the quorum concerning the timing and specifics of the ceremony**.
|
||||
|
||||
## Current version
|
||||
## Current version
|
||||
```
|
||||
<!-- cmdrun ../../../../target/release/nym-api --version | grep "Build Version" | cut -b 21-26 -->
|
||||
```
|
||||
@@ -85,10 +137,10 @@ The API binary currently defaults to running in caching mode. You can run your A
|
||||
./nym-api run
|
||||
```
|
||||
|
||||
By default the API will be trying to query a running `nyxd` process (either a validator or RPC node) on `localhost:26657`. This value can be modified either via the `--nyxd-validator ` flag on `run`:
|
||||
By default the API will be trying to query your full node running locally on `localhost:26657`. If your node is hosted elsewhere, you can specify the RPC location by using the `--nyxd-validator ` flag on `run`:
|
||||
|
||||
```
|
||||
./nym-api run --nyxd-validator https://rpc.nymtech.net:443
|
||||
./nym-api run --nyxd-validator https://rpc-nym.yourcorp.tld:443
|
||||
```
|
||||
|
||||
> You can also change the value of `local_validator` in the config file found by default in `$HOME/.nym/nym-api/<ID>/config/config.toml`.
|
||||
@@ -179,4 +231,6 @@ Starting nym api...
|
||||
You will most likely want to automate your validator restarting if your server reboots. Checkout the [maintenance page](./maintenance.md) for an example `service` file.
|
||||
|
||||
## Exposing web endpoint using HTTPS
|
||||
It is recommended to expose the webserver over HTTPS by using a webserver like Nginx. An example configuration for configuring Nginx is listed [on the maintenance page](maintenance.md#nym-api-configuration)
|
||||
It is recommended to expose the webserver over HTTPS by using a webserver like Nginx. An example configuration for configuring Nginx is listed [on the maintenance page](maintenance.md#nym-api-configuration). If you're using a custom solution, ensure to allow requests from anywhere by setting a permissive CORS policy.
|
||||
|
||||
For example, it is configured in Nginx using: `add_header 'Access-Control-Allow-Origin' '*';`
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "ephemera"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license.workspace = true
|
||||
|
||||
[[bin]]
|
||||
name = "ephemera"
|
||||
|
||||
@@ -16,15 +16,15 @@ itertools = "0.10.3"
|
||||
lazy_static = "1.4.0"
|
||||
log = { workspace = true }
|
||||
maxminddb = "0.23.0"
|
||||
okapi = { version = "0.7.0-rc.1", features = ["impl_json_schema"] }
|
||||
okapi = { version = "0.7.0", features = ["impl_json_schema"] }
|
||||
pretty_env_logger = "0.4.0"
|
||||
rand = "0.8.5"
|
||||
rand_pcg = "0.3.1"
|
||||
rand_seeder = "0.2.3"
|
||||
reqwest = { workspace = true }
|
||||
rocket = { version = "0.5.0-rc.2", features = ["json"] }
|
||||
rocket_cors = { git="https://github.com/lawliet89/rocket_cors", rev="dfd3662c49e2f6fc37df35091cb94d82f7fb5915" }
|
||||
rocket_okapi = { version = "0.8.0-rc.2", features = ["swagger"] }
|
||||
rocket = { version = "0.5.0", features = ["json"] }
|
||||
rocket_cors = { version = "0.6.0" }
|
||||
rocket_okapi = { version = "0.8.0", features = ["swagger"] }
|
||||
schemars = { workspace = true, features = ["preserve_order"] }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use crate::country_statistics::country_nodes_distribution::CountryNodesDistribution;
|
||||
use crate::state::ExplorerApiStateContext;
|
||||
use rocket::serde::json::Json;
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use nym_explorer_api_requests::PrettyDetailedGatewayBond;
|
||||
use rocket::response::status::NotFound;
|
||||
use rocket::serde::json::Json;
|
||||
|
||||
@@ -60,7 +60,7 @@ impl<'r> FromRequest<'r> for Location {
|
||||
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||
match find_location(request) {
|
||||
Ok(loc) => Outcome::Success(loc),
|
||||
Err(e) => Outcome::Failure(e),
|
||||
Err(e) => Outcome::Error(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use crate::mix_node::delegations::{
|
||||
get_single_mixnode_delegations, get_single_mixnode_delegations_summed,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use crate::mix_nodes::models::{MixNodeActiveSetSummary, MixNodeSummary};
|
||||
use crate::state::ExplorerApiStateContext;
|
||||
use nym_explorer_api_requests::{MixnodeStatus, PrettyDetailedMixNodeBond};
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::{Route, State};
|
||||
use rocket_okapi::okapi::openapi3::OpenApi;
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use nym_mixnet_contract_common::{MixId, MixNode};
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::{Route, State};
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use crate::service_providers::models::{
|
||||
DirectoryService, DirectorySpDetailed, HarbourMasterService, PagedResult,
|
||||
};
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use rocket::response::status::NotFound;
|
||||
use rocket::serde::json::Json;
|
||||
use rocket::{Route, State};
|
||||
|
||||
@@ -29,21 +29,23 @@ export const BondBreakdownTable: FCWithChildren = () => {
|
||||
React.useEffect(() => {
|
||||
if (mixNode?.data) {
|
||||
// delegations
|
||||
const decimalisedDelegations = currencyToString(
|
||||
mixNode.data.total_delegation.amount.toString(),
|
||||
mixNode.data.total_delegation.denom,
|
||||
);
|
||||
const decimalisedDelegations = currencyToString({
|
||||
amount: mixNode.data.total_delegation.amount.toString(),
|
||||
denom: mixNode.data.total_delegation.denom,
|
||||
});
|
||||
|
||||
// pledges
|
||||
const decimalisedPledges = currencyToString(
|
||||
mixNode.data.pledge_amount.amount.toString(),
|
||||
mixNode.data.pledge_amount.denom,
|
||||
);
|
||||
const decimalisedPledges = currencyToString({
|
||||
amount: mixNode.data.pledge_amount.amount.toString(),
|
||||
denom: mixNode.data.pledge_amount.denom,
|
||||
});
|
||||
|
||||
// bonds total (del + pledges)
|
||||
const pledgesSum = Number(mixNode.data.pledge_amount.amount);
|
||||
const delegationsSum = Number(mixNode.data.total_delegation.amount);
|
||||
const bondsTotal = currencyToString((delegationsSum + pledgesSum).toString());
|
||||
const bondsTotal = currencyToString({
|
||||
amount: (pledgesSum + delegationsSum).toString(),
|
||||
});
|
||||
|
||||
setBonds({
|
||||
delegations: decimalisedDelegations,
|
||||
@@ -186,12 +188,12 @@ export const BondBreakdownTable: FCWithChildren = () => {
|
||||
</TableHead>
|
||||
|
||||
<TableBody>
|
||||
{uniqDelegations?.data?.map(({ owner, amount: { amount, denom } }) => (
|
||||
{uniqDelegations?.data?.map(({ owner, amount: { amount } }) => (
|
||||
<TableRow key={owner}>
|
||||
<TableCell sx={isMobile ? { width: 190 } : null} align="left">
|
||||
{owner}
|
||||
</TableCell>
|
||||
<TableCell align="left">{currencyToString(amount.toString(), denom)}</TableCell>
|
||||
<TableCell align="left">{currencyToString({ amount: amount.toString() })}</TableCell>
|
||||
<TableCell align="left">{calcBondPercentage(amount)}%</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
|
||||
@@ -11,9 +11,13 @@ export const EconomicsInfoRows = (): EconomicsInfoRowWithIndex => {
|
||||
const { economicDynamicsStats, mixNode } = useMixnodeContext();
|
||||
|
||||
const estimatedNodeRewards =
|
||||
currencyToString((economicDynamicsStats?.data?.estimated_total_node_reward || '').toString()) || '-';
|
||||
currencyToString({
|
||||
amount: economicDynamicsStats?.data?.estimated_total_node_reward.toString() || '',
|
||||
}) || '-';
|
||||
const estimatedOperatorRewards =
|
||||
currencyToString((economicDynamicsStats?.data?.estimated_operator_reward || '').toString()) || '-';
|
||||
currencyToString({
|
||||
amount: economicDynamicsStats?.data?.estimated_operator_reward.toString() || '',
|
||||
}) || '-';
|
||||
const profitMargin = mixNode?.data?.profit_margin_percent
|
||||
? toPercentIntegerString(mixNode?.data?.profit_margin_percent)
|
||||
: '-';
|
||||
|
||||
@@ -142,7 +142,7 @@ export const PageMixnodes: FCWithChildren = () => {
|
||||
component={RRDLink}
|
||||
to={`/network-components/mixnode/${params.row.mix_id}`}
|
||||
>
|
||||
{currencyToString(params.value)}
|
||||
{currencyToString({ amount: params.value, dp: 2 })}
|
||||
</MuiLink>
|
||||
),
|
||||
},
|
||||
@@ -187,7 +187,7 @@ export const PageMixnodes: FCWithChildren = () => {
|
||||
component={RRDLink}
|
||||
to={`/network-components/mixnode/${params.row.mix_id}`}
|
||||
>
|
||||
{currencyToString(params.value)}
|
||||
{currencyToString({ amount: params.value, dp: 2 })}
|
||||
</MuiLink>
|
||||
),
|
||||
},
|
||||
|
||||
@@ -4,11 +4,31 @@ import Big from 'big.js';
|
||||
const DENOM = process.env.CURRENCY_DENOM || 'unym';
|
||||
const DENOM_STAKING = process.env.CURRENCY_STAKING_DENOM || 'unyx';
|
||||
|
||||
export const currencyToString = (amount: string, denom: string = DENOM) =>
|
||||
printableCoin({
|
||||
export const toDisplay = (val: string | number | Big, dp = 4) => {
|
||||
let displayValue;
|
||||
try {
|
||||
displayValue = Big(val).toFixed(dp);
|
||||
} catch (e: any) {
|
||||
console.warn(`${displayValue} not a valid decimal number: ${e}`);
|
||||
}
|
||||
return displayValue;
|
||||
};
|
||||
|
||||
export const currencyToString = ({ amount, dp, denom = DENOM }: { amount: string; dp?: number; denom?: string }) => {
|
||||
if (!dp) {
|
||||
printableCoin({
|
||||
amount,
|
||||
denom,
|
||||
});
|
||||
}
|
||||
|
||||
const [printableAmount, printableDenom] = printableCoin({
|
||||
amount,
|
||||
denom,
|
||||
});
|
||||
}).split(/\s+/);
|
||||
|
||||
return `${toDisplay(printableAmount, dp)} ${printableDenom}`;
|
||||
};
|
||||
|
||||
export const stakingCurrencyToString = (amount: string, denom: string = DENOM_STAKING) =>
|
||||
printableCoin({
|
||||
@@ -24,15 +44,6 @@ export const stakingCurrencyToString = (amount: string, denom: string = DENOM_ST
|
||||
* @param dp - number of decimal places (4 by default ie. 0.0000)
|
||||
* @returns A prettyfied decimal number
|
||||
*/
|
||||
export const toDisplay = (val: string | number | Big, dp = 4) => {
|
||||
let displayValue;
|
||||
try {
|
||||
displayValue = Big(val).toFixed(dp);
|
||||
} catch (e: any) {
|
||||
console.warn(`${displayValue} not a valid decimal number: ${e}`);
|
||||
}
|
||||
return displayValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts a decimal number of μNYM (micro NYM) to NYM.
|
||||
|
||||
@@ -98,3 +98,9 @@ sqlx = { workspace = true, features = [
|
||||
|
||||
[features]
|
||||
wireguard = ["nym-wireguard", "defguard_wireguard_rs"]
|
||||
|
||||
[package.metadata.deb]
|
||||
name = "nym-gateway"
|
||||
maintainer-scripts = "debian"
|
||||
depends = "curl"
|
||||
systemd-units = { enable = false }
|
||||
|
||||
@@ -22,4 +22,46 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
## Install debian
|
||||
|
||||
```bash
|
||||
sudo curl -s --compressed "http://apt.nymtech.net.s3-website.eu-central-1.amazonaws.com/nymtech.gpg" | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/nymtech.gpg > /dev/null
|
||||
sudo echo "deb [signed-by=/etc/apt/trusted.gpg.d/nymtech.gpg] http://apt.nymtech.net.s3-website.eu-central-1.amazonaws.com/ squeeze main" > /etc/apt/sources.list.d/nymtech.list
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install nym-gateway
|
||||
|
||||
# See below for starting and managing the node
|
||||
```
|
||||
|
||||
## Systemd support
|
||||
|
||||
```bash
|
||||
sudo systemctl enable nym-gateway
|
||||
|
||||
# Run
|
||||
sudo systemctl start nym-gateway
|
||||
|
||||
# Check status
|
||||
sudo systemctl status nym-mixnode
|
||||
|
||||
# Logs
|
||||
journalctl -f -u nym-mixnode
|
||||
|
||||
```
|
||||
|
||||
## Build debian package
|
||||
|
||||
```bash
|
||||
# cargo install cargo-deb
|
||||
|
||||
# Build package
|
||||
cargo deb -p nym-gateway
|
||||
|
||||
# Install
|
||||
|
||||
# This will init the mixnode to `/etc/nym` as `nym` user, and create a systemd service
|
||||
sudo dpkg -i target/debian/<PACKAGE>
|
||||
```
|
||||
@@ -0,0 +1,6 @@
|
||||
#DEBHELPER#
|
||||
|
||||
useradd nym
|
||||
mkdir -p /etc/nym
|
||||
chown -R nym /etc/nym
|
||||
su nym -c 'NYM_HOME_DIR=/etc/nym nym-gateway init --host 0.0.0.0 --id nym-gateway --public-ips $(curl https://ipinfo.io/ip)'
|
||||
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Nym Gateway
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/nym-gateway run --id nym-gateway
|
||||
User=nym
|
||||
Environment="NYM_HOME_DIR=/etc/nym"
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -240,6 +240,7 @@ pub(crate) fn override_network_requester_config(
|
||||
)
|
||||
}
|
||||
|
||||
// NOTE: make sure this is in sync with service-providers/ip-packet-router/src/cli/mod.rs::override_config
|
||||
pub(crate) fn override_ip_packet_router_config(
|
||||
mut cfg: nym_ip_packet_router::Config,
|
||||
opts: Option<OverrideIpPacketRouterConfig>,
|
||||
|
||||
@@ -229,26 +229,11 @@ where
|
||||
iv,
|
||||
)?;
|
||||
|
||||
// Get the latest coconut signers and their VK
|
||||
let credential_api_clients = self
|
||||
let aggregated_verification_key = self
|
||||
.inner
|
||||
.coconut_verifier
|
||||
.all_coconut_api_clients(*credential.epoch_id())
|
||||
.verification_key(*credential.epoch_id())
|
||||
.await?;
|
||||
let current_api_clients = self
|
||||
.inner
|
||||
.coconut_verifier
|
||||
.all_current_coconut_api_clients()
|
||||
.await?;
|
||||
if credential_api_clients.is_empty() || current_api_clients.is_empty() {
|
||||
return Err(RequestHandlingError::NotEnoughNymAPIs {
|
||||
received: 0,
|
||||
needed: 1,
|
||||
});
|
||||
}
|
||||
|
||||
let aggregated_verification_key =
|
||||
nym_credentials::obtain_aggregate_verification_key(&credential_api_clients).await?;
|
||||
|
||||
if !credential.verify(&aggregated_verification_key) {
|
||||
return Err(RequestHandlingError::InvalidBandwidthCredential(
|
||||
@@ -256,9 +241,15 @@ where
|
||||
));
|
||||
}
|
||||
|
||||
let api_clients = self
|
||||
.inner
|
||||
.coconut_verifier
|
||||
.api_clients(*credential.epoch_id())
|
||||
.await?;
|
||||
|
||||
self.inner
|
||||
.coconut_verifier
|
||||
.release_funds(current_api_clients, &credential)
|
||||
.release_funds(&api_clients, &credential)
|
||||
.await?;
|
||||
|
||||
let bandwidth = Bandwidth::from(credential);
|
||||
|
||||
@@ -1,57 +1,150 @@
|
||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use super::authenticated::RequestHandlingError;
|
||||
use log::*;
|
||||
use nym_coconut_interface::Credential;
|
||||
use nym_coconut_interface::{Credential, VerificationKey};
|
||||
use nym_validator_client::coconut::all_coconut_api_clients;
|
||||
use nym_validator_client::nym_api::EpochId;
|
||||
use nym_validator_client::nyxd::contract_traits::MultisigQueryClient;
|
||||
use nym_validator_client::nyxd::AccountId;
|
||||
use nym_validator_client::{
|
||||
nyxd::{
|
||||
contract_traits::{
|
||||
CoconutBandwidthSigningClient, DkgQueryClient, MultisigQueryClient,
|
||||
MultisigSigningClient,
|
||||
},
|
||||
contract_traits::{CoconutBandwidthSigningClient, DkgQueryClient, MultisigSigningClient},
|
||||
cosmwasm_client::logs::{find_attribute, BANDWIDTH_PROPOSAL_ID},
|
||||
Coin,
|
||||
},
|
||||
CoconutApiClient, DirectSigningHttpRpcNyxdClient,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
use tokio::sync::RwLock;
|
||||
use tokio::sync::{RwLock, RwLockReadGuard};
|
||||
|
||||
pub(crate) struct CoconutVerifier {
|
||||
address: AccountId,
|
||||
nyxd_client: RwLock<DirectSigningHttpRpcNyxdClient>,
|
||||
|
||||
// **CURRENTLY** api client addresses don't change during the epochs
|
||||
api_clients: RwLock<HashMap<EpochId, Vec<CoconutApiClient>>>,
|
||||
|
||||
// keys never change during epochs
|
||||
master_keys: RwLock<HashMap<EpochId, VerificationKey>>,
|
||||
mix_denom_base: String,
|
||||
}
|
||||
|
||||
impl CoconutVerifier {
|
||||
pub async fn new(nyxd_client: DirectSigningHttpRpcNyxdClient) -> Self {
|
||||
pub async fn new(
|
||||
nyxd_client: DirectSigningHttpRpcNyxdClient,
|
||||
) -> Result<Self, RequestHandlingError> {
|
||||
let mix_denom_base = nyxd_client.current_chain_details().mix_denom.base.clone();
|
||||
let address = nyxd_client.address();
|
||||
|
||||
CoconutVerifier {
|
||||
let mut master_keys = HashMap::new();
|
||||
let mut api_clients = HashMap::new();
|
||||
|
||||
// might as well obtain the key for the current epoch, if applicable
|
||||
let current_epoch = nyxd_client.get_current_epoch().await?;
|
||||
if current_epoch.state.is_in_progress() {
|
||||
// note: even though we're constructing clients here, we will NOT be making any network requests
|
||||
let epoch_api_clients =
|
||||
all_coconut_api_clients(&nyxd_client, current_epoch.epoch_id).await?;
|
||||
let threshold = nyxd_client.get_current_epoch_threshold().await?;
|
||||
|
||||
// SAFETY:
|
||||
// if epoch state is in the 'in progress' state, it means the threshold value MUST HAVE
|
||||
// been established. if it wasn't, there's an underlying issue with the DKG contract in which
|
||||
// case we shouldn't continue anyway because here be dragons
|
||||
#[allow(clippy::expect_used)]
|
||||
let threshold = threshold.expect("unavailable threshold value") as usize;
|
||||
if epoch_api_clients.len() < threshold {
|
||||
return Err(RequestHandlingError::NotEnoughNymAPIs {
|
||||
received: epoch_api_clients.len(),
|
||||
needed: threshold,
|
||||
});
|
||||
}
|
||||
let aggregated_verification_key =
|
||||
nym_credentials::obtain_aggregate_verification_key(&epoch_api_clients).await?;
|
||||
|
||||
api_clients.insert(current_epoch.epoch_id, epoch_api_clients);
|
||||
master_keys.insert(current_epoch.epoch_id, aggregated_verification_key);
|
||||
}
|
||||
|
||||
Ok(CoconutVerifier {
|
||||
address,
|
||||
nyxd_client: RwLock::new(nyxd_client),
|
||||
api_clients: RwLock::new(api_clients),
|
||||
master_keys: RwLock::new(master_keys),
|
||||
mix_denom_base,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn all_current_coconut_api_clients(
|
||||
pub async fn api_clients(
|
||||
&self,
|
||||
) -> Result<Vec<CoconutApiClient>, RequestHandlingError> {
|
||||
let epoch_id = self
|
||||
.nyxd_client
|
||||
.read()
|
||||
.await
|
||||
.get_current_epoch()
|
||||
.await?
|
||||
.epoch_id;
|
||||
self.all_coconut_api_clients(epoch_id).await
|
||||
epoch_id: EpochId,
|
||||
) -> Result<RwLockReadGuard<Vec<CoconutApiClient>>, RequestHandlingError> {
|
||||
let guard = self.api_clients.read().await;
|
||||
|
||||
// the key was already in the map
|
||||
if let Ok(mapped) = RwLockReadGuard::try_map(guard, |clients| clients.get(&epoch_id)) {
|
||||
return Ok(mapped);
|
||||
}
|
||||
|
||||
let api_clients = self.query_api_clients(epoch_id).await?;
|
||||
|
||||
// EDGE CASE:
|
||||
// if this epoch is from the past, we can't query for its threshold
|
||||
// we can only hope that enough valid keys were submitted
|
||||
// the best we can do is check if we have at least a api
|
||||
if api_clients.is_empty() {
|
||||
return Err(RequestHandlingError::NotEnoughNymAPIs {
|
||||
received: 0,
|
||||
needed: 1,
|
||||
});
|
||||
}
|
||||
|
||||
let mut guard = self.api_clients.write().await;
|
||||
guard.insert(epoch_id, api_clients);
|
||||
let guard = guard.downgrade();
|
||||
|
||||
// SAFETY:
|
||||
// we just inserted the entry into the map while NEVER dropping the lock (only downgraded it)
|
||||
// so it MUST exist and thus the unwrap is fine
|
||||
#[allow(clippy::unwrap_used)]
|
||||
Ok(RwLockReadGuard::map(guard, |clients| {
|
||||
clients.get(&epoch_id).unwrap()
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn all_coconut_api_clients(
|
||||
pub async fn verification_key(
|
||||
&self,
|
||||
epoch_id: EpochId,
|
||||
) -> Result<RwLockReadGuard<VerificationKey>, RequestHandlingError> {
|
||||
let guard = self.master_keys.read().await;
|
||||
|
||||
// the key was already in the map
|
||||
if let Ok(mapped) = RwLockReadGuard::try_map(guard, |keys| keys.get(&epoch_id)) {
|
||||
return Ok(mapped);
|
||||
}
|
||||
|
||||
let api_clients = self.api_clients(epoch_id).await?;
|
||||
|
||||
let aggregated_verification_key =
|
||||
nym_credentials::obtain_aggregate_verification_key(&api_clients).await?;
|
||||
|
||||
let mut guard = self.master_keys.write().await;
|
||||
guard.insert(epoch_id, aggregated_verification_key);
|
||||
let guard = guard.downgrade();
|
||||
|
||||
// SAFETY:
|
||||
// we just inserted the entry into the map while NEVER dropping the lock (only downgraded it)
|
||||
// so it MUST exist and thus the unwrap is fine
|
||||
#[allow(clippy::unwrap_used)]
|
||||
Ok(RwLockReadGuard::map(guard, |keys| {
|
||||
keys.get(&epoch_id).unwrap()
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn query_api_clients(
|
||||
&self,
|
||||
epoch_id: u64,
|
||||
) -> Result<Vec<CoconutApiClient>, RequestHandlingError> {
|
||||
@@ -60,7 +153,7 @@ impl CoconutVerifier {
|
||||
|
||||
pub async fn release_funds(
|
||||
&self,
|
||||
api_clients: Vec<CoconutApiClient>,
|
||||
api_clients: &[CoconutApiClient],
|
||||
credential: &Credential,
|
||||
) -> Result<(), RequestHandlingError> {
|
||||
let res = self
|
||||
|
||||
@@ -457,7 +457,7 @@ impl<St> Gateway<St> {
|
||||
let coconut_verifier = {
|
||||
let nyxd_client = self.random_nyxd_client()?;
|
||||
CoconutVerifier::new(nyxd_client).await
|
||||
};
|
||||
}?;
|
||||
|
||||
let mix_forwarding_channel =
|
||||
self.start_packet_forwarder(shutdown.subscribe().named("PacketForwarder"));
|
||||
|
||||
@@ -3,6 +3,7 @@ name = "nym-bity-integration"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
rust-version = "1.56"
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
||||
@@ -35,8 +35,8 @@ By default, the Nym Mixnode will start on port 1789. If desired, you can change
|
||||
## Install debian
|
||||
|
||||
```bash
|
||||
sudo curl -s --compressed "https://nymtech.github.io/nym/nymtech.gpg" | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/nymtech.gpg > /dev/null
|
||||
sudo echo "deb [signed-by=/etc/apt/trusted.gpg.d/nymtech.gpg] https://nymtech.github.io/nym/ /" > nymtech.list
|
||||
sudo curl -s --compressed "http://apt.nymtech.net.s3-website.eu-central-1.amazonaws.com/nymtech.gpg" | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/nymtech.gpg > /dev/null
|
||||
sudo echo "deb [signed-by=/etc/apt/trusted.gpg.d/nymtech.gpg] http://apt.nymtech.net.s3-website.eu-central-1.amazonaws.com/ squeeze main" > /etc/apt/sources.list.d/nymtech.list
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install nym-mixnode
|
||||
|
||||
@@ -32,8 +32,8 @@ pin-project = "1.0"
|
||||
rand = "0.8.5"
|
||||
rand-07 = { package = "rand", version = "0.7.3" } # required for compatibility
|
||||
reqwest = { workspace = true, features = ["json"] }
|
||||
rocket = { version = "0.5.0-rc.2", features = ["json"] }
|
||||
rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", rev = "dfd3662c49e2f6fc37df35091cb94d82f7fb5915" }
|
||||
rocket = { version = "0.5.0", features = ["json"] }
|
||||
rocket_cors = { version = "0.6.0" }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tap = "1.0"
|
||||
@@ -60,8 +60,8 @@ sqlx = { workspace = true, features = [
|
||||
"migrate",
|
||||
] }
|
||||
|
||||
okapi = { version = "0.7.0-rc.1", features = ["impl_json_schema"] }
|
||||
rocket_okapi = { version = "0.8.0-rc.2", features = ["swagger"] }
|
||||
okapi = { version = "0.7.0", features = ["impl_json_schema"] }
|
||||
rocket_okapi = { version = "0.8.0", features = ["swagger"] }
|
||||
schemars = { workspace = true, features = ["preserve_order"] }
|
||||
zeroize = { workspace = true }
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use crate::circulating_supply_api::cache::CirculatingSupplyCache;
|
||||
use crate::node_status_api::models::ErrorResponse;
|
||||
use nym_api_requests::models::CirculatingSupplyResponse;
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use crate::coconut::api_routes::helpers::build_credentials_response;
|
||||
use crate::coconut::error::{CoconutError, Result};
|
||||
use crate::coconut::helpers::{accepted_vote_err, blind_sign};
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use crate::network::models::{ContractInformation, NetworkDetails};
|
||||
use crate::nym_contract_cache::cache::NymContractCache;
|
||||
use nym_contracts_common::ContractBuildInformation;
|
||||
|
||||
@@ -36,7 +36,7 @@ impl<'r> FromRequest<'r> for LocalRequest {
|
||||
"Received a request from {:?} for a local-only route",
|
||||
request.client_ip()
|
||||
);
|
||||
Outcome::Failure((Status::Unauthorized, NonLocalRequestError))
|
||||
Outcome::Error((Status::Unauthorized, NonLocalRequestError))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use super::helpers::_get_gateways_detailed;
|
||||
use super::NodeStatusCache;
|
||||
use crate::node_status_api::helpers::{
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use crate::{
|
||||
node_status_api::{
|
||||
helpers::{_get_active_set_detailed, _get_mixnodes_detailed, _get_rewarded_set_detailed},
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
// due to the macro expansion of rather old rocket macros...
|
||||
#![allow(unused_imports)]
|
||||
|
||||
use crate::node_describe_cache::DescribedNodes;
|
||||
use crate::nym_contract_cache::cache::NymContractCache;
|
||||
use crate::support::caching::cache::SharedCache;
|
||||
|
||||
@@ -6,7 +6,7 @@ repository.workspace = true
|
||||
homepage.workspace = true
|
||||
documentation.workspace = true
|
||||
edition.workspace = true
|
||||
license = "GPL-3"
|
||||
license = "GPL-3.0"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ CREATE TABLE block_signing_reward
|
||||
rewarding_epoch_id INTEGER NOT NULL REFERENCES rewarding_epoch (id),
|
||||
validator_consensus_address TEXT NOT NULL,
|
||||
operator_account TEXT NOT NULL,
|
||||
whitelisted BOOLEAN NOT NULL,
|
||||
amount TEXT NOT NULL,
|
||||
voting_power BIGINT NOT NULL,
|
||||
voting_power_share TEXT NOT NULL,
|
||||
@@ -38,11 +39,11 @@ CREATE TABLE block_signing_reward
|
||||
|
||||
CREATE TABLE epoch_credential_issuance
|
||||
(
|
||||
rewarding_epoch_id INTEGER NOT NULL PRIMARY KEY REFERENCES rewarding_epoch (id),
|
||||
starting_dkg_epoch INTEGER NOT NULL,
|
||||
ending_dkg_epoch INTEGER NOT NULL,
|
||||
rewarding_epoch_id INTEGER NOT NULL PRIMARY KEY REFERENCES rewarding_epoch (id),
|
||||
starting_dkg_epoch INTEGER NOT NULL,
|
||||
ending_dkg_epoch INTEGER NOT NULL,
|
||||
total_issued_partial_credentials INTEGER NOT NULL,
|
||||
budget TEXT NOT NULL
|
||||
budget TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE malformed_credential
|
||||
@@ -56,6 +57,7 @@ CREATE TABLE credential_issuance_reward
|
||||
rewarding_epoch_id INTEGER NOT NULL REFERENCES rewarding_epoch (id),
|
||||
operator_account TEXT NOT NULL,
|
||||
amount TEXT NOT NULL,
|
||||
whitelisted BOOLEAN NOT NULL,
|
||||
api_endpoint TEXT NOT NULL,
|
||||
issued_partial_credentials INTEGER NOT NULL,
|
||||
issued_credentials_share TEXT NOT NULL,
|
||||
|
||||
@@ -53,6 +53,9 @@ pub struct ConfigOverridableArgs {
|
||||
#[clap(long)]
|
||||
pub disable_block_signing_rewarding: bool,
|
||||
|
||||
#[clap(long)]
|
||||
pub block_signing_monitoring_only: bool,
|
||||
|
||||
#[clap(long)]
|
||||
pub disable_credential_issuance_rewarding: bool,
|
||||
|
||||
|
||||
@@ -9,7 +9,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_validator_client::nyxd::Coin;
|
||||
use nym_validator_client::nyxd::{AccountId, Coin};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{serde_as, DisplayFromStr};
|
||||
use std::io;
|
||||
@@ -225,7 +225,7 @@ impl Default for RewardingRatios {
|
||||
impl RewardingRatios {
|
||||
pub fn ensure_is_valid(&self) -> Result<(), NymRewarderError> {
|
||||
if self.block_signing + self.credential_verification + self.credential_issuance != 1.0 {
|
||||
todo!()
|
||||
return Err(NymRewarderError::InvalidRewardingRatios { ratios: *self });
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -238,19 +238,30 @@ pub struct NyxdScraper {
|
||||
// TODO: debug with everything that's currently hardcoded in the scraper
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Copy)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct BlockSigning {
|
||||
/// Specifies whether credential issuance for block signing is enabled.
|
||||
/// Specifies whether rewards for block signing is enabled.
|
||||
pub enabled: bool,
|
||||
|
||||
/// Specifies whether to only monitor and not send rewards.
|
||||
pub monitor_only: bool,
|
||||
|
||||
/// List of validators that will receive rewards for block signing.
|
||||
/// If not on the list, the validator will be treated as if it had 0 voting power.
|
||||
pub whitelist: Vec<AccountId>,
|
||||
}
|
||||
|
||||
impl Default for BlockSigning {
|
||||
fn default() -> Self {
|
||||
BlockSigning { enabled: true }
|
||||
BlockSigning {
|
||||
enabled: true,
|
||||
monitor_only: false,
|
||||
whitelist: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, Copy)]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct IssuanceMonitor {
|
||||
/// Specifies whether credential issuance monitoring (and associated rewards) are enabled.
|
||||
pub enabled: bool,
|
||||
@@ -264,15 +275,20 @@ pub struct IssuanceMonitor {
|
||||
|
||||
/// The sampling rate of the issued credentials
|
||||
pub sampling_rate: f64,
|
||||
|
||||
/// List of validators that will receive rewards for credential issuance.
|
||||
/// If not on the list, the validator will be treated as if it hadn't issued a single credential.
|
||||
pub whitelist: Vec<AccountId>,
|
||||
}
|
||||
|
||||
impl Default for IssuanceMonitor {
|
||||
fn default() -> Self {
|
||||
IssuanceMonitor {
|
||||
enabled: true,
|
||||
enabled: false,
|
||||
run_interval: DEFAULT_MONITOR_RUN_INTERVAL,
|
||||
min_validate_per_issuer: DEFAULT_MONITOR_MIN_VALIDATE,
|
||||
sampling_rate: DEFAULT_MONITOR_SAMPLING_RATE,
|
||||
whitelist: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@ impl ConfigOverride for ConfigOverridableArgs {
|
||||
config.block_signing.enabled = false
|
||||
}
|
||||
|
||||
if self.block_signing_monitoring_only {
|
||||
config.block_signing.monitor_only = true
|
||||
}
|
||||
|
||||
if self.disable_credential_issuance_rewarding {
|
||||
config.issuance_monitor.enabled = false
|
||||
}
|
||||
|
||||
@@ -38,9 +38,19 @@ credential_verification = {{ rewarding.ratios.credential_verification }}
|
||||
|
||||
|
||||
[block_signing]
|
||||
# Specifies whether credential issuance for block signing is enabled.
|
||||
# Specifies whether rewarding for block signing is enabled.
|
||||
enabled = {{ block_signing.enabled }}
|
||||
|
||||
|
||||
# Specifies whether to only monitor and not send rewards.
|
||||
monitor_only = {{ block_signing.monitor_only }}
|
||||
|
||||
# List of validators that will receive rewards for block signing.
|
||||
# If not on the list, the validator will be treated as if it had 0 voting power.
|
||||
whitelist = [
|
||||
# needs to be manually populated; expects nvalcons1... addresses.
|
||||
# you can get them from, for example, `/cosmos/base/tendermint/v1beta1/validatorsets/latest` endpoint
|
||||
]
|
||||
|
||||
|
||||
[issuance_monitor]
|
||||
# Specifies whether credential issuance monitoring (and associated rewards) are enabled.
|
||||
@@ -54,6 +64,12 @@ min_validate_per_issuer = {{ issuance_monitor.min_validate_per_issuer }}
|
||||
|
||||
# The sampling rate of the issued credentials
|
||||
sampling_rate = {{ issuance_monitor.sampling_rate }}
|
||||
|
||||
# List of validators that will receive rewards for credential issuance.
|
||||
# If not on the list, the validator will be treated as if it hadn't issued a single credential.
|
||||
whitelist = [
|
||||
# needs to be manually populated; expects n1... addresses
|
||||
]
|
||||
|
||||
[nyxd_scraper]
|
||||
# Url to the websocket endpoint of a validator, for example `wss://rpc.nymtech.net/websocket`
|
||||
|
||||