Compare commits

..

40 Commits

Author SHA1 Message Date
Tommy Verrall edf10499f6 use docker to optimise contracts 2024-05-23 10:41:47 +02:00
Tommy Verrall 76953df4bb Merge pull request #4605 from nymtech/feature/nym-node-api-location
Feature/nym node api location
2024-05-21 17:28:53 +01:00
Tommy Verrall ce2449f86a Merge pull request #4599 from nymtech/feature/expose-all-api-reports
nym-api: make report/avg_uptime endpoints ignore blacklist
2024-05-21 17:28:07 +01:00
Jędrzej Stuczyński 598014bf30 fixed deserialisation of 'AuxiliaryDetails' api response 2024-05-21 17:06:15 +01:00
Jędrzej Stuczyński 73fe7618db removing needless clones 2024-05-21 17:06:15 +01:00
Jędrzej Stuczyński 7a416f8cf5 aggregate new data with nym-api 2024-05-21 17:06:14 +01:00
Jędrzej Stuczyński 3077c2ea8d create '/api/v1/auxiliary-details' that exposes nodes location 2024-05-21 17:06:13 +01:00
Tommy Verrall be6c63723c Merge pull request #4553 from nymtech/jon/autoinherit
Run cargo autoinherit on the main workspace
2024-05-21 16:33:38 +01:00
Jon Häggblad c5a3cb7707 Update to handle changes in develop 2024-05-21 17:15:38 +02:00
Jon Häggblad cce9f0b183 Merge remote-tracking branch 'origin/develop' into jon/autoinherit 2024-05-21 17:10:02 +02:00
Tommy Verrall 84b74703b2 Merge pull request #4604 from nymtech/jon/ipr-request-sign
Add optional signature to IPR request/response
2024-05-21 15:01:43 +01:00
Tommy Verrall 9bf3600e5b Merge pull request #4601 from nymtech/feature/unstable-tested-nodes-endpoint
Feature/unstable tested nodes endpoint
2024-05-21 14:51:46 +01:00
Jędrzej Stuczyński 9f20c8ed1f Merge pull request #4598 from nymtech/feature/remove-coconut-wait-buffer
removed blocking for coconut in the final epoch state
2024-05-21 10:19:38 +01:00
Jędrzej Stuczyński 84e66c34f2 Merge pull request #4584 from nymtech/feature/wasm-coconut
Feature/wasm coconut
2024-05-21 10:08:40 +01:00
Jędrzej Stuczyński e04df37988 Merge pull request #4595 from nymtech/feature/freepass-admin
allow using explicit admin address for issuing freepasses
2024-05-21 10:07:44 +01:00
import this 0eb6eb855b [DOCs/operators]: Create a Nym ISP sheet, write gateway-probe guide & clean FnF docs (#4590)
* initialise nym versin of good-bad isps by tor community

* syntax edit

* finalise csv2md

* initialise isp-list page

* add last update info

* add python3 plugis to ci/cd runnners

* remove argparse installation

* python3 syntax edit

* pip install attempt

* pip install attempt

* change python version in cmdrun command

* fix python modules installation

* correct command python version

* workflows python env update

* add probe guide, clean FnF pages

* fix typos
2024-05-20 12:27:18 +00:00
Jon Häggblad c91412f949 Restore exact same serde import for common contract crates 2024-05-20 13:45:18 +02:00
Jon Häggblad 0a89f31a29 Merge in new deps in the main list 2024-05-20 13:19:47 +02:00
Jon Häggblad 9badeac832 cargo autoinherit in root workspace 2024-05-20 13:16:25 +02:00
Jon Häggblad b59c41d9cd Fix test 2024-05-20 12:24:39 +02:00
Jon Häggblad 8f083ff91e Add signatures to dynamic connect and disconect, and remove from response 2024-05-20 12:18:28 +02:00
Jon Häggblad 0f44836025 Move signature one layer down 2024-05-20 12:04:05 +02:00
Jon Häggblad 68ee2d747d Add timestamps to requests 2024-05-20 11:53:00 +02:00
Jon Häggblad e29c76678d Add optional signature field to requests and responses 2024-05-20 10:58:10 +02:00
Jon Häggblad a4005c7d81 Add v7 request/responses 2024-05-20 10:57:56 +02:00
Jędrzej Stuczyński efe6d916e2 order results by timestamp desc 2024-05-20 09:29:09 +01:00
Jędrzej Stuczyński 910b6a1369 adding explicit 'unstable' path segment 2024-05-19 10:27:33 +01:00
Jędrzej Stuczyński 7818658ee8 flatten the response 2024-05-17 18:36:50 +01:00
Jędrzej Stuczyński 89e34b4fd3 queries for detailed node statuses with broken pagination 2024-05-17 17:02:29 +01:00
Jędrzej Stuczyński 2f5a00dbda removed blocking for coconut in the final epoch state 2024-05-17 11:04:19 +01:00
Jędrzej Stuczyński 7f87d42f9a nym-api: make report/avg_uptime endpoints ignore blacklist 2024-05-17 11:01:16 +01:00
Jędrzej Stuczyński 93b12bccca updated the lock file after the rebasing fixes 2024-05-14 17:47:43 +01:00
Jędrzej Stuczyński 89fb4ef03f fixing more build issues 2024-05-14 17:45:17 +01:00
Jędrzej Stuczyński b8ab187db0 fixed wrong version of gloo-net and removed reduntant imports 2024-05-14 17:45:17 +01:00
Jędrzej Stuczyński a9790c1f66 removed duplicate 'set_panic_hook' symbol in the browser extension code 2024-05-14 17:45:17 +01:00
Jędrzej Stuczyński b46634b8f7 fixed test import paths 2024-05-14 17:45:17 +01:00
Jędrzej Stuczyński 633e7ffb46 no idea what happened here 2024-05-14 17:45:16 +01:00
Jędrzej Stuczyński dd2077bf12 updated the makefile 2024-05-14 17:45:16 +01:00
Jędrzej Stuczyński 0323ba2bb9 ability to obtain bandwidth voucher from wasm via vpn-api 2024-05-14 17:45:14 +01:00
Jędrzej Stuczyński 07cc47a0ff allow using explicit admin address for issuing freepasses 2024-05-14 16:58:11 +01:00
179 changed files with 6554 additions and 850 deletions
+5 -1
View File
@@ -9,7 +9,11 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler git
run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler git python3 && sudo apt-get update --fix-missing
- name: Install pip3
run: sudo apt install -y python3-pip
- name: Install Python3 modules
run: sudo pip3 install pandas tabulate
- name: Install rsync
run: sudo apt-get install rsync
- uses: rlespinasse/github-slug-action@v3.x
@@ -35,7 +35,7 @@ jobs:
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
toolchain: 1.77.0
target: wasm32-unknown-unknown
override: true
@@ -47,6 +47,17 @@ jobs:
- name: Build release contracts
run: make contracts
- name: Install CosmWasm optimizer
run: |
sudo apt-get update
sudo apt-get install -y docker.io
- name: Optimize WASM contracts
run: |
docker run --rm -v $(pwd)/contracts/target/wasm32-unknown-unknown/release:/code \
--mount type=volume,source=cosmwasm_cache,target=/code/cache \
cosmwasm/workspace-optimizer:0.12.9
- name: Prepare build output
shell: bash
env:
@@ -58,8 +69,6 @@ jobs:
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/nym_service_provider_directory.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/nym_name_service.wasm $OUTPUT_DIR
- name: Deploy branch to CI www
continue-on-error: true
+5 -1
View File
@@ -13,7 +13,11 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler git
run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler git python3 && sudo apt-get update --fix-missing
- name: Install pip3
run: sudo apt install -y python3-pip
- name: Install Python3 modules
run: sudo pip3 install pandas tabulate
- name: Install rsync
run: sudo apt-get install rsync
- uses: rlespinasse/github-slug-action@v3.x
Generated
+74 -21
View File
@@ -714,9 +714,9 @@ dependencies = [
[[package]]
name = "bytemuck"
version = "1.15.0"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5"
[[package]]
name = "byteorder"
@@ -2203,7 +2203,7 @@ dependencies = [
"bip39",
"console_error_panic_hook",
"js-sys",
"serde-wasm-bindgen",
"serde-wasm-bindgen 0.6.5",
"thiserror",
"wasm-bindgen",
"wasm-bindgen-futures",
@@ -2586,14 +2586,14 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "gloo-net"
version = "0.3.1"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a66b4e3c7d9ed8d315fd6b97c8b1f74a7c6ecbbc2320e65ae7ed38b7068cc620"
checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173"
dependencies = [
"futures-channel",
"futures-core",
"futures-sink",
"gloo-utils",
"gloo-utils 0.2.0",
"http 0.2.12",
"js-sys",
"pin-project",
@@ -2630,6 +2630,19 @@ dependencies = [
"web-sys",
]
[[package]]
name = "gloo-utils"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa"
dependencies = [
"js-sys",
"serde",
"serde_json",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "group"
version = "0.13.0"
@@ -3677,7 +3690,7 @@ dependencies = [
"nym-socks5-requests",
"rand 0.7.3",
"serde",
"serde-wasm-bindgen",
"serde-wasm-bindgen 0.6.5",
"thiserror",
"tokio",
"tsify",
@@ -4312,7 +4325,7 @@ dependencies = [
"nym-node-tester-wasm",
"rand 0.7.3",
"serde",
"serde-wasm-bindgen",
"serde-wasm-bindgen 0.6.5",
"serde_json",
"thiserror",
"tsify",
@@ -4576,7 +4589,7 @@ dependencies = [
[[package]]
name = "nym-gateway"
version = "1.1.37"
version = "1.1.36"
dependencies = [
"anyhow",
"async-trait",
@@ -4635,7 +4648,7 @@ version = "0.1.0"
dependencies = [
"futures",
"getrandom 0.2.15",
"gloo-utils",
"gloo-utils 0.2.0",
"log",
"nym-bandwidth-controller",
"nym-credential-storage",
@@ -4702,6 +4715,7 @@ name = "nym-http-api-client"
version = "0.1.0"
dependencies = [
"async-trait",
"http 1.1.0",
"reqwest 0.12.4",
"serde",
"serde_json",
@@ -4770,6 +4784,7 @@ dependencies = [
"rand 0.8.5",
"serde",
"thiserror",
"time",
"tokio",
"tokio-util",
]
@@ -5138,6 +5153,7 @@ version = "0.1.0"
dependencies = [
"async-trait",
"base64 0.21.7",
"celes",
"humantime 2.1.0",
"humantime-serde",
"nym-bin-common",
@@ -5183,7 +5199,7 @@ dependencies = [
"nym-node-tester-utils",
"rand 0.7.3",
"serde",
"serde-wasm-bindgen",
"serde-wasm-bindgen 0.6.5",
"thiserror",
"tokio",
"tsify",
@@ -5266,7 +5282,7 @@ dependencies = [
"dotenvy",
"futures",
"hex",
"http 0.2.12",
"http 1.1.0",
"httpcodec",
"log",
"nym-bandwidth-controller",
@@ -5843,9 +5859,7 @@ dependencies = [
"dashmap",
"hmac 0.12.1",
"log",
"nym-config",
"nym-crypto",
"nym-network-defaults",
"rand 0.7.3",
"serde",
"serde_json",
@@ -6577,9 +6591,9 @@ checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
[[package]]
name = "psl"
version = "2.1.38"
version = "2.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a66783ea3ba6140ffd59462fa46585d7cc0797893fbf3835ad2da832319964c"
checksum = "7b320cda4ad7e8f4269fa415754418f83b38c666a5e2e99ea48825b274a373f3"
dependencies = [
"psl-types",
]
@@ -7607,6 +7621,17 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "serde-wasm-bindgen"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b"
dependencies = [
"js-sys",
"serde",
"wasm-bindgen",
]
[[package]]
name = "serde_bytes"
version = "0.11.14"
@@ -9028,9 +9053,9 @@ version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0"
dependencies = [
"gloo-utils",
"gloo-utils 0.1.7",
"serde",
"serde-wasm-bindgen",
"serde-wasm-bindgen 0.5.0",
"serde_json",
"tsify-macros",
"wasm-bindgen",
@@ -9291,6 +9316,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560"
dependencies = [
"getrandom 0.2.15",
"serde",
"wasm-bindgen",
]
@@ -9472,7 +9498,7 @@ dependencies = [
"nym-validator-client",
"rand 0.7.3",
"serde",
"serde-wasm-bindgen",
"serde-wasm-bindgen 0.6.5",
"thiserror",
"time",
"tsify",
@@ -9494,7 +9520,7 @@ dependencies = [
"js-sys",
"nym-store-cipher",
"serde",
"serde-wasm-bindgen",
"serde-wasm-bindgen 0.6.5",
"thiserror",
"wasm-bindgen",
"wasm-utils",
@@ -9520,7 +9546,7 @@ dependencies = [
"futures",
"getrandom 0.2.15",
"gloo-net",
"gloo-utils",
"gloo-utils 0.2.0",
"js-sys",
"tungstenite",
"wasm-bindgen",
@@ -10021,3 +10047,30 @@ dependencies = [
"crossbeam-utils",
"flate2",
]
[[package]]
name = "zknym-lib"
version = "0.1.0"
dependencies = [
"anyhow",
"async-trait",
"bs58 0.5.1",
"getrandom 0.2.15",
"js-sys",
"nym-bin-common",
"nym-coconut",
"nym-credentials",
"nym-crypto",
"nym-http-api-client",
"rand 0.7.3",
"reqwest 0.12.4",
"serde",
"thiserror",
"tokio",
"tsify",
"uuid 1.6.1",
"wasm-bindgen",
"wasm-utils",
"wasmtimer",
"zeroize",
]
+111 -13
View File
@@ -122,6 +122,7 @@ members = [
# "wasm/full-nym-wasm",
"wasm/mix-fetch",
"wasm/node-tester",
"wasm/zknym-lib",
]
default-members = [
@@ -158,46 +159,142 @@ edition = "2021"
license = "Apache-2.0"
[workspace.dependencies]
addr = "0.15.6"
aes = "0.8.1"
aes-gcm = "0.10.1"
anyhow = "1.0.71"
argon2 = "0.5.0"
async-trait = "0.1.68"
axum = "0.7.5"
axum-extra = "0.9.3"
base64 = "0.21.4"
bs58 = "0.5.0"
bincode = "1.3.3"
bip39 = { version = "2.0.0", features = ["zeroize"] }
clap = "4.4.7"
bitvec = "1.0.0"
blake3 = "1.3.1"
bs58 = "0.5.0"
bytecodec = "0.4.15"
bytes = "1.5.0"
cargo_metadata = "0.18.1"
celes = "2.4.0"
cfg-if = "1.0.0"
chacha20 = "0.9.0"
chacha20poly1305 = "0.10.1"
chrono = "0.4.31"
cipher = "0.4.3"
clap = "4.4.7"
clap_complete = "4.0"
clap_complete_fig = "4.0"
colored = "2.0"
comfy-table = "6.0.0"
console-subscriber = "0.1.1"
console_error_panic_hook = "0.1"
const-str = "0.5.6"
const_format = "0.2.32"
criterion = "0.4"
csv = "1.3.0"
ctr = "0.9.1"
cupid = "0.6.1"
curve25519-dalek = "3.2"
dashmap = "5.5.3"
defguard_wireguard_rs = { git = "https://github.com/neacsu/wireguard-rs.git", rev = "c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed" }
doc-comment = "0.3"
dotenvy = "0.15.6"
ecdsa = "0.16"
ed25519-dalek = "1.0"
etherparse = "0.13.0"
eyre = "0.6.9"
flate2 = "1.0.28"
futures = "0.3.28"
generic-array = "0.14.7"
getrandom = "0.2.10"
getset = "0.1.1"
handlebars = "3.5.5"
headers = "0.4.0"
hex = "0.4.3"
hex-literal = "0.3.3"
hkdf = "0.12.3"
hmac = "0.12.1"
httpcodec = "0.2.3"
humantime = "2.1.0"
humantime-serde = "1.1.1"
http = "1"
hyper = "1.3.1"
indexed_db_futures = "0.3.0"
inquire = "0.6.2"
ip_network = "0.4.1"
isocountry = "0.3.2"
k256 = "0.13"
lazy_static = "1.4.0"
ledger-transport = "0.10.0"
ledger-transport-hid = "0.10.0"
log = "0.4"
maxminddb = "0.23.0"
mime = "0.3.17"
nix = "0.27.1"
notify = "5.1.0"
okapi = "0.7.0"
once_cell = "1.7.2"
opentelemetry = "0.19.0"
opentelemetry-jaeger = "0.18.0"
parking_lot = "0.12.1"
pem = "0.8"
pin-project = "1.0"
pretty_env_logger = "0.4.0"
publicsuffix = "2.2.3"
quote = "1"
rand = "0.8.5"
rand-07 = "0.7.3"
rand_chacha_02 = "0.2"
rand_core = "0.6.3"
rand_distr = "0.3"
rand_pcg = "0.3.1"
rand_seeder = "0.2.3"
rayon = "1.5.1"
regex = "1.8.4"
reqwest = { version = "0.12.4", default-features = false }
rocket = "0.5.0"
rocket_cors = "0.6.0"
rocket_okapi = "0.8.0"
safer-ffi = "0.1.4"
schemars = "0.8.1"
serde = "1.0.152"
serde_bytes = "0.11.6"
serde_derive = "1.0"
serde_json = "1.0.91"
serde_repr = "0.1"
serde_with = "3.4.0"
serde_yaml = "0.9.25"
si-scale = "0.2.2"
sphinx-packet = "0.1.0"
sqlx = "0.6.3"
strum = "0.25"
subtle-encoding = "0.5"
syn = "1"
tap = "1.0.1"
time = "0.3.30"
tar = "0.4.40"
tempfile = "3.5.0"
thiserror = "1.0.48"
time = "0.3.30"
tokio = "1.33.0"
tokio-util = "0.7.10"
tokio-stream = "0.1.14"
tokio-test = "0.4.2"
tokio-tungstenite = { version = "0.20.1" }
tokio-util = "0.7.10"
tower = "0.4.13"
tower-http = "0.5.2"
tracing = "0.1.37"
tungstenite = { version = "0.20.1", default-features = false }
tracing-opentelemetry = "0.19.0"
tracing-subscriber = "0.3.16"
tracing-tree = "0.2.2"
ts-rs = "7.0.0"
tungstenite = { version = "0.20.1", default-features = false }
url = "2.4"
utoipa = "4.2.0"
utoipa-swagger-ui = "6.0.0"
url = "2.4"
vergen = { version = "=8.2.6", default-features = false }
walkdir = "2"
wasm-bindgen-test = "0.3.36"
zeroize = "1.6.0"
prometheus = { version = "0.13.0" }
@@ -209,7 +306,6 @@ bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch = "feature/g
group = "0.13.0"
ff = "0.13.0"
# cosmwasm-related
cosmwasm-derive = "=1.4.3"
cosmwasm-schema = "=1.4.3"
@@ -237,14 +333,16 @@ tendermint-rpc = "0.34" # same version as used by cosmrs
prost = "0.12"
# wasm-related dependencies
gloo-utils = "0.1.7"
js-sys = "0.3.63"
serde-wasm-bindgen = "0.5.0"
gloo-utils = "0.2.0"
gloo-net = "0.5.0"
js-sys = "0.3.69"
serde-wasm-bindgen = "0.6.5"
tsify = "0.4.5"
wasm-bindgen = "0.2.86"
wasm-bindgen-futures = "0.4.37"
wasm-bindgen = "0.2.92"
wasm-bindgen-futures = "0.4.39"
wasmtimer = "0.2.0"
web-sys = "0.3.63"
web-sys = "0.3.69"
# Profile settings for individual crates
+2 -1
View File
@@ -105,6 +105,7 @@ sdk-wasm-build:
$(MAKE) -C wasm/client
$(MAKE) -C wasm/node-tester
$(MAKE) -C wasm/mix-fetch
$(MAKE) -C wasm/zknym-lib
#$(MAKE) -C wasm/full-nym-wasm
# run this from npm/yarn to ensure tools are in the path, e.g. yarn build:sdk from root of repo
@@ -115,7 +116,7 @@ sdk-typescript-build:
yarn --cwd sdk/typescript/codegen/contract-clients build
# NOTE: These targets are part of the main workspace (but not as wasm32-unknown-unknown)
WASM_CRATES = extension-storage nym-client-wasm nym-node-tester-wasm
WASM_CRATES = extension-storage nym-client-wasm nym-node-tester-wasm zknym-lib
sdk-wasm-test:
#cargo test $(addprefix -p , $(WASM_CRATES)) --target wasm32-unknown-unknown -- -Dwarnings
+1 -1
View File
@@ -29,7 +29,7 @@ rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits +
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
serde_json = { workspace = true }
thiserror = { workspace = true }
tap = "1.0.1"
tap = { workspace = true }
time = { workspace = true }
tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] } # async runtime
tokio-tungstenite = { workspace = true }
+2 -2
View File
@@ -13,9 +13,9 @@ clap = { workspace = true, features = ["cargo", "derive"] }
log = { workspace = true }
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
serde_json = { workspace = true }
tap = "1.0.1"
tap = { workspace = true }
thiserror = { workspace = true }
tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] }
tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] }
rand = "0.7.3"
time = { workspace = true }
url = { workspace = true }
+2 -2
View File
@@ -8,6 +8,6 @@ license.workspace = true
[dependencies]
futures = { workspace = true }
log = "0.4"
notify = "5.1.0"
log = { workspace = true }
notify = { workspace = true }
tokio = { workspace = true, features = ["time"] }
+10 -22
View File
@@ -8,40 +8,28 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
const-str = "0.5.6"
const-str = { workspace = true }
clap = { workspace = true, features = ["derive"] }
clap_complete = "4.0"
clap_complete_fig = "4.0"
clap_complete = { workspace = true }
clap_complete_fig = { workspace = true }
log = { workspace = true }
pretty_env_logger = "0.4.0"
pretty_env_logger = { workspace = true }
semver = "0.11"
schemars = { workspace = true, features = ["preserve_order"], optional = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, optional = true }
## tracing
tracing-subscriber = { version = "0.3.16", features = [
"env-filter",
], optional = true }
tracing-tree = { version = "0.2.2", optional = true }
opentelemetry-jaeger = { version = "0.18.0", optional = true, features = [
"rt-tokio",
"collector_client",
"isahc_collector_client",
] }
tracing-opentelemetry = { version = "0.19.0", optional = true }
tracing-subscriber = { workspace = true, features = ["env-filter"], optional = true }
tracing-tree = { workspace = true, optional = true }
opentelemetry-jaeger = { workspace = true, features = ["rt-tokio", "collector_client", "isahc_collector_client"], optional = true }
tracing-opentelemetry = { workspace = true, optional = true }
utoipa = { workspace = true, optional = true }
opentelemetry = { version = "0.19.0", optional = true, features = ["rt-tokio"] }
opentelemetry = { workspace = true, features = ["rt-tokio"], optional = true }
[build-dependencies]
vergen = { version = "=8.2.6", default-features = false, features = [
"build",
"git",
"gitcl",
"rustc",
"cargo",
] }
vergen = { workspace = true, features = ["build", "git", "gitcl", "rustc", "cargo"] }
[features]
default = []
+4 -4
View File
@@ -12,7 +12,7 @@ license.workspace = true
async-trait = { workspace = true }
base64 = "0.21.2"
bs58 = { workspace = true }
cfg-if = "1.0.0"
cfg-if = { workspace = true }
clap = { workspace = true, optional = true }
futures = { workspace = true }
humantime-serde = { workspace = true }
@@ -21,8 +21,8 @@ rand = { version = "0.7.3", features = ["wasm-bindgen"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = "0.10.6"
si-scale = "0.2.2"
tap = "1.0.1"
si-scale = { workspace = true }
tap = { workspace = true }
thiserror = { workspace = true }
url = { workspace = true, features = ["serde"] }
tokio = { workspace = true, features = ["macros"] }
@@ -108,7 +108,7 @@ version = "0.3.17"
features = ["wasm-bindgen"]
[dev-dependencies]
tempfile = "3.1.0"
tempfile = { workspace = true }
[features]
default = []
+2 -2
View File
@@ -15,8 +15,8 @@ log = { workspace = true }
thiserror = { workspace = true }
url = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
tokio = { version = "1.24.1", features = ["macros"] }
si-scale = "0.2.2"
tokio = { workspace = true, features = ["macros"] }
si-scale = { workspace = true }
time.workspace = true
# internal
@@ -10,7 +10,7 @@ license.workspace = true
[dependencies]
base64 = "0.13"
colored = "2.0"
colored = { workspace = true }
nym-coconut-dkg-common = { path = "../../cosmwasm-smart-contracts/coconut-dkg" }
nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" }
@@ -48,14 +48,14 @@ tendermint-rpc = { workspace = true }
# of cargo's feature unification we'd get `bip32/std` meaning we'd get `std::error::Error` for the re-exported (via cosmrs) bip32::Error type
bip32 = { workspace = true, default-features = false, features = ["std"] }
eyre = { version = "0.6" }
eyre = { workspace = true }
cw-utils = { workspace = true }
cw2 = { workspace = true }
cw3 = { workspace = true }
cw4 = { workspace = true }
cw-controllers = { workspace = true }
prost = { workspace = true, default-features = false }
flate2 = { version = "1.0.20" }
flate2 = { workspace = true }
sha2 = { version = "0.9.5" }
itertools = { version = "0.10" }
zeroize = { workspace = true, features = ["zeroize_derive"] }
+7 -7
View File
@@ -10,26 +10,26 @@ anyhow = { workspace = true }
base64 = "0.13.0"
bip39 = { workspace = true }
bs58 = { workspace = true }
comfy-table = "6.0.0"
cfg-if = "1.0.0"
comfy-table = { workspace = true }
cfg-if = { workspace = true }
clap = { workspace = true, features = ["derive"] }
csv = "1.3.0"
csv = { workspace = true }
cw-utils = { workspace = true }
futures = { workspace = true }
handlebars = "3.0.1"
handlebars = { workspace = true }
humantime-serde = { workspace = true }
inquire = "0.6.2"
inquire = { workspace = true }
k256 = { workspace = true, features = ["ecdsa", "sha256"] }
log = { workspace = true }
rand = {version = "0.6", features = ["std"] }
serde = { version = "1.0", features = ["derive"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
time = { workspace = true, features = ["parsing", "formatting"] }
tokio = { workspace = true, features = ["sync"]}
toml = "0.5.6"
url = { workspace = true }
tap = "1"
tap = { workspace = true }
zeroize = { workspace = true }
cosmrs = { workspace = true }
+1 -1
View File
@@ -9,7 +9,7 @@ license.workspace = true
[dependencies]
dirs = { version = "5.0.1", optional = true }
handlebars = "3.5.5"
handlebars = { workspace = true }
log = { workspace = true }
serde = { workspace = true, features = ["derive"] }
toml = "0.7.4"
@@ -11,7 +11,7 @@ repository = { workspace = true }
bs58 = { workspace = true }
cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
schemars = "0.8"
schemars = { workspace = true }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
@@ -10,5 +10,5 @@ license.workspace = true
cosmwasm-schema = { workspace = true }
cw4 = { workspace = true }
cw-controllers = { workspace = true }
schemars = "0.8"
schemars = { workspace = true }
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
@@ -14,14 +14,14 @@ cosmwasm-std = { workspace = true }
cosmwasm-schema = { workspace = true }
cw2 = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"] }
serde_repr = "0.1"
serde_repr = { workspace = true }
# we still have to preserve that import for `JsonSchema` for `Layer` type (since we can't use cw_serde macro due to custom serde impl)
schemars = "0.8"
schemars = { workspace = true }
thiserror = { workspace = true }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" }
serde-json-wasm = { workspace = true }
humantime-serde = "1.1.1"
humantime-serde = { workspace = true }
# TO CHECK WHETHER STILL NEEDED:
log = { workspace = true }
@@ -13,6 +13,6 @@ cw4 = { workspace = true }
cw-storage-plus = { workspace = true }
cosmwasm-schema = { workspace = true }
cosmwasm-std = { workspace = true }
schemars = "0.8"
schemars = { workspace = true }
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
thiserror = { workspace = true }
@@ -13,7 +13,7 @@ cosmwasm-schema = { workspace = true }
cw2 = { workspace = true, optional = true }
mixnet-contract-common = { path = "../mixnet-contract", package = "nym-mixnet-contract-common", version = "0.6.0" }
contracts-common = { path = "../contracts-common", package = "nym-contracts-common", version = "0.5.0" }
serde = { version = "1.0", features = ["derive"] }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
ts-rs = { workspace = true, optional = true}
+1 -1
View File
@@ -26,4 +26,4 @@ features = [ "rt-multi-thread", "net", "signal", "fs" ]
[build-dependencies]
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
-10
View File
@@ -11,11 +11,8 @@ use nym_validator_client::nyxd::contract_traits::{
};
use nym_validator_client::nyxd::Coin;
use std::path::PathBuf;
use std::process::exit;
use std::time::{Duration, SystemTime};
const SAFETY_BUFFER_SECS: u64 = 60; // 1 minute
pub async fn issue_credential<C>(
client: &C,
amount: Coin,
@@ -92,13 +89,6 @@ where
.as_secs();
if epoch.state.is_final() {
if let Some(finish_timestamp) = epoch.deadline {
if current_timestamp_secs + SAFETY_BUFFER_SECS >= finish_timestamp.seconds() {
info!("In the next {} minute(s), a transition will take place in the coconut system. Deposits should be halted in this time for safety reasons.", SAFETY_BUFFER_SECS / 60);
exit(0);
}
}
break;
} else if let Some(final_timestamp) = epoch.final_timestamp_secs() {
// Use 1 additional second to not start the next iteration immediately and spam get_current_epoch queries
+1 -1
View File
@@ -8,7 +8,7 @@ license.workspace = true
[dependencies]
bls12_381 = { workspace = true, default-features = false, features = ["pairings", "alloc", "experimental"] }
bincode = "1.3.3"
bincode = { workspace = true }
cosmrs = { workspace = true }
thiserror = { workspace = true }
log = { workspace = true }
@@ -155,11 +155,6 @@ impl IssuedBandwidthCredential {
})
}
pub fn randomise_signature(&mut self) {
let signature_prime = self.signature.randomise(bandwidth_credential_params());
self.signature = signature_prime.0
}
pub fn default_parameters() -> Parameters {
IssuanceBandwidthCredential::default_parameters()
}
@@ -30,6 +30,10 @@ impl<'a> From<&'a BandwidthVoucherIssuanceData> for BandwidthVoucherIssuedData {
}
impl BandwidthVoucherIssuedData {
pub fn new(value: Coin) -> Self {
BandwidthVoucherIssuedData { value }
}
pub fn value(&self) -> &Coin {
&self.value
}
+9 -9
View File
@@ -8,21 +8,21 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
aes = { version = "0.8.1", optional = true }
aes = { workspace = true, optional = true }
bs58 = { workspace = true }
blake3 = { version = "1.3.1", features = ["traits-preview"], optional = true }
ctr = { version = "0.9.1", optional = true }
blake3 = { workspace = true, features = ["traits-preview"], optional = true }
ctr = { workspace = true, optional = true }
digest = { version = "0.10.3", optional = true }
generic-array = { workspace = true, optional = true }
hkdf = { version = "0.12.3", optional = true }
hmac = { version = "0.12.1", optional = true }
cipher = { version = "0.4.3", optional = true }
hkdf = { workspace = true, optional = true }
hmac = { workspace = true, optional = true }
cipher = { workspace = true, optional = true }
x25519-dalek = { version = "1.1", optional = true }
ed25519-dalek = { version = "1.0", optional = true }
ed25519-dalek = { workspace = true, optional = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"], optional = true }
serde_bytes = { version = "0.11.6", optional = true }
serde_bytes = { workspace = true, optional = true }
serde_crate = { version = "1.0", optional = true, default_features = false, features = ["derive"], package = "serde" }
subtle-encoding = { version = "0.5", features = ["bech32-preview"]}
subtle-encoding = { workspace = true, features = ["bech32-preview"] }
thiserror = { workspace = true }
zeroize = { workspace = true, optional = true, features = ["zeroize_derive"] }
@@ -200,6 +200,14 @@ impl<'a> From<&'a PrivateKey> for PublicKey {
}
}
impl FromStr for PrivateKey {
type Err = KeyRecoveryError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
PrivateKey::from_base58_string(s)
}
}
impl PrivateKey {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
@@ -227,6 +227,14 @@ impl<'a> From<&'a PrivateKey> for PublicKey {
}
}
impl FromStr for PrivateKey {
type Err = Ed25519RecoveryError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
PrivateKey::from_base58_string(s)
}
}
impl PrivateKey {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
+5 -5
View File
@@ -8,7 +8,7 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bitvec = "1.0.0"
bitvec = { workspace = true }
# unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork
# as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm
@@ -17,13 +17,13 @@ nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common",
bs58 = { workspace = true }
lazy_static = "1.4.0"
lazy_static = { workspace = true }
rand = { version = "0.8.5", default-features = false}
rand_chacha = "0.3"
rand_core = "0.6.3"
rand_core = { workspace = true }
sha2 = "0.9"
serde = { workspace = true }
serde_derive = "1.0"
serde_derive = { workspace = true }
thiserror = { workspace = true }
zeroize = { workspace = true, features = ["zeroize_derive"] }
@@ -38,7 +38,7 @@ workspace = true
default-features = false
[dev-dependencies]
criterion = "0.4"
criterion = { workspace = true }
[[bench]]
name = "benchmarks"
+2 -2
View File
@@ -8,5 +8,5 @@ license.workspace = true
proc-macro = true
[dependencies]
syn = { version = "1", features = ["full"] }
quote = "1"
syn = { workspace = true, features = ["full"] }
quote = { workspace = true }
+1
View File
@@ -13,6 +13,7 @@ license.workspace = true
[dependencies]
async-trait = { workspace = true }
reqwest = { workspace = true, features = ["json"] }
http.workspace = true
url = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
+130 -31
View File
@@ -2,7 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
use async_trait::async_trait;
use reqwest::{IntoUrl, Response, StatusCode};
use reqwest::header::HeaderValue;
use reqwest::{RequestBuilder, Response, StatusCode};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use std::fmt::Display;
@@ -11,6 +12,8 @@ use thiserror::Error;
use tracing::warn;
use url::Url;
pub use reqwest::IntoUrl;
pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
pub type PathSegments<'a> = &'a [&'a str];
@@ -52,6 +55,88 @@ pub enum HttpClientError<E: Display = String> {
RequestTimeout,
}
pub struct ClientBuilder {
url: Url,
timeout: Option<Duration>,
custom_user_agent: bool,
reqwest_client_builder: reqwest::ClientBuilder,
}
impl ClientBuilder {
pub fn new<U, E>(url: U) -> Result<Self, HttpClientError<E>>
where
U: IntoUrl,
E: Display,
{
// a naive check: if the provided URL does not start with http(s), add that scheme
let str_url = url.as_str();
if !str_url.starts_with("http") {
let alt = format!("http://{str_url}");
warn!("the provided url ('{str_url}') does not contain scheme information. Changing it to '{alt}' ...");
// TODO: or should we maybe default to https?
Self::new(alt)
} else {
Ok(ClientBuilder {
url: url.into_url()?,
timeout: None,
custom_user_agent: false,
reqwest_client_builder: reqwest::ClientBuilder::new(),
})
}
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub fn with_reqwest_builder(mut self, reqwest_builder: reqwest::ClientBuilder) -> Self {
self.reqwest_client_builder = reqwest_builder;
self
}
pub fn with_user_agent<V>(mut self, value: V) -> Self
where
V: TryInto<HeaderValue>,
V::Error: Into<http::Error>,
{
self.custom_user_agent = true;
self.reqwest_client_builder = self.reqwest_client_builder.user_agent(value);
self
}
pub fn build<E>(self) -> Result<Client, HttpClientError<E>>
where
E: Display,
{
#[cfg(target_arch = "wasm32")]
let reqwest_client = self.reqwest_client_builder.build()?;
// TODO: we should probably be propagating the error rather than panicking,
// but that'd break bunch of things due to type changes
#[cfg(not(target_arch = "wasm32"))]
let reqwest_client = {
let mut builder = self
.reqwest_client_builder
.timeout(self.timeout.unwrap_or(DEFAULT_TIMEOUT));
if !self.custom_user_agent {
builder =
builder.user_agent(format!("nym-http-api-client/{}", env!("CARGO_PKG_VERSION")))
}
builder.build()?
};
Ok(Client {
base_url: self.url,
reqwest_client,
#[cfg(target_arch = "wasm32")]
request_timeout: self.timeout.unwrap_or(DEFAULT_TIMEOUT),
})
}
}
/// A simple extendable client wrapper for http request with extra url sanitization.
#[derive(Debug, Clone)]
pub struct Client {
@@ -65,25 +150,9 @@ pub struct Client {
impl Client {
// no timeout until https://github.com/seanmonstar/reqwest/issues/1135 is fixed
pub fn new(base_url: Url, timeout: Option<Duration>) -> Self {
#[cfg(target_arch = "wasm32")]
let reqwest_client = reqwest::Client::new();
// TODO: we should probably be propagating the error rather than panicking,
// but that'd break bunch of things due to type changes
#[cfg(not(target_arch = "wasm32"))]
let reqwest_client = reqwest::ClientBuilder::new()
.timeout(timeout.unwrap_or(DEFAULT_TIMEOUT))
.user_agent(format!("nym-http-api-client/{}", env!("CARGO_PKG_VERSION")))
.build()
.expect("Client::new()");
Client {
base_url,
reqwest_client,
#[cfg(target_arch = "wasm32")]
request_timeout: timeout.unwrap_or(DEFAULT_TIMEOUT),
}
Self::new_url::<_, String>(base_url, timeout).expect(
"we provided valid url and we were unwrapping previous construction errors anyway",
)
}
pub fn new_url<U, E>(url: U, timeout: Option<Duration>) -> Result<Self, HttpClientError<E>>
@@ -91,19 +160,21 @@ impl Client {
U: IntoUrl,
E: Display,
{
// a naive check: if the provided URL does not start with http(s), add that scheme
let str_url = url.as_str();
if !str_url.starts_with("http") {
let alt = format!("http://{str_url}");
warn!("the provided url ('{str_url}') does not contain scheme information. Changing it to '{alt}' ...");
// TODO: or should we maybe default to https?
Self::new_url(alt, timeout)
} else {
Ok(Self::new(url.into_url()?, timeout))
let builder = Self::builder(url)?;
match timeout {
Some(timeout) => builder.with_timeout(timeout).build(),
None => builder.build(),
}
}
pub fn builder<U, E>(url: U) -> Result<ClientBuilder, HttpClientError<E>>
where
U: IntoUrl,
E: Display,
{
ClientBuilder::new(url)
}
pub fn change_base_url(&mut self, new_url: Url) {
self.base_url = new_url
}
@@ -112,6 +183,19 @@ impl Client {
&self.base_url
}
pub fn create_get_request<K, V>(
&self,
path: PathSegments<'_>,
params: Params<'_, K, V>,
) -> RequestBuilder
where
K: AsRef<str>,
V: AsRef<str>,
{
let url = sanitize_url(&self.base_url, path, params);
self.reqwest_client.get(url)
}
async fn send_get_request<K, V, E>(
&self,
path: PathSegments<'_>,
@@ -142,6 +226,21 @@ impl Client {
}
}
pub fn create_post_request<B, K, V>(
&self,
path: PathSegments<'_>,
params: Params<'_, K, V>,
json_body: &B,
) -> RequestBuilder
where
B: Serialize + ?Sized,
K: AsRef<str>,
V: AsRef<str>,
{
let url = sanitize_url(&self.base_url, path, params);
self.reqwest_client.post(url).json(json_body)
}
async fn send_post_request<B, K, V, E>(
&self,
path: PathSegments<'_>,
@@ -407,7 +506,7 @@ pub fn sanitize_url<K: AsRef<str>, V: AsRef<str>>(
url
}
async fn parse_response<T, E>(res: Response, allow_empty: bool) -> Result<T, HttpClientError<E>>
pub async fn parse_response<T, E>(res: Response, allow_empty: bool) -> Result<T, HttpClientError<E>>
where
T: DeserializeOwned,
E: DeserializeOwned + Display,
+3 -3
View File
@@ -12,9 +12,9 @@ license.workspace = true
[dependencies]
axum.workspace = true
bytes = "1.5.0"
mime = "0.3.17"
bytes = { workspace = true }
mime = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
serde_yaml = "0.9.25"
serde_yaml = { workspace = true }
utoipa = { workspace = true }
+3 -2
View File
@@ -9,12 +9,13 @@ edition.workspace = true
license.workspace = true
[dependencies]
bincode = "1.3.3"
bytes = "1.5.0"
bincode = { workspace = true }
bytes = { workspace = true }
nym-bin-common = { path = "../bin-common" }
nym-sphinx = { path = "../nymsphinx" }
rand = "0.8.5"
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
time = { workspace = true }
tokio = { workspace = true, features = ["time"] }
tokio-util = { workspace = true, features = ["codec"] }
+2
View File
@@ -12,11 +12,13 @@ pub use v6::response;
pub mod codec;
pub mod v6;
pub mod v7;
// version 3: initial version
// version 4: IPv6 support
// version 5: Add severity level to info response
// version 6: Increase the available IPs
// version 7: Add signature support (for the future)
pub const CURRENT_VERSION: u8 = 6;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
+2
View File
@@ -0,0 +1,2 @@
pub mod request;
pub mod response;
+395
View File
@@ -0,0 +1,395 @@
use nym_sphinx::addressing::clients::Recipient;
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use crate::{make_bincode_serializer, IpPair, CURRENT_VERSION};
fn generate_random() -> u64 {
use rand::RngCore;
let mut rng = rand::rngs::OsRng;
rng.next_u64()
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IpPacketRequest {
pub version: u8,
pub data: IpPacketRequestData,
}
impl IpPacketRequest {
pub fn new_static_connect_request(
ips: IpPair,
reply_to: Recipient,
reply_to_hops: Option<u8>,
reply_to_avg_mix_delays: Option<f64>,
buffer_timeout: Option<u64>,
) -> (Self, u64) {
let request_id = generate_random();
(
Self {
version: CURRENT_VERSION,
data: IpPacketRequestData::StaticConnect(SignedStaticConnectRequest {
request: StaticConnectRequest {
request_id,
ips,
reply_to,
reply_to_hops,
reply_to_avg_mix_delays,
buffer_timeout,
timestamp: OffsetDateTime::now_utc(),
},
signature: None,
}),
},
request_id,
)
}
pub fn new_dynamic_connect_request(
reply_to: Recipient,
reply_to_hops: Option<u8>,
reply_to_avg_mix_delays: Option<f64>,
buffer_timeout: Option<u64>,
) -> (Self, u64) {
let request_id = generate_random();
(
Self {
version: CURRENT_VERSION,
data: IpPacketRequestData::DynamicConnect(SignedDynamicConnectRequest {
request: DynamicConnectRequest {
request_id,
reply_to,
reply_to_hops,
reply_to_avg_mix_delays,
buffer_timeout,
timestamp: OffsetDateTime::now_utc(),
},
signature: None,
}),
},
request_id,
)
}
pub fn new_disconnect_request(reply_to: Recipient) -> (Self, u64) {
let request_id = generate_random();
(
Self {
version: CURRENT_VERSION,
data: IpPacketRequestData::Disconnect(SignedDisconnectRequest {
request: DisconnectRequest {
request_id,
reply_to,
timestamp: OffsetDateTime::now_utc(),
},
signature: None,
}),
},
request_id,
)
}
pub fn new_data_request(ip_packets: bytes::Bytes) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketRequestData::Data(DataRequest { ip_packets }),
}
}
pub fn new_ping(reply_to: Recipient) -> (Self, u64) {
let request_id = generate_random();
(
Self {
version: CURRENT_VERSION,
data: IpPacketRequestData::Ping(PingRequest {
request_id,
reply_to,
timestamp: OffsetDateTime::now_utc(),
}),
},
request_id,
)
}
pub fn new_health_request(reply_to: Recipient) -> (Self, u64) {
let request_id = generate_random();
(
Self {
version: CURRENT_VERSION,
data: IpPacketRequestData::Health(HealthRequest {
request_id,
reply_to,
timestamp: OffsetDateTime::now_utc(),
}),
},
request_id,
)
}
pub fn id(&self) -> Option<u64> {
match &self.data {
IpPacketRequestData::StaticConnect(request) => Some(request.request.request_id),
IpPacketRequestData::DynamicConnect(request) => Some(request.request.request_id),
IpPacketRequestData::Disconnect(request) => Some(request.request.request_id),
IpPacketRequestData::Data(_) => None,
IpPacketRequestData::Ping(request) => Some(request.request_id),
IpPacketRequestData::Health(request) => Some(request.request_id),
}
}
pub fn recipient(&self) -> Option<&Recipient> {
match &self.data {
IpPacketRequestData::StaticConnect(request) => Some(&request.request.reply_to),
IpPacketRequestData::DynamicConnect(request) => Some(&request.request.reply_to),
IpPacketRequestData::Disconnect(request) => Some(&request.request.reply_to),
IpPacketRequestData::Data(_) => None,
IpPacketRequestData::Ping(request) => Some(&request.reply_to),
IpPacketRequestData::Health(request) => Some(&request.reply_to),
}
}
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
pub fn from_reconstructed_message(
message: &nym_sphinx::receiver::ReconstructedMessage,
) -> Result<Self, bincode::Error> {
use bincode::Options;
make_bincode_serializer().deserialize(&message.message)
}
}
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum IpPacketRequestData {
StaticConnect(SignedStaticConnectRequest),
DynamicConnect(SignedDynamicConnectRequest),
Disconnect(SignedDisconnectRequest),
Data(DataRequest),
Ping(PingRequest),
Health(HealthRequest),
}
impl IpPacketRequestData {
pub fn add_signature(&mut self, signature: Vec<u8>) -> Option<Vec<u8>> {
match self {
IpPacketRequestData::StaticConnect(request) => {
request.signature = Some(signature);
request.signature.clone()
}
IpPacketRequestData::DynamicConnect(request) => {
request.signature = Some(signature);
request.signature.clone()
}
IpPacketRequestData::Disconnect(request) => {
request.signature = Some(signature);
request.signature.clone()
}
IpPacketRequestData::Data(_)
| IpPacketRequestData::Ping(_)
| IpPacketRequestData::Health(_) => None,
}
}
}
// A static connect request is when the client provides the internal IP address it will use on the
// ip packet router.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct StaticConnectRequest {
pub request_id: u64,
pub ips: IpPair,
// The nym-address the response should be sent back to
pub reply_to: Recipient,
// The number of mix node hops that responses should take, in addition to the entry and exit
// node. Zero means only client -> entry -> exit -> client.
pub reply_to_hops: Option<u8>,
// The average delay at each mix node, in milliseconds. Currently this is not supported by the
// ip packet router.
pub reply_to_avg_mix_delays: Option<f64>,
// The maximum time in milliseconds the IPR should wait when filling up a mix packet
// with ip packets.
pub buffer_timeout: Option<u64>,
// Timestamp of when the request was sent by the client.
pub timestamp: OffsetDateTime,
}
impl StaticConnectRequest {
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct SignedStaticConnectRequest {
pub request: StaticConnectRequest,
pub signature: Option<Vec<u8>>,
}
// A dynamic connect request is when the client does not provide the internal IP address it will use
// on the ip packet router, and instead requests one to be assigned to it.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct DynamicConnectRequest {
pub request_id: u64,
// The nym-address the response should be sent back to
pub reply_to: Recipient,
// The number of mix node hops that responses should take, in addition to the entry and exit
// node. Zero means only client -> entry -> exit -> client.
pub reply_to_hops: Option<u8>,
// The average delay at each mix node, in milliseconds. Currently this is not supported by the
// ip packet router.
pub reply_to_avg_mix_delays: Option<f64>,
// The maximum time in milliseconds the IPR should wait when filling up a mix packet
// with ip packets.
pub buffer_timeout: Option<u64>,
// Timestamp of when the request was sent by the client.
pub timestamp: OffsetDateTime,
}
impl DynamicConnectRequest {
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct SignedDynamicConnectRequest {
pub request: DynamicConnectRequest,
pub signature: Option<Vec<u8>>,
}
// A disconnect request is when the client wants to disconnect from the ip packet router and free
// up the allocated IP address.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct DisconnectRequest {
pub request_id: u64,
// The nym-address the response should be sent back to
pub reply_to: Recipient,
// Timestamp of when the request was sent by the client.
pub timestamp: OffsetDateTime,
}
impl DisconnectRequest {
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct SignedDisconnectRequest {
pub request: DisconnectRequest,
pub signature: Option<Vec<u8>>,
}
// A data request is when the client wants to send an IP packet to a destination.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct DataRequest {
pub ip_packets: bytes::Bytes,
}
// A ping request is when the client wants to check if the ip packet router is still alive.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct PingRequest {
pub request_id: u64,
// The nym-address the response should be sent back to
pub reply_to: Recipient,
// Timestamp of when the request was sent by the client.
pub timestamp: OffsetDateTime,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct HealthRequest {
pub request_id: u64,
// The nym-address the response should be sent back to
pub reply_to: Recipient,
// Timestamp of when the request was sent by the client.
pub timestamp: OffsetDateTime,
}
#[cfg(test)]
mod tests {
use super::*;
use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
#[test]
fn check_size_of_request() {
let connect = IpPacketRequest {
version: 4,
data: IpPacketRequestData::StaticConnect(
SignedStaticConnectRequest {
request: StaticConnectRequest {
request_id: 123,
ips: IpPair::new(Ipv4Addr::from_str("10.0.0.1").unwrap(), Ipv6Addr::from_str("2001:db8:a160::1").unwrap()),
reply_to: Recipient::try_from_base58_string("D1rrpsysCGCYXy9saP8y3kmNpGtJZUXN9SvFoUcqAsM9.9Ssso1ea5NfkbMASdiseDSjTN1fSWda5SgEVjdSN4CvV@GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN").unwrap(),
reply_to_hops: None,
reply_to_avg_mix_delays: None,
buffer_timeout: None,
timestamp: OffsetDateTime::now_utc(),
},
signature: None,
}
),
};
assert_eq!(connect.to_bytes().unwrap().len(), 139);
}
#[test]
fn check_size_of_data() {
let data = IpPacketRequest {
version: 4,
data: IpPacketRequestData::Data(DataRequest {
ip_packets: bytes::Bytes::from(vec![1u8; 32]),
}),
};
assert_eq!(data.to_bytes().unwrap().len(), 35);
}
#[test]
fn serialize_and_deserialize_data_request() {
let data = IpPacketRequest {
version: 4,
data: IpPacketRequestData::Data(DataRequest {
ip_packets: bytes::Bytes::from(vec![1, 2, 4, 2, 5]),
}),
};
let serialized = data.to_bytes().unwrap();
let deserialized = IpPacketRequest::from_reconstructed_message(
&nym_sphinx::receiver::ReconstructedMessage {
message: serialized,
sender_tag: None,
},
)
.unwrap();
assert_eq!(deserialized.version, 4);
assert_eq!(
deserialized.data,
IpPacketRequestData::Data(DataRequest {
ip_packets: bytes::Bytes::from(vec![1, 2, 4, 2, 5]),
})
);
}
}
@@ -0,0 +1,410 @@
use nym_sphinx::addressing::clients::Recipient;
use serde::{Deserialize, Serialize};
use crate::{make_bincode_serializer, IpPair, CURRENT_VERSION};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IpPacketResponse {
pub version: u8,
pub data: IpPacketResponseData,
}
impl IpPacketResponse {
pub fn new_static_connect_success(request_id: u64, reply_to: Recipient) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
request_id,
reply_to,
reply: StaticConnectResponseReply::Success,
}),
}
}
pub fn new_static_connect_failure(
request_id: u64,
reply_to: Recipient,
reason: StaticConnectFailureReason,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::StaticConnect(StaticConnectResponse {
request_id,
reply_to,
reply: StaticConnectResponseReply::Failure(reason),
}),
}
}
pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ips: IpPair) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
request_id,
reply_to,
reply: DynamicConnectResponseReply::Success(DynamicConnectSuccess { ips }),
}),
}
}
pub fn new_dynamic_connect_failure(
request_id: u64,
reply_to: Recipient,
reason: DynamicConnectFailureReason,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse {
request_id,
reply_to,
reply: DynamicConnectResponseReply::Failure(reason),
}),
}
}
pub fn new_disconnect_success(request_id: u64, reply_to: Recipient) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Disconnect(DisconnectResponse {
request_id,
reply_to,
reply: DisconnectResponseReply::Success,
}),
}
}
pub fn new_disconnect_failure(
request_id: u64,
reply_to: Recipient,
reason: DisconnectFailureReason,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Disconnect(DisconnectResponse {
request_id,
reply_to,
reply: DisconnectResponseReply::Failure(reason),
}),
}
}
pub fn new_unrequested_disconnect(
reply_to: Recipient,
reason: UnrequestedDisconnectReason,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::UnrequestedDisconnect(UnrequestedDisconnect {
reply_to,
reason,
}),
}
}
pub fn new_ip_packet(ip_packet: bytes::Bytes) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Data(DataResponse { ip_packet }),
}
}
pub fn new_version_mismatch(
request_id: u64,
reply_to: Recipient,
request_version: u8,
our_version: u8,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Info(InfoResponse {
request_id,
reply_to,
reply: InfoResponseReply::VersionMismatch {
request_version,
response_version: our_version,
},
level: InfoLevel::Error,
}),
}
}
pub fn new_data_info_response(
reply_to: Recipient,
reply: InfoResponseReply,
level: InfoLevel,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Info(InfoResponse {
request_id: 0,
reply_to,
reply,
level,
}),
}
}
pub fn new_pong(request_id: u64, reply_to: Recipient) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Pong(PongResponse {
request_id,
reply_to,
}),
}
}
pub fn new_health_response(
request_id: u64,
reply_to: Recipient,
build_info: nym_bin_common::build_information::BinaryBuildInformationOwned,
routable: Option<bool>,
) -> Self {
Self {
version: CURRENT_VERSION,
data: IpPacketResponseData::Health(HealthResponse {
request_id,
reply_to,
reply: HealthResponseReply {
build_info,
routable,
},
}),
}
}
pub fn id(&self) -> Option<u64> {
match &self.data {
IpPacketResponseData::StaticConnect(response) => Some(response.request_id),
IpPacketResponseData::DynamicConnect(response) => Some(response.request_id),
IpPacketResponseData::Disconnect(response) => Some(response.request_id),
IpPacketResponseData::UnrequestedDisconnect(_) => None,
IpPacketResponseData::Data(_) => None,
IpPacketResponseData::Pong(response) => Some(response.request_id),
IpPacketResponseData::Health(response) => Some(response.request_id),
IpPacketResponseData::Info(response) => Some(response.request_id),
}
}
pub fn recipient(&self) -> Option<&Recipient> {
match &self.data {
IpPacketResponseData::StaticConnect(response) => Some(&response.reply_to),
IpPacketResponseData::DynamicConnect(response) => Some(&response.reply_to),
IpPacketResponseData::Disconnect(response) => Some(&response.reply_to),
IpPacketResponseData::UnrequestedDisconnect(response) => Some(&response.reply_to),
IpPacketResponseData::Data(_) => None,
IpPacketResponseData::Pong(response) => Some(&response.reply_to),
IpPacketResponseData::Health(response) => Some(&response.reply_to),
IpPacketResponseData::Info(response) => Some(&response.reply_to),
}
}
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
pub fn from_reconstructed_message(
message: &nym_sphinx::receiver::ReconstructedMessage,
) -> Result<Self, bincode::Error> {
use bincode::Options;
make_bincode_serializer().deserialize(&message.message)
}
}
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum IpPacketResponseData {
// Response for a static connect request
StaticConnect(StaticConnectResponse),
// Response for a dynamic connect request
DynamicConnect(DynamicConnectResponse),
// Response for a disconnect initiqated by the client
Disconnect(DisconnectResponse),
// Message from the server that the client got disconnected without the client initiating it
UnrequestedDisconnect(UnrequestedDisconnect),
// Response to a data request
Data(DataResponse),
// Response to ping request
Pong(PongResponse),
// Response for a health request
Health(HealthResponse),
// Info response. This can be anything from informative messages to errors
Info(InfoResponse),
}
impl IpPacketResponseData {
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StaticConnectResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: StaticConnectResponseReply,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum StaticConnectResponseReply {
Success,
Failure(StaticConnectFailureReason),
}
impl StaticConnectResponseReply {
pub fn is_success(&self) -> bool {
match self {
StaticConnectResponseReply::Success => true,
StaticConnectResponseReply::Failure(_) => false,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
pub enum StaticConnectFailureReason {
#[error("requested ip address is already in use")]
RequestedIpAlreadyInUse,
#[error("requested nym-address is already in use")]
RequestedNymAddressAlreadyInUse,
#[error("{0}")]
Other(String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DynamicConnectResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: DynamicConnectResponseReply,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum DynamicConnectResponseReply {
Success(DynamicConnectSuccess),
Failure(DynamicConnectFailureReason),
}
impl DynamicConnectResponseReply {
pub fn is_success(&self) -> bool {
match self {
DynamicConnectResponseReply::Success(_) => true,
DynamicConnectResponseReply::Failure(_) => false,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DynamicConnectSuccess {
pub ips: IpPair,
}
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
pub enum DynamicConnectFailureReason {
#[error("requested nym-address is already in use")]
RequestedNymAddressAlreadyInUse,
#[error("no available ip address")]
NoAvailableIp,
#[error("{0}")]
Other(String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DisconnectResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: DisconnectResponseReply,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum DisconnectResponseReply {
Success,
Failure(DisconnectFailureReason),
}
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
pub enum DisconnectFailureReason {
#[error("requested nym-address is not currently connected")]
RequestedNymAddressNotConnected,
#[error("{0}")]
Other(String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct UnrequestedDisconnect {
pub reply_to: Recipient,
pub reason: UnrequestedDisconnectReason,
}
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
pub enum UnrequestedDisconnectReason {
#[error("client mixnet traffic timeout")]
ClientMixnetTrafficTimeout,
#[error("client tun traffic timeout")]
ClientTunTrafficTimeout,
#[error("{0}")]
Other(String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DataResponse {
pub ip_packet: bytes::Bytes,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PongResponse {
pub request_id: u64,
pub reply_to: Recipient,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct HealthResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: HealthResponseReply,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct HealthResponseReply {
// Return the binary build information of the IPR
pub build_info: nym_bin_common::build_information::BinaryBuildInformationOwned,
// Return if the IPR has performed a successful routing test.
pub routable: Option<bool>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct InfoResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: InfoResponseReply,
pub level: InfoLevel,
}
#[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)]
pub enum InfoResponseReply {
#[error("{msg}")]
Generic { msg: String },
#[error(
"version mismatch: response is v{request_version} and response is v{response_version}"
)]
VersionMismatch {
request_version: u8,
response_version: u8,
},
#[error("destination failed exit policy filter check: {dst}")]
ExitPolicyFilterCheckFailed { dst: String },
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum InfoLevel {
Info,
Warn,
Error,
}
+3 -3
View File
@@ -7,8 +7,8 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bip32 = "0.5.1"
bip32 = { workspace = true }
k256 = { workspace = true }
ledger-transport = "0.10.0"
ledger-transport-hid = "0.10.0"
ledger-transport = { workspace = true }
ledger-transport-hid = { workspace = true }
thiserror = { workspace = true }
+2 -2
View File
@@ -8,7 +8,7 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bytes = "1.0"
bytes = { workspace = true }
futures = { workspace = true }
humantime-serde = { workspace = true }
log = { workspace = true }
@@ -38,4 +38,4 @@ nym-task = { path = "../task" }
nym-validator-client = { path = "../client-libs/validator-client" }
nym-bin-common = { path = "../bin-common" }
nym-metrics = { path = "../nym-metrics" }
nym-node-http-api = { path = "../../nym-node/nym-node-http-api" }
nym-node-http-api = { path = "../../nym-node/nym-node-http-api" }
+1 -1
View File
@@ -10,7 +10,7 @@ repository.workspace = true
[dependencies]
cfg-if = { workspace = true }
dotenvy = { workspace = true }
hex-literal = "0.3.3"
hex-literal = { workspace = true }
log = { workspace = true }
once_cell = { workspace = true }
schemars = { workspace = true, features = ["preserve_order"] }
+1 -1
View File
@@ -8,7 +8,7 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio-stream = "0.1.11" # this one seems to be a thing until `Stream` trait is stabilised in stdlib
tokio-stream = { workspace = true } # this one seems to be a thing until `Stream` trait is stabilised in stdlib
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
workspace = true
+1 -1
View File
@@ -14,4 +14,4 @@ license.workspace = true
prometheus = { workspace = true }
log = { workspace = true }
dashmap = { workspace = true }
lazy_static = "1.4"
lazy_static = { workspace = true }
+3 -3
View File
@@ -14,7 +14,7 @@ digest = "0.9"
rand = "0.8"
thiserror = { workspace = true }
serde = { workspace = true }
serde_derive = "1.0"
serde_derive = { workspace = true }
bs58 = { workspace = true }
sha2 = "0.9"
zeroize = { workspace = true, optional = true }
@@ -31,8 +31,8 @@ workspace = true
default-features = false
[dev-dependencies]
criterion = { version="0.4", features=["html_reports"] }
doc-comment = "0.3"
criterion = { workspace = true, features = ["html_reports"] }
doc-comment = { workspace = true }
rand_chacha = "0.3"
[[bench]]
+1 -1
View File
@@ -10,7 +10,7 @@ repository = { workspace = true }
[dependencies]
log = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
rand_distr = "0.3"
rand_distr = { workspace = true }
thiserror = { workspace = true }
nym-sphinx-acknowledgements = { path = "acknowledgements" }
+2 -2
View File
@@ -10,9 +10,9 @@ repository = { workspace = true }
[dependencies]
nym-crypto = { path = "../../crypto", features = ["asymmetric"] } # all addresses are expressed in terms on their crypto keys
nym-sphinx-types = { path = "../types", features = ["sphinx"] } # we need to be able to refer to some types defined inside sphinx crate
serde = "1.0" # implementing serialization/deserialization for some types, like `Recipient`
serde = { workspace = true } # implementing serialization/deserialization for some types, like `Recipient`
thiserror = { workspace = true }
[dev-dependencies]
rand = "0.7"
nym-crypto = { path = "../../crypto", features = ["rand"] }
nym-crypto = { path = "../../crypto", features = ["rand"] }
+1 -1
View File
@@ -8,7 +8,7 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
bytes = "1.0"
bytes = { workspace = true }
tokio-util = { workspace = true, features = ["codec"] }
thiserror = { workspace = true }
+1 -1
View File
@@ -8,7 +8,7 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
sphinx-packet = { version = "0.1.0", optional = true }
sphinx-packet = { workspace = true, optional = true }
nym-outfox = { path = "../../../nym-outfox", optional = true }
thiserror = { workspace = true }
+5 -5
View File
@@ -12,11 +12,11 @@ license.workspace = true
[dependencies]
async-trait.workspace = true
const_format = "0.2.32"
const_format = { workspace = true }
cosmrs.workspace = true
eyre = "0.6.9"
eyre = { workspace = true }
futures.workspace = true
humantime = "2.1.0"
humantime = { workspace = true }
sha2 = "0.10.8"
serde = { workspace = true, features = ["derive"] }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate", "time"] }
@@ -25,8 +25,8 @@ tendermint-rpc = { workspace = true, features = ["websocket-client", "http-clien
thiserror.workspace = true
time = { workspace = true }
tokio = { workspace = true, features = ["full"] }
tokio-stream = "0.1.14"
tokio-util = { version = "0.7.10", features = ["rt"] }
tokio-stream = { workspace = true }
tokio-util = { workspace = true, features = ["rt"] }
tracing.workspace = true
url.workspace = true
+1 -1
View File
@@ -8,4 +8,4 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
pem = "0.8"
pem = { workspace = true }
+3 -3
View File
@@ -11,14 +11,14 @@ anyhow = { workspace = true }
dirs = "4.0"
futures = { workspace = true }
log = { workspace = true }
pin-project = "1.0"
pin-project = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
reqwest = { workspace = true }
schemars = { workspace = true, features = ["preserve_order"] }
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
tap = "1.0.1"
tap = { workspace = true }
thiserror = { workspace = true }
tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] }
tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] }
url = { workspace = true }
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
+2 -2
View File
@@ -8,7 +8,7 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bytes = "1.0"
bytes = { workspace = true }
tokio = { workspace = true, features = [ "net", "io-util", "sync", "macros", "time", "rt-multi-thread" ] }
tokio-util = { workspace = true, features = [ "io" ] } # reason for getting this guy is to to able to port to tokio 1.X more quickly by being able to use
# their `read_buf` [from the util crate] replacement rather than having to rethink/reimplement `AvailableReader` with the new AsyncRead trait definition.
@@ -22,4 +22,4 @@ nym-socks5-requests = { path = "../requests" }
nym-task = { path = "../../task" }
[dev-dependencies]
tokio-test = "0.4.2"
tokio-test = { workspace = true }
+1 -1
View File
@@ -8,7 +8,7 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
bincode = "1.3.3"
bincode = { workspace = true }
log = { workspace = true }
nym-exit-policy = { path = "../../../common/exit-policy"}
nym-service-providers-common = { path = "../../../service-providers/common" }
+3 -3
View File
@@ -13,8 +13,8 @@ license.workspace = true
async-trait = { workspace = true }
log = { workspace = true }
reqwest = { workspace = true, features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "chrono"]}
thiserror = { workspace = true }
tokio = { version = "1.24.1", features = [ "time" ] }
tokio = { workspace = true, features = ["time"] }
+3 -3
View File
@@ -7,14 +7,14 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
aes-gcm = { version = "0.10.1" }
argon2 = { version = "0.5.0" }
aes-gcm = { workspace = true }
argon2 = { workspace = true }
generic-array = { workspace = true, features = ["zeroize"] }
rand = "0.8.5"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, optional = true }
thiserror = { workspace = true }
zeroize = { version = "1.6.0", features = ["zeroize_derive"] }
zeroize = { workspace = true, features = ["zeroize_derive"] }
[target.'cfg(target_env = "wasm32-unknown-unknown")'.dependencies]
getrandom = { version = "0.2", features = ["js"] }
+1 -1
View File
@@ -13,7 +13,7 @@ license.workspace = true
[dependencies]
thiserror.workspace = true
tokio = { workspace = true, features = ["rt-multi-thread", "net", "io-util", "time", "sync", "macros"] }
etherparse = "0.13.0"
etherparse = { workspace = true }
log.workspace = true
nym-wireguard-types = { path = "../wireguard-types", optional = true }
+6 -6
View File
@@ -9,16 +9,16 @@ license.workspace = true
[dependencies]
base64 = "0.21.4"
eyre = "0.6.5"
hmac = "0.12.1"
eyre = { workspace = true }
hmac = { workspace = true }
itertools = "0.11"
log = { workspace = true }
reqwest = { workspace = true }
schemars = "0.8"
serde = { version = "1.0", features = ["derive"] }
schemars = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = "0.10.8"
strum = { version = "0.25", features = ["derive"] }
strum = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
ts-rs = { workspace = true }
url = { workspace = true }
@@ -34,7 +34,7 @@ nym-config = { path = "../../common/config" }
nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] }
[dev-dependencies]
tempfile = "3.3.0"
tempfile = { workspace = true }
[features]
default = []
-22
View File
@@ -171,25 +171,3 @@ impl fmt::Display for GatewayIpPacketRouterDetails {
writeln!(f, "\taddress: {}", self.address)
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct GatewayWireguardDetails {
pub enabled: bool,
pub announced_port: u16,
pub private_network_prefix: u8,
}
impl fmt::Display for GatewayWireguardDetails {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "wireguard:")?;
writeln!(f, "\tenabled: {}", self.enabled)?;
writeln!(f, "\tannounced_port: {}", self.announced_port)?;
writeln!(
f,
"\tprivate_network_prefix: {}",
self.private_network_prefix
)
}
}
+2 -2
View File
@@ -41,7 +41,7 @@ wasm-storage = { path = "../storage" }
# logging them with `console.error`. This is great for development, but requires
# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for
# code size when deploying.
console_error_panic_hook = { version = "0.1", optional = true }
console_error_panic_hook = { workspace = true, optional = true }
[features]
default = ["console_error_panic_hook"]
default = ["console_error_panic_hook"]
-1
View File
@@ -3,7 +3,6 @@
use crate::storage::wasm_client_traits::WasmClientStorageError;
use crate::topology::WasmTopologyError;
use js_sys::Promise;
use nym_client_core::client::base_client::storage::gateways_storage::BadGateway;
use nym_client_core::error::ClientCoreError;
use nym_crypto::asymmetric::identity::Ed25519RecoveryError;
+1 -14
View File
@@ -32,17 +32,4 @@ pub use nym_validator_client::{DirectSigningReqwestRpcNyxdClient, QueryReqwestRp
pub use nym_validator_client::client::IdentityKey;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[cfg(target_arch = "wasm32")]
pub fn set_panic_hook() {
// When the `console_error_panic_hook` feature is enabled, we can call the
// `set_panic_hook` function at least once during initialization, and then
// we will get better error messages if our code ever panics.
//
// For more details see
// https://github.com/rustwasm/console_error_panic_hook#readme
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
}
pub use wasm_utils::set_panic_hook;
+1 -1
View File
@@ -14,7 +14,7 @@ js-sys = { workspace = true }
wasm-bindgen = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde-wasm-bindgen = { workspace = true }
indexed_db_futures = { version = " 0.3.0"}
indexed_db_futures = { workspace = true }
thiserror = { workspace = true }
nym-store-cipher = { path = "../../store-cipher", features = ["json"] }
+2 -2
View File
@@ -12,9 +12,9 @@ futures = { workspace = true }
js-sys = { workspace = true }
wasm-bindgen = { workspace = true }
wasm-bindgen-futures = { workspace = true }
getrandom = { workspace = true, features=["js"], optional = true }
getrandom = { workspace = true, features = ["js"], optional = true }
gloo-utils = { workspace = true }
gloo-net = { version = "0.3.1", features = ["websocket"], optional = true }
gloo-net = { workspace = true, features = ["websocket"], optional = true }
#gloo-net = { path = "../../../../gloo/crates/net", features = ["websocket"], optional = true }
# we don't want entire tokio-tungstenite, tungstenite itself is just fine - we just want message and error enums
+1 -1
View File
@@ -21,7 +21,7 @@ macro_rules! wasm_error {
impl From<$struct> for js_sys::Promise {
fn from(value: $struct) -> Self {
Promise::reject(&value.into())
js_sys::Promise::reject(&value.into())
}
}
};
+12
View File
@@ -41,6 +41,18 @@ macro_rules! console_error {
($($t:tt)*) => ($crate::error(&format_args!($($t)*).to_string()))
}
#[wasm_bindgen]
pub fn set_panic_hook() {
// When the `console_error_panic_hook` feature is enabled, we can call the
// `set_panic_hook` function at least once during initialization, and then
// we will get better error messages if our code ever panics.
//
// For more details see
// https://github.com/rustwasm/console_error_panic_hook#readme
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
}
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
+1 -3
View File
@@ -17,14 +17,12 @@ log = { workspace = true }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
nym-config = { path = "../config" }
nym-crypto = { path = "../crypto", features = ["asymmetric"] }
nym-network-defaults = { path = "../network-defaults" }
# feature-specific dependencies:
## verify:
hmac = { version = "0.12.1", optional = true }
hmac = { workspace = true, optional = true }
sha2 = { version = "0.10.8", optional = true }
## openapi:
-23
View File
@@ -1,23 +0,0 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::net::{IpAddr, SocketAddr};
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct Config {
/// Socket address this node will use for binding its wireguard interface.
/// default: `0.0.0.0:51822`
pub bind_address: SocketAddr,
/// Private IP address of the wireguard gateway.
/// default: `10.1.0.1`
pub private_ip: IpAddr,
/// Port announced to external clients wishing to connect to the wireguard interface.
/// Useful in the instances where the node is behind a proxy.
pub announced_port: u16,
/// The prefix denoting the maximum number of the clients that can be connected via Wireguard.
/// The maximum value for IPv4 is 32 and for IPv6 is 128
pub private_network_prefix: u8,
}
+1 -37
View File
@@ -1,51 +1,15 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use dashmap::DashMap;
use nym_crypto::asymmetric::encryption::KeyPair;
use std::sync::Arc;
pub mod config;
pub mod error;
pub mod public_key;
pub mod registration;
pub use config::Config;
pub use error::Error;
pub use public_key::PeerPublicKey;
pub use registration::{
ClientMac, ClientMessage, ClientRegistrationResponse, GatewayClient, GatewayClientRegistry,
InitMessage, Nonce,
ClientMac, ClientMessage, ClientRegistrationResponse, GatewayClient, InitMessage, Nonce,
};
#[cfg(feature = "verify")]
pub use registration::HmacSha256;
#[derive(Clone)]
pub struct WireguardGatewayData {
config: Config,
keypair: Arc<KeyPair>,
client_registry: Arc<GatewayClientRegistry>,
}
impl WireguardGatewayData {
pub fn new(config: Config, keypair: Arc<KeyPair>) -> Self {
WireguardGatewayData {
config,
keypair,
client_registry: Arc::new(DashMap::default()),
}
}
pub fn config(&self) -> Config {
self.config
}
pub fn keypair(&self) -> &Arc<KeyPair> {
&self.keypair
}
pub fn client_registry(&self) -> &Arc<GatewayClientRegistry> {
&self.client_registry
}
}
-4
View File
@@ -24,10 +24,6 @@ impl PeerPublicKey {
pub fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
pub fn inner(&self) -> PublicKey {
self.0
}
}
impl fmt::Display for PeerPublicKey {
+4 -2
View File
@@ -12,7 +12,7 @@ use std::{fmt, ops::Deref, str::FromStr};
#[cfg(feature = "verify")]
use hmac::{Hmac, Mac};
#[cfg(feature = "verify")]
use nym_crypto::asymmetric::encryption::PrivateKey;
use nym_crypto::asymmetric::encryption::{PrivateKey, PublicKey};
#[cfg(feature = "verify")]
use sha2::Sha256;
@@ -87,7 +87,7 @@ impl GatewayClient {
#[cfg(feature = "verify")]
pub fn new(
local_secret: &PrivateKey,
remote_public: x25519_dalek::PublicKey,
remote_public: PublicKey,
private_ip: IpAddr,
nonce: u64,
) -> Self {
@@ -96,6 +96,8 @@ impl GatewayClient {
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
let remote_public = x25519_dalek::PublicKey::from(remote_public.to_bytes());
let dh = static_secret.diffie_hellman(&remote_public);
// TODO: change that to use our nym_crypto::hmac module instead
+1 -1
View File
@@ -16,7 +16,7 @@ base64 = "0.21.3"
# version mismatch with x25519-dalek/curve25519-dalek that is resolved in the
# latest commit. So pick that for now.
x25519-dalek = "2.0.0"
ip_network = "0.4.1"
ip_network = { workspace = true }
log.workspace = true
nym-network-defaults = { path = "../network-defaults" }
nym-task = { path = "../task" }
+18 -15
View File
@@ -3,37 +3,40 @@
// #![warn(clippy::expect_used)]
// #![warn(clippy::unwrap_used)]
pub mod setup;
/// Start wireguard device
#[cfg(target_os = "linux")]
pub async fn start_wireguard(
mut task_client: nym_task::TaskClient,
wireguard_data: std::sync::Arc<nym_wireguard_types::WireguardGatewayData>,
_gateway_client_registry: std::sync::Arc<
nym_wireguard_types::registration::GatewayClientRegistry,
>,
) -> Result<defguard_wireguard_rs::WGApi, Box<dyn std::error::Error + Send + Sync + 'static>> {
use base64::{prelude::BASE64_STANDARD, Engine};
use crate::setup::{peer_allowed_ips, peer_static_public_key, PRIVATE_KEY};
use defguard_wireguard_rs::{
host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi,
};
let mut peers = vec![];
for peer_client in wireguard_data.client_registry().iter() {
let mut peer = Peer::new(Key::new(peer_client.pub_key.to_bytes()));
let peer_ip_mask = IpAddrMask::new(peer_client.private_ip, 32);
peer.set_allowed_ips(vec![peer_ip_mask]);
peers.push(peer);
}
use nym_network_defaults::{WG_PORT, WG_TUN_DEVICE_ADDRESS};
let ifname = String::from("wg0");
let wgapi = WGApi::new(ifname.clone(), false)?;
wgapi.create_interface()?;
let interface_config = InterfaceConfiguration {
name: ifname.clone(),
prvkey: BASE64_STANDARD.encode(wireguard_data.keypair().private_key().to_bytes()),
address: wireguard_data.config().private_ip.to_string(),
port: wireguard_data.config().announced_port as u32,
peers,
prvkey: PRIVATE_KEY.to_string(),
address: WG_TUN_DEVICE_ADDRESS.to_string(),
port: WG_PORT as u32,
peers: vec![],
};
wgapi.configure_interface(&interface_config)?;
// wgapi.configure_peer_routing(&peers)?;
let peer = peer_static_public_key();
let mut peer = Peer::new(Key::new(peer.to_bytes()));
let peer_ip = peer_allowed_ips();
let peer_ip_mask = IpAddrMask::new(peer_ip.network_address(), peer_ip.netmask());
peer.set_allowed_ips(vec![peer_ip_mask]);
wgapi.configure_peer(&peer)?;
wgapi.configure_peer_routing(&[peer.clone()])?;
tokio::spawn(async move { task_client.recv().await });
+56
View File
@@ -0,0 +1,56 @@
use std::net::IpAddr;
use base64::{engine::general_purpose, Engine as _};
use log::info;
// The wireguard UDP listener
pub const WG_ADDRESS: &str = "0.0.0.0";
// The private key of the listener
// Corresponding public key: "WM8s8bYegwMa0TJ+xIwhk+dImk2IpDUKslDBCZPizlE="
pub(crate) const PRIVATE_KEY: &str = "AEqXrLFT4qjYq3wmX0456iv94uM6nDj5ugp6Jedcflg=";
// The AllowedIPs for the connected peer, which is one a single IP and the same as the IP that the
// peer has configured on their side.
const ALLOWED_IPS: &str = "10.1.0.2";
fn decode_base64_key(base64_key: &str) -> [u8; 32] {
general_purpose::STANDARD
.decode(base64_key)
.unwrap()
.try_into()
.unwrap()
}
pub fn server_static_private_key() -> x25519_dalek::StaticSecret {
// TODO: this is a temporary solution for development
let static_private_bytes: [u8; 32] = decode_base64_key(PRIVATE_KEY);
let static_private = x25519_dalek::StaticSecret::from(static_private_bytes);
let static_public = x25519_dalek::PublicKey::from(&static_private);
info!(
"wg public key: {}",
general_purpose::STANDARD.encode(static_public)
);
static_private
}
pub fn peer_static_public_key() -> x25519_dalek::PublicKey {
// A single static public key is used during development
// Read from NYM_PEER_PUBLIC_KEY env variable
let peer = std::env::var("NYM_PEER_PUBLIC_KEY").expect("NYM_PEER_PUBLIC_KEY must be set");
let peer_static_public_bytes: [u8; 32] = decode_base64_key(&peer);
let peer_static_public = x25519_dalek::PublicKey::from(peer_static_public_bytes);
info!(
"Adding wg peer public key: {}",
general_purpose::STANDARD.encode(peer_static_public)
);
peer_static_public
}
pub fn peer_allowed_ips() -> ip_network::IpNetwork {
let key: IpAddr = ALLOWED_IPS.parse().unwrap();
let cidr = 32u8;
ip_network::IpNetwork::new_truncate(key, cidr).unwrap()
}
+6 -3
View File
@@ -27,13 +27,15 @@
- [Maintenance](nodes/maintenance.md)
- [Manual Node Upgrade](nodes/manual-upgrade.md)
- [Automatic Node Upgrade: Nymvisor Setup and Usage](nodes/nymvisor-upgrade.md)
- [Performance Testing](testing/performance.md)
- [Node Setup](testing/node-setup.md)
- [Metrics Monitoring](testing/templates.md)
- [Performance Monitoring & Testing](testing/performance.md)
<!--- [Node Setup](testing/node-setup.md)-->
- [Gateway Probe](testing/gateway-probe.md)
- [Prometheus & Grafana](testing/prometheus-grafana.md)
- [ExploreNYM scripts](testing/explorenym-scripts.md)
<!-- - [Run in a Docker](testing/docker-monitor.md) -->
# Troubleshooting
- [VPS Setup](troubleshooting/vps-isp.md)
@@ -56,6 +58,7 @@
- [Exit Gateway](legal/exit-gateway.md)
- [Community Counsel](legal/community-counsel.md)
- [ISP List](legal/isp-list.md)
- [Jurisdictions](legal/jurisdictions.md)
- [Switzerland](legal/swiss.md)
- [United States](legal/united-states.md)
@@ -0,0 +1,8 @@
**ISP**,**Locations**,**Public IPv6**,**Crypto Payments**,**Comments**,**Last Updated**
[Flokinet](https://flokinet.is),"Netherlands, Iceland, Romania,France","Yes, needs a ticket and custom setup","yes, including XMR","Very slow customer support","05/2024"
[BitLaunch](https://bitlaunch.io),"Canada, USA, UK","No","Yes","Expensive. Digial Ocean through BitLanch has IPv6","05/2024"
[Hostinger](https://hostinger.com),"France, Lithuania, India, USA, Brazil","Yes, out of the box","Yes","Crypto payments must be done per each server monthly or annually.","05/2024"
[Linode](https://linode.com),"USA, Canada, Japan, India, Indonesia, Sweden, Netherlands, Germany, Brazil, France, UK, Australia, Italy","Yes out of the box","No, only through [BitLAunch](https://bitlaunch.io)","IPv6 sometimes need to be re-added in Networking tab, no reboot needed","05/2024"
[Cherry Servers](https://www.cherryservers.com),"Lithuania, Netherlands, USA, Singapore","No","Yes","Issued IP doesnt match the location offered by the provider.","05/2024"
[Njalla](https://nja.la),"Sweden","Yes","Yes","Privacy vandguards! The biggest VPS 45 is 3 cores only, but it works better than many “larger” servers on the market.","05/2024"
[HostSailor](https://hostsailor.com),"USA","Yes, based on ticket","Yes","The IPv6 setup needs custom research and is not documented","05/2024"
1 **ISP** **Locations** **Public IPv6** **Crypto Payments** **Comments** **Last Updated**
2 [Flokinet](https://flokinet.is) Netherlands, Iceland, Romania,France Yes, needs a ticket and custom setup yes, including XMR Very slow customer support 05/2024
3 [BitLaunch](https://bitlaunch.io) Canada, USA, UK No Yes Expensive. Digial Ocean through BitLanch has IPv6 05/2024
4 [Hostinger](https://hostinger.com) France, Lithuania, India, USA, Brazil Yes, out of the box Yes Crypto payments must be done per each server monthly or annually. 05/2024
5 [Linode](https://linode.com) USA, Canada, Japan, India, Indonesia, Sweden, Netherlands, Germany, Brazil, France, UK, Australia, Italy Yes out of the box No, only through [BitLAunch](https://bitlaunch.io) IPv6 sometimes need to be re-added in Networking tab, no reboot needed 05/2024
6 [Cherry Servers](https://www.cherryservers.com) Lithuania, Netherlands, USA, Singapore No Yes Issued IP doesn’t match the location offered by the provider. 05/2024
7 [Njalla](https://nja.la) Sweden Yes Yes Privacy vandguards! The biggest VPS 45 is 3 cores only, but it works better than many “larger” servers on the market. 05/2024
8 [HostSailor](https://hostsailor.com) USA Yes, based on ticket Yes The IPv6 setup needs custom research and is not documented 05/2024
@@ -0,0 +1,25 @@
# Where to host your `nym-node`?
```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/).
```
Inspired by a valuable resource, done by Tor community - [*Good Bad ISPs*](https://community.torproject.org/relay/community-resources/good-bad-isps/), LunarDAO squad initiated a table customised for Nym Exit Gateways operators.
This ISP list is fully managed by Nym operator community and it serves as a space to share their experience of running Exit Gateways on various Internet Service Providers (ISPs). The ISPs greatly differ in regards to services they offer as well as to their openess of hosting exit routing software.
Please share any experiences running a node like policies, complains, legal issues and solutions, discrepancy between offers and reality (bandwidth, IP range, locations) or anything regarding pricing or customer support.
If you came across any legal findings, please share them in our [list of jurisdictions](jurisdictions.md).
While we trust that Nym node operators are honest, we would like to ask everyone to do your own research.
```admonish caution title=""
To edit or add information to the ISP list, make changes to the csv file located [here](https://github.com/nymtech/nym/blob/develop/documentation/operators/src/data/isp-sheet.csv) and submit your edits as a pull request according to [this guide](add-content.md).
```
```admonish note title=""
As of now the list is quite short. When it grows, we can divide it according the localities of the listed ISPs.
```
<!--cmdrun python3 ../../../scripts/csv2md.py ../data/isp-sheet.csv -s 0 -->
+2 -2
View File
@@ -148,8 +148,8 @@ Options:
Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, false]
--wireguard-bind-address <WIREGUARD_BIND_ADDRESS>
Socket address this node will use for binding its wireguard interface. default: `0.0.0.0:51822` [env: NYMNODE_WG_BIND_ADDRESS=]
--wireguard-private-gw-ip <WIREGUARD_PRIVATE_IP>
Private IP address of the wireguard gateway. default: `10.1.0.1` [env: NYMNODE_WG_IP=]
--wireguard-private-network-ip <WIREGUARD_PRIVATE_NETWORK_IP>
Ip address of the private wireguard network. default: `10.1.0.0` [env: NYMNODE_WG_IP_NETWORK=]
--wireguard-announced-port <WIREGUARD_ANNOUNCED_PORT>
Port announced to external clients wishing to connect to the wireguard interface. Useful in the instances where the node is behind a proxy [env: NYMNODE_WG_ANNOUNCED_PORT=]
--wireguard-private-network-prefix <WIREGUARD_PRIVATE_NETWORK_PREFIX>
@@ -10,9 +10,9 @@ A suboptimally configured VPS often results in a non-functional node. To follow
You will need to rent a VPS to run your node on. One key reason for this is that your node **must be able to send TCP data using both IPv4 and IPv6** (as other nodes you talk to may use either protocol).
Tor community created a very helpful table called [*Good Bad ISPs*](https://community.torproject.org/relay/community-resources/good-bad-isps/), use that one as a guideline for your choice of ISP for your VPS.
Tor community created a very helpful table called [*Good Bad ISPs*](https://community.torproject.org/relay/community-resources/good-bad-isps/), you can use that one as a guideline for your choice of ISP for your VPS.
Currently we run [performance testing](../testing/performance.md) events to find out the best optimization. Sphinx packet decryption is CPU-bound, so more fast cores the better throughput.
**Update:** Nym community started an ISP table called [*Where to host your nym node?*](../legal/isp-list.md), check it out and add your findings!
### `nym-node`
@@ -0,0 +1,79 @@
# Nym Gateway Probe
Nym Node operators running Gateway functionality are already familiar with the monitoring tool [Harbourmaster.nymtech.net](https://harbourmaster.nymtech.net). Under the hood of Nym Harbourmaster runs iterations of `nym-gateway-probe` doing various checks and displaying the results on the interface. Operators don't have to rely on the probe ran by Nym and wait for the data to refresh. With `nym-gateway-probe` everyone can check any Gateway's networking status from their own computer at any time. In one command the client queries data from:
- [`nym-api`](https://validator.nymtech.net/api/)
- [`explorer-api`](https://explorer.nymtech.net/api/)
- [`harbour-master`](https://harbourmaster.nymtech.net/)
## Preparation
We recommend to have install all [the prerequisites](../binaries/building-nym.md#prerequisites) needed to build `nym-node` from source including latest [Rust Toolchain](https://www.rust-lang.org/tools/install).
## Installation
`nym-gateway-probe` source code is in [`nym-vpn-client`](https://github.com/nymtech/nym-vpn-client) repository. The client needs to be build from source.
1. Clone the repository:
```sh
git clone https://github.com/nymtech/nym-vpn-client.git
```
2. Build `nym-gateway-probe`:
```sh
cd nym-vpn-client
cargo build --release -p nym-gateway-probe
```
## Running the client
```sh
./target/release/nym-gateway-probe --help
```
~~~admonish collapsible=true
```
Usage: nym-gateway-probe [OPTIONS]
Options:
-c, --config-env-file <CONFIG_ENV_FILE> Path pointing to an env file describing the network
-g, --gateway <GATEWAY>
-n, --no-log
-h, --help Print help
-V, --version Print version
```
~~~
To run the client, simply add a flag `--gateway` with a targeted gateway identity key.
```sh
./target/release/nym-gateway-probe --gateway <GATEWAY_IDENTITY_KEY>
```
For any `nym-node --mode exit-gateway` the aim is to have this outcome:
```sh
{
"gateway": "<GATEWAY_IDENTITY_KEY>",
"outcome": {
"as_entry": {
"can_connect": true,
"can_route": true
},
"as_exit": {
"can_connect": true,
"can_route_ip_v4": true,
"can_route_ip_external_v4": true,
"can_route_ip_v6": true,
"can_route_ip_external_v6": true
}
}
}
```
If you don't provide a `--gateway` flag it will pick a random one to test.
@@ -1,10 +1,14 @@
# Node Setup for Performance Testing Event
```admonish info
For the moment we paused Fast and Furious `perf` environment. Nym Mainnet environment will be used for future tests, please wait for further instructions.
```
To join the [Performance testing event]({{performance_testing_webpage}}) node operators need to do proceed with the following tasks:
1. **[Sign their node]({{performance_testing_webpage}}) into the testing environment**
2. **[Configure their node](#node-configuration) for the test**
3. (*Not mandatory*) [Setup metric monitoring system](templates.md) to observe node performance at any time
3. (*Not mandatory*) [Setup metric monitoring system](performance.md#monitoring) to observe node performance at any time
## Node Configuration
@@ -1,8 +1,34 @@
# Performance Testing
# Performance Monitoring & Testing
> To configure your node for a testing event, visit [node setup page](node-setup.md).
Nym Mixnet has been running on mainnet for quite some time. There is still work to be done in order for the network to meet its full potential - mass adoption of privacy through fully distributed Mixnet.
Nym Mixnet has been running on mainnet for quite some time. There is still work to be done in order for the network to meet its full potential - mass adoption of privacy through fully distributed Mixnet.
As developers we need to be constantly improving the software. Operators have as much important role, keep their nodes up to date, monitor their performance and share their feedback with the rest of the community and core developers.
Therefore [monitoring](#monitoring) and [testing](#testing) are essential pieces of our common work. We call out all Nym operators to join the efforts!
## Monitoring
There are multiple ways to monitor performance of nodes and the machines on which they run. For the purpose of maximal privacy and decentralisation of the data - preventing Nym Mixnet from any global adversary takeover - we created these pages as a source of mutual empowerment, a place where operators can share and learn new skills to **setup metrics monitors on their own infrastructure**.
### Guides to Setup Own Metrics
A list of different scripts, templates and guides for easier navigation:
* [`nym-gateway-probe`](gateway-probe.md) - a useful tool used under the hood of [harbourmaster.nymtech.net](https://harbourmaster.nymtech.net)
* [Prometheus and Grafana](prometheus-grafana.md) self-hosted setup
* [Nym-node CPU cron service](https://gist.github.com/tommyv1987/97e939a7adf491333d686a8eaa68d4bd) - an easy bash script by Nym core developer [@tommy1987](https://gist.github.com/tommyv1987), designed to monitor a CPU usage of your node, running locally
* Nym's script [`prom_targets.py`](https://github.com/nymtech/nym/blob/develop/scripts/prom_targets.py) - a useful python program to request data from API and can be run on its own or plugged to more sophisticated flows
### Collecting Testing Metrics
For the purpose of the performance testing Nym core developers plan to run instances of Prometheus and Grafana connected to Node explorer in the house. The network overall key insights we seek from these tests are primarily internal. We're focused on pinpointing bottlenecks, capacity loads, and monitoring cpu usage on the nodes' machines.
## Testing
```admonish info
For the moment we paused Fast and Furious `perf` environment. Nym Mainnet environment will be used for future tests, please wait for further instructions.
```
Nym asks its decentralised community of operators to join a series of performance testing events in order to **increase the overall quality of the Mixnet**. The main takeaways of such event are:
@@ -21,7 +47,7 @@ Visit [Fast and Furious web page]({{performance_testing_webpage}}) and [Nym Harb
* Nym runs a paralel network environment [validator.performance.nymte.ch]({{performance_validator}}) with a chain ID `perf`
* Operators of Nym Nodes join by following easy steps on [performance testing web page]({{performance_testing_webpage}}), including simplified node authentication signature (while keep running their nodes on the mainnet)
* Once signed in, operators will be asked to swap their binary for the modified version with metrics endpoint to be able to connect their own [monitoring system](templates.md)
* Once signed in, operators will be asked to swap their binary for the modified version with metrics endpoint to be able to connect their own [monitoring system](#monitoring)
* Core node data will be fed to a unique mixnet contract for the `perf` side chain
* Nym starts a new API and start packet transition in high load through these nodes in both settings
* Nym tracks packet flow using Prometheus and Grafana
@@ -31,4 +57,5 @@ Visit [Fast and Furious web page]({{performance_testing_webpage}}) and [Nym Harb
## More Information
* What happens after the test or what operators get for participating is shared up to date on the [performance testing web page]({{performance_testing_webpage}})
* Visit our guides to [setup metrics template](templates.md) and learn how to operate them in self-custodial way
@@ -16,6 +16,8 @@ Begin with the steps listed in [*Connectivity Test and Configuration*](../nodes/
2. Checkout your VPS dashboard and make sure your IPv6-public enabled.
3. If you are able to add IPv6 address `/64` range, do it.
**Update:** Nym community started an ISP table called [*Where to host your nym node?*](../legal/isp-list.md), check it out and add your findings!
![](../images/ipv6_64.png)
4. Search or ask your ISP for additional documentation related to IPv6 routing and ask them to provide you with `IPv6 IP address` and `IPv6 IP gateway address`
+59
View File
@@ -0,0 +1,59 @@
#!/usr/bin/python3
"""CLI to display .csv files as markdown"""
import argparse
import pandas as pd
import sys
import csv
def create_table(args):
"""Imports csv and creates a table"""
file = args.file
csv = pd.read_csv(file)
if args.sort != None:
csv = csv.sort_values(csv.columns[args.sort])
if args.table:
table = csv.to_markdown(tablefmt="grid", index=args.index)
else:
table = csv.to_markdown(index=args.index)
return table
def display_file(args):
"""Display csv file as a table"""
table = create_table(args)
print(table)
def panic(msg):
"""Error message print"""
print(f"error: {msg}", file=sys.stderr)
sys.exit(-1)
def parser_main():
"""Main function initializing ArgumentParser, storing arguments and executing commands."""
# Top level parser
parser = argparse.ArgumentParser(
prog='CSV2MD',
description='''Displays .csv files in markdown''',
epilog='''Code is power!'''
)
# Parser arguments
parser.add_argument("-V","--version", action="version", version='%(prog)s 1.1.0')
parser.add_argument("file", help="path/to/file.csv")
parser.add_argument("-t","--table", default=False, action="store_true", help="output with a tabulate option for terminal reading - does not render in mdbook")
parser.add_argument("-i","--index", default=False, action="store_true", help="output with an index column")
parser.add_argument("-s","--sort", type=int, help="supply with column index to sort your output accordingly (ascending way)")
parser.set_defaults(func=display_file)
args = parser.parse_args()
try:
args.func(args)
except AttributeError as e:
msg = f"{e}.\nPlease run with --help or read the error message in case your .csv file is corrupted."
panic(msg)
if __name__ == '__main__':
parser_main()
+11 -11
View File
@@ -7,28 +7,28 @@ license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
chrono = { version = "0.4.31", features = ["serde"] }
chrono = { workspace = true, features = ["serde"] }
clap = { workspace = true, features = ["cargo", "derive"] }
dotenvy = { workspace = true }
humantime-serde = { workspace = true }
isocountry = "0.3.2"
isocountry = { workspace = true }
itertools = "0.10.3"
log = { workspace = true }
maxminddb = "0.23.0"
okapi = { version = "0.7.0", features = ["impl_json_schema"] }
pretty_env_logger = "0.4.0"
maxminddb = { workspace = true }
okapi = { workspace = true, features = ["impl_json_schema"] }
pretty_env_logger = { workspace = true }
rand = "0.8.5"
rand_pcg = "0.3.1"
rand_seeder = "0.2.3"
rand_pcg = { workspace = true }
rand_seeder = { workspace = true }
reqwest = { workspace = true }
rocket = { version = "0.5.0", features = ["json"] }
rocket_cors = { version = "0.6.0" }
rocket_okapi = { version = "0.8.0", features = ["swagger"] }
rocket = { workspace = true, features = ["json"] }
rocket_cors = { workspace = true }
rocket_okapi = { workspace = true, features = ["swagger"] }
schemars = { workspace = true, features = ["preserve_order"] }
serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
tokio = {version = "1.21.2", features = ["full"] }
tokio = { workspace = true, features = ["full"] }
nym-bin-common = { path = "../common/bin-common"}
nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" }
@@ -9,5 +9,5 @@ nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts
nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" }
nym-api-requests = { path = "../../nym-api/nym-api-requests" }
schemars = { workspace = true, features = ["preserve_order"] }
serde = { version = "1.0", features = ["derive"] }
serde = { workspace = true, features = ["derive"] }
ts-rs = { workspace = true, optional = true }
+6 -6
View File
@@ -4,7 +4,7 @@
[package]
name = "nym-gateway"
license = "GPL-3.0"
version = "1.1.37"
version = "1.1.36"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
@@ -21,7 +21,7 @@ async-trait = { workspace = true }
bip39 = { workspace = true }
bs58 = { workspace = true }
clap = { workspace = true, features = ["cargo", "derive"] }
colored = "2.0"
colored = { workspace = true }
dashmap = { workspace = true }
dirs = "4.0"
dotenvy = { workspace = true }
@@ -29,7 +29,7 @@ futures = { workspace = true }
humantime-serde = { workspace = true }
ipnetwork = "0.16"
log = { workspace = true }
once_cell = "1.7.2"
once_cell = { workspace = true }
rand = "0.7"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
@@ -40,7 +40,7 @@ sqlx = { workspace = true, features = [
"migrate",
"time"
] }
subtle-encoding = { version = "0.5", features = ["bech32-preview"] }
subtle-encoding = { workspace = true, features = ["bech32-preview"] }
thiserror = { workspace = true }
tokio = { workspace = true, features = [
"rt-multi-thread",
@@ -49,7 +49,7 @@ tokio = { workspace = true, features = [
"fs",
"time",
] }
tokio-stream = { version = "0.1.11", features = ["fs"] }
tokio-stream = { workspace = true, features = ["fs"] }
tokio-tungstenite = { workspace = true }
tokio-util = { workspace = true, features = ["codec"] }
url = { workspace = true, features = ["serde"] }
@@ -81,7 +81,7 @@ nym-ip-packet-router = { path = "../service-providers/ip-packet-router" }
nym-wireguard = { path = "../common/wireguard", optional = true }
nym-wireguard-types = { path = "../common/wireguard-types", default-features = false }
defguard_wireguard_rs = { git = "https://github.com/neacsu/wireguard-rs.git", rev = "c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed", optional = true }
defguard_wireguard_rs = { workspace = true, optional = true }
[build-dependencies]
+2 -2
View File
@@ -84,13 +84,13 @@ fn try_upgrade_v1_1_29_config(id: &str) -> Result<bool, GatewayError> {
}
fn try_upgrade_v1_1_31_config(id: &str) -> Result<bool, GatewayError> {
// explicitly load it as v1.1.35 (which is incompatible with the current, i.e. 1.1.36+)
// explicitly load it as v1.1.30 (which is incompatible with the current, i.e. 1.1.31+)
let Ok(old_config) = ConfigV1_1_31::read_from_default_path(id) else {
// if we failed to load it, there might have been nothing to upgrade
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
return Ok(false);
};
info!("It seems the gateway is using <= v1.1.35 config template.");
info!("It seems the gateway is using <= v1.1.30 config template.");
info!("It is going to get updated to the current specification.");
let updated: Config = old_config.into();
+45 -2
View File
@@ -11,7 +11,7 @@ use nym_config::{
must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate,
DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR,
};
use nym_network_defaults::{mainnet, DEFAULT_NYM_NODE_HTTP_PORT};
use nym_network_defaults::{mainnet, DEFAULT_NYM_NODE_HTTP_PORT, WG_PORT};
use serde::{Deserialize, Serialize};
use std::io;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
@@ -20,7 +20,7 @@ use std::time::Duration;
use url::Url;
use zeroize::{Zeroize, ZeroizeOnDrop};
pub use crate::config::persistence::paths::GatewayPaths;
pub use crate::config::persistence::paths::{GatewayPaths, WireguardPaths};
pub mod old_config_v1_1_20;
pub mod old_config_v1_1_28;
@@ -85,6 +85,10 @@ pub struct Config {
pub gateway: Gateway,
// currently not really used for anything useful
#[serde(default)]
pub wireguard: Wireguard,
pub storage_paths: GatewayPaths,
pub network_requester: NetworkRequester,
@@ -117,6 +121,7 @@ impl Config {
},
http: Default::default(),
gateway: default_gateway,
wireguard: Default::default(),
storage_paths: GatewayPaths::new_default(id.as_ref()),
network_requester: Default::default(),
ip_packet_router: Default::default(),
@@ -130,6 +135,7 @@ impl Config {
host: impl Into<Host>,
http: impl Into<Http>,
gateway: impl Into<Gateway>,
wireguard: impl Into<Wireguard>,
storage_paths: impl Into<GatewayPaths>,
network_requester: impl Into<NetworkRequester>,
ip_packet_router: impl Into<IpPacketRouter>,
@@ -141,6 +147,7 @@ impl Config {
host: host.into(),
http: http.into(),
gateway: gateway.into(),
wireguard: wireguard.into(),
storage_paths: storage_paths.into(),
network_requester: network_requester.into(),
ip_packet_router: ip_packet_router.into(),
@@ -255,6 +262,8 @@ impl Config {
let http_port = self.http.bind_address.port();
self.http.bind_address = SocketAddr::new(listening_address, http_port);
let wg_port = self.wireguard.bind_address.port();
self.wireguard.bind_address = SocketAddr::new(listening_address, wg_port);
self
}
@@ -338,6 +347,40 @@ impl Default for Http {
}
}
#[derive(Debug, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Wireguard {
/// Specifies whether the wireguard service is enabled on this node.
pub enabled: bool,
/// Socket address this node will use for binding its wireguard interface.
/// default: `0.0.0.0:51822`
pub bind_address: SocketAddr,
/// Port announced to external clients wishing to connect to the wireguard interface.
/// Useful in the instances where the node is behind a proxy.
pub announced_port: u16,
/// The prefix denoting the maximum number of the clients that can be connected via Wireguard.
/// The maximum value for IPv4 is 32 and for IPv6 is 128
pub private_network_prefix: u8,
/// Paths for wireguard keys, client registries, etc.
pub storage_paths: WireguardPaths,
}
impl Default for Wireguard {
fn default() -> Self {
Wireguard {
enabled: false,
bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), WG_PORT),
announced_port: WG_PORT,
private_network_prefix: 16,
storage_paths: WireguardPaths {},
}
}
}
// we only really care about the mnemonic being zeroized
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Zeroize, ZeroizeOnDrop)]
pub struct Gateway {
+13 -3
View File
@@ -1,6 +1,8 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::config::persistence::paths::{GatewayPaths, WireguardPaths};
use nym_bin_common::logging::LoggingSettings;
use nym_config::{
must_get_home, read_config_from_toml_file, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, NYM_DIR,
};
@@ -12,9 +14,8 @@ use std::path::{Path, PathBuf};
use std::time::Duration;
use url::Url;
use super::{Host, Http};
use crate::config::persistence::paths::KeysPaths;
use crate::config::{Config, Debug, Gateway, GatewayPaths, LoggingSettings, NetworkRequester};
use super::persistence::paths::KeysPaths;
use super::{Config, Debug, Gateway, Host, Http, NetworkRequester, Wireguard};
const DEFAULT_GATEWAYS_DIR: &str = "gateways";
@@ -124,6 +125,15 @@ impl From<ConfigV1_1_31> for Config {
nyxd_urls: value.gateway.nyxd_urls,
cosmos_mnemonic: value.gateway.cosmos_mnemonic,
},
wireguard: Wireguard {
enabled: value.wireguard.enabled,
bind_address: value.wireguard.bind_address,
announced_port: value.wireguard.announced_port,
private_network_prefix: Default::default(),
storage_paths: WireguardPaths {
// no fields (yet)
},
},
storage_paths: GatewayPaths {
keys: KeysPaths {
private_identity_key_file: value.storage_paths.keys.private_identity_key_file,
+12
View File
@@ -169,3 +169,15 @@ impl KeysPaths {
&self.public_sphinx_key_file
}
}
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)]
#[serde(deny_unknown_fields)]
pub struct WireguardPaths {
// pub keys:
}
impl WireguardPaths {
pub fn new_empty() -> Self {
WireguardPaths {}
}
}
-22
View File
@@ -63,17 +63,6 @@ pub enum GatewayError {
source: io::Error,
},
#[error(
"failed to load config file for wireguard (gateway-id: '{id}') using path '{}'. detailed message: {source}",
path.display()
)]
WireguardConfigLoadFailure {
id: String,
path: PathBuf,
#[source]
source: io::Error,
},
#[error(
"failed to save config file for id {id} using path '{}'. detailed message: {source}", path.display()
)]
@@ -178,17 +167,6 @@ pub enum GatewayError {
#[cfg(all(feature = "wireguard", target_os = "linux"))]
#[error("failed to remove wireguard interface: {0}")]
WireguardInterfaceError(#[from] defguard_wireguard_rs::error::WireguardInterfaceError),
#[cfg(all(feature = "wireguard", target_os = "linux"))]
#[error("wireguard not set")]
WireguardNotSet,
#[cfg(all(feature = "wireguard", target_os = "linux"))]
#[error("failed to catch an interrupt: {source}")]
StdError {
#[source]
source: Box<dyn std::error::Error + Send + Sync>,
},
}
impl From<ClientCoreError> for GatewayError {
+34 -8
View File
@@ -4,6 +4,7 @@
use crate::config::Config;
use crate::error::GatewayError;
use crate::helpers::load_public_key;
use ipnetwork::IpNetwork;
use log::{debug, error, warn};
use nym_bin_common::bin_info_owned;
use nym_crypto::asymmetric::{encryption, identity};
@@ -11,19 +12,30 @@ use nym_network_requester::RequestFilter;
use nym_node_http_api::api::api_requests;
use nym_node_http_api::api::api_requests::v1::network_requester::exit_policy::models::UsedExitPolicy;
use nym_node_http_api::api::api_requests::SignedHostInformation;
use nym_node_http_api::router::WireguardAppState;
use nym_node_http_api::NymNodeHttpError;
use nym_sphinx::addressing::clients::Recipient;
use nym_task::TaskClient;
use nym_wireguard_types::WireguardGatewayData;
use nym_wireguard_types::registration::GatewayClientRegistry;
use std::net::{IpAddr, Ipv4Addr};
use std::sync::Arc;
fn load_gateway_details(
config: &Config,
) -> Result<api_requests::v1::gateway::models::Gateway, GatewayError> {
let wireguard = if config.wireguard.enabled {
Some(api_requests::v1::gateway::models::Wireguard {
port: config.wireguard.announced_port,
public_key: "placeholder key value".to_string(),
})
} else {
None
};
Ok(api_requests::v1::gateway::models::Gateway {
enforces_zk_nyms: config.gateway.only_coconut_credentials,
client_interfaces: api_requests::v1::gateway::models::ClientInterfaces {
wireguard: None,
wireguard,
mixnet_websockets: Some(api_requests::v1::gateway::models::WebSockets {
ws_port: config.gateway.clients_port,
wss_port: config.gateway.clients_wss_port,
@@ -142,7 +154,7 @@ pub(crate) struct HttpApiBuilder<'a> {
// TODO: this should be a wg specific key and not re-used sphinx
sphinx_keypair: Arc<encryption::KeyPair>,
wireguard_data: Option<Arc<WireguardGatewayData>>,
client_registry: Option<Arc<GatewayClientRegistry>>,
}
impl<'a> HttpApiBuilder<'a> {
@@ -158,7 +170,7 @@ impl<'a> HttpApiBuilder<'a> {
exit_policy: None,
identity_keypair,
sphinx_keypair,
wireguard_data: None,
client_registry: None,
}
}
@@ -223,11 +235,11 @@ impl<'a> HttpApiBuilder<'a> {
}
#[must_use]
pub(crate) fn with_wireguard_data(
pub(crate) fn with_wireguard_client_registry(
mut self,
wireguard_data: Option<Arc<WireguardGatewayData>>,
client_registry: Arc<GatewayClientRegistry>,
) -> Self {
self.wireguard_data = wireguard_data;
self.client_registry = Some(client_registry);
self
}
@@ -269,8 +281,22 @@ impl<'a> HttpApiBuilder<'a> {
)?);
}
let wireguard_private_network = IpNetwork::new(
IpAddr::from(Ipv4Addr::new(10, 1, 0, 0)),
self.gateway_config.wireguard.private_network_prefix,
)?;
let wg_state = self.client_registry.and_then(|client_registry| {
WireguardAppState::new(
client_registry,
Default::default(),
self.gateway_config.wireguard.bind_address.port(),
wireguard_private_network,
)
.ok()
});
let bind_address = self.gateway_config.http.bind_address;
let router = nym_node_http_api::NymNodeRouter::new(config, None, None);
let router = nym_node_http_api::NymNodeRouter::new(config, None, wg_state);
tokio::spawn(async move {
let server = match router.build_server(&bind_address).await {
+15 -23
View File
@@ -16,6 +16,7 @@ use crate::node::client_handling::websocket::connection_handler::coconut::Coconu
use crate::node::helpers::{initialise_main_storage, load_network_requester_config};
use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler;
use crate::node::statistics::collector::GatewayStatisticsCollector;
use dashmap::DashMap;
use futures::channel::{mpsc, oneshot};
use log::*;
use nym_crypto::asymmetric::{encryption, identity};
@@ -27,7 +28,7 @@ use nym_task::{TaskClient, TaskHandle, TaskManager};
use nym_types::gateway::GatewayNodeDetailsResponse;
use nym_validator_client::nyxd::{Coin, CosmWasmClient};
use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient};
use nym_wireguard_types::WireguardGatewayData;
use nym_wireguard_types::registration::GatewayClientRegistry;
use rand::seq::SliceRandom;
use rand::thread_rng;
use std::net::SocketAddr;
@@ -125,10 +126,9 @@ pub struct Gateway<St = PersistentStorage> {
/// x25519 keypair used for Diffie-Hellman. Currently only used for sphinx key derivation.
sphinx_keypair: Arc<encryption::KeyPair>,
storage: St,
wireguard_data: Option<Arc<WireguardGatewayData>>,
client_registry: Arc<GatewayClientRegistry>,
run_http_server: bool,
task_client: Option<TaskClient>,
@@ -149,7 +149,7 @@ impl<St> Gateway<St> {
config,
network_requester_opts,
ip_packet_router_opts,
wireguard_data: None,
client_registry: Arc::new(DashMap::new()),
run_http_server: true,
task_client: None,
})
@@ -170,7 +170,7 @@ impl<St> Gateway<St> {
identity_keypair,
sphinx_keypair,
storage,
wireguard_data: None,
client_registry: Arc::new(DashMap::new()),
run_http_server: true,
task_client: None,
}
@@ -184,14 +184,12 @@ impl<St> Gateway<St> {
self.task_client = Some(task_client)
}
pub fn set_wireguard_data(&mut self, wireguard_data: Arc<WireguardGatewayData>) {
pub fn set_wireguard_client_registry(&mut self, client_registry: Arc<GatewayClientRegistry>) {
// sanity check:
if let Some(wg_data) = self.wireguard_data.as_ref() {
if Arc::strong_count(wg_data) != 1 {
panic!("the client registry is already being used elsewhere")
}
if Arc::strong_count(&self.client_registry) != 1 {
panic!("the client registry is already being used elsewhere")
}
self.wireguard_data = Some(wireguard_data)
self.client_registry = client_registry
}
pub async fn node_details(&self) -> Result<GatewayNodeDetailsResponse, GatewayError> {
@@ -232,11 +230,7 @@ impl<St> Gateway<St> {
&self,
shutdown: TaskClient,
) -> Result<defguard_wireguard_rs::WGApi, Box<dyn std::error::Error + Send + Sync>> {
if let Some(wireguard_data) = self.wireguard_data.as_ref() {
nym_wireguard::start_wireguard(shutdown, Arc::clone(wireguard_data)).await
} else {
Err(Box::new(GatewayError::WireguardNotSet))
}
nym_wireguard::start_wireguard(shutdown, Arc::clone(&self.client_registry)).await
}
#[cfg(all(feature = "wireguard", not(target_os = "linux")))]
@@ -561,7 +555,7 @@ impl<St> Gateway<St> {
self.identity_keypair.as_ref(),
self.sphinx_keypair.clone(),
)
.with_wireguard_data(self.wireguard_data.clone())
.with_wireguard_client_registry(self.client_registry.clone())
.with_maybe_network_requester(self.network_requester_opts.as_ref().map(|o| &o.config))
.with_maybe_network_request_filter(nr_request_filter)
.with_maybe_ip_packet_router(self.ip_packet_router_opts.as_ref().map(|o| &o.config))
@@ -571,10 +565,7 @@ impl<St> Gateway<St> {
// Once this is a bit more mature, make this a commandline flag instead of a compile time
// flag
#[cfg(all(feature = "wireguard", target_os = "linux"))]
let wg_api = self
.start_wireguard(shutdown.fork("wireguard"))
.await
.map_err(|source| GatewayError::StdError { source })?;
let wg_api = self.start_wireguard(shutdown.fork("wireguard")).await.ok();
#[cfg(all(feature = "wireguard", not(target_os = "linux")))]
self.start_wireguard(shutdown.fork("wireguard")).await;
@@ -586,8 +577,9 @@ impl<St> Gateway<St> {
return Err(GatewayError::ShutdownFailure { source });
}
#[cfg(all(feature = "wireguard", target_os = "linux"))]
defguard_wireguard_rs::WireguardInterfaceApi::remove_interface(&wg_api)?;
if let Some(wg_api) = wg_api {
defguard_wireguard_rs::WireguardInterfaceApi::remove_interface(&wg_api)?;
}
Ok(())
}
}
+4 -4
View File
@@ -6,11 +6,11 @@ rust-version = "1.56"
license.workspace = true
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
k256 = { workspace = true, features = ["ecdsa", "sha256"] }
eyre = "0.6.5"
eyre = { workspace = true }
cosmrs = { workspace = true }
@@ -18,4 +18,4 @@ nym-cli-commands = { path = "../../common/commands" }
nym-validator-client = { path = "../../common/client-libs/validator-client" }
[dev-dependencies]
anyhow = "1"
anyhow = { workspace = true }
+3 -3
View File
@@ -21,12 +21,12 @@ axum = { workspace = true }
anyhow = { workspace = true }
bs58 = { workspace = true }
clap = { workspace = true, features = ["cargo", "derive"] }
colored = "2.0"
cupid = "0.6.1"
colored = { workspace = true }
cupid = { workspace = true }
dirs = "4.0"
futures = { workspace = true }
humantime-serde = { workspace = true }
lazy_static = "1.4"
lazy_static = { workspace = true }
log = { workspace = true }
rand = "0.7.3"
serde = { workspace = true, features = ["derive"] }
+15 -20
View File
@@ -11,7 +11,7 @@ authors = [
"Drazen Urch <durch@users.noreply.github.com>",
]
edition = "2021"
rust-version = "1.70.0"
rust-version = "1.76.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -19,39 +19,34 @@ rust-version = "1.70.0"
async-trait = { workspace = true }
bs58 = { workspace = true }
bip39 = { workspace = true }
cfg-if = "1.0"
cfg-if = { workspace = true }
clap = { workspace = true, features = ["cargo", "derive"] }
console-subscriber = { version = "0.1.1", optional = true } # validator-api needs to be built with RUSTFLAGS="--cfg tokio_unstable"
console-subscriber = { workspace = true, optional = true } # validator-api needs to be built with RUSTFLAGS="--cfg tokio_unstable"
dirs = "4.0"
futures = { workspace = true }
itertools = "0.12.0"
humantime-serde = { workspace = true }
k256 = { version = "*", features = ["ecdsa-core"] } # needed for the Verifier trait; pull whatever version is used by other dependencies
k256 = { workspace = true, features = ["ecdsa-core"] } # needed for the Verifier trait; pull whatever version is used by other dependencies
log = { workspace = true }
pin-project = "1.0"
pin-project = { workspace = true }
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", features = ["json"] }
rocket_cors = { version = "0.6.0" }
rocket = { workspace = true, features = ["json"] }
rocket_cors = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tap = "1.0"
tap = { workspace = true }
thiserror = { workspace = true }
time = { workspace = true, features = ["serde-human-readable", "parsing"] }
tokio = { version = "1.24.1", features = [
"rt-multi-thread",
"macros",
"signal",
"time",
] }
tokio-stream = "0.1.11"
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "signal", "time"] }
tokio-stream = { workspace = true }
url = { workspace = true }
ts-rs = { workspace = true, optional = true}
ts-rs = { workspace = true, optional = true }
anyhow = { workspace = true }
getset = "0.1.1"
getset = { workspace = true }
sqlx = { workspace = true, features = [
"runtime-tokio-rustls",
@@ -60,8 +55,8 @@ sqlx = { workspace = true, features = [
"migrate",
] }
okapi = { version = "0.7.0", features = ["impl_json_schema"] }
rocket_okapi = { version = "0.8.0", features = ["swagger"] }
okapi = { workspace = true, features = ["impl_json_schema"] }
rocket_okapi = { workspace = true, features = ["swagger"] }
schemars = { workspace = true, features = ["preserve_order"] }
zeroize = { workspace = true }
@@ -121,7 +116,7 @@ sqlx = { workspace = true, features = [
] }
[dev-dependencies]
tempfile = "3.3.0"
tempfile = { workspace = true }
cw3 = { workspace = true }
cw-utils = { workspace = true }
rand_chacha = "0.3"
+2 -2
View File
@@ -10,7 +10,7 @@ license.workspace = true
bs58 = { workspace = true }
cosmrs = { workspace = true }
cosmwasm-std = { workspace = true }
getset = "0.1.1"
getset = { workspace = true }
schemars = { workspace = true, features = ["preserve_order"] }
serde = { workspace = true, features = ["derive"] }
ts-rs = { workspace = true, optional = true }
@@ -19,7 +19,7 @@ time = { workspace = true, features = ["serde", "parsing", "formatting"] }
# for serde on secp256k1 signatures
ecdsa = { version = "0.16", features = ["serde"] }
ecdsa = { workspace = true, features = ["serde"] }
nym-credentials-interface = { path = "../../common/credentials-interface" }
nym-crypto = { path = "../../common/crypto", features = ["serde", "asymmetric"] }
+1
View File
@@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize};
pub mod coconut;
pub mod models;
pub mod pagination;
pub trait Deprecatable {
fn deprecate(self) -> Deprecated<Self>
+31 -1
View File
@@ -1,6 +1,7 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::pagination::PaginatedResponse;
use cosmwasm_std::{Addr, Coin, Decimal};
use nym_mixnet_contract_common::families::FamilyHead;
use nym_mixnet_contract_common::mixnode::MixNodeDetails;
@@ -9,7 +10,7 @@ use nym_mixnet_contract_common::rewarding::RewardEstimate;
use nym_mixnet_contract_common::{
GatewayBond, IdentityKey, Interval, MixId, MixNode, Percent, RewardedSetNodeStatus,
};
use nym_node_requests::api::v1::node::models::BinaryBuildInformationOwned;
use nym_node_requests::api::v1::node::models::{AuxiliaryDetails, BinaryBuildInformationOwned};
use schemars::gen::SchemaGenerator;
use schemars::schema::{InstanceType, Schema, SchemaObject};
use schemars::JsonSchema;
@@ -482,6 +483,7 @@ impl JsonSchema for OffsetDateTimeJsonSchemaWrapper {
}
}
// this struct is getting quite bloated...
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)]
pub struct NymNodeDescription {
#[serde(default)]
@@ -489,6 +491,9 @@ pub struct NymNodeDescription {
pub host_information: HostInformation,
#[serde(default)]
pub auxiliary_details: AuxiliaryDetails,
// TODO: do we really care about ALL build info or just the version?
pub build_information: BinaryBuildInformationOwned,
@@ -569,3 +574,28 @@ pub struct SignerInformationResponse {
pub verification_key: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema, Default)]
pub struct TestNode {
pub node_id: Option<u32>,
pub identity_key: Option<String>,
}
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)]
pub struct TestRoute {
pub gateway: TestNode,
pub layer1: TestNode,
pub layer2: TestNode,
pub layer3: TestNode,
}
#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)]
pub struct PartialTestResult {
pub monitor_run_id: i64,
pub timestamp: i64,
pub overall_reliability_for_all_routes_in_monitor_run: Option<u8>,
pub test_routes: TestRoute,
}
pub type MixnodeTestResultResponse = PaginatedResponse<PartialTestResult>;
pub type GatewayTestResultResponse = PaginatedResponse<PartialTestResult>;
@@ -0,0 +1,18 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, JsonSchema)]
pub struct Pagination {
pub total: usize,
pub page: u32,
pub size: usize,
}
#[derive(Serialize, Deserialize, JsonSchema)]
pub struct PaginatedResponse<T> {
pub pagination: Pagination,
pub data: Vec<T>,
}

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