Compare commits

...

98 Commits

Author SHA1 Message Date
fmtabbara 8f7e51c093 remove browser extension 2024-06-10 16:55:43 +01:00
Bogdan-Ștefan Neacşu bb46235b54 Add generic wg private network routing (#4636) 2024-06-10 16:55:05 +03:00
Bogdan-Ștefan Neacşu 70fa41c165 Update kernel peers on peer modification (#4622)
* Include wireguard in gw config

* Support nym node first

* Create wg keypair

* Activate wg feature in gw dep

* Move key paths to separate structure

* Use client reg

* Generate and use own private key

* Rename network to ip for wg gw

* Propagate wireguard setup error message

* Remove logs

* Bump gateway version number

* Remove upgrade code

* Init wireguard on migration

* Upgrade code for nym-node too

* Wireguard paths upgrade

* Init wg keys on upgrade

* Simplify pub key translatations

* Fix clippy

* Undo comment change

* Fix tests

* Don't bump version just yet

* Remove redundant source attr

* Remove unused wg details

* Rename wg device

* Init for mixnode migration as well

* Add upgrade for gw wireguard deleted field

* Move interface removal to Drop trait impl

* Fix clippy

* Wgapi could be included on other platforms

* Handle peer control msgs

* Send add peer msg

* Handle double registration

* Fix deadlock

* Fix clippy

* More clippy

* Use same defguard

* Fix unit test

* Fix wasm build

* Move implementations from types to wireguard crate

* Fix linux
2024-06-07 14:02:47 +03:00
Jędrzej Stuczyński 102a8a0d8b Merge pull request #4607 from nymtech/simon/sphinx_update
Update crypto and rand crates
2024-06-05 10:34:42 +01:00
Tommy Verrall ae28a45915 Merge pull request #4618 from vitorsantanna2/patch-1
Update isp-sheet.csv
2024-06-05 11:09:11 +02:00
import this cffb8d98af [DOCs/operators]: fix wireguard syntax (#4628)
* fix wireguard syntax

* simplify syntax

* clean
2024-06-03 14:16:30 +00:00
import this a40c2239d7 [DOCs/operators]: Routine update && Fix a probe syntax (#4627)
* update probe and simplify nym gw flow

* add gw troubleshooting
2024-06-03 07:45:27 +00:00
Jon Häggblad 5a990a58ff Extend the return error when connecting to gateway fails (#4626) 2024-05-31 19:18:31 +02:00
Simon Wicky 2a1d37dd22 update crypto and rand crates 2024-05-31 11:33:16 +01:00
Bogdan-Ștefan Neacşu be79042a23 Bump defguard wg (#4625) 2024-05-30 16:00:51 +02:00
Bogdan-Ștefan Neacşu 3acf521fc1 Refine wireguard on gateway side (#4615)
* Include wireguard in gw config

* Support nym node first

* Create wg keypair

* Activate wg feature in gw dep

* Move key paths to separate structure

* Use client reg

* Generate and use own private key

* Rename network to ip for wg gw

* Propagate wireguard setup error message

* Remove logs

* Bump gateway version number

* Remove upgrade code

* Init wireguard on migration

* Upgrade code for nym-node too

* Wireguard paths upgrade

* Init wg keys on upgrade

* Simplify pub key translatations

* Fix clippy

* Undo comment change

* Fix tests

* Don't bump version just yet

* Remove redundant source attr

* Remove unused wg details

* Rename wg device

* Init for mixnode migration as well

* Add upgrade for gw wireguard deleted field

* Move interface removal to Drop trait impl

* Fix clippy

* Wgapi could be included on other platforms
2024-05-28 11:52:14 +02:00
Vitor Santanna 1afcfb0842 Update isp-sheet.csv
Add Misaka and IsHosting VPS
2024-05-24 12:55:10 -03:00
benedetta davico 759e2fa2c5 Merge pull request #4617 from nymtech/master
Merge Master into Develop with the recent Ragusa changes
2024-05-24 14:06:57 +02:00
Tommy Verrall 489914fb42 Merge pull request #4608 from nymtech/release/2024.5-ragusa
Release 2024.5-ragusa into master - DO NO MERGE
2024-05-24 12:35:01 +01:00
import this bca8992115 [DOCs/operators]: 2024.5-ragusa updates (#4609)
* initialise changelog updates

* fix formatting

* finalise changelog

* change formating - PR ready for review

* review comments resolved
2024-05-23 16:49:17 +00:00
mx f94d900d18 update mixfetch docs (#4614)
* * added info on gateway habourmaster
* fixed broken examples with new infra addresses
* bump node version in ts sdk docs ci script

---------

Co-authored-by: mfahampshire <mfahampshire@pm.me>
2024-05-23 15:15:51 +00:00
Tommy Verrall dab55a12c7 update changelog 2024-05-23 16:26:09 +02:00
Tommy Verrall 82f722936f Merge branch 'release/2024.5-ragusa' of https://github.com/nymtech/nym into release/2024.5-ragusa 2024-05-23 16:09:07 +02:00
benedettadavico 7f08020d4f update changelog and bump versions 2024-05-23 16:08:37 +02:00
Tommy Verrall 579e41d57e Merge pull request #4613 from nymtech/bugfix/last_polled-backwards-compat
make sure 'OffsetDateTimeJsonSchemaWrapper' is serialised with legacy format
2024-05-23 15:00:38 +01:00
Jędrzej Stuczyński 06953298eb ibid for nym-connect 2024-05-23 12:10:41 +01:00
Jędrzej Stuczyński 1d78f8747f update wallet 'time' dep due to broken semver 2024-05-23 10:21:08 +01:00
Tommy Verrall a6e9414cb8 Update ci-contracts-upload-binaries.yml
use version 1.77 so it's compatible with ecash
2024-05-23 11:03:40 +02:00
Jędrzej Stuczyński 23d7230d33 make sure 'OffsetDateTimeJsonSchemaWrapper' is serialised with legacy format 2024-05-23 10:01:46 +01:00
benedettadavico 496f172070 update changelog and bump versions 2024-05-22 10:28:38 +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
Jon Häggblad a06ae48e2f Add methods to MixnetClient to sign messages (#4602) 2024-05-20 10:22:28 +02: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
Fouad e5f41731ae Explorer NextJS Rebuild (#4534)
* bootstrap next app + add overview page

* fix AssetList type

* fix up nav stuff

* Refactor Nav component and add network components pages

* Refactor WorldMap component and update TelegramIcon, GitHubIcon, NymVpnIcon, DiscordIcon, and TwitterIcon components

* add service providers page

* mixnodes page

* delegations page + use material react table for all tables

* nodes map page

* Refactor StyledLink component and remove unnecessary console.log statements

* Refactor ESLint configuration, remove unused dependencies, and update component imports

* update deps

* Refactor imports and update dependencies

* fix dark mode

* build single mixnode page

* build single gateway page

* Refactor handleOnDelegate function to use useCallback in mixnodes page.tsx

* Add defaults for constants

---------

Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
2024-05-16 16:12:06 +01:00
Jędrzej Stuczyński a6fda391ae Feature/rewarder voucher issuance (#4548)
* retrieve ed25519 identities of issuers

* signature verification on issued credentials

* wip

* persisting information about verified deposits, any failures and foul plays

* clippy
2024-05-16 10:15:24 +02:00
Tommy Verrall 1ded24dcfc Merge pull request #4586 from nymtech/bugfix/nym-api-noop-nobanner
[bugfix] noop flag for nym-api for nymvisor compatibility
2024-05-15 14:07:30 +01:00
Tommy Verrall 8c42640853 Merge pull request #4591 from nymtech/jon/described-offsettime-parsing
Use rfc3339 for last_polled in described nym-api endpoint
2024-05-15 14:03:42 +01:00
Tommy Verrall 38aabc7983 Merge pull request #4593 from nymtech/feature/extend-max-freepass-validity
change maximum validity of issuable freepass
2024-05-15 13:40:49 +01:00
Tommy Verrall 4324845d29 Merge pull request #4596 from nymtech/update-contract-addr
update mainnet contract addresses
2024-05-15 10:07:08 +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 b9524a0f58 Chore/additional helpers (#4585)
* exposed additional helpers

* changes lost in rebasing
2024-05-14 18:33:56 +02:00
Sachin Kamath e7cd417894 update mainnet contract addresses 2024-05-14 21:30:31 +05:30
Jędrzej Stuczyński 07cc47a0ff allow using explicit admin address for issuing freepasses 2024-05-14 16:58:11 +01:00
benedetta davico ca25db845a Merge pull request #4573 from nymtech/feature/axum-upgrade
upgraded axum and related deps to the most recent version
2024-05-14 17:38:15 +02:00
benedetta davico 64a0ce31a8 Merge branch 'develop' into feature/axum-upgrade 2024-05-14 17:21:44 +02:00
Jędrzej Stuczyński a8fe8d9bfb change maximum validity of issuable freepass 2024-05-14 14:35:53 +01:00
Jędrzej Stuczyński c346f145d1 backwards compatibility to fallback to default in case of failures 2024-05-14 10:15:16 +01:00
Jon Häggblad 45dd6f2632 Fix typo for StorageError::ConstraintUnique (#4592) 2024-05-13 17:48:58 +02:00
Jon Häggblad 22d28759ab Explicitly use rfc3339 for last_polled 2024-05-13 15:55:32 +02:00
Jędrzej Stuczyński 890d0f7440 fixed incorrect dependency path for 'axum-extra' 2024-05-13 14:18:33 +01:00
Jędrzej Stuczyński b342eb870e removed explicit drops 2024-05-13 11:31:34 +01:00
Jędrzej Stuczyński fc71e0cafd fixed tests 2024-05-13 11:31:33 +01:00
Tommy Verrall 1ecb57fda0 Merge pull request #4588 from nymtech/jon/explicitly-handle-sqlite-constraint-violation
Explicitly handle constraint unique violation when importing credential
2024-05-13 11:30:31 +01:00
Tommy Verrall 3c1ec82289 Merge pull request #4588 from nymtech/jon/explicitly-handle-sqlite-constraint-violation
Explicitly handle constraint unique violation when importing credential
2024-05-13 09:57:42 +01:00
Tommy Verrall 089e403d87 Merge pull request #4589 from nymtech/master
merge latest master to develop
2024-05-13 09:56:34 +01:00
Tommy Verrall dd2b477cda Merge pull request #4587 from nymtech/jon/lock-files
Update stale lock files
2024-05-13 09:54:52 +01:00
benedetta davico 0902539332 Merge pull request #4583 from nymtech/release/2024.4-nutella
Release 2024.4-nutella to master
2024-05-13 10:27:08 +02:00
Jon Häggblad 0783c532de Explicitly handle constraint unique violation when importing credential 2024-05-13 10:19:01 +02:00
Jon Häggblad 8817ae7805 Update stale lock files 2024-05-13 08:57:49 +02:00
Jędrzej Stuczyński 6a900c3c42 fixed linter issue in nyxd-scraper 2024-05-10 15:05:37 +01:00
Jędrzej Stuczyński 0ba80c9a86 moved startup 'Starting nym api...' message from stdout to stderr 2024-05-10 11:16:10 +01:00
Jędrzej Stuczyński d712b65ec5 [bugfix] noop flag for nym-api for nymvisor compatibility 2024-05-10 11:02:21 +01:00
Tommy Verrall 383b2c1351 Merge pull request #4552 from nymtech/jon/validator-client-rustls
Add rustls-tls to reqwest in validator-client
2024-05-08 16:51:46 +01:00
benedettadavico f0a4350e83 pruning
version bump and changelog updates
2024-05-08 11:01:50 +02:00
Jon Häggblad 6f4b00b5c2 Add default-features = true for tungstenite and non-wasm in client-core 2024-04-30 14:14:44 +02:00
Jon Häggblad d681ad20cf Keep default features off for tungstenite and wasm 2024-04-30 14:14:44 +02:00
Jon Häggblad 5818d58caf tweak feature args to tungstenite 2024-04-30 14:14:42 +02:00
Jon Häggblad da4eab8fdb Add rustls-tls to reqwest in validator-client 2024-04-30 14:14:00 +02:00
487 changed files with 63690 additions and 12211 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
target: wasm32-unknown-unknown
override: 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
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v3
with:
node-version: 18
node-version: 18.17
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
+49
View File
@@ -4,6 +4,55 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
## [Unreleased]
## [2024.5-ragusa] (2024-05-22)
- Feature/nym node api location ([#4605])
- Add optional signature to IPR request/response ([#4604])
- Feature/unstable tested nodes endpoint ([#4601])
- nym-api: make report/avg_uptime endpoints ignore blacklist ([#4599])
- removed blocking for coconut in the final epoch state ([#4598])
- allow using explicit admin address for issuing freepasses ([#4595])
- Use rfc3339 for last_polled in described nym-api endpoint ([#4591])
- Explicitly handle constraint unique violation when importing credential ([#4588])
- [bugfix] noop flag for nym-api for nymvisor compatibility ([#4586])
- Chore/additional helpers ([#4585])
- Feature/wasm coconut ([#4584])
- upgraded axum and related deps to the most recent version ([#4573])
- Feature/nyxd scraper pruning ([#4564])
- Run cargo autoinherit on the main workspace ([#4553])
- Add rustls-tls to reqwest in validator-client ([#4552])
- Feature/rewarder voucher issuance ([#4548])
- make sure 'OffsetDateTimeJsonSchemaWrapper' is serialised with legacy format ([#4613])
[#4613]: https://github.com/nymtech/nym/pull/4613
[#4605]: https://github.com/nymtech/nym/pull/4605
[#4604]: https://github.com/nymtech/nym/pull/4604
[#4601]: https://github.com/nymtech/nym/pull/4601
[#4599]: https://github.com/nymtech/nym/pull/4599
[#4598]: https://github.com/nymtech/nym/pull/4598
[#4595]: https://github.com/nymtech/nym/pull/4595
[#4591]: https://github.com/nymtech/nym/pull/4591
[#4588]: https://github.com/nymtech/nym/pull/4588
[#4586]: https://github.com/nymtech/nym/pull/4586
[#4585]: https://github.com/nymtech/nym/pull/4585
[#4584]: https://github.com/nymtech/nym/pull/4584
[#4573]: https://github.com/nymtech/nym/pull/4573
[#4564]: https://github.com/nymtech/nym/pull/4564
[#4553]: https://github.com/nymtech/nym/pull/4553
[#4552]: https://github.com/nymtech/nym/pull/4552
[#4548]: https://github.com/nymtech/nym/pull/4548
## [2024.4-nutella] (2024-05-08)
- [fix] apply disable_poisson_rate from internal NR/IPR cfgs ([#4579])
- updating sign commands to include nym-node ([#4578])
- changed nym-node redirects from 308 'Permanent Redirect' to 303: 'See Other' ([#4572])
[#4579]: https://github.com/nymtech/nym/pull/4579
[#4578]: https://github.com/nymtech/nym/pull/4578
[#4572]: https://github.com/nymtech/nym/pull/4572
## [2024.3-eclipse] (2024-04-22)
- Initial release of the first iteration of the Nym Node
Generated
+1433 -3306
View File
File diff suppressed because it is too large Load Diff
+117 -17
View File
@@ -122,6 +122,7 @@ members = [
# "wasm/full-nym-wasm",
"wasm/mix-fetch",
"wasm/node-tester",
"wasm/zknym-lib",
]
default-members = [
@@ -158,44 +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.6.20"
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.1"
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 = "4.1"
dashmap = "5.5.3"
defguard_wireguard_rs = "0.4.2"
doc-comment = "0.3"
dotenvy = "0.15.6"
ecdsa = "0.16"
ed25519-dalek = "2.1"
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"
hyper = "0.14.27"
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"
reqwest = { version = "0.11.22", default-features = false }
rand-07 = "0.7.3"
rand_chacha_02 = "0.2"
rand_core = "0.6.3"
rand_distr = "0.4"
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.1"
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"
utoipa = "3.5.0"
utoipa-swagger-ui = "3.1.5"
tungstenite = { version = "0.20.1", default-features = false }
url = "2.4"
utoipa = "4.2.0"
utoipa-swagger-ui = "6.0.0"
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" }
@@ -207,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"
@@ -235,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
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.1.34"
version = "1.1.35"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
@@ -25,11 +25,11 @@ bs58 = { workspace = true }
clap = { workspace = true, features = ["cargo", "derive"] }
dirs = "4.0"
log = { workspace = true } # self explanatory
rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use
rand = { workspace = true }
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 }
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-socks5-client"
version = "1.1.34"
version = "1.1.35"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021"
@@ -13,10 +13,10 @@ 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"] }
rand = "0.7.3"
tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] }
rand = { workspace = true }
time = { workspace = true }
url = { workspace = true }
zeroize = { 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"] }
+1 -1
View File
@@ -9,7 +9,7 @@ license.workspace = true
[dependencies]
bip39 = { workspace = true }
log = { workspace = true }
rand = "0.7.3"
rand = { workspace = true }
thiserror = { workspace = true }
url = { workspace = true }
zeroize = { workspace = true }
+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 = []
+16 -8
View File
@@ -12,20 +12,19 @@ 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 }
log = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
rand = { workspace = true }
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"] }
tungstenite = { workspace = true, default-features = false }
tokio = { workspace = true, features = ["macros"] }
time = { workspace = true }
zeroize = { workspace = true }
@@ -74,8 +73,17 @@ workspace = true
features = ["time"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-tungstenite]
version = "0.20.1"
features = ["rustls-tls-native-roots"]
workspace = true
features = ["rustls-tls-webpki-roots"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tungstenite]
workspace = true
default-features = true
features = ["rustls-tls-webpki-roots"]
[target."cfg(target_arch = \"wasm32\")".dependencies.tungstenite]
workspace = true
default-features = false
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen-futures]
workspace = true
@@ -100,7 +108,7 @@ version = "0.3.17"
features = ["wasm-bindgen"]
[dev-dependencies]
tempfile = "3.1.0"
tempfile = { workspace = true }
[features]
default = []
@@ -39,7 +39,7 @@ use log::{debug, error, info, warn};
use nym_bandwidth_controller::BandwidthController;
use nym_client_core_gateways_storage::{GatewayDetails, GatewaysDetailsStore};
use nym_credential_storage::storage::Storage as CredentialStorage;
use nym_crypto::asymmetric::encryption;
use nym_crypto::asymmetric::{encryption, identity};
use nym_gateway_client::{
AcknowledgementReceiver, GatewayClient, GatewayConfig, MixnetMessageReceiver, PacketRouter,
};
@@ -670,6 +670,7 @@ where
let self_address = Self::mix_address(&init_res);
let ack_key = init_res.client_keys.ack_key();
let encryption_keys = init_res.client_keys.encryption_keypair();
let identity_keys = init_res.client_keys.identity_keypair();
// the components are started in very specific order. Unless you know what you are doing,
// do not change that.
@@ -792,6 +793,7 @@ where
Ok(BaseClient {
address: self_address,
identity_keys,
client_input: ClientInputStatus::AwaitingProducer {
client_input: ClientInput {
connection_command_sender: client_connection_tx,
@@ -816,6 +818,7 @@ where
pub struct BaseClient {
pub address: Recipient,
pub identity_keys: Arc<identity::KeyPair>,
pub client_input: ClientInputStatus,
pub client_output: ClientOutputStatus,
pub client_state: ClientState,
+4 -7
View File
@@ -14,9 +14,9 @@ futures = { workspace = true }
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"
rand = { workspace = true }
tokio = { workspace = true, features = ["macros"] }
si-scale = { workspace = true }
time.workspace = true
# internal
@@ -48,10 +48,7 @@ features = ["net", "sync", "time"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-tungstenite]
workspace = true
# the choice of this particular tls feature was arbitrary;
# if you reckon a different one would be more appropriate, feel free to change it
# features = ["native-tls"]
features = ["rustls-tls-native-roots"]
features = ["rustls-tls-webpki-roots"]
# wasm-only dependencies
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen]
@@ -220,9 +220,18 @@ impl<C, St> GatewayClient<C, St> {
#[cfg(not(target_arch = "wasm32"))]
pub async fn establish_connection(&mut self) -> Result<(), GatewayClientError> {
debug!(
"Attemting to establish connection to gateway at: {}",
self.gateway_address
);
let ws_stream = match connect_async(&self.gateway_address).await {
Ok((ws_stream, _)) => ws_stream,
Err(e) => return Err(GatewayClientError::NetworkError(e)),
Err(error) => {
return Err(GatewayClientError::NetworkConnectionFailed {
address: self.gateway_address.clone(),
source: error,
})
}
};
self.connection = SocketState::Available(Box::new(ws_stream));
@@ -23,6 +23,9 @@ pub enum GatewayClientError {
#[error("There was a network error: {0}")]
NetworkErrorWasm(#[from] JsError),
#[error("connection failed: {address}: {source}")]
NetworkConnectionFailed { address: String, source: WsError },
#[error("Invalid URL: {0}")]
InvalidURL(String),
+11 -4
View File
@@ -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" }
@@ -24,7 +24,6 @@ nym-group-contract-common = { path = "../../cosmwasm-smart-contracts/group-contr
nym-service-provider-directory-common = { path = "../../cosmwasm-smart-contracts/service-provider-directory" }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
reqwest = { workspace = true, features = ["json"] }
nym-http-api-client = { path = "../../../common/http-api-client"}
thiserror = { workspace = true }
log = { workspace = true }
@@ -49,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"] }
@@ -67,6 +66,14 @@ cosmwasm-std = { workspace = true }
workspace = true
features = ["tokio"]
[target."cfg(target_arch = \"wasm32\")".dependencies.reqwest]
workspace = true
features = ["json"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.reqwest]
workspace = true
features = ["json", "rustls-tls"]
[dev-dependencies]
bip39 = { workspace = true }
cosmrs = { workspace = true, features = ["bip32"] }
+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"
@@ -328,4 +328,8 @@ impl EpochState {
pub fn is_dealing_exchange(&self) -> bool {
matches!(self, EpochState::DealingExchange { .. })
}
pub fn is_waiting_initialisation(&self) -> bool {
matches!(self, EpochState::WaitingInitialisation)
}
}
@@ -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"] }
+3
View File
@@ -18,4 +18,7 @@ pub enum StorageError {
#[error("No unused credential in database. You need to buy at least one")]
NoCredential,
#[error("Database unique constraint violation. Is the credential already imported?")]
ConstraintUnique,
}
@@ -69,9 +69,21 @@ impl Storage for PersistentStorage {
bandwidth_credential.credential_data,
bandwidth_credential.epoch_id,
)
.await?;
Ok(())
.await
.map_err(|err| {
// There is one error we want to handle specifically.
// Check if database_error is `SqliteError` with code 2067 which
// means UNIQUE constraint violation
if let Some(db_error) = err.as_database_error() {
if db_error.code().map_or(false, |code| code == "2067") {
StorageError::ConstraintUnique
} else {
err.into()
}
} else {
err.into()
}
})
}
async fn get_next_unspent_credential(
-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
+5 -5
View File
@@ -8,11 +8,11 @@ use std::str::FromStr;
use thiserror::Error;
pub use nym_coconut::{
aggregate_signature_shares_and_verify, aggregate_verification_keys, blind_sign, hash_to_scalar,
keygen, prepare_blind_sign, prove_bandwidth_credential, verify_credential, Attribute, Base58,
BlindSignRequest, BlindedSerialNumber, BlindedSignature, Bytable, CoconutError, KeyPair,
Parameters, PrivateAttribute, PublicAttribute, SecretKey, Signature, SignatureShare,
VerificationKey, VerifyCredentialRequest,
aggregate_signature_shares, aggregate_signature_shares_and_verify, aggregate_verification_keys,
blind_sign, hash_to_scalar, keygen, prepare_blind_sign, prove_bandwidth_credential,
verify_credential, Attribute, Base58, BlindSignRequest, BlindedSerialNumber, BlindedSignature,
Bytable, CoconutError, KeyPair, Parameters, PrivateAttribute, PublicAttribute, SecretKey,
Signature, SignatureShare, VerificationKey, VerifyCredentialRequest,
};
pub const VOUCHER_INFO_TYPE: &str = "BandwidthVoucher";
+2 -2
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 }
@@ -23,5 +23,5 @@ nym-api-requests = { path = "../../nym-api/nym-api-requests" }
nym-validator-client = { path = "../client-libs/validator-client", default-features = false }
[dev-dependencies]
rand = "0.7.3"
rand = "0.8.5"
@@ -12,7 +12,8 @@ use serde::{Deserialize, Serialize};
use time::{Duration, OffsetDateTime, Time};
use zeroize::{Zeroize, ZeroizeOnDrop};
pub const MAX_FREE_PASS_VALIDITY: Duration = Duration::WEEK; // 1 week
pub const DEFAULT_FREE_PASS_VALIDITY: Duration = Duration::WEEK; // 1 week
pub const MAX_FREE_PASS_VALIDITY: Duration = Duration::weeks(12); // 12 weeks
#[derive(Debug, Zeroize, ZeroizeOnDrop, Serialize, Deserialize)]
pub struct FreePassIssuedData {
@@ -77,9 +78,9 @@ impl FreePassIssuanceData {
}
pub fn default_expiry_date() -> OffsetDateTime {
// set it to furthest midnight in the future such as it's no more than a week away,
// set it to the furthest midnight in the future such as it's no more than a week away,
// i.e. if it's currently for example 9:43 on 2nd March 2024, it will set it to 0:00 on 9th March 2024
(OffsetDateTime::now_utc() + MAX_FREE_PASS_VALIDITY).replace_time(Time::MIDNIGHT)
(OffsetDateTime::now_utc() + DEFAULT_FREE_PASS_VALIDITY).replace_time(Time::MIDNIGHT)
}
pub fn expiry_date_attribute(&self) -> &Attribute {
@@ -10,9 +10,9 @@ use crate::coconut::bandwidth::{
use crate::coconut::utils::scalar_serde_helper;
use crate::error::Error;
use nym_credentials_interface::{
aggregate_signature_shares_and_verify, hash_to_scalar, prepare_blind_sign, Attribute,
BlindedSerialNumber, BlindedSignature, Parameters, PrivateAttribute, PublicAttribute,
Signature, SignatureShare, VerificationKey,
aggregate_signature_shares, aggregate_signature_shares_and_verify, hash_to_scalar,
prepare_blind_sign, Attribute, BlindedSerialNumber, BlindedSignature, Parameters,
PrivateAttribute, PublicAttribute, Signature, SignatureShare, VerificationKey,
};
use nym_crypto::asymmetric::{encryption, identity};
use nym_validator_client::nym_api::EpochId;
@@ -266,6 +266,13 @@ impl IssuanceBandwidthCredential {
self.unblind_signature(validator_vk, &signing_data, blinded_signature)
}
pub fn unchecked_aggregate_signature_shares(
&self,
shares: &[SignatureShare],
) -> Result<Signature, Error> {
aggregate_signature_shares(shares).map_err(Error::SignatureAggregationError)
}
pub fn aggregate_signature_shares(
&self,
verification_key: &VerificationKey,
@@ -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()
}
@@ -6,7 +6,7 @@ use crate::coconut::utils::scalar_serde_helper;
use crate::error::Error;
use nym_api_requests::coconut::BlindSignRequestBody;
use nym_credentials_interface::{
hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature, PublicAttribute,
hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature, CredentialType, PublicAttribute,
};
use nym_crypto::asymmetric::{encryption, identity};
use nym_validator_client::nyxd::{Coin, Hash};
@@ -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
}
@@ -123,6 +127,10 @@ impl BandwidthVoucherIssuanceData {
&self.value_prehashed
}
pub fn typ() -> CredentialType {
CredentialType::Voucher
}
pub fn tx_hash(&self) -> Hash {
self.deposit_tx_hash
}
+11 -11
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 }
x25519-dalek = { version = "1.1", optional = true }
ed25519-dalek = { version = "1.0", optional = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"], optional = true }
hkdf = { workspace = true, optional = true }
hmac = { workspace = true, optional = true }
cipher = { workspace = true, optional = true }
x25519-dalek = { version = "2.0", optional = true, features = ["static_secrets"]}
ed25519-dalek = { version = "2.1", features = ["rand_core"], optional = true }
rand = { workspace = true, optional = true }
serde_bytes = { version = "0.11.6", 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"] }
@@ -31,7 +31,7 @@ nym-sphinx-types = { path = "../nymsphinx/types", version = "0.2.0", default-fea
nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
[dev-dependencies]
rand_chacha = "0.2"
rand_chacha = "0.3"
[features]
default = ["sphinx"]
+19 -4
View File
@@ -56,7 +56,7 @@ pub struct KeyPair {
impl KeyPair {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let private_key = x25519_dalek::StaticSecret::new(rng);
let private_key = x25519_dalek::StaticSecret::random_from_rng(rng);
let public_key = (&private_key).into();
KeyPair {
@@ -200,10 +200,18 @@ 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 {
let x25519_secret = x25519_dalek::StaticSecret::new(rng);
let x25519_secret = x25519_dalek::StaticSecret::random_from_rng(rng);
PrivateKey(x25519_secret)
}
@@ -350,16 +358,23 @@ mod sphinx_key_conversion {
let private = &keys.private_key;
let public = &keys.public_key;
let private_bytes = private.to_bytes();
let dummy_remote = KeyPair::new(&mut rng);
let dh1 = private.diffie_hellman(&dummy_remote.public_key);
let public_bytes = public.to_bytes();
let sphinx_private: nym_sphinx_types::PrivateKey = private.into();
let recovered_private = PrivateKey::from(sphinx_private);
let dh2 = recovered_private.diffie_hellman(&dummy_remote.public_key);
let sphinx_public: nym_sphinx_types::PublicKey = public.into();
let recovered_public = PublicKey::from(sphinx_public);
assert_eq!(private_bytes, recovered_private.to_bytes());
assert_eq!(public_bytes, recovered_public.to_bytes());
// even though the byte representation of the private key changed, the resultant DH is the same
// which is what matters
assert_eq!(dh1, dh2);
}
}
+29 -15
View File
@@ -1,8 +1,8 @@
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub use ed25519_dalek::ed25519::signature::Signature as SignatureTrait;
pub use ed25519_dalek::SignatureError;
use ed25519_dalek::{Signer, SigningKey};
pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH};
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
use std::fmt::{self, Display, Formatter};
@@ -30,6 +30,9 @@ pub enum Ed25519RecoveryError {
#[error(transparent)]
MalformedBytes(#[from] SignatureError),
#[error(transparent)]
BytesLengthError(#[from] std::array::TryFromSliceError),
#[error("the base58 representation of the public key was malformed - {source}")]
MalformedPublicKeyString {
#[source]
@@ -64,11 +67,11 @@ pub struct KeyPair {
impl KeyPair {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let ed25519_keypair = ed25519_dalek::Keypair::generate(rng);
let ed25519_signing_key = ed25519_dalek::SigningKey::generate(rng);
KeyPair {
private_key: PrivateKey(ed25519_keypair.secret),
public_key: PublicKey(ed25519_keypair.public),
private_key: PrivateKey(ed25519_signing_key.to_bytes()),
public_key: PublicKey(ed25519_signing_key.verifying_key()),
}
}
@@ -109,7 +112,7 @@ impl PemStorableKeyPair for KeyPair {
/// ed25519 EdDSA Public Key
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct PublicKey(ed25519_dalek::PublicKey);
pub struct PublicKey(ed25519_dalek::VerifyingKey);
impl Display for PublicKey {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@@ -135,7 +138,9 @@ impl PublicKey {
}
pub fn from_bytes(b: &[u8]) -> Result<Self, Ed25519RecoveryError> {
Ok(PublicKey(ed25519_dalek::PublicKey::from_bytes(b)?))
Ok(PublicKey(ed25519_dalek::VerifyingKey::from_bytes(
b.try_into()?,
)?))
}
pub fn to_base58_string(self) -> String {
@@ -189,7 +194,7 @@ impl<'d> Deserialize<'d> for PublicKey {
where
D: Deserializer<'d>,
{
Ok(PublicKey(ed25519_dalek::PublicKey::deserialize(
Ok(PublicKey(ed25519_dalek::VerifyingKey::deserialize(
deserializer,
)?))
}
@@ -223,14 +228,22 @@ impl Display for PrivateKey {
impl<'a> From<&'a PrivateKey> for PublicKey {
fn from(pk: &'a PrivateKey) -> Self {
PublicKey((&pk.0).into())
PublicKey(SigningKey::from_bytes(&pk.0).verifying_key())
}
}
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 {
let ed25519_secret = ed25519_dalek::SecretKey::generate(rng);
let ed25519_secret = ed25519_dalek::SigningKey::generate(rng).to_bytes();
PrivateKey(ed25519_secret)
}
@@ -240,11 +253,11 @@ impl PrivateKey {
}
pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
self.0.to_bytes()
self.0
}
pub fn from_bytes(b: &[u8]) -> Result<Self, Ed25519RecoveryError> {
Ok(PrivateKey(ed25519_dalek::SecretKey::from_bytes(b)?))
Ok(PrivateKey(b.try_into()?))
}
pub fn to_base58_string(&self) -> String {
@@ -259,9 +272,8 @@ impl PrivateKey {
}
pub fn sign<M: AsRef<[u8]>>(&self, message: M) -> Signature {
let expanded_secret_key = ed25519_dalek::ExpandedSecretKey::from(&self.0);
let public_key: PublicKey = self.into();
let sig = expanded_secret_key.sign(message.as_ref(), &public_key.0);
let signing_key: SigningKey = self.0.into();
let sig = signing_key.sign(message.as_ref());
Signature(sig)
}
@@ -330,7 +342,9 @@ impl Signature {
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Ed25519RecoveryError> {
Ok(Signature(ed25519_dalek::Signature::from_bytes(bytes)?))
Ok(Signature(ed25519_dalek::Signature::from_bytes(
bytes.try_into()?,
)))
}
}
+2 -2
View File
@@ -3,11 +3,11 @@
use crate::asymmetric::encryption;
use crate::hkdf;
#[cfg(feature = "rand")]
use cipher::crypto_common::rand_core::{CryptoRng, RngCore};
use cipher::{Key, KeyIvInit, StreamCipher};
use digest::crypto_common::BlockSizeUser;
use digest::Digest;
#[cfg(feature = "rand")]
use rand::{CryptoRng, RngCore};
/// Generate an ephemeral encryption keypair and perform diffie-hellman to establish
/// shared key with the remote.
+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"] }
+6 -3
View File
@@ -18,9 +18,12 @@ pub const VESTING_CONTRACT_ADDRESS: &str =
"n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw";
pub const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = "";
pub const GROUP_CONTRACT_ADDRESS: &str = "";
pub const MULTISIG_CONTRACT_ADDRESS: &str = "";
pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "";
pub const GROUP_CONTRACT_ADDRESS: &str =
"n1e2zq4886zzewpvpucmlw8v9p7zv692f6yck4zjzxh699dkcmlrfqk2knsr";
pub const MULTISIG_CONTRACT_ADDRESS: &str =
"n1txayqfz5g9qww3rlflpg025xd26m9payz96u54x4fe3s2ktz39xqk67gzx";
pub const COCONUT_DKG_CONTRACT_ADDRESS: &str =
"n19604yflqggs9mk2z26mqygq43q2kr3n932egxx630svywd5mpxjsztfpvx";
pub const EPHEMERA_CONTRACT_ADDRESS: &str = "";
pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy";
+1 -1
View File
@@ -8,7 +8,7 @@ license.workspace = true
[dependencies]
futures = { workspace = true }
rand = "0.7.3"
rand = { workspace = true }
serde = { workspace = true }
serde_json = { 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]
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]]
+4
View File
@@ -157,6 +157,10 @@ impl BlindSignRequest {
)
}
pub fn verify_commitment_hash(&self, public_attributes: &[&Attribute]) -> bool {
self.commitment_hash == compute_hash(self.commitment, public_attributes)
}
pub fn get_commitment_hash(&self) -> G1Projective {
self.commitment_hash
}
+2 -2
View File
@@ -9,8 +9,8 @@ repository = { workspace = true }
[dependencies]
log = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
rand_distr = "0.3"
rand = { workspace = true }
rand_distr = { workspace = true }
thiserror = { workspace = true }
nym-sphinx-acknowledgements = { path = "acknowledgements" }
+1 -1
View File
@@ -8,7 +8,7 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
rand = { workspace = true }
serde_crate = { version = "1.0", optional = true, default_features = false, features = ["derive"], package = "serde" }
generic-array = { workspace = true, optional = true, features = ["serde"] }
thiserror = { workspace = true }
+3 -3
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"] }
rand = "0.8.5"
nym-crypto = { path = "../../crypto", features = ["rand"] }
@@ -8,7 +8,7 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
rand = { workspace = true }
bs58 = { workspace = true }
serde = { workspace = true }
thiserror = { workspace = true }
@@ -24,4 +24,4 @@ nym-topology = { path = "../../topology" }
version = "0.2.83"
[dev-dependencies]
rand_chacha = "0.2"
rand_chacha = "0.3"
+1 -1
View File
@@ -11,7 +11,7 @@ repository = { workspace = true }
[dependencies]
log = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
rand = { workspace = true }
thiserror = { workspace = true }
nym-sphinx-addressing = { path = "../addressing" }
+1 -1
View File
@@ -8,7 +8,7 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
rand = { workspace = true }
thiserror = { workspace = true }
nym-crypto = { path = "../../crypto" }
+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 }
+1 -1
View File
@@ -15,7 +15,7 @@ pub use sphinx_packet::{
self, DESTINATION_ADDRESS_LENGTH, IDENTIFIER_LENGTH, MAX_PATH_LENGTH, NODE_ADDRESS_LENGTH,
PAYLOAD_KEY_SIZE,
},
crypto::{self, EphemeralSecret, PrivateKey, PublicKey, SharedSecret},
crypto::{self, PrivateKey, PublicKey},
header::{self, delays, delays::Delay, ProcessedHeader, SphinxHeader, HEADER_SIZE},
packet::builder::DEFAULT_PAYLOAD_SIZE,
payload::{Payload, PAYLOAD_OVERHEAD_SIZE},
+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
@@ -249,7 +249,7 @@ impl BlockProcessor {
match to_prune {
v if v > 1000 => warn!("approximately {v} blocks worth of data will be pruned"),
v if v > 100 => info!("approximately {v} blocks worth of data will be pruned"),
v if v == 0 => trace!("no blocks to prune"),
0 => trace!("no blocks to prune"),
v => debug!("approximately {v} blocks worth of data will be pruned"),
}
+1 -1
View File
@@ -8,4 +8,4 @@ license = { workspace = true }
repository = { workspace = true }
[dependencies]
pem = "0.8"
pem = { workspace = true }
+4 -4
View File
@@ -11,14 +11,14 @@ anyhow = { workspace = true }
dirs = "4.0"
futures = { workspace = true }
log = { workspace = true }
pin-project = "1.0"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
pin-project = { workspace = true }
rand = { workspace = true }
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
@@ -14,7 +14,7 @@ documentation = { workspace = true }
[dependencies]
bs58 = { workspace = true }
log = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
rand = { workspace = true }
thiserror = { workspace = true }
async-trait = { workspace = true, optional = true }
semver = "0.11"
+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 = []
+3 -3
View File
@@ -11,7 +11,7 @@ repository = "https://github.com/nymtech/nym"
[dependencies]
async-trait = { workspace = true }
js-sys = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
rand = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde-wasm-bindgen = { workspace = true }
thiserror = { workspace = true }
@@ -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)]
+4 -2
View File
@@ -17,12 +17,14 @@ 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:
@@ -32,7 +34,7 @@ serde_json = { workspace = true, optional = true }
x25519-dalek = { version = "2.0.0", features = ["static_secrets"] }
[dev-dependencies]
rand = "0.7.3"
rand = "0.8.5"
nym-crypto = { path = "../crypto", features = ["rand"]}
+23
View File
@@ -0,0 +1,23 @@
// 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,
}
+3
View File
@@ -32,4 +32,7 @@ pub enum Error {
#[source]
source: hmac::digest::MacError,
},
#[error("peers can't be modified anymore")]
PeerModifyStopped,
}
+4 -1
View File
@@ -1,14 +1,17 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
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, InitMessage, Nonce,
ClientMac, ClientMessage, ClientRegistrationResponse, GatewayClient, GatewayClientRegistry,
InitMessage, Nonce,
};
#[cfg(feature = "verify")]
+4
View File
@@ -24,6 +24,10 @@ impl PeerPublicKey {
pub fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
pub fn inner(&self) -> PublicKey {
self.0
}
}
impl fmt::Display for PeerPublicKey {
+14 -14
View File
@@ -12,12 +12,12 @@ use std::{fmt, ops::Deref, str::FromStr};
#[cfg(feature = "verify")]
use hmac::{Hmac, Mac};
#[cfg(feature = "verify")]
use nym_crypto::asymmetric::encryption::{PrivateKey, PublicKey};
use nym_crypto::asymmetric::encryption::PrivateKey;
#[cfg(feature = "verify")]
use sha2::Sha256;
pub type GatewayClientRegistry = DashMap<PeerPublicKey, GatewayClient>;
pub type PendingRegistrations = DashMap<PeerPublicKey, Nonce>;
pub type PendingRegistrations = DashMap<PeerPublicKey, RegistrationData>;
pub type PrivateIPs = DashMap<IpAddr, Free>;
#[cfg(feature = "verify")]
@@ -56,14 +56,16 @@ impl InitMessage {
#[serde(tag = "type", rename_all = "camelCase")]
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
pub enum ClientRegistrationResponse {
PendingRegistration {
nonce: u64,
gateway_data: GatewayClient,
wg_port: u16,
},
Registered {
success: bool,
},
PendingRegistration(RegistrationData),
Registered,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
pub struct RegistrationData {
pub nonce: u64,
pub gateway_data: GatewayClient,
pub wg_port: u16,
}
/// Client that wants to register sends its PublicKey bytes mac digest encrypted with a DH shared secret.
@@ -87,7 +89,7 @@ impl GatewayClient {
#[cfg(feature = "verify")]
pub fn new(
local_secret: &PrivateKey,
remote_public: PublicKey,
remote_public: x25519_dalek::PublicKey,
private_ip: IpAddr,
nonce: u64,
) -> Self {
@@ -96,8 +98,6 @@ 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
@@ -220,7 +220,7 @@ mod tests {
let client = GatewayClient::new(
client_key_pair.private_key(),
*gateway_key_pair.public_key(),
x25519_dalek::PublicKey::from(gateway_key_pair.public_key().to_bytes()),
"10.0.0.42".parse().unwrap(),
nonce,
);
+4 -4
View File
@@ -12,16 +12,16 @@ license.workspace = true
[dependencies]
base64 = "0.21.3"
dashmap = { workspace = true }
defguard_wireguard_rs = { workspace = true }
# The latest version on crates.io at the time of writing this (6.0.0) has a
# 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-crypto = { path = "../crypto", features = ["asymmetric"] }
nym-network-defaults = { path = "../network-defaults" }
nym-task = { path = "../task" }
nym-wireguard-types = { path = "../wireguard-types" }
tokio = { workspace = true, features = ["rt-multi-thread", "net", "io-util"] }
[target."cfg(target_os = \"linux\")".dependencies]
defguard_wireguard_rs = { git = "https://github.com/neacsu/wireguard-rs.git", rev = "c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed" }
+126 -28
View File
@@ -3,44 +3,142 @@
// #![warn(clippy::expect_used)]
// #![warn(clippy::unwrap_used)]
pub mod setup;
use dashmap::DashMap;
use defguard_wireguard_rs::{host::Peer, key::Key, net::IpAddrMask, WGApi};
use nym_crypto::asymmetric::encryption::KeyPair;
use nym_wireguard_types::{Config, Error, GatewayClient, GatewayClientRegistry};
use peer_controller::PeerControlMessage;
use std::sync::Arc;
use tokio::sync::mpsc::{self, UnboundedReceiver};
const WG_TUN_NAME: &str = "nymwg";
pub mod peer_controller;
pub struct WgApiWrapper {
inner: WGApi,
}
impl WgApiWrapper {
pub fn new(wg_api: WGApi) -> Self {
WgApiWrapper { inner: wg_api }
}
}
impl Drop for WgApiWrapper {
fn drop(&mut self) {
if let Err(e) = defguard_wireguard_rs::WireguardInterfaceApi::remove_interface(&self.inner)
{
log::error!("Could not remove the wireguard interface: {:?}", e);
}
}
}
#[derive(Clone)]
pub struct WireguardGatewayData {
config: Config,
keypair: Arc<KeyPair>,
client_registry: Arc<GatewayClientRegistry>,
peer_tx: mpsc::UnboundedSender<PeerControlMessage>,
}
impl WireguardGatewayData {
pub fn new(
config: Config,
keypair: Arc<KeyPair>,
) -> (Self, mpsc::UnboundedReceiver<PeerControlMessage>) {
let (peer_tx, peer_rx) = mpsc::unbounded_channel();
(
WireguardGatewayData {
config,
keypair,
client_registry: Arc::new(DashMap::default()),
peer_tx,
},
peer_rx,
)
}
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
}
pub fn add_peer(&self, client: &GatewayClient) -> Result<(), Error> {
let mut peer = Peer::new(Key::new(client.pub_key.to_bytes()));
peer.allowed_ips
.push(IpAddrMask::new(client.private_ip, 32));
let msg = PeerControlMessage::AddPeer(peer);
self.peer_tx.send(msg).map_err(|_| Error::PeerModifyStopped)
}
pub fn remove_peer(&self, client: &GatewayClient) -> Result<(), Error> {
let key = Key::new(client.pub_key().to_bytes());
let msg = PeerControlMessage::RemovePeer(key);
self.peer_tx.send(msg).map_err(|_| Error::PeerModifyStopped)
}
}
pub struct WireguardData {
pub inner: WireguardGatewayData,
pub peer_rx: UnboundedReceiver<PeerControlMessage>,
}
/// Start wireguard device
#[cfg(target_os = "linux")]
pub async fn start_wireguard(
mut task_client: nym_task::TaskClient,
_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 crate::setup::{peer_allowed_ips, peer_static_public_key, PRIVATE_KEY};
use defguard_wireguard_rs::{
host::Peer, key::Key, net::IpAddrMask, InterfaceConfiguration, WGApi, WireguardInterfaceApi,
};
use nym_network_defaults::{WG_PORT, WG_TUN_DEVICE_ADDRESS};
task_client: nym_task::TaskClient,
wireguard_data: WireguardData,
) -> Result<std::sync::Arc<WgApiWrapper>, Box<dyn std::error::Error + Send + Sync + 'static>> {
use base64::{prelude::BASE64_STANDARD, Engine};
use defguard_wireguard_rs::{InterfaceConfiguration, WireguardInterfaceApi};
use ip_network::IpNetwork;
use peer_controller::PeerController;
let ifname = String::from("wg0");
let wgapi = WGApi::new(ifname.clone(), false)?;
wgapi.create_interface()?;
let mut peers = vec![];
for peer_client in wireguard_data.inner.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);
}
let ifname = String::from(WG_TUN_NAME);
let wg_api = defguard_wireguard_rs::WGApi::new(ifname.clone(), false)?;
wg_api.create_interface()?;
let interface_config = InterfaceConfiguration {
name: ifname.clone(),
prvkey: PRIVATE_KEY.to_string(),
address: WG_TUN_DEVICE_ADDRESS.to_string(),
port: WG_PORT as u32,
peers: vec![],
prvkey: BASE64_STANDARD.encode(wireguard_data.inner.keypair().private_key().to_bytes()),
address: wireguard_data.inner.config().private_ip.to_string(),
port: wireguard_data.inner.config().announced_port as u32,
peers,
};
wgapi.configure_interface(&interface_config)?;
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()])?;
wg_api.configure_interface(&interface_config)?;
tokio::spawn(async move { task_client.recv().await });
// Use a dummy peer to create routing rule for the entire network space
let mut catch_all_peer = Peer::new(Key::new([0; 32]));
let network = IpNetwork::new_truncate(
wireguard_data.inner.config().private_ip,
wireguard_data.inner.config().private_network_prefix,
)?;
catch_all_peer.set_allowed_ips(vec![IpAddrMask::new(
network.network_address(),
network.netmask(),
)]);
wg_api.configure_peer_routing(&[catch_all_peer])?;
Ok(wgapi)
let wg_api = std::sync::Arc::new(WgApiWrapper::new(wg_api));
let mut controller = PeerController::new(wg_api.clone(), wireguard_data.peer_rx);
tokio::spawn(async move { controller.run(task_client).await });
Ok(wg_api)
}
#[cfg(not(target_os = "linux"))]
+58
View File
@@ -0,0 +1,58 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::sync::Arc;
use defguard_wireguard_rs::{host::Peer, key::Key, WireguardInterfaceApi};
use tokio::sync::mpsc;
use crate::WgApiWrapper;
pub enum PeerControlMessage {
AddPeer(Peer),
RemovePeer(Key),
}
pub struct PeerController {
peer_rx: mpsc::UnboundedReceiver<PeerControlMessage>,
wg_api: Arc<WgApiWrapper>,
}
impl PeerController {
pub fn new(
wg_api: Arc<WgApiWrapper>,
peer_rx: mpsc::UnboundedReceiver<PeerControlMessage>,
) -> Self {
PeerController { wg_api, peer_rx }
}
pub async fn run(&mut self, mut task_client: nym_task::TaskClient) {
loop {
tokio::select! {
_ = task_client.recv() => {
log::trace!("PeerController handler: Received shutdown");
break;
}
msg = self.peer_rx.recv() => {
match msg {
Some(PeerControlMessage::AddPeer(peer)) => {
if let Err(e) = self.wg_api.inner.configure_peer(&peer) {
log::error!("Could not configure peer: {:?}", e);
}
}
Some(PeerControlMessage::RemovePeer(peer_pubkey)) => {
if let Err(e) = self.wg_api.inner.remove_peer(&peer_pubkey) {
log::error!("Could not remove peer: {:?}", e);
}
}
None => {
log::trace!("PeerController [main loop]: stopping since channel closed");
break;
}
}
}
}
}
}
}
-56
View File
@@ -1,56 +0,0 @@
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()
}
+285 -349
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -32,7 +32,7 @@ cw-multi-test = { workspace = true }
cw3-flex-multisig = { path = "../multisig/cw3-flex-multisig" }
cw4-group = { path = "../multisig/cw4-group" }
rand_chacha = "0.2"
rand_chacha = "0.3"
[[test]]
name = "coconut-test"
@@ -25,7 +25,7 @@ nym-vesting-contract = { path = "../vesting" }
nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] }
# external dependencies
rand_chacha = "0.2"
rand_chacha = "0.3"
[[test]]
name = "mixnet-vesting-test"

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