Compare commits

...

141 Commits

Author SHA1 Message Date
Bogdan-Ștefan Neacşu 3f922cc0ae Update peer refresh value (#4754)
* Use a more proper timeout value

* Move const to wireguard types
2024-08-06 16:16:27 +00:00
Jon Häggblad e5d68a5e7f Don't set NYM_VPN_API to default (#4740) 2024-07-31 11:45:36 +02:00
Tommy Verrall 7ddd819ff3 Merge pull request #4739 from nymtech/tommy/add-wireguard-publish-binaries
Update publish-nym-binaries.yml
2024-07-30 11:41:43 +02:00
Tommy Verrall 83b416d12d amend build all binaries command 2024-07-30 11:38:07 +02:00
Tommy Verrall b9c775c3ae Update publish-nym-binaries.yml
add wireguard to builds
2024-07-30 11:27:50 +02:00
mx 6f669866e9 Max/doc link fix (#4737)
* fix broken link in header dropdown

---------

Co-authored-by: serinko <97586125+serinko@users.noreply.github.com>
Co-authored-by: mfahampshire <mfahampshire@pm.me>
2024-07-30 08:48:14 +00:00
Tommy Verrall 4e61fefec8 Merge pull request #4736 from nymtech/jon/nym-vpn-api-env
Add NYM_VPN_API to network config
2024-07-30 10:04:55 +02:00
Jon Häggblad b4514ecd83 update for wallet 2024-07-29 23:50:52 +02:00
Jon Häggblad 4f6902525e restore explorer-api 2024-07-29 23:30:09 +02:00
Jon Häggblad 881139e36f Add nym_vpn_api_url 2024-07-29 23:30:09 +02:00
Jon Häggblad 32e2557456 Fix tokio error in 1.39 (#4730)
* Fix tokio error in 1.39

Fix the error generated by tokio 1.39

72 | /             tokio::select! {
173 | |                 daemon_res = &mut fused_runner => {
174 | |                     warn!("the daemon has terminated by itself - was it a short lived command?");
175 | |                     let exit_status = daemon_res?;
...   |
179 | |                 event = &mut self.upgrade_plan_watcher.next() => {
    | |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
...   |
201 | |                 }
202 | |             }
    | |             -
    | |             |
    | |_____________temporary value is freed at the end of this statement
    |               borrow later used here

and

62 | /         select! {
63 | |             connection_message = &mut mix_receiver.next() => {
   | |                                       ^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
64 | |                 if let Some(connection_message) = connection_message {
65 | |                     if deal_with_message(connection_message, &mut writer, &local_destination_address, &remote_source_address, connection_id).await {
...  |
86 | |             }
87 | |         }
   | |         -
   | |         |
   | |_________temporary value is freed at the end of this statement
   |           borrow later used here

* Upgrade to tokio 1.39.1

* Simpler attempt

* Revert fixes and instead bump to tokio 1.39.2

* update

* bump msrv for nym-node-tester-wasm
2024-07-29 20:45:26 +02:00
Jon Häggblad 8b44820e51 Re-export RecipientFormattingError in nym sdk (#4735) 2024-07-29 19:20:26 +02:00
import this 5e6417f837 clarify syntax - PR ready (#4734) 2024-07-29 13:51:31 +00:00
Jędrzej Stuczyński dfb2a2f380 Merge pull request #4716 from nymtech/feature/vesting-purge-plus-ranged-cost-params
Feature/vesting purge plus ranged cost params
2024-07-26 18:01:29 +01:00
fmtabbara d1de751850 fix ci 2024-07-26 17:28:24 +01:00
Jędrzej Stuczyński ecee6ca863 chore: cargo fmt 2024-07-26 15:08:38 +01:00
fmtabbara 31ea3f92e2 update bonding oc and pm validation 2024-07-26 15:08:38 +01:00
fmtabbara f19c934fae finish migrate vested bonded node work 2024-07-26 15:08:38 +01:00
Mark Sinclair 10d6f20de7 wip: add profit margin and cost params into validation from mixnet contract via MainContext 2024-07-26 15:08:38 +01:00
Mark Sinclair 96b33bfbe4 Regenerate TS types 2024-07-26 15:08:38 +01:00
Mark Sinclair 444c787d0a Add kind prop to vesting contract migration modal 2024-07-26 15:08:38 +01:00
Mark Sinclair 61fcd4ac69 Dialog and mock for migrating vesting contract delegations 2024-07-26 15:08:38 +01:00
Jędrzej Stuczyński b76802e6eb exposed tauri operations for vesting migrations 2024-07-26 15:08:38 +01:00
Mark Sinclair 7d351029a4 Fix dependency issue 2024-07-26 15:08:37 +01:00
Jędrzej Stuczyński 4ee445c119 cargo fmt 2024-07-26 15:05:47 +01:00
Jędrzej Stuczyński 61ddeea495 fixed post-rebasing imports 2024-07-26 15:05:47 +01:00
Jędrzej Stuczyński 7b802033b3 missing test fixture 2024-07-26 15:05:47 +01:00
Jędrzej Stuczyński b484f47369 fix nym-cli 2024-07-26 15:05:47 +01:00
Jędrzej Stuczyński 66979df10c update contract schema 2024-07-26 15:05:47 +01:00
Jędrzej Stuczyński 82f161fb91 added associated [hacky] wallet types 2024-07-26 15:05:47 +01:00
Jędrzej Stuczyński 9d0fd681d4 introducing allowed range of operator interval operating cost 2024-07-26 15:05:47 +01:00
Jędrzej Stuczyński c2ab47a102 profit margin range validation 2024-07-26 15:05:46 +01:00
Jędrzej Stuczyński 8704c21621 normalise node's profit margin during rewarding 2024-07-26 15:05:46 +01:00
Jędrzej Stuczyński 03ffb25bf9 introduced the concept of allowed profit margin ranges 2024-07-26 15:05:46 +01:00
Jędrzej Stuczyński 70db1ad062 fixed vesting contract tests 2024-07-26 15:05:46 +01:00
Jędrzej Stuczyński 952ed9b642 fixed wallet vesting-related tests 2024-07-26 15:05:46 +01:00
Jędrzej Stuczyński f57fe79686 updated contract schema 2024-07-26 15:05:46 +01:00
Jędrzej Stuczyński 9179f1c351 exposed migration commands to nym-cli + clippy 2024-07-26 15:05:46 +01:00
Jędrzej Stuczyński c4f7a1e09d implemented migration into non-vesting mixnodes/delegations 2024-07-26 15:05:46 +01:00
Jędrzej Stuczyński 701012a968 ensure no pending proxy events when migrating 2024-07-26 15:05:46 +01:00
Jędrzej Stuczyński 9767f72b8f removed all on_behalf mixnet contract methods 2024-07-26 15:05:46 +01:00
Jędrzej Stuczyński 7b10d92ca4 Merge pull request #4731 from nymtech/chore/1.80-lints
chore: fix 1.80 lint issues
2024-07-26 11:51:23 +01:00
Jędrzej Stuczyński 2c6e5eb673 cherry-pick: fix build issues 2024-07-26 11:11:52 +01:00
Jon Häggblad 02fde4e530 Handle clients with different versions in IPR (#4723)
* Add signable_request function

* Export key type in function signature

* Cargo.lock

* Track client version and respond using it

* Internally use v7 and then down convert if needed

* Local response type

* Streamline

* Strong type for client version

* Remove commented out code

* rustfmt

* Ignore sign verification fail for v6
2024-07-24 15:35:59 +02:00
import this cc25fc1f32 [DOCs/operators]: Changelog for v2024.8 wispa & guide syntax edits (#4728)
* changelog for release v2024.8-wispa

* clarify syntax

* typo fix
2024-07-24 12:38:25 +00:00
benedetta davico c971e486b5 Merge pull request #4726 from nymtech/release/2024.8-wispa
Release/2024.8 wispa into develop
2024-07-24 12:48:57 +02:00
import this 96a9eb6f6a [DOCs/docs]: Commnet out extra stubs (#4727)
* commnet out stubs

* fix broken links - ready to merge
2024-07-24 11:58:14 +02:00
benedetta davico 9eeb61ea0a Merge branch 'develop' into release/2024.8-wispa 2024-07-24 10:56:03 +02:00
John Smith 08042c61ad [DOCs/operators]: Update troubleshooting/vps-isp.md with manual IPv6 configuration (#4651)
* Update vps-isp.md

Added an extra diagnostic step, which helped me to debug lack of routability.

* Update vps-isp.md

Implementing serinko's comments

* Update vps-isp.md

Changed possibly to possible and added how to find IPv6 Gateway.

* Update vps-isp.md

Fixed ifup/ifdown link
2024-07-24 08:53:49 +00:00
Stefano Piermatteo 36c74f30e5 [DOCs/operators]: Syntax fix in setup.md (#4682) 2024-07-24 08:37:33 +00:00
Bogdan-Ștefan Neacşu fd1d437211 Add 1GB/day/user bandwidth cap (#4717)
* Add check for 1GB/day/user and remove stale check

* Use saturated_sub

* Remove from wg peers

* Use 10 seconds instead of 1

* Query bandwidth message

* Ad client query message too

* Keep stale check

* Make bandwidth cap value public

* Fix consumed vs available bug

* Don't overwrite existing registrations

* Use self pub key instead of peer's
2024-07-23 20:49:49 +02:00
Tommy Verrall 4956d13bdc fix conflicts 2024-07-23 17:32:49 +02:00
Jędrzej Stuczyński 6478736654 Merge pull request #4706 from nymtech/chore/remove-old-migration-code
removed mixnode/gateway config migration code and disabled cli without explicit flag
2024-07-23 15:11:36 +01:00
benedettadavico d9f6c0723e updating versions 2024-07-23 15:37:04 +02:00
Jon Häggblad f86050d916 Default construct NodeRole for backwards compatibility (#4722) 2024-07-22 16:04:29 +02:00
Tommy Verrall 52f5656190 Merge pull request #4721 from nymtech/jon/node-role-default
Default construct NodeRole
2024-07-22 15:09:27 +02:00
Jon Häggblad 21cd90f238 Default construct NodeRole for backwards compatibility 2024-07-22 14:59:18 +02:00
import this 4e51188d35 [DOCs/operators]: Guide to back up and restore nym-node (#4720)
* add node backup & node restore guides

* finished: ready to review

* finished: ready to review
2024-07-22 11:17:55 +00:00
John Smith 22eb199936 Update isp-sheet.csv (#4718)
* Update isp-sheet.csv

Added a few known VPS providers which (a) support crypto payment (b) allow TOR in some shape or form (c) more or less know for their stability. Will add more eventually.

* Update isp-sheet.csv

added a few more providers
2024-07-22 10:57:57 +00:00
Tommy Verrall a2fc1bbc96 Merge pull request #4719 from nymtech/serinko/bug-fix/wss-guide
[DOCs/operators]: BugFix - add ssl cert to WSS server block
2024-07-19 12:48:36 +02:00
import this 621599692f add ssl cert to WSS server block 2024-07-19 10:43:02 +00:00
import this 3ad3837c87 done: fix wrong URL and picture formatting (#4714) 2024-07-17 10:47:41 +00:00
import this 4d745e3b7e [DOCs/operators]: Correct ports for bonding (#4707)
* fix port issue for nym-node mixnode

* fix port issue for nym-node mixnode

* simplify language

* clarify moving node info

* syntax fix
2024-07-16 14:00:38 +00:00
Sachin Kamath 3a053b8dd6 fix links (#4712) 2024-07-15 18:06:56 +02:00
Bogdan-Ștefan Neacşu 1f144690da Add upgrades to nym-node for authenticator changes (#4703) (#4710)
* Add iterative upgrades to nym-node

* Authenticator correct configuration

* Add info log

* Enable auth opts on entry gw

* Move ephemeral config from exit_gateway

* Fix fmt

* Fix clippy

* Pass custom transceiver for authenticator

* Fix non-linux build

* Feature gate wg_api

* Change naming from semver to simple incremental

* Move opts unwrap inside the mutable function

* Remove unneeded authenticator_description
2024-07-12 14:45:59 +02:00
Tommy Verrall eec1895acc Merge pull request #4709 from nymtech/dependabot/npm_and_yarn/nym-wallet/webdriver/braces-3.0.3
Bump braces from 3.0.2 to 3.0.3 in /nym-wallet/webdriver
2024-07-12 12:14:04 +02:00
Bogdan-Ștefan Neacşu 72e243042e Add upgrades to nym-node for authenticator changes (#4703)
* Add iterative upgrades to nym-node

* Authenticator correct configuration

* Add info log

* Enable auth opts on entry gw

* Move ephemeral config from exit_gateway

* Fix fmt

* Fix clippy

* Pass custom transceiver for authenticator

* Fix non-linux build

* Feature gate wg_api

* Change naming from semver to simple incremental

* Move opts unwrap inside the mutable function

* Remove unneeded authenticator_description
2024-07-12 12:02:22 +02:00
dependabot[bot] 99864cb7a9 Bump braces from 3.0.2 to 3.0.3 in /nym-wallet/webdriver
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-12 09:09:14 +00:00
Fouad 3155728119 fix explorer mui deps (#4708) 2024-07-12 10:08:29 +01:00
Jędrzej Stuczyński c253b22f69 fixed the positional argument 2024-07-11 16:20:20 +01:00
Jędrzej Stuczyński 66f3a3e9a8 removed mixnode/gateway config migration code and disabled commands without explicit flag 2024-07-11 15:53:10 +01:00
Sachin Kamath 65a1d6d91e switch to new vanity link (#4705) 2024-07-11 13:04:56 +01:00
mx 44cf9b054b Max/dev portal update (#4696)
* updated tutorials with archive + stub

* removed out of date faq pages

* added binary build instructions section

* removed clients from docs

* added clients to devportal

* moved nym-vs-others to docs from devportal

* removed ood quickstart stuff

* tweaked integration options page

* summary changes for new structure

* moved sdk to devportal

* removed sdk from docs

* changed summary file for new structure

* added intro client overview page

* added wallet gif

* fixed now broken links

* removed old comm pages

* added references to newer apps (oreowallet + zcash demo)

* updated darkfi irc socks5

* fixed broken link

---------

Co-authored-by: mfahampshire <mfahampshire@pm.me>
2024-07-10 13:54:13 +02:00
Tommy Verrall 39e2473ef3 Merge pull request #4702 from nymtech/release/2024.7-doubledecker
Release/2024.7 doubledecker
2024-07-10 13:25:11 +02:00
import this 93a108863c add node description and release changelog (#4701) 2024-07-10 10:59:47 +00:00
import this 0905593123 [DOCs/operators]: Test WSS for exit-gateway, write a tutorial & update reversed proxy page (#4694)
* initialise wss guide

* update reverse proxy guide to post smoosh

* finish draft - missing correct script and testing

* syntax edit

* syntax edit

* update WSS configs and script

* edit WSS configs and script

* dinish wss guide - ready to review

* dinish wss guide - ready to review
2024-07-10 10:59:22 +00:00
Tommy Verrall ed9223d5a3 Merge branch 'develop' into release/2024.7-doubledecker 2024-07-10 11:46:21 +02:00
benedettadavico c2ad4e5bb4 Update changelog and bump versions 2024-07-10 11:01:20 +02:00
Tommy Verrall 5f7f5ef92d Merge pull request #4699 from nymtech/release/2024.7-doubledecker
Release/2024.7 doubledecker
2024-07-10 10:46:03 +02:00
Tommy Verrall 962684ff56 Merge pull request #4667 from nymtech/feature/authenticator
Add authenticator
2024-07-10 10:14:58 +02:00
Tommy Verrall 7b3804c078 Merge pull request #4697 from nymtech/event-parsing
add event parsing to support cosmos_sdk > 0.50
2024-07-10 09:55:43 +02:00
Sachin Kamath 170f1823e1 fix tests 2024-07-09 21:54:57 +05:30
Sachin Kamath dc2020559a parse attributes from events instead of raw logs 2024-07-09 21:24:58 +05:30
Tommy Verrall 2b9444cce3 add an early return in parse_raw_str_logs for empty raw log strings.
this accommodates for the v50 chain upgrade
2024-07-09 20:36:36 +05:30
Bogdan-Ștefan Neacşu 68c1c068ac Add old config upgrade flow 2024-07-09 09:16:00 +00:00
Drazen Urch 3d0b70a237 Add mixnodes to self describing api cache (#4684)
* Add mixnodes to self describing api cache

* Use NodeRole enum

* Add route for described mixnodes

* Cleanup contract_cache

* Remove nodestatuscache

* wait_until_ready impl
2024-07-09 10:54:48 +02:00
Bogdan-Ștefan Neacşu 65a6edc78c Add authenticator debug to entry gateway config 2024-07-08 11:00:53 +00:00
Sachin Kamath 2ec8349897 update social links (#4695)
* replace vanity link

* fix links
2024-07-05 14:19:09 +00:00
Bogdan-Ștefan Neacşu 38a2d94f80 Fix clippy 2024-07-05 11:36:15 +00:00
Bogdan-Ștefan Neacşu c7fa910516 Fix add of req id 2024-07-05 10:36:18 +00:00
Bogdan-Ștefan Neacşu 2fe08274dd Add another layer for request id field 2024-07-05 10:20:56 +00:00
mx be89d848dc Max/try fix doc search (#4692)
* minimised dropdown bar

* update ci scripts

* theme changes to dev portal

* theme changes to operators

* theme changes to docs

* theme -> themes

* fixed theme -> themes import in book

* removed bak files

* remove logging from post_process + remove search feature from mdbook

---------

Co-authored-by: mfahampshire <mfahampshire@pm.me>
2024-07-05 12:19:14 +02:00
Bogdan-Ștefan Neacşu a230a9b8b9 Merge remote-tracking branch 'origin/develop' into feature/authenticator 2024-07-05 09:57:48 +00:00
Bogdan-Ștefan Neacşu 72eae7cdf3 Remove stale mid-registrations 2024-07-05 09:38:17 +00:00
Bogdan-Ștefan Neacşu 7cae195370 Typo 2024-07-05 07:54:29 +00:00
Bogdan-Ștefan Neacşu dfb16e385c Rand from workspace 2024-07-05 07:53:33 +00:00
Bogdan-Ștefan Neacşu 660e1cad0a Reconstruction msg 2024-07-04 14:26:37 +00:00
Bogdan-Ștefan Neacşu 7c1aa57a7e Add curr version 2024-07-04 14:15:25 +00:00
Bogdan-Ștefan Neacşu a06e496f78 Add final req creation 2024-07-04 13:54:13 +00:00
Jon Häggblad 70599b97b9 Send bandwidth status messages when connecting (#4691)
* Send bandwidth status messages when connecting

* Rename to task_client

* Move status message type to bandwidth controller
2024-07-04 13:10:16 +02:00
Bogdan-Ștefan Neacşu 02b194bde0 Function to create AuthReq 2024-07-04 10:40:53 +00:00
Bogdan-Ștefan Neacşu 20ec049db5 Remove more unnecessary structures 2024-07-04 09:41:17 +00:00
Bogdan-Ștefan Neacşu fec3d46b33 Include auth in self description 2024-07-03 13:50:44 +00:00
Bogdan-Ștefan Neacşu a4eb3a7dbf Named fork for better logging 2024-07-03 13:03:32 +00:00
Bogdan-Ștefan Neacşu 28d15f2c4f Remove unused import 2024-07-03 11:28:09 +00:00
Jon Häggblad 6078787daa Remove constructor since it's weakly typed (#4689) 2024-07-03 12:26:47 +02:00
Jon Häggblad 6d93f36c82 Fix NR config compatibility (#4690)
* Make NR able to read config with old keys in

We removed stuff related to the old statistics service, so we ignore
unknown fields to be nice to our users

* Remove deleted config keys from NR template
2024-07-03 12:10:41 +02:00
Bogdan-Ștefan Neacşu c6f93e38f5 Remove unused post function 2024-07-03 09:34:03 +00:00
Bogdan-Ștefan Neacşu 2159f71888 Fix wg feature 2024-07-03 09:04:01 +00:00
Bogdan-Ștefan Neacşu a9abea3446 Fix macos build 2024-07-03 08:27:10 +00:00
Bogdan-Ștefan Neacşu 8e2713c9ba Remove unwrap 2024-07-03 08:21:58 +00:00
Bogdan-Ștefan Neacşu 2ba0ef0e35 Remove unused wg http endpoint 2024-07-02 14:09:34 +00:00
Bogdan-Ștefan Neacşu d3713cbc79 Fix user agent arg 2024-07-02 16:40:11 +03:00
Bogdan-Ștefan Neacşu 4d3fb2b585 Merge remote-tracking branch 'origin/develop' into feature/authenticator 2024-07-02 16:25:29 +03:00
import this e65e611859 remove roles selection on blacklisting node - PR done (#4687) 2024-07-02 13:37:23 +01:00
Bogdan-Ștefan Neacşu c465eb3efc Fix error type 2024-07-02 08:58:48 +00:00
Bogdan-Ștefan Neacşu b90136ac4e Uniformise non-linux wg function 2024-07-01 15:10:36 +00:00
Bogdan-Ștefan Neacşu ae5373168d Fmt 2024-07-01 14:42:10 +00:00
Bogdan-Ștefan Neacşu 6f3942f6b7 Move implementation for final request 2024-07-01 14:38:48 +00:00
import this 4a25725a11 README.md update (#4685)
* start README update

* test alpha on github preview

* test alpha on github preview

* comment out rewards

* finish README update
2024-07-01 16:27:59 +02:00
Bogdan-Ștefan Neacşu 13f38343aa Finalize cli build 2024-07-01 13:44:59 +00:00
Jon Häggblad d34c829174 Create UserAgent that can be passed from the binary to the nym api client (#4677)
* Create UserAgent that can be passed from the binary to the nym api client

* TryFrom for UserAgent to HeaderValue

* Add user agent for getting the list of gateways

* Fix wasm client

* Move clap behind feature flag in bin-common

* Implement conversion to UserAgent

* Set user_agent on base client in native and socks5 clients

* Set user agent in socks5-listener lib

* wip

* wip

* Deserialize cargo_triple to unknown by default

* Abbreviate git hash

* Remove unused import

* Add missing dep, and remove dbg statements

* Reorder string representation

* Remove commented out code

* Revert temporary log level change
2024-07-01 13:29:10 +02:00
Bogdan-Ștefan Neacşu f75b4843e8 Merge remote-tracking branch 'origin/develop' into feature/authenticator 2024-07-01 09:56:34 +00:00
Jędrzej Stuczyński 6963ead65a minor cleanup 2024-07-01 08:25:31 +01:00
Jon Häggblad 0425cdeaf0 Merge pull request #4680 from nymtech/jon/deps-to-workspace
Move and whole bump of crates to workspace and upgrade some
2024-06-27 13:25:21 +02:00
import this 789914b096 [DOCs/operators]: Updates v2024.6-chomp and T&Cs (#4674)
* initialise updates and ToC

* add toc flag

* changelog and node black-xit improvement

* add node-api-check option

* syntax fix

* syntax fix

* change CI/CD with git reset

* fix typo

* add T&C AMA explanation link - ready for review

* fix typo

* resolve review comments

* add ToC standalone page

* minor edit - ready to go
2024-06-27 09:59:57 +00:00
benedetta davico 008afe7a85 Merge pull request #4676 from nymtech/release/2024.6-chomp
Release/2024.6-chomp to master
2024-06-27 11:47:55 +02:00
Jon Häggblad 8acd3a0975 Move a few more deps partially to workspace 2024-06-27 10:52:15 +02:00
Jon Häggblad fa1519ec6a Move itertools to workspace deps 2024-06-27 10:52:15 +02:00
Jon Häggblad da94b7e8df Sort list 2024-06-27 10:52:15 +02:00
Jon Häggblad 4aa8cb4647 Move dalek and rand_chacha crates to workspace 2024-06-27 10:52:15 +02:00
Jon Häggblad 5d13538508 Use workspace base64 dep 2024-06-27 10:52:15 +02:00
Jon Häggblad 4bbbcf629d Fix warning for default_features 2024-06-27 10:52:15 +02:00
Jon Häggblad 34ef970fd8 Move dirs 4.0 to workspace deps 2024-06-27 10:52:14 +02:00
Jon Häggblad fec570613c Remove code that refers to removed nym-network-statistics (#4679)
* Remove nym-network-statistics from workspace

* Remove nym-network-statistics

* Cargo.lock

* Update ci workflow

* Remove code that refers to removed nym-network-statistics

* Remove more

* Remove nym-statistics-common

* Delete commented out modules

* Remove commented out code

* Remove more commented out code

* Remove more commented out stuff

* Remove unused function
2024-06-27 10:32:32 +02:00
Jon Häggblad 14a904eff0 Remove nym-network-statistics (#4678)
* Remove nym-network-statistics from workspace

* Remove nym-network-statistics

* Cargo.lock

* Update ci workflow
2024-06-27 10:32:09 +02:00
Bogdan-Ștefan Neacşu b43844bd7a Embed into gateway 2024-06-21 15:51:02 +00:00
Bogdan-Ștefan Neacşu cd89feb57e Fix path 2024-06-20 15:15:05 +00:00
Bogdan-Ștefan Neacşu 17553d606e Requests and responses 2024-06-20 16:58:21 +03:00
Bogdan-Ștefan Neacşu b6d9ed960b Specify version 2024-06-19 11:37:09 +03:00
Bogdan-Ștefan Neacşu 1d89a887fb Add authenticator 2024-06-18 19:05:23 +03:00
475 changed files with 10362 additions and 12175 deletions
+2 -2
View File
@@ -41,8 +41,8 @@ jobs:
# This is a workaround replacement which builds on the last working commit b332a6b55668f60988e36961f3f62a794ba82ddb and then on current branch
- name: Save current branch to ~/current_branch
run: git rev-parse --abbrev-ref HEAD > ~/current_branch
- name: Git pull & switch to b332a6b55668f60988e36961f3f62a794ba82ddb
run: git pull && git checkout b332a6b55668f60988e36961f3f62a794ba82ddb
- name: Git pull, reset & switch to b332a6b55668f60988e36961f3f62a794ba82ddb
run: git pull && git reset --hard && git checkout b332a6b55668f60988e36961f3f62a794ba82ddb
- name: Build all projects in documentation/ & move to ~/dist/docs/ from b332a6b55668f60988e36961f3f62a794ba82ddb
run: cd documentation && ./build_all_to_dist.sh
+2 -2
View File
@@ -46,8 +46,8 @@ jobs:
# This is a workaround replacement which builds on the last working commit b332a6b55668f60988e36961f3f62a794ba82ddb and then on current branch
- name: Save current branch to ~/current_branch
run: git rev-parse --abbrev-ref HEAD > ~/current_branch
- name: Git pull & switch to b332a6b55668f60988e36961f3f62a794ba82ddb
run: git pull && git checkout b332a6b55668f60988e36961f3f62a794ba82ddb
- name: Git pull, reset & switch to b332a6b55668f60988e36961f3f62a794ba82ddb
run: git pull && git reset --hard && git checkout b332a6b55668f60988e36961f3f62a794ba82ddb
- name: Build all projects in documentation/ & move to ~/dist/docs/ from b332a6b55668f60988e36961f3f62a794ba82ddb
run: cd documentation && ./build_all_to_dist.sh
+6 -2
View File
@@ -51,6 +51,10 @@ jobs:
echo 'RUSTFLAGS="--cfg tokio_unstable"' >> $GITHUB_ENV
if: github.event_name == 'workflow_dispatch' && inputs.add_tokio_unstable == true
- name: Set CARGO_FEATURES
run: |
echo 'CARGO_FEATURES=--features wireguard' >> $GITHUB_ENV
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
@@ -60,8 +64,8 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --release
args: --workspace --release ${{ env.CARGO_FEATURES }}
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
+24 -1
View File
@@ -4,6 +4,30 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
## [Unreleased]
## [2024.8-wispa] (2024-07-10)
- add event parsing to support cosmos_sdk > 0.50 ([#4697])
- Fix NR config compatibility ([#4690])
- Remove UserAgent constructor since it's weakly typed ([#4689])
- [bugfix]: Node_api_check CLI looked over roles on blacklisted nodes ([#4687])
- Add mixnodes to self describing api cache ([#4684])
- Move and whole bump of crates to workspace and upgrade some ([#4680])
- Remove code that refers to removed nym-network-statistics ([#4679])
- Remove nym-network-statistics ([#4678])
- Create UserAgent that can be passed from the binary to the nym api client ([#4677])
- Add authenticator ([#4667])
[#4697]: https://github.com/nymtech/nym/pull/4697
[#4690]: https://github.com/nymtech/nym/pull/4690
[#4689]: https://github.com/nymtech/nym/pull/4689
[#4687]: https://github.com/nymtech/nym/pull/4687
[#4684]: https://github.com/nymtech/nym/pull/4684
[#4680]: https://github.com/nymtech/nym/pull/4680
[#4679]: https://github.com/nymtech/nym/pull/4679
[#4678]: https://github.com/nymtech/nym/pull/4678
[#4677]: https://github.com/nymtech/nym/pull/4677
[#4667]: https://github.com/nymtech/nym/pull/4667
## [2024.7-doubledecker] (2024-07-04)
- Add an early return in `parse_raw_str_logs` for empty raw log strings. ([#4686])
@@ -513,7 +537,6 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
[#3187]: https://github.com/nymtech/nym/issues/3187
[#3203]: https://github.com/nymtech/nym/pull/3203
[#3199]: https://github.com/nymtech/nym/pull/3199
>>>>>>> master
## [v1.1.13] (2023-03-15)
Generated
+101 -77
View File
@@ -1378,7 +1378,7 @@ dependencies = [
"bitflags 1.3.2",
"crossterm_winapi",
"libc",
"mio",
"mio 0.8.11",
"parking_lot 0.12.2",
"signal-hook",
"signal-hook-mio",
@@ -1394,7 +1394,7 @@ dependencies = [
"bitflags 1.3.2",
"crossterm_winapi",
"libc",
"mio",
"mio 0.8.11",
"parking_lot 0.12.2",
"signal-hook",
"signal-hook-mio",
@@ -2093,14 +2093,14 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "explorer-api"
version = "1.1.36"
version = "1.1.37"
dependencies = [
"chrono",
"clap 4.5.4",
"dotenvy",
"humantime-serde",
"isocountry",
"itertools 0.10.5",
"itertools 0.12.1",
"log",
"maxminddb",
"nym-bin-common",
@@ -2221,7 +2221,7 @@ dependencies = [
"atomic 0.6.0",
"pear",
"serde",
"toml 0.8.12",
"toml 0.8.14",
"uncased",
"version_check",
]
@@ -3272,15 +3272,6 @@ dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.12.1"
@@ -3605,6 +3596,18 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "mio"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
dependencies = [
"hermit-abi 0.3.9",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.52.0",
]
[[package]]
name = "mix-fetch-wasm"
version = "1.3.0-rc.0"
@@ -3786,7 +3789,7 @@ dependencies = [
"inotify",
"kqueue",
"libc",
"mio",
"mio 0.8.11",
"walkdir",
"windows-sys 0.45.0",
]
@@ -3858,7 +3861,7 @@ dependencies = [
[[package]]
name = "nym-api"
version = "1.1.40"
version = "1.1.41"
dependencies = [
"anyhow",
"async-trait",
@@ -3959,6 +3962,54 @@ dependencies = [
"tokio",
]
[[package]]
name = "nym-authenticator"
version = "0.1.0"
dependencies = [
"anyhow",
"bincode",
"bs58 0.5.1",
"bytes",
"clap 4.5.4",
"fastrand 2.1.0",
"futures",
"ipnetwork 0.16.0",
"log",
"nym-authenticator-requests",
"nym-bin-common",
"nym-client-core",
"nym-config",
"nym-crypto",
"nym-id",
"nym-network-defaults",
"nym-sdk",
"nym-service-providers-common",
"nym-sphinx",
"nym-task",
"nym-types",
"nym-wireguard",
"nym-wireguard-types",
"rand 0.8.5",
"serde",
"serde_json",
"thiserror",
"tokio",
"tokio-stream",
"tokio-util",
"url",
]
[[package]]
name = "nym-authenticator-requests"
version = "0.1.0"
dependencies = [
"bincode",
"nym-sphinx",
"nym-wireguard-types",
"rand 0.8.5",
"serde",
]
[[package]]
name = "nym-bandwidth-controller"
version = "0.1.0"
@@ -4018,7 +4069,7 @@ dependencies = [
[[package]]
name = "nym-cli"
version = "1.1.38"
version = "1.1.39"
dependencies = [
"anyhow",
"base64 0.13.1",
@@ -4097,7 +4148,7 @@ dependencies = [
[[package]]
name = "nym-client"
version = "1.1.37"
version = "1.1.38"
dependencies = [
"bs58 0.5.1",
"clap 4.5.4",
@@ -4282,7 +4333,7 @@ dependencies = [
"ff",
"getrandom 0.2.15",
"group",
"itertools 0.10.5",
"itertools 0.12.1",
"nym-dkg",
"nym-pemstore",
"rand 0.8.5",
@@ -4523,6 +4574,7 @@ dependencies = [
"ipnetwork 0.16.0",
"log",
"nym-api-requests",
"nym-authenticator",
"nym-bin-common",
"nym-config",
"nym-credentials",
@@ -4537,7 +4589,6 @@ dependencies = [
"nym-node-http-api",
"nym-pemstore",
"nym-sphinx",
"nym-statistics-common",
"nym-task",
"nym-types",
"nym-validator-client",
@@ -4633,6 +4684,7 @@ version = "0.1.0"
dependencies = [
"async-trait",
"http 1.1.0",
"nym-bin-common",
"reqwest 0.12.4",
"serde",
"serde_json",
@@ -4910,7 +4962,7 @@ dependencies = [
[[package]]
name = "nym-network-requester"
version = "1.1.38"
version = "1.1.39"
dependencies = [
"addr",
"anyhow",
@@ -4939,7 +4991,6 @@ dependencies = [
"nym-socks5-proxy-helpers",
"nym-socks5-requests",
"nym-sphinx",
"nym-statistics-common",
"nym-task",
"nym-types",
"pretty_env_logger",
@@ -4960,26 +5011,9 @@ dependencies = [
"zeroize",
]
[[package]]
name = "nym-network-statistics"
version = "1.1.34"
dependencies = [
"dirs 4.0.0",
"log",
"nym-bin-common",
"nym-statistics-common",
"nym-task",
"pretty_env_logger",
"rocket",
"serde",
"sqlx",
"thiserror",
"tokio",
]
[[package]]
name = "nym-node"
version = "1.1.4"
version = "1.1.5"
dependencies = [
"anyhow",
"bip39",
@@ -4991,6 +5025,7 @@ dependencies = [
"cupid",
"humantime-serde",
"ipnetwork 0.16.0",
"nym-authenticator",
"nym-bin-common",
"nym-client-core-config-types",
"nym-config",
@@ -5014,7 +5049,7 @@ dependencies = [
"sysinfo 0.30.12",
"thiserror",
"tokio",
"toml 0.8.12",
"toml 0.8.14",
"tracing",
"url",
"zeroize",
@@ -5160,7 +5195,7 @@ dependencies = [
"chacha20poly1305",
"criterion",
"curve25519-dalek 4.1.2",
"fastrand 1.9.0",
"fastrand 2.1.0",
"getrandom 0.2.15",
"log",
"rand 0.8.5",
@@ -5241,7 +5276,7 @@ dependencies = [
[[package]]
name = "nym-socks5-client"
version = "1.1.37"
version = "1.1.38"
dependencies = [
"bs58 0.5.1",
"clap 4.5.4",
@@ -5260,6 +5295,7 @@ dependencies = [
"nym-socks5-client-core",
"nym-sphinx",
"nym-topology",
"nym-validator-client",
"rand 0.8.5",
"serde",
"serde_json",
@@ -5505,20 +5541,6 @@ dependencies = [
"thiserror",
]
[[package]]
name = "nym-statistics-common"
version = "1.0.1"
dependencies = [
"async-trait",
"log",
"reqwest 0.12.4",
"serde",
"serde_json",
"sqlx",
"thiserror",
"tokio",
]
[[package]]
name = "nym-store-cipher"
version = "0.1.0"
@@ -5593,7 +5615,7 @@ dependencies = [
"cosmwasm-std",
"eyre",
"hmac",
"itertools 0.11.0",
"itertools 0.12.1",
"log",
"nym-config",
"nym-crypto",
@@ -5632,7 +5654,7 @@ dependencies = [
"eyre",
"flate2",
"futures",
"itertools 0.10.5",
"itertools 0.12.1",
"log",
"nym-api-requests",
"nym-coconut",
@@ -5732,6 +5754,7 @@ name = "nym-wireguard"
version = "0.1.0"
dependencies = [
"base64 0.21.7",
"chrono",
"dashmap",
"defguard_wireguard_rs",
"ip_network",
@@ -5740,6 +5763,7 @@ dependencies = [
"nym-network-defaults",
"nym-task",
"nym-wireguard-types",
"thiserror",
"tokio",
"tokio-stream",
"x25519-dalek",
@@ -5767,7 +5791,7 @@ dependencies = [
[[package]]
name = "nymvisor"
version = "0.1.3"
version = "0.1.4"
dependencies = [
"anyhow",
"bytes",
@@ -7594,9 +7618,9 @@ dependencies = [
[[package]]
name = "serde_spanned"
version = "0.6.5"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
dependencies = [
"serde",
]
@@ -7733,7 +7757,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
dependencies = [
"libc",
"mio",
"mio 0.8.11",
"signal-hook",
]
@@ -8442,22 +8466,21 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.37.0"
version = "1.39.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
dependencies = [
"backtrace",
"bytes",
"libc",
"mio",
"num_cpus",
"mio 1.0.1",
"parking_lot 0.12.2",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"tracing",
"windows-sys 0.48.0",
"windows-sys 0.52.0",
]
[[package]]
@@ -8472,9 +8495,9 @@ dependencies = [
[[package]]
name = "tokio-macros"
version = "2.2.0"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
dependencies = [
"proc-macro2",
"quote",
@@ -8616,21 +8639,21 @@ dependencies = [
[[package]]
name = "toml"
version = "0.8.12"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.22.12",
"toml_edit 0.22.14",
]
[[package]]
name = "toml_datetime"
version = "0.6.5"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
dependencies = [
"serde",
]
@@ -8650,9 +8673,9 @@ dependencies = [
[[package]]
name = "toml_edit"
version = "0.22.12"
version = "0.22.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef"
checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
dependencies = [
"indexmap 2.2.6",
"serde",
@@ -9427,6 +9450,7 @@ dependencies = [
name = "wasm-utils"
version = "0.1.0"
dependencies = [
"console_error_panic_hook",
"futures",
"getrandom 0.2.15",
"gloo-net",
+18 -8
View File
@@ -20,6 +20,7 @@ members = [
"clients/native",
"clients/native/websocket-requests",
"clients/socks5",
"common/authenticator-requests",
"common/async-file-watcher",
"common/bandwidth-controller",
"common/bin-common",
@@ -76,7 +77,6 @@ members = [
"common/socks5-client-core",
"common/socks5/proxy-helpers",
"common/socks5/requests",
"common/statistics",
"common/store-cipher",
"common/task",
"common/topology",
@@ -96,10 +96,10 @@ members = [
"mixnode",
"sdk/lib/socks5-listener",
"sdk/rust/nym-sdk",
"service-providers/authenticator",
"service-providers/common",
"service-providers/ip-packet-router",
"service-providers/network-requester",
"service-providers/network-statistics",
"nym-api",
"nym-browser-extension/storage",
"nym-api/nym-api-requests",
@@ -127,7 +127,6 @@ default-members = [
"clients/socks5",
"gateway",
"service-providers/network-requester",
"service-providers/network-statistics",
"mixnode",
"nym-api",
"tools/nymvisor",
@@ -192,12 +191,15 @@ cupid = "0.6.1"
curve25519-dalek = "4.1"
dashmap = "5.5.3"
defguard_wireguard_rs = "0.4.2"
digest = "0.10.7"
dirs = "4.0"
doc-comment = "0.3"
dotenvy = "0.15.6"
ecdsa = "0.16"
ed25519-dalek = "2.1"
etherparse = "0.13.0"
eyre = "0.6.9"
fastrand = "2.1.0"
flate2 = "1.0.28"
futures = "0.3.28"
generic-array = "0.14.7"
@@ -209,14 +211,15 @@ hex = "0.4.3"
hex-literal = "0.3.3"
hkdf = "0.12.3"
hmac = "0.12.1"
http = "1"
httpcodec = "0.2.3"
humantime = "2.1.0"
humantime-serde = "1.1.1"
http = "1"
hyper = "1.3.1"
indexed_db_futures = "0.3.0"
inquire = "0.6.2"
ip_network = "0.4.1"
ipnetwork = "0.16"
isocountry = "0.3.2"
k256 = "0.13"
lazy_static = "1.4.0"
@@ -239,6 +242,7 @@ publicsuffix = "2.2.3"
quote = "1"
rand = "0.8.5"
rand-07 = "0.7.3"
rand_chacha = "0.3"
rand_chacha_02 = "0.2"
rand_core = "0.6.3"
rand_distr = "0.4"
@@ -252,6 +256,7 @@ rocket_cors = "0.6.0"
rocket_okapi = "0.8.0"
safer-ffi = "0.1.4"
schemars = "0.8.1"
semver = "1.0.23"
serde = "1.0.152"
serde_bytes = "0.11.6"
serde_derive = "1.0"
@@ -259,22 +264,25 @@ serde_json = "1.0.91"
serde_repr = "0.1"
serde_with = "3.4.0"
serde_yaml = "0.9.25"
sha2 = "0.10.8"
si-scale = "0.2.2"
sphinx-packet = "0.1.1"
sqlx = "0.6.3"
strum = "0.25"
subtle-encoding = "0.5"
syn = "1"
sysinfo = "0.30.12"
tap = "1.0.1"
tar = "0.4.40"
tempfile = "3.5.0"
thiserror = "1.0.48"
time = "0.3.30"
tokio = "1.33.0"
tokio-stream = "0.1.14"
tokio-test = "0.4.2"
tokio = "1.39"
tokio-stream = "0.1.15"
tokio-test = "0.4.4"
tokio-tungstenite = { version = "0.20.1" }
tokio-util = "0.7.10"
tokio-util = "0.7.11"
toml = "0.8.14"
tower = "0.4.13"
tower-http = "0.5.2"
tracing = "0.1.37"
@@ -289,6 +297,7 @@ utoipa-swagger-ui = "6.0.0"
vergen = { version = "=8.3.1", default-features = false }
walkdir = "2"
wasm-bindgen-test = "0.3.36"
x25519-dalek = "2.0.0"
zeroize = "1.6.0"
prometheus = { version = "0.13.0" }
@@ -336,6 +345,7 @@ wasm-bindgen = "0.2.92"
wasm-bindgen-futures = "0.4.39"
wasmtimer = "0.2.0"
web-sys = "0.3.69"
itertools = "0.12.0"
# Profile settings for individual crates
+36 -56
View File
@@ -7,86 +7,66 @@ SPDX-License-Identifier: Apache-2.0
The platform is composed of multiple Rust crates. Top-level executable binary crates include:
* nym-mixnode - shuffles [Sphinx](https://github.com/nymtech/sphinx) packets together to provide privacy against network-level attackers.
* nym-client - an executable which you can build into your own applications. Use it for interacting with Nym nodes.
* nym-socks5-client - a Socks5 proxy you can run on your machine and use with existing applications.
* nym-gateway - acts sort of like a mailbox for mixnet messages, which removes the need for direct delivery to potentially offline or firewalled devices.
* nym-network-monitor - sends packets through the full system to check that they are working as expected, and stores node uptime histories as the basis of a rewards system ("mixmining" or "proof-of-mixing").
* nym-explorer - a (projected) block explorer and (existing) mixnet viewer.
* nym-wallet - a desktop wallet implemented using the [Tauri](https://tauri.studio/en/docs/about/intro) framework.
* `nym-node` - a tool for running a node within the Nym network. Nym Nodes containing functionality such as `mixnode`, `entry-gateway` and `exit-gateway` are fundamental components of Nym Mixnet architecture. Nym Nodes are ran by decentralised node operators. Read more about `nym-node` in [Operators Guide documentation](https://nymtech.net/operators/nodes/nym-node.html). Network functionality of `nym-node` (labeled with `--mode` flag) can be:
- `mixnode` - shuffles [Sphinx](https://github.com/nymtech/sphinx) packets together to provide privacy against network-level attackers.
- `gateway` - acts sort of like a mailbox for mixnet messages, which removes the need for direct delivery to potentially offline or firewalled devices. Gateways can be further categorized as `entry-gateway` and `exit-gateway`. The latter has an extra embedded IP packet router and Network requester to route data to the internet.
* `nym-client` - an executable which you can build into your own applications. Use it for interacting with Nym nodes.
* `nym-socks5-client` - a Socks5 proxy you can run on your machine and use with existing applications.
* `nym-explorer` - a (projected) block explorer and (existing) mixnet viewer.
* `nym-wallet` - a desktop wallet implemented using the [Tauri](https://tauri.studio/en/docs/about/intro) framework.
<!-- coming soon
* `nym-network-monitor` - sends packets through the full system to check that they are working as expected, and stores node uptime histories as the basis of a rewards system ("mixmining" or "proof-of-mixing").
-->
```ascii
┌─►mix──┐ mix mix
│ │
Entry │ │ Exit
client ───► Gateway ──┘ mix │ mix ┌─►mix ───► Gateway ───► internet
│ │
│ │
mix └─►mix──┘ mix
```
[![Build Status](https://img.shields.io/github/actions/workflow/status/nymtech/nym/build.yml?branch=develop&style=for-the-badge&logo=github-actions)](https://github.com/nymtech/nym/actions?query=branch%3Adevelop)
### Building
Platform build instructions are available on [our docs site](https://nymtech.net/docs/binaries/pre-built-binaries.html).
Wallet build instructions are also available on [our docs site](https://nymtech.net/docs/wallet/desktop-wallet.html).
* Platform build instructions are available on Nym [Operators Guide documentation](https://nymtech.net/operators/binaries/building-nym.html).
* Wallet build instructions are available on Nym [Technical docs](https://nymtech.net/docs/wallet/desktop-wallet.html).
### Developing
There's a `.env.sample-dev` file provided which you can rename to `.env` if you want convenient logging, backtrace, or other environment variables pre-set. The `.env` file is ignored so you don't need to worry about checking it in.
There's a [`sandbox.env`](https://github.com/nymtech/nym/envs/sandbox.env) file provided which you can rename to `.env` if you want convenient testing environment. Read more about sandbox environment in our [Operators Guide page](https://nymtech.net/operators/sandbox.html).
For Typescript components, please see [ts-packages](./ts-packages).
References for developers:
* [Developers Portal](https://nymtech.net/developers)
* [Typescript SDKs](https://sdk.nymtech.net/)
* [Technical Documentation - Nym network overview](https://nymtech.net/docs/)
* [Release Cycle - git flow](https://nymtech.net/operators/release-cycle.html)
### Developer chat
> We used to use Keybase for developer chats, but we have since migrated to Matrix and Discord. We no longer check the old **nymtech.friends** Keybase team.
You can chat to us in two places:
* The #dev channel on [Matrix](https://matrix.to/#/#dev:nymtech.chat)
* The various developer channels on [Discord](https://discord.gg/nym)
* The various developer channels on [Discord](https://nymtech.net/go/discord)
### Rewards
### Tokenomics & Rewards
Node, node operator and delegator rewards are determined according to the principles laid out in the section 6 of [Nym Whitepaper](https://nymtech.net/nym-whitepaper.pdf). Below is a TLDR of the variables and formulas involved in calculating the epoch rewards. Initial reward pool is set to 250 million Nym, making the circulating supply 750 million Nym.
|Symbol|Definition|
|---|---|
|<img src="https://render.githubusercontent.com/render/math?math=R#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}R#gh-dark-mode-only">|global share of rewards available, starts at 2% of the reward pool.
|<img src="https://render.githubusercontent.com/render/math?math=R_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}R_{i}#gh-dark-mode-only">|node reward for mixnode `i`.
|<img src="https://render.githubusercontent.com/render/math?math=\sigma_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}\sigma_{i}#gh-dark-mode-only">|ratio of total node stake (node bond + all delegations) to the token circulating supply.
|<img src="https://render.githubusercontent.com/render/math?math=\lambda_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}\lambda_{i}#gh-dark-mode-only">|ratio of stake operator has pledged to their node to the token circulating supply.
|<img src="https://render.githubusercontent.com/render/math?math=\omega_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}\omega_{i}#gh-dark-mode-only">|fraction of total effort undertaken by node `i`, set to `1/k`.
|<img src="https://render.githubusercontent.com/render/math?math=k#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}k#gh-dark-mode-only">|number of nodes stakeholders are incentivised to create, set by the validators, a matter of governance. Currently determined by the `reward set` size, and set to 720 in testnet Sandbox.
|<img src="https://render.githubusercontent.com/render/math?math=\alpha#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}\alpha#gh-dark-mode-only">|A Sybil attack resistance parameter - the higher this parameter is set, the stronger the reduction in competitiveness for a Sybil attacker.
|<img src="https://render.githubusercontent.com/render/math?math=PM_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}PM_{i}#gh-dark-mode-only">|declared profit margin of operator `i`, defaults to 10%.
|<img src="https://render.githubusercontent.com/render/math?math=PF_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}PF_{i}#gh-dark-mode-only">|uptime of node `i`, scaled to 0 - 1, for the rewarding epoch
|<img src="https://render.githubusercontent.com/render/math?math=PP_{i}#gh-light-mode-only"><img src="https://render.githubusercontent.com/render/math?math=\color{white}PP_{i}#gh-dark-mode-only">|cost of operating node `i` for the duration of the rewarding epoch, set to 40 NYMs.
Node reward for node `i` is determined as:
<img src="https://render.githubusercontent.com/render/math?math=R_{i}=PF_{i} \cdot R \cdot (\sigma^'_{i} \cdot \omega_{i} \cdot k %2b \alpha \cdot \lambda^'_{i} \cdot \sigma^'_{i} \cdot k)/(1 %2b \alpha)#gh-light-mode-only">
<img src="https://render.githubusercontent.com/render/math?math=\color{white}R_{i}=PF_{i} \cdot R \cdot (\sigma^'_{i} \cdot \omega_{i} \cdot k %2b \alpha \cdot \lambda^'_{i} \cdot \sigma^'_{i} \cdot k)/(1 %2b \alpha)#gh-dark-mode-only">
where:
<img src="https://render.githubusercontent.com/render/math?math=\sigma^'_{i} = min\{\sigma_{i}, 1/k\}#gh-light-mode-only">
<img src="https://render.githubusercontent.com/render/math?math=\color{white}\sigma^'_{i} = min\{\sigma_{i}, 1/k\}#gh-dark-mode-only">
and
<img src="https://render.githubusercontent.com/render/math?math=\lambda^'_{i} = min\{\lambda_{i}, 1/k\}#gh-light-mode-only">
<img src="https://render.githubusercontent.com/render/math?math=\color{white}\lambda^'_{i} = min\{\lambda_{i}, 1/k\}#gh-dark-mode-only">
Operator of node `i` is credited with the following amount:
<img src="https://render.githubusercontent.com/render/math?math=min\{PP_{i},R_{i})\} %2b max\{0, (PM_{i} %2b (1 - PM_{i}) \cdot \lambda_{i}/\delta_{i}) \cdot (R_{i} - PP_{i})\}#gh-light-mode-only">
<img src="https://render.githubusercontent.com/render/math?math=\color{white}min\{PP_{i},R_{i})\} %2b max\{0, (PM_{i} %2b (1 - PM_{i}) \cdot \lambda_{i}/\delta_{i}) \cdot (R_{i} - PP_{i})\}#gh-dark-mode-only">
Delegate with stake `s` receives:
<img src="https://render.githubusercontent.com/render/math?math=max\{0, (1-PM_{i}) \cdot (s^'/\sigma_{i}) \cdot (R_{i} - PP_{i})\}#gh-light-mode-only">
<img src="https://render.githubusercontent.com/render/math?math=\color{white}max\{0, (1-PM_{i}) \cdot (s^'/\sigma_{i}) \cdot (R_{i} - PP_{i})\}#gh-dark-mode-only">
where `s'` is stake `s` scaled over total token circulating supply.
Nym network economic incentives, operator and validator rewards, and scalability of the network are determined according to the principles laid out in the section 6 of [Nym Whitepaper](https://nymtech.net/nym-whitepaper.pdf).
Initial reward pool is set to 250 million Nym, making the circulating supply 750 million Nym.
### Licensing and copyright information
This is a monorepo and components that make up Nym as a system are licensed individually, so for accurate information, please check individual files.
As a general approach, licensing is as follows this pattern:
- applications and binaries are GPLv3
- libraries and components are Apache 2.0 or MIT
- documentation is Apache 2.0 or CC0-1.0
Again, for accurate information, please check individual files.
Nym Node Operators and Validators Temrs and Conditions can be found [here](https://nymtech.net/terms-and-conditions/operators/v1.0.0).
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.1.37"
version = "1.1.38"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
@@ -23,7 +23,7 @@ url = { workspace = true }
bs58 = { workspace = true }
clap = { workspace = true, features = ["cargo", "derive"] }
dirs = "4.0"
dirs = { workspace = true }
log = { workspace = true } # self explanatory
rand = { workspace = true }
serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization
@@ -37,7 +37,7 @@ zeroize = { workspace = true }
## internal
nym-bandwidth-controller = { path = "../../common/bandwidth-controller" }
nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] }
nym-bin-common = { path = "../../common/bin-common", features = ["output_format", "clap"] }
nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "fs-gateways-storage", "cli"] }
nym-config = { path = "../../common/config" }
nym-credential-storage = { path = "../../common/credential-storage" }
+3 -1
View File
@@ -106,8 +106,10 @@ impl SocketClient {
};
let storage = self.initialise_storage().await?;
let user_agent = nym_bin_common::bin_info!().into();
let mut base_client = BaseClientBuilder::new(&self.config.base, storage, dkg_query_client);
let mut base_client = BaseClientBuilder::new(&self.config.base, storage, dkg_query_client)
.with_user_agent(user_agent);
if let Some(custom_mixnet) = &self.custom_mixnet {
base_client = base_client.with_stored_topology(custom_mixnet)?;
+2 -1
View File
@@ -22,8 +22,9 @@ impl AsRef<CommonClientAddGatewayArgs> for Args {
}
pub(crate) async fn execute(args: Args) -> Result<(), ClientError> {
let user_agent = nym_bin_common::bin_info!().into();
let output = args.output;
let res = add_gateway::<CliNativeClient, _>(args).await?;
let res = add_gateway::<CliNativeClient, _>(args, Some(user_agent)).await?;
println!("{}", output.format(&res));
Ok(())
+2 -1
View File
@@ -114,8 +114,9 @@ impl Display for InitResults {
pub(crate) async fn execute(args: Init) -> Result<(), ClientError> {
eprintln!("Initialising client...");
let user_agent = nym_bin_common::bin_info!().into();
let output = args.output;
let res = initialise_client::<CliNativeClient>(args).await?;
let res = initialise_client::<CliNativeClient>(args, Some(user_agent)).await?;
let init_results = InitResults::new(res);
println!("{}", output.format(&init_results));
+6 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-socks5-client"
version = "1.1.37"
version = "1.1.38"
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"
@@ -25,17 +25,18 @@ zeroize = { workspace = true }
nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] }
nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "fs-gateways-storage", "cli"] }
nym-config = { path = "../../common/config" }
nym-credential-storage = { path = "../../common/credential-storage" }
nym-credentials = { path = "../../common/credentials" }
nym-crypto = { path = "../../common/crypto" }
nym-gateway-requests = { path = "../../gateway/gateway-requests" }
nym-credential-storage = { path = "../../common/credential-storage" }
nym-id = { path = "../../common/nym-id" }
nym-network-defaults = { path = "../../common/network-defaults" }
nym-sphinx = { path = "../../common/nymsphinx" }
nym-ordered-buffer = { path = "../../common/socks5/ordered-buffer" }
nym-pemstore = { path = "../../common/pemstore" }
nym-topology = { path = "../../common/topology" }
nym-socks5-client-core = { path = "../../common/socks5-client-core" }
nym-id = { path = "../../common/nym-id" }
nym-sphinx = { path = "../../common/nymsphinx" }
nym-topology = { path = "../../common/topology" }
nym-validator-client = { path = "../../common/client-libs/validator-client", features = ["http-client"] }
[features]
default = []
+2 -1
View File
@@ -22,8 +22,9 @@ impl AsRef<CommonClientAddGatewayArgs> for Args {
}
pub(crate) async fn execute(args: Args) -> Result<(), Socks5ClientError> {
let user_agent = nym_bin_common::bin_info!().into();
let output = args.output;
let res = add_gateway::<CliSocks5Client, _>(args).await?;
let res = add_gateway::<CliSocks5Client, _>(args, Some(user_agent)).await?;
println!("{}", output.format(&res));
Ok(())
+2 -1
View File
@@ -129,8 +129,9 @@ impl Display for InitResults {
pub(crate) async fn execute(args: Init) -> Result<(), Socks5ClientError> {
eprintln!("Initialising client...");
let user_agent = nym_bin_common::bin_info!().into();
let output = args.output;
let res = initialise_client::<CliSocks5Client>(args).await?;
let res = initialise_client::<CliSocks5Client>(args, Some(user_agent)).await?;
let init_results = InitResults::new(res);
println!("{}", output.format(&init_results));
+9 -3
View File
@@ -116,7 +116,13 @@ pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn std::error::Error +
let storage =
OnDiskPersistent::from_paths(config.storage_paths.common_paths, &config.core.base.debug)
.await?;
NymClient::new(config.core, storage, args.common_args.custom_mixnet)
.run_forever()
.await
let user_agent = nym_bin_common::bin_info!().into();
NymClient::new(
config.core,
storage,
user_agent,
args.common_args.custom_mixnet,
)
.run_forever()
.await
}
+17
View File
@@ -0,0 +1,17 @@
[package]
name = "nym-authenticator-requests"
version = "0.1.0"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
documentation.workspace = true
edition.workspace = true
license.workspace = true
[dependencies]
bincode = { workspace = true }
rand = { workspace = true }
serde = { workspace = true, features = ["derive"] }
nym-sphinx = { path = "../nymsphinx" }
nym-wireguard-types = { path = "../wireguard-types" }
+13
View File
@@ -0,0 +1,13 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod v1;
pub const CURRENT_VERSION: u8 = 1;
fn make_bincode_serializer() -> impl bincode::Options {
use bincode::Options;
bincode::DefaultOptions::new()
.with_big_endian()
.with_varint_encoding()
}
@@ -0,0 +1,7 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod request;
pub mod response;
const VERSION: u8 = 1;
@@ -0,0 +1,84 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use nym_sphinx::addressing::Recipient;
use nym_wireguard_types::{GatewayClient, InitMessage, PeerPublicKey};
use serde::{Deserialize, Serialize};
use crate::make_bincode_serializer;
use super::VERSION;
fn generate_random() -> u64 {
use rand::RngCore;
let mut rng = rand::rngs::OsRng;
rng.next_u64()
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AuthenticatorRequest {
pub version: u8,
pub data: AuthenticatorRequestData,
pub reply_to: Recipient,
pub request_id: u64,
}
impl AuthenticatorRequest {
pub fn from_reconstructed_message(
message: &nym_sphinx::receiver::ReconstructedMessage,
) -> Result<Self, bincode::Error> {
use bincode::Options;
make_bincode_serializer().deserialize(&message.message)
}
pub fn new_initial_request(init_message: InitMessage, reply_to: Recipient) -> (Self, u64) {
let request_id = generate_random();
(
Self {
version: VERSION,
data: AuthenticatorRequestData::Initial(init_message),
reply_to,
request_id,
},
request_id,
)
}
pub fn new_final_request(gateway_client: GatewayClient, reply_to: Recipient) -> (Self, u64) {
let request_id = generate_random();
(
Self {
version: VERSION,
data: AuthenticatorRequestData::Final(gateway_client),
reply_to,
request_id,
},
request_id,
)
}
pub fn new_query_request(peer_public_key: PeerPublicKey, reply_to: Recipient) -> (Self, u64) {
let request_id = generate_random();
(
Self {
version: VERSION,
data: AuthenticatorRequestData::QueryBandwidth(peer_public_key),
reply_to,
request_id,
},
request_id,
)
}
pub fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
use bincode::Options;
make_bincode_serializer().serialize(self)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum AuthenticatorRequestData {
Initial(InitMessage),
Final(GatewayClient),
QueryBandwidth(PeerPublicKey),
}
@@ -0,0 +1,119 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use nym_sphinx::addressing::Recipient;
use nym_wireguard_types::registration::{RegistrationData, RegistredData, RemainingBandwidthData};
use serde::{Deserialize, Serialize};
use crate::make_bincode_serializer;
use super::VERSION;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AuthenticatorResponse {
pub version: u8,
pub data: AuthenticatorResponseData,
pub reply_to: Recipient,
}
impl AuthenticatorResponse {
pub fn new_pending_registration_success(
registration_data: RegistrationData,
request_id: u64,
reply_to: Recipient,
) -> Self {
Self {
version: VERSION,
data: AuthenticatorResponseData::PendingRegistration(PendingRegistrationResponse {
reply: registration_data,
reply_to,
request_id,
}),
reply_to,
}
}
pub fn new_registered(
registred_data: RegistredData,
reply_to: Recipient,
request_id: u64,
) -> Self {
Self {
version: VERSION,
data: AuthenticatorResponseData::Registered(RegisteredResponse {
reply: registred_data,
reply_to,
request_id,
}),
reply_to,
}
}
pub fn new_remaining_bandwidth(
remaining_bandwidth_data: Option<RemainingBandwidthData>,
reply_to: Recipient,
request_id: u64,
) -> Self {
Self {
version: VERSION,
data: AuthenticatorResponseData::RemainingBandwidth(RemainingBandwidthResponse {
reply: remaining_bandwidth_data,
reply_to,
request_id,
}),
reply_to,
}
}
pub fn recipient(&self) -> Recipient {
self.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)
}
pub fn id(&self) -> Option<u64> {
match &self.data {
AuthenticatorResponseData::PendingRegistration(response) => Some(response.request_id),
AuthenticatorResponseData::Registered(response) => Some(response.request_id),
AuthenticatorResponseData::RemainingBandwidth(response) => Some(response.request_id),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum AuthenticatorResponseData {
PendingRegistration(PendingRegistrationResponse),
Registered(RegisteredResponse),
RemainingBandwidth(RemainingBandwidthResponse),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PendingRegistrationResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: RegistrationData,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RegisteredResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: RegistredData,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RemainingBandwidthResponse {
pub request_id: u64,
pub reply_to: Recipient,
pub reply: Option<RemainingBandwidthData>,
}
+13
View File
@@ -0,0 +1,13 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// See other comments for other TaskStatus message enumds about abusing the Error trait when we
// should have a new trait for TaskStatus messages
#[derive(Debug, thiserror::Error)]
pub enum BandwidthStatusMessage {
#[error("remaining bandwidth: {0}")]
RemainingBandwidth(i64),
#[error("no bandwidth left")]
NoBandwidth,
}
+3
View File
@@ -14,8 +14,11 @@ use nym_validator_client::coconut::all_coconut_api_clients;
use nym_validator_client::nym_api::EpochId;
use nym_validator_client::nyxd::contract_traits::DkgQueryClient;
pub use event::BandwidthStatusMessage;
pub mod acquire;
pub mod error;
mod event;
mod utils;
#[derive(Debug)]
+5 -4
View File
@@ -9,9 +9,9 @@ repository = { workspace = true }
[dependencies]
const-str = { workspace = true }
clap = { workspace = true, features = ["derive"] }
clap_complete = { workspace = true }
clap_complete_fig = { workspace = true }
clap = { workspace = true, features = ["derive"], optional = true }
clap_complete = { workspace = true, optional = true }
clap_complete_fig = { workspace = true, optional = true }
log = { workspace = true }
pretty_env_logger = { workspace = true }
semver = "0.11"
@@ -34,7 +34,7 @@ vergen = { workspace = true, features = ["build", "git", "gitcl", "rustc", "carg
[features]
default = []
openapi = ["utoipa"]
output_format = ["serde_json"]
output_format = ["serde_json", "dep:clap"]
bin_info_schema = ["schemars"]
basic_tracing = ["tracing-subscriber"]
tracing = [
@@ -44,3 +44,4 @@ tracing = [
"tracing-opentelemetry",
"opentelemetry",
]
clap = [ "dep:clap", "dep:clap_complete", "dep:clap_complete_fig" ]
@@ -44,6 +44,10 @@ pub struct BinaryBuildInformation {
/// Provides the cargo debug mode that was used for the build.
// NOTE: keep the old name cargo_profile instead of cargo_debug for backwards compatibility
pub cargo_profile: &'static str,
// VERGEN_CARGO_TARGET_TRIPLE
/// Provides the cargo target triple that was used for the build.
pub cargo_triple: &'static str,
}
impl BinaryBuildInformation {
@@ -66,6 +70,7 @@ impl BinaryBuildInformation {
rustc_version: env!("VERGEN_RUSTC_SEMVER"),
rustc_channel: env!("VERGEN_RUSTC_CHANNEL"),
cargo_profile,
cargo_triple: env!("VERGEN_CARGO_TARGET_TRIPLE"),
}
}
@@ -95,6 +100,7 @@ impl BinaryBuildInformation {
rustc_version: env!("VERGEN_RUSTC_SEMVER"),
rustc_channel: env!("VERGEN_RUSTC_CHANNEL"),
cargo_profile,
cargo_triple: env!("VERGEN_CARGO_TARGET_TRIPLE"),
}
}
@@ -109,6 +115,7 @@ impl BinaryBuildInformation {
rustc_version: self.rustc_version.to_owned(),
rustc_channel: self.rustc_channel.to_owned(),
cargo_profile: self.cargo_profile.to_owned(),
cargo_triple: self.cargo_triple.to_owned(),
}
}
@@ -156,6 +163,15 @@ pub struct BinaryBuildInformationOwned {
/// Provides the cargo debug mode that was used for the build.
// NOTE: keep the old name cargo_profile instead of cargo_debug for backwards compatibility
pub cargo_profile: String,
// VERGEN_CARGO_TARGET_TRIPLE
/// Provides the cargo target triple that was used for the build.
#[serde(default = "unknown")]
pub cargo_triple: String,
}
fn unknown() -> String {
"unknown".to_string()
}
impl Display for BinaryBuildInformationOwned {
+3 -1
View File
@@ -2,9 +2,11 @@
// SPDX-License-Identifier: Apache-2.0
pub mod build_information;
pub mod completions;
pub mod logging;
pub mod version_checker;
#[cfg(feature = "clap")]
pub mod completions;
#[cfg(feature = "output_format")]
pub mod output_format;
+2 -2
View File
@@ -10,7 +10,7 @@ license.workspace = true
[dependencies]
async-trait = { workspace = true }
base64 = "0.21.2"
base64 = { workspace = true }
bs58 = { workspace = true }
cfg-if = { workspace = true }
clap = { workspace = true, optional = true }
@@ -20,7 +20,7 @@ log = { workspace = true }
rand = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = "0.10.6"
sha2 = { workspace = true }
si-scale = { workspace = true }
tap = { workspace = true }
thiserror = { workspace = true }
@@ -16,6 +16,7 @@ use log::info;
use nym_client_core_gateways_storage::GatewayDetails;
use nym_crypto::asymmetric::identity;
use nym_topology::NymTopology;
use nym_validator_client::UserAgent;
use std::path::PathBuf;
#[cfg_attr(feature = "cli", derive(clap::Args))]
@@ -60,7 +61,10 @@ pub struct CommonClientAddGatewayArgs {
pub custom_mixnet: Option<PathBuf>,
}
pub async fn add_gateway<C, A>(args: A) -> Result<GatewayInfo, C::Error>
pub async fn add_gateway<C, A>(
args: A,
user_agent: Option<UserAgent>,
) -> Result<GatewayInfo, C::Error>
where
A: AsRef<CommonClientAddGatewayArgs>,
C: CliClient,
@@ -111,7 +115,8 @@ where
hardcoded_topology.get_gateways()
} else {
let mut rng = rand::thread_rng();
crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await?
crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls, user_agent)
.await?
};
// since we're registering with a brand new gateway,
@@ -16,6 +16,7 @@ use log::info;
use nym_client_core_gateways_storage::GatewayDetails;
use nym_crypto::asymmetric::identity;
use nym_topology::NymTopology;
use nym_validator_client::UserAgent;
use rand::rngs::OsRng;
use std::path::PathBuf;
@@ -96,6 +97,7 @@ pub struct InitResultsWithConfig<T> {
pub async fn initialise_client<C>(
init_args: C::InitArgs,
user_agent: Option<UserAgent>,
) -> Result<InitResultsWithConfig<C::Config>, C::Error>
where
C: InitialisableClient,
@@ -163,7 +165,8 @@ where
hardcoded_topology.get_gateways()
} else {
let mut rng = rand::thread_rng();
crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await?
crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls, user_agent)
.await?
};
let gateway_setup = GatewaySetup::New {
@@ -53,7 +53,7 @@ use nym_task::connections::{ConnectionCommandReceiver, ConnectionCommandSender,
use nym_task::{TaskClient, TaskHandle};
use nym_topology::provider_trait::TopologyProvider;
use nym_topology::HardcodedTopologyProvider;
use nym_validator_client::nyxd::contract_traits::DkgQueryClient;
use nym_validator_client::{nyxd::contract_traits::DkgQueryClient, UserAgent};
use rand::rngs::OsRng;
use std::fmt::Debug;
use std::os::raw::c_int as RawFd;
@@ -184,6 +184,7 @@ pub struct BaseClientBuilder<'a, C, S: MixnetClientStorage> {
custom_topology_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
custom_gateway_transceiver: Option<Box<dyn GatewayTransceiver + Send>>,
shutdown: Option<TaskClient>,
user_agent: Option<UserAgent>,
setup_method: GatewaySetup,
}
@@ -207,6 +208,7 @@ where
custom_topology_provider: None,
custom_gateway_transceiver: None,
shutdown: None,
user_agent: None,
setup_method: GatewaySetup::MustLoad { gateway_id: None },
}
}
@@ -250,6 +252,12 @@ where
self
}
#[must_use]
pub fn with_user_agent(mut self, user_agent: UserAgent) -> Self {
self.user_agent = Some(user_agent);
self
}
pub fn with_stored_topology<P: AsRef<Path>>(
mut self,
file: P,
@@ -467,6 +475,7 @@ where
custom_provider: Option<Box<dyn TopologyProvider + Send + Sync>>,
config_topology: config::Topology,
nym_api_urls: Vec<Url>,
user_agent: Option<UserAgent>,
) -> Box<dyn TopologyProvider + Send + Sync> {
// if no custom provider was ... provided ..., create one using nym-api
custom_provider.unwrap_or_else(|| match config_topology.topology_structure {
@@ -477,6 +486,7 @@ where
},
nym_api_urls,
env!("CARGO_PKG_VERSION").to_string(),
user_agent,
)),
config::TopologyStructure::GeoAware(group_by) => {
Box::new(GeoAwareTopologyProvider::new(
@@ -689,6 +699,7 @@ where
self.custom_topology_provider.take(),
self.config.debug.topology,
self.config.get_nym_api_endpoints(),
self.user_agent.clone(),
);
// needs to be started as the first thing to block if required waiting for the gateway
@@ -5,6 +5,7 @@ use async_trait::async_trait;
use log::{debug, error, warn};
use nym_topology::provider_trait::TopologyProvider;
use nym_topology::{NymTopology, NymTopologyError};
use nym_validator_client::UserAgent;
use rand::prelude::SliceRandom;
use rand::thread_rng;
use url::Url;
@@ -39,14 +40,26 @@ pub(crate) struct NymApiTopologyProvider {
}
impl NymApiTopologyProvider {
pub(crate) fn new(config: Config, mut nym_api_urls: Vec<Url>, client_version: String) -> Self {
pub(crate) fn new(
config: Config,
mut nym_api_urls: Vec<Url>,
client_version: String,
user_agent: Option<UserAgent>,
) -> Self {
nym_api_urls.shuffle(&mut thread_rng());
let validator_client = if let Some(user_agent) = user_agent {
nym_validator_client::client::NymApiClient::new_with_user_agent(
nym_api_urls[0].clone(),
user_agent,
)
} else {
nym_validator_client::client::NymApiClient::new(nym_api_urls[0].clone())
};
NymApiTopologyProvider {
config,
validator_client: nym_validator_client::client::NymApiClient::new(
nym_api_urls[0].clone(),
),
validator_client,
nym_api_urls,
client_version,
currently_used_api: 0,
+7 -1
View File
@@ -9,6 +9,7 @@ use nym_crypto::asymmetric::identity;
use nym_gateway_client::GatewayClient;
use nym_topology::{filter::VersionFilterable, gateway, mix};
use nym_validator_client::client::IdentityKeyRef;
use nym_validator_client::UserAgent;
use rand::{seq::SliceRandom, Rng};
use std::{sync::Arc, time::Duration};
use tungstenite::Message;
@@ -59,11 +60,16 @@ impl<'a> GatewayWithLatency<'a> {
pub async fn current_gateways<R: Rng>(
rng: &mut R,
nym_apis: &[Url],
user_agent: Option<UserAgent>,
) -> Result<Vec<gateway::Node>, ClientCoreError> {
let nym_api = nym_apis
.choose(rng)
.ok_or(ClientCoreError::ListOfNymApisIsEmpty)?;
let client = nym_validator_client::client::NymApiClient::new(nym_api.clone());
let client = if let Some(user_agent) = user_agent {
nym_validator_client::client::NymApiClient::new_with_user_agent(nym_api.clone(), user_agent)
} else {
nym_validator_client::client::NymApiClient::new(nym_api.clone())
};
log::debug!("Fetching list of gateways from: {nym_api}");
+15 -12
View File
@@ -11,7 +11,7 @@ use crate::traits::GatewayPacketRouter;
use crate::{cleanup_socket_message, try_decrypt_binary_message};
use futures::{SinkExt, StreamExt};
use log::*;
use nym_bandwidth_controller::BandwidthController;
use nym_bandwidth_controller::{BandwidthController, BandwidthStatusMessage};
use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage;
use nym_credential_storage::storage::Storage as CredentialStorage;
use nym_credentials::CredentialSpendingData;
@@ -105,8 +105,8 @@ pub struct GatewayClient<C, St = EphemeralCredentialStorage> {
// currently unused (but populated)
negotiated_protocol: Option<u8>,
/// Listen to shutdown messages.
shutdown: TaskClient,
/// Listen to shutdown messages and send notifications back to the task manager
task_client: TaskClient,
}
impl<C, St> GatewayClient<C, St> {
@@ -117,7 +117,7 @@ impl<C, St> GatewayClient<C, St> {
shared_key: Option<Arc<SharedKeys>>,
packet_router: PacketRouter,
bandwidth_controller: Option<BandwidthController<C, St>>,
shutdown: TaskClient,
task_client: TaskClient,
) -> Self {
GatewayClient {
authenticated: false,
@@ -135,7 +135,7 @@ impl<C, St> GatewayClient<C, St> {
reconnection_attempts: DEFAULT_RECONNECTION_ATTEMPTS,
reconnection_backoff: DEFAULT_RECONNECTION_BACKOFF,
negotiated_protocol: None,
shutdown,
task_client,
}
}
@@ -299,7 +299,7 @@ impl<C, St> GatewayClient<C, St> {
loop {
tokio::select! {
_ = self.shutdown.recv() => {
_ = self.task_client.recv() => {
log::trace!("GatewayClient control response: Received shutdown");
log::debug!("GatewayClient control response: Exiting");
break Err(GatewayClientError::ConnectionClosedGatewayShutdown);
@@ -540,6 +540,9 @@ impl<C, St> GatewayClient<C, St> {
self.bandwidth_remaining = bandwidth_remaining;
self.negotiated_protocol = protocol_version;
log::debug!("authenticated: {status}, bandwidth remaining: {bandwidth_remaining}");
self.task_client.send_status_msg(Box::new(
BandwidthStatusMessage::RemainingBandwidth(bandwidth_remaining),
));
Ok(())
}
ServerResponse::Error { message } => Err(GatewayClientError::GatewayError(message)),
@@ -805,7 +808,7 @@ impl<C, St> GatewayClient<C, St> {
.as_ref()
.expect("no shared key present even though we're authenticated!"),
),
self.shutdown.clone(),
self.task_client.clone(),
)
}
_ => unreachable!(),
@@ -879,8 +882,8 @@ impl GatewayClient<InitOnly, EphemeralCredentialStorage> {
// perfectly fine here, because it's not meant to be used
let (ack_tx, _) = mpsc::unbounded();
let (mix_tx, _) = mpsc::unbounded();
let shutdown = TaskClient::dummy();
let packet_router = PacketRouter::new(ack_tx, mix_tx, shutdown.clone());
let task_client = TaskClient::dummy();
let packet_router = PacketRouter::new(ack_tx, mix_tx, task_client.clone());
GatewayClient {
authenticated: false,
@@ -898,7 +901,7 @@ impl GatewayClient<InitOnly, EphemeralCredentialStorage> {
reconnection_attempts: DEFAULT_RECONNECTION_ATTEMPTS,
reconnection_backoff: DEFAULT_RECONNECTION_BACKOFF,
negotiated_protocol: None,
shutdown,
task_client,
}
}
@@ -906,7 +909,7 @@ impl GatewayClient<InitOnly, EphemeralCredentialStorage> {
self,
packet_router: PacketRouter,
bandwidth_controller: Option<BandwidthController<C, St>>,
shutdown: TaskClient,
task_client: TaskClient,
) -> GatewayClient<C, St> {
// invariants that can't be broken
// (unless somebody decided to expose some field that wasn't meant to be exposed)
@@ -930,7 +933,7 @@ impl GatewayClient<InitOnly, EphemeralCredentialStorage> {
reconnection_attempts: self.reconnection_attempts,
reconnection_backoff: self.reconnection_backoff,
negotiated_protocol: self.negotiated_protocol,
shutdown,
task_client,
}
}
}
@@ -54,7 +54,7 @@ cw-controllers = { workspace = true }
prost = { workspace = true, default-features = false }
flate2 = { workspace = true }
sha2 = { version = "0.9.5" }
itertools = { version = "0.10" }
itertools = { workspace = true }
zeroize = { workspace = true, features = ["zeroize_derive"] }
cosmwasm-std = { workspace = true }
@@ -19,6 +19,7 @@ use nym_api_requests::models::{
RewardEstimationResponse, StakeSaturationResponse,
};
use nym_api_requests::nym_nodes::SkimmedNode;
use nym_http_api_client::UserAgent;
use nym_network_defaults::NymNetworkDetails;
use url::Url;
@@ -258,6 +259,16 @@ impl NymApiClient {
NymApiClient { nym_api }
}
pub fn new_with_user_agent(api_url: Url, user_agent: UserAgent) -> Self {
let nym_api = nym_api::Client::builder::<_, ValidatorClientError>(api_url)
.expect("invalid api url")
.with_user_agent(user_agent)
.build::<ValidatorClientError>()
.expect("failed to build nym api client");
NymApiClient { nym_api }
}
pub fn api_url(&self) -> &Url {
self.nym_api.current_url()
}
@@ -17,6 +17,7 @@ pub use crate::signing::direct_wallet::DirectSecp256k1HdWallet;
pub use client::NymApiClient;
pub use client::{Client, CoconutApiClient, Config};
pub use nym_api_requests::*;
pub use nym_http_api_client::UserAgent;
#[cfg(feature = "http-client")]
pub use cosmrs::rpc::HttpClient as HttpRpcClient;
@@ -683,6 +683,24 @@ pub trait MixnetSigningClient {
.await
}
async fn migrate_vested_mixnode(&self, fee: Option<Fee>) -> Result<ExecuteResult, NyxdError> {
self.execute_mixnet_contract(fee, MixnetExecuteMsg::MigrateVestedMixNode {}, vec![])
.await
}
async fn migrate_vested_delegation(
&self,
mix_id: MixId,
fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> {
self.execute_mixnet_contract(
fee,
MixnetExecuteMsg::MigrateVestedDelegation { mix_id },
vec![],
)
.await
}
#[cfg(feature = "contract-testing")]
async fn testing_resolve_all_pending_events(
&self,
@@ -928,6 +946,12 @@ mod tests {
MixnetExecuteMsg::WithdrawDelegatorRewardOnBehalf { mix_id, owner } => client
.withdraw_delegator_reward_on_behalf(owner.parse().unwrap(), mix_id, None)
.ignore(),
MixnetExecuteMsg::MigrateVestedMixNode { .. } => {
client.migrate_vested_mixnode(None).ignore()
}
MixnetExecuteMsg::MigrateVestedDelegation { mix_id } => {
client.migrate_vested_delegation(mix_id, None).ignore()
}
#[cfg(feature = "contract-testing")]
MixnetExecuteMsg::TestingResolveAllPendingEvents { .. } => {
@@ -437,6 +437,7 @@ where
mod tests {
use super::*;
use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue};
use nym_vesting_contract_common::ExecuteMsg;
// it's enough that this compiles and clippy is happy about it
#[allow(dead_code)]
@@ -560,6 +561,9 @@ mod tests {
VestingExecuteMsg::UpdateLockedPledgeCap { address, cap } => client
.update_locked_pledge_cap(address.parse().unwrap(), cap, None)
.ignore(),
// those will never be manually called by clients
ExecuteMsg::TrackMigratedMixnode { .. } => "explicitly_ignored".ignore(),
ExecuteMsg::TrackMigratedDelegation { .. } => "explicitly_ignored".ignore(),
};
}
}
@@ -3,7 +3,7 @@
use crate::nyxd::cosmwasm_client::client_traits::CosmWasmClient;
use crate::nyxd::cosmwasm_client::helpers::{compress_wasm_code, CheckResponse};
use crate::nyxd::cosmwasm_client::logs::{self, parse_raw_logs};
use crate::nyxd::cosmwasm_client::logs::parse_raw_logs;
use crate::nyxd::cosmwasm_client::types::*;
use crate::nyxd::error::NyxdError;
use crate::nyxd::fee::{Fee, DEFAULT_SIMULATED_GAS_MULTIPLIER};
@@ -19,6 +19,7 @@ use cosmrs::feegrant::{
};
use cosmrs::proto::cosmos::tx::signing::v1beta1::SignMode;
use cosmrs::staking::{MsgDelegate, MsgUndelegate};
use cosmrs::tendermint::abci::{Event, EventAttribute};
use cosmrs::tx::{self, Msg};
use cosmrs::{cosmwasm, AccountId, Any, Tx};
use log::debug;
@@ -51,6 +52,20 @@ fn single_unspecified_signer_auth(
}
.auth_info(empty_fee())
}
// Searches in events for an event of the given event type which contains an
// attribute for with the given key.
fn find_attribute<'a>(
events: &'a [Event],
event_type: &str,
attr_key: &str,
) -> Option<&'a EventAttribute> {
events
.iter()
.find(|attr| attr.kind == event_type)?
.attributes
.iter()
.find(|attr| attr.key == attr_key)
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
@@ -118,6 +133,7 @@ where
.check_response()?;
let logs = parse_raw_logs(tx_res.tx_result.log)?;
let events = tx_res.tx_result.events;
let gas_info = GasInfo {
gas_wanted: tx_res.tx_result.gas_wanted.try_into().unwrap_or_default(),
gas_used: tx_res.tx_result.gas_used.try_into().unwrap_or_default(),
@@ -127,7 +143,7 @@ where
// the reason I think unwrap here is fine is that if the transaction succeeded and those
// fields do not exist or code_id is not a number, there's no way we can recover, we're probably connected
// to wrong validator or something
let code_id = logs::find_attribute(&logs, "store_code", "code_id")
let code_id = find_attribute(&events, "store_code", "code_id")
.unwrap()
.value
.parse()
@@ -140,6 +156,7 @@ where
compressed_checksum,
code_id,
logs,
events,
transaction_hash: tx_res.hash,
gas_info,
})
@@ -182,6 +199,7 @@ where
.check_response()?;
let logs = parse_raw_logs(tx_res.tx_result.log)?;
let events = tx_res.tx_result.events;
let gas_info = GasInfo {
gas_wanted: tx_res.tx_result.gas_wanted.try_into().unwrap_or_default(),
gas_used: tx_res.tx_result.gas_used.try_into().unwrap_or_default(),
@@ -190,7 +208,7 @@ where
// the reason I think unwrap here is fine is that if the transaction succeeded and those
// fields do not exist or address is malformed, there's no way we can recover, we're probably connected
// to wrong validator or something
let contract_address = logs::find_attribute(&logs, "instantiate", "_contract_address")
let contract_address = find_attribute(&events, "instantiate", "_contract_address")
.unwrap()
.value
.parse()
@@ -199,6 +217,7 @@ where
Ok(InstantiateResult {
contract_address,
logs,
events,
transaction_hash: tx_res.hash,
gas_info,
})
@@ -231,6 +250,7 @@ where
};
Ok(ChangeAdminResult {
logs: parse_raw_logs(tx_res.tx_result.log)?,
events: tx_res.tx_result.events,
transaction_hash: tx_res.hash,
gas_info,
})
@@ -261,6 +281,7 @@ where
};
Ok(ChangeAdminResult {
logs: parse_raw_logs(tx_res.tx_result.log)?,
events: tx_res.tx_result.events,
transaction_hash: tx_res.hash,
gas_info,
})
@@ -298,6 +319,7 @@ where
};
Ok(MigrateResult {
logs: parse_raw_logs(tx_res.tx_result.log)?,
events: tx_res.tx_result.events,
transaction_hash: tx_res.hash,
gas_info,
})
@@ -335,6 +357,7 @@ where
};
Ok(ExecuteResult {
logs: parse_raw_logs(tx_res.tx_result.log)?,
events: tx_res.tx_result.events,
data: tx_res.tx_result.data.into(),
transaction_hash: tx_res.hash,
gas_info,
@@ -378,6 +401,7 @@ where
};
Ok(ExecuteResult {
logs: parse_raw_logs(tx_res.tx_result.log)?,
events: tx_res.tx_result.events,
data: tx_res.tx_result.data.into(),
transaction_hash: tx_res.hash,
gas_info,
@@ -35,6 +35,7 @@ pub fn find_attribute<'a>(
// these two functions were separated so that the internal logic could actually be tested
fn parse_raw_str_logs(raw: &str) -> Result<Vec<Log>, NyxdError> {
// From Cosmos SDK > 0.50 onwards, log field is not populated
if raw.is_empty() {
return Ok(Vec::new());
}
@@ -1,6 +1,11 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// TEMPORARY WORKAROUND:
// those features are expected as the below should only get activated whenever
// the corresponding features in tendermint-rpc are enabled transitively
#![allow(unexpected_cfgs)]
use crate::nyxd::cosmwasm_client::client_traits::SigningCosmWasmClient;
use crate::nyxd::error::NyxdError;
use crate::nyxd::{Config, GasPrice, Hash, Height};
@@ -232,6 +232,8 @@ pub struct UploadResult {
pub logs: Vec<Log>,
pub events: Vec<abci::Event>,
/// Transaction hash (might be used as transaction ID)
pub transaction_hash: Hash,
@@ -269,6 +271,8 @@ pub struct InstantiateResult {
pub logs: Vec<Log>,
pub events: Vec<abci::Event>,
/// Transaction hash (might be used as transaction ID)
pub transaction_hash: Hash,
@@ -279,6 +283,8 @@ pub struct InstantiateResult {
pub struct ChangeAdminResult {
pub logs: Vec<Log>,
pub events: Vec<abci::Event>,
/// Transaction hash (might be used as transaction ID)
pub transaction_hash: Hash,
@@ -289,6 +295,8 @@ pub struct ChangeAdminResult {
pub struct MigrateResult {
pub logs: Vec<Log>,
pub events: Vec<abci::Event>,
/// Transaction hash (might be used as transaction ID)
pub transaction_hash: Hash,
@@ -301,6 +309,8 @@ pub struct ExecuteResult {
pub data: Vec<u8>,
pub events: Vec<abci::Event>,
/// Transaction hash (might be used as transaction ID)
pub transaction_hash: Hash,
@@ -1,6 +1,11 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// TEMPORARY WORKAROUND:
// those features are expected as the below should only get activated whenever
// the corresponding features in tendermint-rpc are enabled transitively
#![allow(unexpected_cfgs)]
use crate::nyxd::contract_traits::{NymContractsProvider, TypedNymContracts};
use crate::nyxd::cosmwasm_client::types::{
ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, InstantiateResult,
@@ -1,6 +1,11 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// TEMPORARY WORKAROUND:
// those features are expected as the below should only get activated whenever
// the corresponding features in tendermint-rpc are enabled transitively
#![allow(unexpected_cfgs)]
use async_trait::async_trait;
use cosmrs::tendermint::{self, abci, block::Height, evidence::Evidence, Genesis, Hash};
use serde::{de::DeserializeOwned, Serialize};
@@ -1,15 +1,26 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use clap::Parser;
use log::{debug, info};
use cosmwasm_std::Decimal;
use nym_mixnet_contract_common::{InitialRewardingParams, InstantiateMsg, Percent};
use nym_validator_client::nyxd::AccountId;
use log::{debug, info};
use nym_mixnet_contract_common::{
InitialRewardingParams, InstantiateMsg, OperatingCostRange, Percent, ProfitMarginRange,
};
use nym_network_defaults::mainnet::MIX_DENOM;
use nym_network_defaults::TOTAL_SUPPLY;
use nym_validator_client::nyxd::{AccountId, Coin};
use std::str::FromStr;
use std::time::Duration;
pub fn default_maximum_operating_cost() -> Coin {
Coin::new(TOTAL_SUPPLY, MIX_DENOM.base)
}
pub fn default_minimum_operating_cost() -> Coin {
Coin::new(0, MIX_DENOM.base)
}
#[derive(Debug, Parser)]
pub struct Args {
#[clap(long)]
@@ -50,6 +61,18 @@ pub struct Args {
#[clap(long, default_value_t = 240)]
pub active_set_size: u32,
#[clap(long, default_value_t = Percent::zero())]
pub minimum_profit_margin_percent: Percent,
#[clap(long, default_value_t = Percent::hundred())]
pub maximum_profit_margin_percent: Percent,
#[clap(long, default_value_t = default_minimum_operating_cost())]
pub minimum_interval_operating_cost: Coin,
#[clap(long, default_value_t = default_maximum_operating_cost())]
pub maximum_interval_operating_cost: Coin,
}
pub async fn generate(args: Args) {
@@ -97,6 +120,10 @@ pub async fn generate(args: Args) {
.expect("Rewarding (mix) denom has to be set")
});
if args.minimum_interval_operating_cost.denom != args.maximum_interval_operating_cost.denom {
panic!("different denoms for operating cost bounds")
}
let instantiate_msg = InstantiateMsg {
rewarding_validator_address: rewarding_validator_address.to_string(),
vesting_contract_address: vesting_contract_address.to_string(),
@@ -104,6 +131,14 @@ pub async fn generate(args: Args) {
epochs_in_interval: args.epochs_in_interval,
epoch_duration: Duration::from_secs(args.epoch_duration),
initial_rewarding_params,
profit_margin: ProfitMarginRange {
minimum: args.minimum_profit_margin_percent,
maximum: args.maximum_profit_margin_percent,
},
interval_operating_cost: OperatingCostRange {
minimum: args.minimum_interval_operating_cost.amount.into(),
maximum: args.maximum_interval_operating_cost.amount.into(),
},
};
debug!("instantiate_msg: {:?}", instantiate_msg);
@@ -0,0 +1,42 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::context::SigningClient;
use clap::Parser;
use log::info;
use nym_mixnet_contract_common::MixId;
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient};
#[derive(Debug, Parser)]
pub struct Args {
#[clap(long)]
pub mix_id: Option<MixId>,
#[clap(long)]
pub identity_key: Option<String>,
}
pub async fn migrate_vested_delegation(args: Args, client: SigningClient) {
let mix_id = match args.mix_id {
Some(mix_id) => mix_id,
None => {
let identity_key = args
.identity_key
.expect("either mix_id or mix_identity has to be specified");
let node_details = client
.get_mixnode_details_by_identity(identity_key)
.await
.expect("contract query failed")
.mixnode_details
.expect("mixnode with the specified identity doesnt exist");
node_details.mix_id()
}
};
let res = client
.migrate_vested_delegation(mix_id, None)
.await
.expect("failed to migrate delegation!");
info!("migration result: {:?}", res)
}
@@ -7,6 +7,7 @@ pub mod rewards;
pub mod delegate_to_mixnode;
pub mod delegate_to_multiple_mixnodes;
pub mod migrate_vested_delegation;
pub mod query_for_delegations;
pub mod undelegate_from_mixnode;
pub mod vesting_delegate_to_mixnode;
@@ -35,4 +36,6 @@ pub enum MixnetDelegatorsCommands {
DelegateVesting(vesting_delegate_to_mixnode::Args),
/// Undelegate from a mixnode (when originally using locked tokens)
UndelegateVesting(vesting_undelegate_from_mixnode::Args),
/// Migrate the delegation to use liquid tokens
MigrateVestedDelegation(migrate_vested_delegation::Args),
}
@@ -96,6 +96,7 @@ async fn print_delegation_events(events: Vec<PendingEpochEvent>, client: &Signin
mix_id,
amount,
proxy,
..
} => {
if owner.as_str() == client.nyxd.address().as_ref() {
table.add_row(vec![
@@ -111,6 +112,7 @@ async fn print_delegation_events(events: Vec<PendingEpochEvent>, client: &Signin
owner,
mix_id,
proxy,
..
} => {
if owner.as_str() == client.nyxd.address().as_ref() {
table.add_row(vec![
@@ -8,7 +8,7 @@ use cosmwasm_std::Coin;
use nym_bin_common::output_format::OutputFormat;
use nym_mixnet_contract_common::construct_gateway_bonding_sign_payload;
use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, NymContractsProvider};
use nym_validator_client::nyxd::contract_traits::MixnetQueryClient;
#[derive(Debug, Parser)]
pub struct Args {
@@ -39,10 +39,6 @@ pub struct Args {
)]
pub amount: u128,
/// Indicates whether the gateway is going to get bonded via a vesting account
#[arg(long)]
pub with_vesting_account: bool,
#[clap(short, long, default_value_t = OutputFormat::default())]
output: OutputFormat,
}
@@ -74,15 +70,8 @@ pub async fn create_payload(args: Args, client: SigningClient) {
};
let address = account_id_to_cw_addr(&client.address());
let proxy = if args.with_vesting_account {
Some(account_id_to_cw_addr(
client.vesting_contract_address().unwrap(),
))
} else {
None
};
let payload = construct_gateway_bonding_sign_payload(nonce, address, proxy, coin, gateway);
let payload = construct_gateway_bonding_sign_payload(nonce, address, coin, gateway);
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
println!("{}", args.output.format(&wrapper))
}
@@ -5,33 +5,21 @@ use crate::context::SigningClient;
use clap::Parser;
use log::info;
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
use nym_validator_client::nyxd::contract_traits::VestingSigningClient;
#[derive(Debug, Parser)]
pub struct Args {
/// Label that is going to be used for creating the family
#[arg(long)]
pub family_label: String,
/// Indicates whether the family is going to get created via a vesting account
#[arg(long)]
pub with_vesting_account: bool,
}
pub async fn create_family(args: Args, client: SigningClient) {
info!("Create family");
let res = if args.with_vesting_account {
client
.vesting_create_family(args.family_label, None)
.await
.expect("failed to create family with vesting account")
} else {
client
.create_family(args.family_label, None)
.await
.expect("failed to create family")
};
let res = client
.create_family(args.family_label, None)
.await
.expect("failed to create family");
info!("Family creation result: {:?}", res);
}
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::context::QueryClient;
use crate::utils::{account_id_to_cw_addr, DataWrapper};
use crate::utils::DataWrapper;
use clap::Parser;
use cosmrs::AccountId;
use log::info;
@@ -10,7 +10,7 @@ use nym_bin_common::output_format::OutputFormat;
use nym_crypto::asymmetric::identity;
use nym_mixnet_contract_common::construct_family_join_permit;
use nym_mixnet_contract_common::families::FamilyHead;
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, NymContractsProvider};
use nym_validator_client::nyxd::contract_traits::MixnetQueryClient;
#[derive(Debug, Parser)]
pub struct Args {
@@ -18,10 +18,6 @@ pub struct Args {
#[arg(long)]
pub address: AccountId,
/// Indicates whether the member joining the family is going to use the vesting account for joining.
#[arg(long)]
pub with_vesting_account: bool,
// might as well validate the value when parsing the arguments
/// Identity of the member for whom we're issuing the permit
#[arg(long)]
@@ -68,18 +64,9 @@ pub async fn create_family_join_permit_sign_payload(args: Args, client: QueryCli
}
};
// let address = account_id_to_cw_addr(&args.address);
let proxy = if args.with_vesting_account {
Some(account_id_to_cw_addr(
client.vesting_contract_address().unwrap(),
))
} else {
None
};
let head = FamilyHead::new(mixnode.bond_information.identity());
let payload = construct_family_join_permit(nonce, head, proxy, args.member.to_base58_string());
let payload = construct_family_join_permit(nonce, head, args.member.to_base58_string());
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
println!("{}", args.output.format(&wrapper))
}
@@ -8,7 +8,6 @@ use nym_contracts_common::signing::MessageSignature;
use nym_crypto::asymmetric::identity;
use nym_mixnet_contract_common::families::FamilyHead;
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
use nym_validator_client::nyxd::contract_traits::VestingSigningClient;
#[derive(Debug, Parser)]
pub struct Args {
@@ -16,10 +15,6 @@ pub struct Args {
#[arg(long)]
pub family_head: identity::PublicKey,
/// Indicates whether the member joining the family is going to do so via the vesting contract
#[arg(long)]
pub with_vesting_account: bool,
/// Permission, as provided by the family head, for joining the family
#[arg(long)]
pub join_permit: MessageSignature,
@@ -30,17 +25,10 @@ pub async fn join_family(args: Args, client: SigningClient) {
let family_head = FamilyHead::new(args.family_head.to_base58_string());
let res = if args.with_vesting_account {
client
.vesting_join_family(args.join_permit, family_head, None)
.await
.expect("failed to join family with vesting account")
} else {
client
.join_family(args.join_permit, family_head, None)
.await
.expect("failed to join family")
};
let res = client
.join_family(args.join_permit, family_head, None)
.await
.expect("failed to join family");
info!("Family join result: {:?}", res);
}
@@ -7,17 +7,12 @@ use log::info;
use nym_crypto::asymmetric::identity;
use nym_mixnet_contract_common::families::FamilyHead;
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
use nym_validator_client::nyxd::contract_traits::VestingSigningClient;
#[derive(Debug, Parser)]
pub struct Args {
/// The head of the family that we intend to leave
#[arg(long)]
pub family_head: identity::PublicKey,
/// Indicates whether we joined the family via the vesting contract
#[arg(long)]
pub with_vesting_account: bool,
}
pub async fn leave_family(args: Args, client: SigningClient) {
@@ -25,17 +20,10 @@ pub async fn leave_family(args: Args, client: SigningClient) {
let family_head = FamilyHead::new(args.family_head.to_base58_string());
let res = if args.with_vesting_account {
client
.vesting_leave_family(family_head, None)
.await
.expect("failed to leave family with vesting account")
} else {
client
.leave_family(family_head, None)
.await
.expect("failed to leave family")
};
let res = client
.leave_family(family_head, None)
.await
.expect("failed to leave family");
info!("Family leave result: {:?}", res);
}
@@ -0,0 +1,19 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::context::SigningClient;
use clap::Parser;
use log::info;
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
#[derive(Debug, Parser)]
pub struct Args {}
pub async fn migrate_vested_mixnode(_args: Args, client: SigningClient) {
let res = client
.migrate_vested_mixnode(None)
.await
.expect("failed to migrate mixnode!");
info!("migration result: {:?}", res)
}
@@ -11,7 +11,7 @@ use nym_mixnet_contract_common::{construct_mixnode_bonding_sign_payload, MixNode
use nym_network_defaults::{
DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT,
};
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, NymContractsProvider};
use nym_validator_client::nyxd::contract_traits::MixnetQueryClient;
use nym_validator_client::nyxd::CosmWasmCoin;
#[derive(Debug, Parser)]
@@ -52,10 +52,6 @@ pub struct Args {
)]
pub amount: u128,
/// Indicates whether the mixnode is going to get bonded via a vesting account
#[arg(long)]
pub with_vesting_account: bool,
#[clap(short, long, default_value_t = OutputFormat::default())]
output: OutputFormat,
}
@@ -100,16 +96,9 @@ pub async fn create_payload(args: Args, client: SigningClient) {
};
let address = account_id_to_cw_addr(&client.address());
let proxy = if args.with_vesting_account {
Some(account_id_to_cw_addr(
client.vesting_contract_address().unwrap(),
))
} else {
None
};
let payload =
construct_mixnode_bonding_sign_payload(nonce, address, proxy, coin, mixnode, cost_params);
construct_mixnode_bonding_sign_payload(nonce, address, coin, mixnode, cost_params);
let wrapper = DataWrapper::new(payload.to_base58_string().unwrap());
println!("{}", args.output.format(&wrapper))
}
@@ -7,6 +7,7 @@ pub mod bond_mixnode;
pub mod decrease_pledge;
pub mod families;
pub mod keys;
pub mod migrate_vested_mixnode;
pub mod mixnode_bonding_sign_payload;
pub mod pledge_more;
pub mod rewards;
@@ -52,4 +53,6 @@ pub enum MixnetOperatorsMixnodeCommands {
DecreasePledge(decrease_pledge::Args),
/// Decrease pledge with locked tokens
DecreasePledgeVesting(vesting_decrease_pledge::Args),
/// Migrate the mixnode to use liquid tokens
MigrateVestedNode(migrate_vested_mixnode::Args),
}
@@ -218,7 +218,6 @@ where
#[derive(Serialize)]
pub struct ContractMessageContent<T> {
pub sender: Addr,
pub proxy: Option<Addr>,
pub funds: Vec<Coin>,
pub data: T,
}
@@ -233,25 +232,17 @@ where
}
impl<T> ContractMessageContent<T> {
pub fn new(sender: Addr, proxy: Option<Addr>, funds: Vec<Coin>, data: T) -> Self {
pub fn new(sender: Addr, funds: Vec<Coin>, data: T) -> Self {
ContractMessageContent {
sender,
proxy,
funds,
data,
}
}
pub fn new_with_info(info: MessageInfo, signer: Addr, data: T) -> Self {
let proxy = if info.sender == signer {
None
} else {
Some(info.sender)
};
ContractMessageContent {
sender: signer,
proxy,
funds: info.funds,
data,
}
@@ -29,7 +29,7 @@ time = { workspace = true, features = ["parsing", "formatting"] }
ts-rs = { workspace = true, optional = true }
[dev-dependencies]
rand_chacha = "0.3"
rand_chacha = { workspace = true }
time = { workspace = true, features = ["serde", "macros"] }
[features]
@@ -65,7 +65,6 @@ impl Delegation {
cumulative_reward_ratio: Decimal,
amount: Coin,
height: u64,
proxy: Option<Addr>,
) -> Self {
assert!(
amount.amount <= TOKEN_SUPPLY,
@@ -78,7 +77,7 @@ impl Delegation {
cumulative_reward_ratio,
amount,
height,
proxy,
proxy: None,
}
}
@@ -1,8 +1,9 @@
// Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{EpochEventId, EpochState, IdentityKey, MixId};
use crate::{EpochEventId, EpochState, IdentityKey, MixId, OperatingCostRange, ProfitMarginRange};
use contracts_common::signing::verifier::ApiVerifierError;
use contracts_common::Percent;
use cosmwasm_std::{Addr, Coin, Decimal, Uint128};
use thiserror::Error;
@@ -76,21 +77,11 @@ pub enum MixnetContractError {
#[error("Received multiple coin types during staking")]
MultipleDenoms,
#[error("Proxy address mismatch, expected {existing}, got {incoming}")]
ProxyMismatch { existing: String, incoming: String },
#[error("Proxy address ({received}) is not set to the vesting contract ({vesting_contract})")]
ProxyIsNotVestingContract {
received: Addr,
vesting_contract: Addr,
},
#[error(
"Sender of this message ({received}) is not the vesting contract ({vesting_contract})"
)]
SenderIsNotVestingContract {
received: Addr,
vesting_contract: Addr,
},
#[error("Failed to recover ed25519 public key from its base58 representation - {0}")]
MalformedEd25519IdentityKey(String),
@@ -239,6 +230,30 @@ pub enum MixnetContractError {
#[from]
source: ApiVerifierError,
},
#[error("this operation is no longer allowed to be performed with vesting tokens. please move them to your liquid balance and try again")]
DisabledVestingOperation,
#[error(
"this mixnode has not been bonded with the vesting tokens or has already been migrated"
)]
NotAVestingMixnode,
#[error("this delegation has not been performed with the vesting tokens or has already been migrated")]
NotAVestingDelegation,
#[error("the provided profit margin ({provided}) is outside the allowed range: {range}")]
ProfitMarginOutsideRange {
provided: Percent,
range: ProfitMarginRange,
},
#[error("the provided interval operating cost ({provided}{denom}) is outside the allowed range: {range}")]
OperatingCostOutsideRange {
denom: String,
provided: Uint128,
range: OperatingCostRange,
},
}
impl MixnetContractError {
@@ -103,7 +103,6 @@ impl Display for MixnetEventType {
// attributes that are used in multiple places
pub const OWNER_KEY: &str = "owner";
pub const AMOUNT_KEY: &str = "amount";
pub const PROXY_KEY: &str = "proxy";
// event-specific attributes
@@ -163,7 +162,6 @@ pub const NEW_EPOCHS_IN_INTERVAL: &str = "new_epochs_in_interval";
pub fn new_delegation_event(
created_at: BlockHeight,
delegator: &Addr,
proxy: &Option<Addr>,
amount: &Coin,
mix_id: MixId,
unit_reward: Decimal,
@@ -171,58 +169,34 @@ pub fn new_delegation_event(
Event::new(MixnetEventType::Delegation)
.add_attribute(EVENT_CREATION_HEIGHT_KEY, created_at.to_string())
.add_attribute(DELEGATOR_KEY, delegator)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(AMOUNT_KEY, amount.to_string())
.add_attribute(DELEGATION_TARGET_KEY, mix_id.to_string())
.add_attribute(UNIT_REWARD_KEY, unit_reward.to_string())
}
pub fn new_delegation_on_unbonded_node_event(
delegator: &Addr,
proxy: &Option<Addr>,
mix_id: MixId,
) -> Event {
pub fn new_delegation_on_unbonded_node_event(delegator: &Addr, mix_id: MixId) -> Event {
Event::new(MixnetEventType::Delegation)
.add_attribute(DELEGATOR_KEY, delegator)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(DELEGATION_TARGET_KEY, mix_id.to_string())
}
pub fn new_pending_delegation_event(
delegator: &Addr,
proxy: &Option<Addr>,
amount: &Coin,
mix_id: MixId,
) -> Event {
pub fn new_pending_delegation_event(delegator: &Addr, amount: &Coin, mix_id: MixId) -> Event {
Event::new(MixnetEventType::PendingDelegation)
.add_attribute(DELEGATOR_KEY, delegator)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(AMOUNT_KEY, amount.to_string())
.add_attribute(DELEGATION_TARGET_KEY, mix_id.to_string())
}
pub fn new_withdraw_operator_reward_event(
owner: &Addr,
proxy: &Option<Addr>,
amount: Coin,
mix_id: MixId,
) -> Event {
pub fn new_withdraw_operator_reward_event(owner: &Addr, amount: Coin, mix_id: MixId) -> Event {
Event::new(MixnetEventType::WithdrawOperatorReward)
.add_attribute(OWNER_KEY, owner.as_str())
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(AMOUNT_KEY, amount.to_string())
.add_attribute(MIX_ID_KEY, mix_id.to_string())
}
pub fn new_withdraw_delegator_reward_event(
delegator: &Addr,
proxy: &Option<Addr>,
amount: Coin,
mix_id: MixId,
) -> Event {
pub fn new_withdraw_delegator_reward_event(delegator: &Addr, amount: Coin, mix_id: MixId) -> Event {
Event::new(MixnetEventType::WithdrawDelegatorReward)
.add_attribute(DELEGATOR_KEY, delegator)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(AMOUNT_KEY, amount.to_string())
.add_attribute(DELEGATION_TARGET_KEY, mix_id.to_string())
}
@@ -278,59 +252,43 @@ pub fn new_pending_rewarding_params_update_event(
)
}
pub fn new_undelegation_event(
created_at: BlockHeight,
delegator: &Addr,
proxy: &Option<Addr>,
mix_id: MixId,
) -> Event {
pub fn new_undelegation_event(created_at: BlockHeight, delegator: &Addr, mix_id: MixId) -> Event {
Event::new(MixnetEventType::Undelegation)
.add_attribute(EVENT_CREATION_HEIGHT_KEY, created_at.to_string())
.add_attribute(DELEGATOR_KEY, delegator)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(MIX_ID_KEY, mix_id.to_string())
}
pub fn new_pending_undelegation_event(
delegator: &Addr,
proxy: &Option<Addr>,
mix_id: MixId,
) -> Event {
pub fn new_pending_undelegation_event(delegator: &Addr, mix_id: MixId) -> Event {
Event::new(MixnetEventType::PendingUndelegation)
.add_attribute(DELEGATOR_KEY, delegator)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(MIX_ID_KEY, mix_id.to_string())
}
pub fn new_gateway_bonding_event(
owner: &Addr,
proxy: &Option<Addr>,
amount: &Coin,
identity: IdentityKeyRef<'_>,
) -> Event {
Event::new(MixnetEventType::GatewayBonding)
.add_attribute(OWNER_KEY, owner)
.add_attribute(NODE_IDENTITY_KEY, identity)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(AMOUNT_KEY, amount.to_string())
}
pub fn new_gateway_unbonding_event(
owner: &Addr,
proxy: &Option<Addr>,
amount: &Coin,
identity: IdentityKeyRef<'_>,
) -> Event {
Event::new(MixnetEventType::GatewayUnbonding)
.add_attribute(OWNER_KEY, owner)
.add_attribute(NODE_IDENTITY_KEY, identity)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(AMOUNT_KEY, amount.to_string())
}
pub fn new_mixnode_bonding_event(
owner: &Addr,
proxy: &Option<Addr>,
amount: &Coin,
identity: IdentityKeyRef<'_>,
mix_id: MixId,
@@ -341,7 +299,6 @@ pub fn new_mixnode_bonding_event(
.add_attribute(MIX_ID_KEY, mix_id.to_string())
.add_attribute(NODE_IDENTITY_KEY, identity)
.add_attribute(OWNER_KEY, owner)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(ASSIGNED_LAYER_KEY, assigned_layer)
.add_attribute(AMOUNT_KEY, amount.to_string())
}
@@ -380,7 +337,6 @@ pub fn new_mixnode_unbonding_event(created_at: BlockHeight, mix_id: MixId) -> Ev
pub fn new_pending_mixnode_unbonding_event(
owner: &Addr,
proxy: &Option<Addr>,
identity: IdentityKeyRef<'_>,
mix_id: MixId,
) -> Event {
@@ -388,43 +344,33 @@ pub fn new_pending_mixnode_unbonding_event(
.add_attribute(MIX_ID_KEY, mix_id.to_string())
.add_attribute(NODE_IDENTITY_KEY, identity)
.add_attribute(OWNER_KEY, owner)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
}
pub fn new_mixnode_config_update_event(
mix_id: MixId,
owner: &Addr,
proxy: &Option<Addr>,
update: &MixNodeConfigUpdate,
) -> Event {
Event::new(MixnetEventType::MixnodeConfigUpdate)
.add_attribute(MIX_ID_KEY, mix_id.to_string())
.add_attribute(OWNER_KEY, owner)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(UPDATED_MIXNODE_CONFIG_KEY, update.to_inline_json())
}
pub fn new_gateway_config_update_event(
owner: &Addr,
proxy: &Option<Addr>,
update: &GatewayConfigUpdate,
) -> Event {
pub fn new_gateway_config_update_event(owner: &Addr, update: &GatewayConfigUpdate) -> Event {
Event::new(MixnetEventType::GatewayConfigUpdate)
.add_attribute(OWNER_KEY, owner)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(UPDATED_GATEWAY_CONFIG_KEY, update.to_inline_json())
}
pub fn new_mixnode_pending_cost_params_update_event(
mix_id: MixId,
owner: &Addr,
proxy: &Option<Addr>,
new_costs: &MixNodeCostParams,
) -> Event {
Event::new(MixnetEventType::PendingMixnodeCostParamsUpdate)
.add_attribute(MIX_ID_KEY, mix_id.to_string())
.add_attribute(OWNER_KEY, owner)
.add_optional_attribute(PROXY_KEY, proxy.as_ref())
.add_attribute(UPDATED_MIXNODE_COST_PARAMS_KEY, new_costs.to_inline_json())
}
@@ -3,7 +3,6 @@
use crate::{IdentityKey, IdentityKeyRef};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr;
use schemars::JsonSchema;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt::{Display, Formatter};
@@ -84,10 +83,10 @@ impl FamilyHead {
}
impl Family {
pub fn new(head: FamilyHead, proxy: Option<Addr>, label: String) -> Self {
pub fn new(head: FamilyHead, label: String) -> Self {
Family {
head,
proxy: proxy.map(|p| p.to_string()),
proxy: None,
label,
}
}
@@ -55,19 +55,13 @@ pub struct GatewayBond {
}
impl GatewayBond {
pub fn new(
pledge_amount: Coin,
owner: Addr,
block_height: u64,
gateway: Gateway,
proxy: Option<Addr>,
) -> Self {
pub fn new(pledge_amount: Coin, owner: Addr, block_height: u64, gateway: Gateway) -> Self {
GatewayBond {
pledge_amount,
owner,
block_height,
gateway,
proxy,
proxy: None,
}
}
@@ -10,7 +10,10 @@ use crate::helpers::IntoBaseDecimal;
use crate::reward_params::{NodeRewardParams, RewardingParams};
use crate::rewarding::helpers::truncate_reward;
use crate::rewarding::RewardDistribution;
use crate::{Delegation, EpochEventId, EpochId, IdentityKey, MixId, Percent, SphinxKey};
use crate::{
Delegation, EpochEventId, EpochId, IdentityKey, MixId, OperatingCostRange, Percent,
ProfitMarginRange, SphinxKey,
};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Addr, Coin, Decimal, StdResult, Uint128};
use schemars::JsonSchema;
@@ -152,6 +155,16 @@ impl MixNodeRewarding {
})
}
pub fn normalise_profit_margin(&mut self, allowed_range: ProfitMarginRange) {
self.cost_params.profit_margin_percent =
allowed_range.normalise(self.cost_params.profit_margin_percent)
}
pub fn normalise_operating_cost(&mut self, allowed_range: OperatingCostRange) {
self.cost_params.interval_operating_cost.amount =
allowed_range.normalise(self.cost_params.interval_operating_cost.amount)
}
/// Determines whether this node is still bonded. This is performed via a simple check,
/// if there are no tokens left associated with the operator, it means they have unbonded
/// and those params only exist for the purposes of calculating rewards for delegators that
@@ -518,7 +531,6 @@ impl MixNodeBond {
original_pledge: Coin,
layer: Layer,
mix_node: MixNode,
proxy: Option<Addr>,
bonding_height: u64,
) -> Self {
MixNodeBond {
@@ -527,7 +539,7 @@ impl MixNodeBond {
original_pledge,
layer,
mix_node,
proxy,
proxy: None,
bonding_height,
is_unbonding: false,
}
@@ -1,4 +1,4 @@
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::delegation::{self, OwnerProxySubKey};
@@ -12,6 +12,7 @@ use crate::reward_params::{
IntervalRewardParams, IntervalRewardingParamsUpdate, Performance, RewardingParams,
};
use crate::types::{ContractStateParams, LayerAssignment, MixId};
use crate::{OperatingCostRange, ProfitMarginRange};
use contracts_common::{signing::MessageSignature, IdentityKey, Percent};
use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Coin, Decimal};
@@ -57,6 +58,12 @@ pub struct InstantiateMsg {
pub epochs_in_interval: u32,
pub epoch_duration: Duration,
pub initial_rewarding_params: InitialRewardingParams,
#[serde(default)]
pub profit_margin: ProfitMarginRange,
#[serde(default)]
pub interval_operating_cost: OperatingCostRange,
}
#[cw_serde]
@@ -269,6 +276,12 @@ pub enum ExecuteMsg {
owner: String,
},
// vesting migration:
MigrateVestedMixNode {},
MigrateVestedDelegation {
mix_id: MixId,
},
// testing-only
#[cfg(feature = "contract-testing")]
TestingResolveAllPendingEvents {
@@ -381,6 +394,9 @@ impl ExecuteMsg {
ExecuteMsg::WithdrawDelegatorRewardOnBehalf { mix_id, .. } => {
format!("withdrawing delegator reward from mixnode {mix_id} on behalf")
}
ExecuteMsg::MigrateVestedMixNode { .. } => "migrate vested mixnode".into(),
ExecuteMsg::MigrateVestedDelegation { .. } => "migrate vested delegation".to_string(),
#[cfg(feature = "contract-testing")]
ExecuteMsg::TestingResolveAllPendingEvents { .. } => {
"resolving all pending events".into()
@@ -38,6 +38,7 @@ pub enum PendingEpochEventKind {
/// Request to create a delegation towards particular mixnode.
/// Note that if such delegation already exists, it will get updated with the provided token amount.
#[serde(alias = "Delegate")]
#[non_exhaustive]
Delegate {
/// The address of the owner of the delegation.
owner: Addr,
@@ -55,6 +56,7 @@ pub enum PendingEpochEventKind {
/// Request to remove delegation from particular mixnode.
#[serde(alias = "Undelegate")]
#[non_exhaustive]
Undelegate {
/// The address of the owner of the delegation.
owner: Addr,
@@ -109,6 +111,23 @@ impl PendingEpochEventKind {
kind: self,
}
}
pub fn new_delegate(owner: Addr, mix_id: MixId, amount: Coin) -> Self {
PendingEpochEventKind::Delegate {
owner,
mix_id,
amount,
proxy: None,
}
}
pub fn new_undelegate(owner: Addr, mix_id: MixId) -> Self {
PendingEpochEventKind::Undelegate {
owner,
mix_id,
proxy: None,
}
}
}
impl From<(EpochEventId, PendingEpochEventData)> for PendingEpochEvent {
@@ -47,7 +47,6 @@ impl SimulatedNode {
self.rewarding_details.total_unit_reward,
delegation,
42,
None,
);
self.delegations.insert(delegator, delegation);
@@ -37,13 +37,12 @@ impl SigningPurpose for MixnodeBondingPayload {
pub fn construct_mixnode_bonding_sign_payload(
nonce: Nonce,
sender: Addr,
proxy: Option<Addr>,
pledge: Coin,
mix_node: MixNode,
cost_params: MixNodeCostParams,
) -> SignableMixNodeBondingMsg {
let payload = MixnodeBondingPayload::new(mix_node, cost_params);
let content = ContractMessageContent::new(sender, proxy, vec![pledge], payload);
let content = ContractMessageContent::new(sender, vec![pledge], payload);
SignableMessage::new(nonce, content)
}
@@ -68,12 +67,11 @@ impl SigningPurpose for GatewayBondingPayload {
pub fn construct_gateway_bonding_sign_payload(
nonce: Nonce,
sender: Addr,
proxy: Option<Addr>,
pledge: Coin,
gateway: Gateway,
) -> SignableGatewayBondingMsg {
let payload = GatewayBondingPayload::new(gateway);
let content = ContractMessageContent::new(sender, proxy, vec![pledge], payload);
let content = ContractMessageContent::new(sender, vec![pledge], payload);
SignableMessage::new(nonce, content)
}
@@ -82,17 +80,14 @@ pub fn construct_gateway_bonding_sign_payload(
pub struct FamilyJoinPermit {
// the granter of this permit
family_head: FamilyHead,
// whether the **member** will want to join via the proxy (i.e. vesting contract)
proxy: Option<Addr>,
// the actual member we want to permit to join
member_node: IdentityKey,
}
impl FamilyJoinPermit {
pub fn new(family_head: FamilyHead, proxy: Option<Addr>, member_node: IdentityKey) -> Self {
pub fn new(family_head: FamilyHead, member_node: IdentityKey) -> Self {
Self {
family_head,
proxy,
member_node,
}
}
@@ -107,10 +102,9 @@ impl SigningPurpose for FamilyJoinPermit {
pub fn construct_family_join_permit(
nonce: Nonce,
family_head: FamilyHead,
proxy: Option<Addr>,
member_node: IdentityKey,
) -> SignableFamilyJoinPermitMsg {
let payload = FamilyJoinPermit::new(family_head, proxy, member_node);
let payload = FamilyJoinPermit::new(family_head, member_node);
// note: we're NOT wrapping it in `ContractMessageContent` because the family head is not going to be the one
// sending the message to the contract
@@ -3,9 +3,11 @@
use crate::error::MixnetContractError;
use crate::Layer;
use contracts_common::Percent;
use cosmwasm_schema::cw_serde;
use cosmwasm_std::Addr;
use cosmwasm_std::Coin;
use cosmwasm_std::{Addr, Uint128};
use std::fmt::{Display, Formatter};
use std::ops::Index;
// type aliases for better reasoning about available data
@@ -15,6 +17,65 @@ pub type SphinxKeyRef<'a> = &'a str;
pub type MixId = u32;
pub type BlockHeight = u64;
#[cw_serde]
pub struct RangedValue<T> {
pub minimum: T,
pub maximum: T,
}
impl<T> Copy for RangedValue<T> where T: Copy {}
pub type ProfitMarginRange = RangedValue<Percent>;
pub type OperatingCostRange = RangedValue<Uint128>;
impl<T> Display for RangedValue<T>
where
T: Display,
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{} - {}", self.minimum, self.maximum)
}
}
impl Default for ProfitMarginRange {
fn default() -> Self {
ProfitMarginRange {
minimum: Percent::zero(),
maximum: Percent::hundred(),
}
}
}
impl Default for OperatingCostRange {
fn default() -> Self {
OperatingCostRange {
minimum: Uint128::zero(),
// 1 billion (native tokens, i.e. 1 billion * 1'000'000 base tokens) - the total supply
maximum: Uint128::new(1_000_000_000_000_000),
}
}
}
impl<T> RangedValue<T>
where
T: Copy + PartialOrd + PartialEq,
{
pub fn normalise(&self, value: T) -> T {
if value < self.minimum {
self.minimum
} else if value > self.maximum {
self.maximum
} else {
value
}
}
pub fn within_range(&self, value: T) -> bool {
value >= self.minimum && value <= self.maximum
}
}
/// Specifies layer assignment for the given mixnode.
#[cw_serde]
pub struct LayerAssignment {
@@ -154,4 +215,14 @@ pub struct ContractStateParams {
/// Minimum amount a gateway must pledge to get into the system.
pub minimum_gateway_pledge: Coin,
/// Defines the allowed profit margin range of operators.
/// default: 0% - 100%
#[serde(default)]
pub profit_margin: ProfitMarginRange,
/// Defines the allowed interval operating cost range of operators.
/// default: 0 - 1'000'000'000'000'000 (1 Billion native tokens - the total supply)
#[serde(default)]
pub interval_operating_cost: OperatingCostRange,
}
@@ -167,3 +167,11 @@ pub fn new_track_undelegation_event() -> Event {
pub fn new_track_reward_event() -> Event {
Event::new(TRACK_REWARD_EVENT_TYPE)
}
pub fn new_track_migrate_mixnode_event() -> Event {
Event::new("track_migrate_vesting_mixnode")
}
pub fn new_track_migrate_delegation_event() -> Event {
Event::new("track_migrate_vesting_delegation")
}
@@ -136,6 +136,14 @@ pub enum ExecuteMsg {
address: String,
cap: PledgeCap,
},
TrackMigratedMixnode {
owner: String,
},
// no need to track migrated gateways as there are no vesting gateways on mainnet
TrackMigratedDelegation {
owner: String,
mix_id: MixId,
},
}
impl ExecuteMsg {
@@ -171,6 +179,10 @@ impl ExecuteMsg {
ExecuteMsg::TransferOwnership { .. } => "VestingExecuteMsg::TransferOwnership",
ExecuteMsg::UpdateStakingAddress { .. } => "VestingExecuteMsg::UpdateStakingAddress",
ExecuteMsg::UpdateLockedPledgeCap { .. } => "VestingExecuteMsg::UpdateLockedPledgeCap",
ExecuteMsg::TrackMigratedMixnode { .. } => "VestingExecuteMsg::TrackMigratedMixnode",
ExecuteMsg::TrackMigratedDelegation { .. } => {
"VestingExecuteMsg::TrackMigratedDelegation"
}
}
}
}
+5 -5
View File
@@ -12,16 +12,16 @@ aes = { workspace = true, optional = true }
bs58 = { workspace = true }
blake3 = { workspace = true, features = ["traits-preview"], optional = true }
ctr = { workspace = true, optional = true }
digest = { version = "0.10.3", optional = true }
digest = { workspace = true, optional = true }
generic-array = { workspace = true, 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 }
x25519-dalek = { workspace = true, features = ["static_secrets"], optional = true }
ed25519-dalek = { workspace = true, 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" }
serde_crate = { version = "1.0", optional = true, default-features = false, features = ["derive"], package = "serde" }
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.3"
rand_chacha = { workspace = true }
[features]
default = ["sphinx"]
+1 -1
View File
@@ -19,7 +19,7 @@ bs58 = { workspace = true }
lazy_static = { workspace = true }
rand = { version = "0.8.5", default-features = false}
rand_chacha = "0.3"
rand_chacha = { workspace = true }
rand_core = { workspace = true }
sha2 = "0.9"
serde = { workspace = true }
+2
View File
@@ -20,6 +20,8 @@ serde_json = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
nym-bin-common = { path = "../bin-common" }
# for request timeout until https://github.com/seanmonstar/reqwest/issues/1135 is fixed
[target."cfg(target_arch = \"wasm32\")".dependencies.wasmtimer]
workspace = true
+4
View File
@@ -14,6 +14,10 @@ use url::Url;
pub use reqwest::IntoUrl;
pub use user_agent::UserAgent;
mod user_agent;
pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
pub type PathSegments<'a> = &'a [&'a str];
+56
View File
@@ -0,0 +1,56 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::fmt;
use http::HeaderValue;
use nym_bin_common::build_information::{BinaryBuildInformation, BinaryBuildInformationOwned};
#[derive(Clone, Debug)]
pub struct UserAgent {
pub application: String,
pub version: String,
pub platform: String,
pub git_commit: String,
}
impl fmt::Display for UserAgent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let abbreviated_commit = self.git_commit.chars().take(7).collect::<String>();
write!(
f,
"{}/{}/{}/{}",
self.application, self.version, self.platform, abbreviated_commit
)
}
}
impl TryFrom<UserAgent> for HeaderValue {
type Error = http::header::InvalidHeaderValue;
fn try_from(user_agent: UserAgent) -> Result<Self, Self::Error> {
HeaderValue::from_str(&user_agent.to_string())
}
}
impl From<BinaryBuildInformation> for UserAgent {
fn from(build_info: BinaryBuildInformation) -> Self {
UserAgent {
application: build_info.binary_name.to_string(),
version: build_info.build_version.to_string(),
platform: build_info.cargo_triple.to_string(),
git_commit: build_info.commit_sha.to_string(),
}
}
}
impl From<BinaryBuildInformationOwned> for UserAgent {
fn from(build_info: BinaryBuildInformationOwned) -> Self {
UserAgent {
application: build_info.binary_name,
version: build_info.build_version,
platform: build_info.cargo_triple,
git_commit: build_info.commit_sha,
}
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ bytes = { workspace = true }
nym-bin-common = { path = "../bin-common" }
nym-crypto = { path = "../crypto" }
nym-sphinx = { path = "../nymsphinx" }
rand = "0.8.5"
rand = { workspace = true }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
time = { workspace = true }
@@ -0,0 +1,69 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{v6, v7};
impl From<v7::response::StaticConnectFailureReason> for v6::response::StaticConnectFailureReason {
fn from(failure: v7::response::StaticConnectFailureReason) -> Self {
match failure {
v7::response::StaticConnectFailureReason::RequestedIpAlreadyInUse => {
v6::response::StaticConnectFailureReason::RequestedIpAlreadyInUse
}
v7::response::StaticConnectFailureReason::RequestedNymAddressAlreadyInUse => {
v6::response::StaticConnectFailureReason::RequestedNymAddressAlreadyInUse
}
v7::response::StaticConnectFailureReason::OutOfDateTimestamp => {
v6::response::StaticConnectFailureReason::Other("out of date timestamp".to_string())
}
v7::response::StaticConnectFailureReason::Other(reason) => {
v6::response::StaticConnectFailureReason::Other(reason)
}
}
}
}
impl From<v7::response::DynamicConnectFailureReason> for v6::response::DynamicConnectFailureReason {
fn from(failure: v7::response::DynamicConnectFailureReason) -> Self {
match failure {
v7::response::DynamicConnectFailureReason::RequestedNymAddressAlreadyInUse => {
v6::response::DynamicConnectFailureReason::RequestedNymAddressAlreadyInUse
}
v7::response::DynamicConnectFailureReason::NoAvailableIp => {
v6::response::DynamicConnectFailureReason::NoAvailableIp
}
v7::response::DynamicConnectFailureReason::Other(err) => {
v6::response::DynamicConnectFailureReason::Other(err)
}
}
}
}
impl From<v7::response::InfoResponseReply> for v6::response::InfoResponseReply {
fn from(reply: v7::response::InfoResponseReply) -> Self {
match reply {
v7::response::InfoResponseReply::Generic { msg } => {
v6::response::InfoResponseReply::Generic { msg }
}
v7::response::InfoResponseReply::VersionMismatch {
request_version,
response_version,
} => v6::response::InfoResponseReply::VersionMismatch {
request_version,
response_version,
},
v7::response::InfoResponseReply::ExitPolicyFilterCheckFailed { dst } => {
v6::response::InfoResponseReply::ExitPolicyFilterCheckFailed { dst }
}
}
}
}
impl From<v7::response::InfoLevel> for v6::response::InfoLevel {
fn from(level: v7::response::InfoLevel) -> Self {
match level {
v7::response::InfoLevel::Info => v6::response::InfoLevel::Info,
v7::response::InfoLevel::Warn => v6::response::InfoLevel::Warn,
v7::response::InfoLevel::Error => v6::response::InfoLevel::Error,
}
}
}
+1
View File
@@ -1,3 +1,4 @@
pub mod conversion;
pub mod request;
pub mod response;
@@ -198,6 +198,17 @@ impl IpPacketRequestData {
| IpPacketRequestData::Health(_) => None,
}
}
pub fn signable_request(&self) -> Option<Result<Vec<u8>, SignatureError>> {
match self {
IpPacketRequestData::StaticConnect(request) => Some(request.request()),
IpPacketRequestData::DynamicConnect(request) => Some(request.request()),
IpPacketRequestData::Disconnect(request) => Some(request.request()),
IpPacketRequestData::Data(_) => None,
IpPacketRequestData::Ping(_) => None,
IpPacketRequestData::Health(_) => None,
}
}
}
// A static connect request is when the client provides the internal IP address it will use on the
+17
View File
@@ -42,6 +42,7 @@ pub struct NymNetworkDetails {
pub endpoints: Vec<ValidatorDetails>,
pub contracts: NymContracts,
pub explorer_api: Option<String>,
pub nym_vpn_api_url: Option<String>,
}
// by default we assume the same defaults as mainnet, i.e. same prefixes and denoms
@@ -71,6 +72,7 @@ impl NymNetworkDetails {
endpoints: Default::default(),
contracts: Default::default(),
explorer_api: Default::default(),
nym_vpn_api_url: Default::default(),
}
}
@@ -126,6 +128,7 @@ impl NymNetworkDetails {
.with_multisig_contract(get_optional_env(var_names::MULTISIG_CONTRACT_ADDRESS))
.with_coconut_dkg_contract(get_optional_env(var_names::COCONUT_DKG_CONTRACT_ADDRESS))
.with_explorer_api(get_optional_env(var_names::EXPLORER_API))
.with_nym_vpn_api_url(get_optional_env(var_names::NYM_VPN_API))
}
pub fn new_mainnet() -> Self {
@@ -155,6 +158,7 @@ impl NymNetworkDetails {
),
},
explorer_api: parse_optional_str(mainnet::EXPLORER_API),
nym_vpn_api_url: parse_optional_str(mainnet::NYM_VPN_API),
}
}
@@ -263,6 +267,19 @@ impl NymNetworkDetails {
self.explorer_api = endpoint.map(Into::into);
self
}
#[must_use]
pub fn with_nym_vpn_api_url<S: Into<String>>(mut self, endpoint: Option<S>) -> Self {
self.nym_vpn_api_url = endpoint.map(Into::into);
self
}
pub fn nym_vpn_api_url(&self) -> Option<Url> {
self.nym_vpn_api_url.as_ref().map(|url| {
url.parse()
.expect("the provided nym-vpn api url is invalid!")
})
}
}
#[derive(Debug, Copy, Serialize, Deserialize, Clone, PartialEq, Eq)]
+2 -9
View File
@@ -27,11 +27,11 @@ pub const COCONUT_DKG_CONTRACT_ADDRESS: &str =
pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy";
pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/";
pub const NYXD_URL: &str = "https://rpc.nymtech.net";
pub const NYM_API: &str = "https://validator.nymtech.net/api/";
pub const NYXD_WS: &str = "wss://rpc.nymtech.net/websocket";
pub const EXPLORER_API: &str = "https://explorer.nymtech.net/api/";
pub const NYM_VPN_API: &str = "https://nymvpn.net/api/";
// I'm making clippy mad on purpose, because that url HAS TO be updated and deployed before merging
pub const EXIT_POLICY_URL: &str =
@@ -110,15 +110,12 @@ pub fn export_to_env() {
var_names::REWARDING_VALIDATOR_ADDRESS,
REWARDING_VALIDATOR_ADDRESS,
);
set_var_to_default(
var_names::STATISTICS_SERVICE_DOMAIN_ADDRESS,
STATISTICS_SERVICE_DOMAIN_ADDRESS,
);
set_var_to_default(var_names::NYXD, NYXD_URL);
set_var_to_default(var_names::NYM_API, NYM_API);
set_var_to_default(var_names::NYXD_WEBSOCKET, NYXD_WS);
set_var_to_default(var_names::EXPLORER_API, EXPLORER_API);
set_var_to_default(var_names::EXIT_POLICY_URL, EXIT_POLICY_URL);
set_var_to_default(var_names::NYM_VPN_API, NYM_VPN_API);
}
pub fn export_to_env_if_not_set() {
@@ -155,10 +152,6 @@ pub fn export_to_env_if_not_set() {
var_names::REWARDING_VALIDATOR_ADDRESS,
REWARDING_VALIDATOR_ADDRESS,
);
set_var_conditionally_to_default(
var_names::STATISTICS_SERVICE_DOMAIN_ADDRESS,
STATISTICS_SERVICE_DOMAIN_ADDRESS,
);
set_var_conditionally_to_default(var_names::NYXD, NYXD_URL);
set_var_conditionally_to_default(var_names::NYM_API, NYM_API);
set_var_conditionally_to_default(var_names::NYXD_WEBSOCKET, NYXD_WS);
+1 -1
View File
@@ -19,12 +19,12 @@ pub const GROUP_CONTRACT_ADDRESS: &str = "GROUP_CONTRACT_ADDRESS";
pub const MULTISIG_CONTRACT_ADDRESS: &str = "MULTISIG_CONTRACT_ADDRESS";
pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "COCONUT_DKG_CONTRACT_ADDRESS";
pub const REWARDING_VALIDATOR_ADDRESS: &str = "REWARDING_VALIDATOR_ADDRESS";
pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "STATISTICS_SERVICE_DOMAIN_ADDRESS";
pub const NYXD: &str = "NYXD";
pub const NYM_API: &str = "NYM_API";
pub const NYXD_WEBSOCKET: &str = "NYXD_WS";
pub const EXPLORER_API: &str = "EXPLORER_API";
pub const EXIT_POLICY_URL: &str = "EXIT_POLICY";
pub const NYM_VPN_API: &str = "NYM_VPN_API";
pub const DKG_TIME_CONFIGURATION: &str = "DKG_TIME_CONFIGURATION";
+2 -2
View File
@@ -9,7 +9,7 @@ license.workspace = true
[dependencies]
bls12_381 = { workspace = true, default-features = false, features = ["pairings", "alloc", "experimental"] }
itertools = "0.10"
itertools = { workspace = true }
digest = "0.9"
rand = "0.8"
thiserror = { workspace = true }
@@ -33,7 +33,7 @@ default-features = false
[dev-dependencies]
criterion = { workspace = true, features = ["html_reports"] }
doc-comment = { workspace = true }
rand_chacha = "0.3"
rand_chacha = { workspace = true }
[[bench]]
name = "benchmarks"
+1 -1
View File
@@ -9,7 +9,7 @@ repository = { workspace = true }
[dependencies]
rand = { workspace = true }
serde_crate = { version = "1.0", optional = true, default_features = false, features = ["derive"], package = "serde" }
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 }
zeroize = { workspace = true }
@@ -24,4 +24,4 @@ nym-topology = { path = "../../topology" }
version = "0.2.83"
[dev-dependencies]
rand_chacha = "0.3"
rand_chacha = { workspace = true }
+1 -1
View File
@@ -17,7 +17,7 @@ cosmrs.workspace = true
eyre = { workspace = true }
futures.workspace = true
humantime = { workspace = true }
sha2 = "0.10.8"
sha2 = { workspace = true }
serde = { workspace = true, features = ["derive"] }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate", "time"] }
tendermint.workspace = true
+1 -1
View File
@@ -8,7 +8,7 @@ license.workspace = true
[dependencies]
anyhow = { workspace = true }
dirs = "4.0"
dirs = { workspace = true }
futures = { workspace = true }
log = { workspace = true }
pin-project = { workspace = true }
+12 -2
View File
@@ -27,6 +27,7 @@ use nym_task::manager::TaskStatus;
use nym_task::{TaskClient, TaskHandle};
use anyhow::anyhow;
use nym_validator_client::UserAgent;
use std::error::Error;
use std::path::PathBuf;
@@ -61,6 +62,8 @@ pub struct NymClient<S> {
setup_method: GatewaySetup,
user_agent: UserAgent,
/// Optional path to a .json file containing standalone network details.
custom_mixnet: Option<PathBuf>,
}
@@ -74,11 +77,17 @@ where
<S::GatewaysDetailsStore as GatewaysDetailsStore>::StorageError: Sync + Send,
<S::KeyStore as KeyStore>::StorageError: Send + Sync,
{
pub fn new(config: Config, storage: S, custom_mixnet: Option<PathBuf>) -> Self {
pub fn new(
config: Config,
storage: S,
user_agent: UserAgent,
custom_mixnet: Option<PathBuf>,
) -> Self {
NymClient {
config,
storage,
setup_method: GatewaySetup::MustLoad { gateway_id: None },
user_agent,
custom_mixnet,
}
}
@@ -226,7 +235,8 @@ where
let mut base_builder =
BaseClientBuilder::new(&self.config.base, self.storage, dkg_query_client)
.with_gateway_setup(self.setup_method);
.with_gateway_setup(self.setup_method)
.with_user_agent(self.user_agent);
if let Some(custom_mixnet) = &self.custom_mixnet {
base_builder = base_builder.with_stored_topology(custom_mixnet)?;
-20
View File
@@ -1,20 +0,0 @@
# Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
# SPDX-License-Identifier: Apache-2.0
[package]
name = "nym-statistics-common"
version = "1.0.1"
edition = "2021"
license.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
async-trait = { workspace = true }
log = { workspace = true }
reqwest = { workspace = true, features = ["json"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sqlx = { workspace = true, features = ["runtime-tokio-rustls", "chrono"]}
thiserror = { workspace = true }
tokio = { workspace = true, features = ["time"] }
-51
View File
@@ -1,51 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::error::StatsError;
use crate::StatsMessage;
pub const DEFAULT_STATISTICS_SERVICE_ADDRESS: &str = "127.0.0.1";
pub const DEFAULT_STATISTICS_SERVICE_PORT: u16 = 8091;
pub const STATISTICS_SERVICE_VERSION: &str = "/v1";
pub const STATISTICS_SERVICE_API_STATISTICS: &str = "statistic";
pub async fn build_and_send_statistics_request(
msg: StatsMessage,
url: String,
) -> Result<(), StatsError> {
reqwest::Client::new()
.post(format!(
"{url}{STATISTICS_SERVICE_VERSION}/{STATISTICS_SERVICE_API_STATISTICS}"
))
.json(&msg)
.send()
.await?;
Ok(())
}
pub fn build_statistics_request_bytes(msg: StatsMessage) -> Result<Vec<u8>, StatsError> {
let json_msg = msg.to_json()?;
let req = reqwest::Request::new(
reqwest::Method::POST,
reqwest::Url::parse(&format!(
"http://{DEFAULT_STATISTICS_SERVICE_ADDRESS}:{DEFAULT_STATISTICS_SERVICE_PORT}{STATISTICS_SERVICE_VERSION}/{STATISTICS_SERVICE_API_STATISTICS}"
))
.unwrap(),
);
let data = format!(
"{} {} {:?}\n\
Content-Type: application/json\n\
Content-Length: {}\n\n\
{}\n",
req.method().as_str(),
req.url().as_str(),
req.version(),
json_msg.len(),
json_msg
);
Ok(data.into_bytes())
}
-57
View File
@@ -1,57 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use async_trait::async_trait;
use log::error;
use sqlx::types::chrono::{DateTime, Utc};
use std::time::Duration;
use tokio::time;
use crate::error::StatsError;
use crate::StatsMessage;
const STATISTICS_TIMER_INTERVAL: Duration = Duration::from_secs(60);
#[async_trait]
pub trait StatisticsCollector {
async fn create_stats_message(
&self,
interval: Duration,
timestamp: DateTime<Utc>,
) -> StatsMessage;
async fn send_stats_message(&self, stats_message: StatsMessage) -> Result<(), StatsError>;
async fn reset_stats(&mut self);
}
pub struct StatisticsSender<T: StatisticsCollector> {
collector: T,
interval: Duration,
timestamp: DateTime<Utc>,
}
impl<T: StatisticsCollector> StatisticsSender<T> {
pub fn new(collector: T) -> Self {
StatisticsSender {
collector,
interval: STATISTICS_TIMER_INTERVAL,
timestamp: Utc::now(),
}
}
pub async fn run(&mut self) {
let mut interval = time::interval(self.interval);
loop {
interval.tick().await;
let stats_message = self
.collector
.create_stats_message(self.interval, self.timestamp)
.await;
if let Err(e) = self.collector.send_stats_message(stats_message).await {
error!("Statistics not sent: {}", e);
}
self.collector.reset_stats().await;
self.timestamp = Utc::now();
}
}
}
-13
View File
@@ -1,13 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use thiserror::Error;
#[derive(Debug, Error)]
pub enum StatsError {
#[error("Serde JSON error: {0}")]
SerdeJsonError(#[from] serde_json::Error),
#[error("Reqwest error: {0}")]
ReqwestError(#[from] reqwest::Error),
}
-65
View File
@@ -1,65 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use serde::{Deserialize, Serialize};
use error::StatsError;
pub mod api;
pub mod collector;
pub mod error;
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct StatsMessage {
pub stats_data: Vec<StatsData>,
pub interval_seconds: u32,
pub timestamp: String,
}
impl StatsMessage {
pub fn to_json(&self) -> Result<String, StatsError> {
Ok(serde_json::to_string(self)?)
}
pub fn from_json(s: &str) -> Result<Self, StatsError> {
Ok(serde_json::from_str(s)?)
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum StatsData {
Service(StatsServiceData),
Gateway(StatsGatewayData),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct StatsGatewayData {
pub gateway_id: String,
pub inbox_count: u32,
}
impl StatsGatewayData {
pub fn new(gateway_id: String, inbox_count: u32) -> Self {
StatsGatewayData {
gateway_id,
inbox_count,
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct StatsServiceData {
pub requested_service: String,
pub request_bytes: u32,
pub response_bytes: u32,
}
impl StatsServiceData {
pub fn new(requested_service: String, request_bytes: u32, response_bytes: u32) -> Self {
StatsServiceData {
requested_service,
request_bytes,
response_bytes,
}
}
}
-1
View File
@@ -44,7 +44,6 @@ pub enum NymTopologyError {
PayloadBuilder,
#[error("Outfox: {0}")]
#[cfg(feature = "outfox")]
Outfox(#[from] nym_sphinx_types::OutfoxError),
#[error("{0}")]
@@ -7,6 +7,7 @@ use nym_sphinx_routing::SphinxRouteMaker;
use nym_sphinx_types::Node;
use rand::{CryptoRng, Rng};
#[allow(dead_code)]
pub struct NymTopologyRouteProvider<R> {
rng: R,
inner: NymTopology,
+4 -4
View File
@@ -8,21 +8,21 @@ rust-version = "1.58"
license.workspace = true
[dependencies]
base64 = "0.21.4"
base64 = { workspace = true }
eyre = { workspace = true }
hmac = { workspace = true }
itertools = "0.11"
itertools = { workspace = true }
log = { workspace = true }
reqwest = { workspace = true }
schemars = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
sha2 = "0.10.8"
sha2 = { workspace = true }
strum = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
ts-rs = { workspace = true }
url = { workspace = true }
x25519-dalek = { version = "2.0.0", features = ["static_secrets"] }
x25519-dalek = { workspace = true, features = ["static_secrets"] }
cosmwasm-std = { workspace = true }
cosmrs = { workspace = true }
+4
View File
@@ -1,3 +1,4 @@
use nym_mixnet_contract_common::ContractsCommonError;
use nym_validator_client::error::TendermintRpcError;
use nym_validator_client::nym_api::error::NymAPIError;
use nym_validator_client::{nyxd::error::NyxdError, ValidatorClientError};
@@ -8,6 +9,9 @@ use thiserror::Error;
// TODO: ask @MS why this even exists
#[derive(Error, Debug)]
pub enum TypesError {
#[error(transparent)]
ContractsCommon(#[from] ContractsCommonError),
#[error("{source}")]
NyxdError {
#[from]
+1 -3
View File
@@ -124,7 +124,6 @@ pub struct GatewayNetworkRequesterDetails {
pub encryption_key: String,
pub open_proxy: bool,
pub enabled_statistics: bool,
// just a convenience wrapper around all the keys
pub address: String,
@@ -142,8 +141,7 @@ impl fmt::Display for GatewayNetworkRequesterDetails {
writeln!(f, "\tencryption key: {}", self.encryption_key)?;
writeln!(f, "\taddress: {}", self.address)?;
writeln!(f, "\tuses open proxy: {}", self.open_proxy)?;
writeln!(f, "\tsends statistics: {}", self.enabled_statistics)
writeln!(f, "\tuses open proxy: {}", self.open_proxy)
}
}
+2
View File
@@ -84,6 +84,7 @@ impl PendingEpochEventData {
mix_id,
amount,
proxy,
..
} => Ok(PendingEpochEventData::Delegate {
owner: owner.into_string(),
mix_id,
@@ -94,6 +95,7 @@ impl PendingEpochEventData {
owner,
mix_id,
proxy,
..
} => Ok(PendingEpochEventData::Undelegate {
owner: owner.into_string(),
mix_id,
+1 -1
View File
@@ -122,7 +122,7 @@ pub async fn setup_gateway_from_api(
nym_apis: &[Url],
) -> Result<InitialisationResult, WasmCoreError> {
let mut rng = thread_rng();
let gateways = current_gateways(&mut rng, nym_apis).await?;
let gateways = current_gateways(&mut rng, nym_apis, None).await?;
setup_gateway_wasm(client_store, force_tls, chosen_gateway, &gateways).await
}

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