Compare commits

..

12 Commits

Author SHA1 Message Date
fmtabbara 43d6908d22 display loading modal for initial loading of values
run cargo fmt

fix clippy error

minor fixes
2022-12-19 09:38:00 +00:00
fmtabbara e10f291ee9 set active set to be always true 2022-12-19 09:38:00 +00:00
Jon Häggblad ecc89ced08 Make ComputeRewardEstParam derive Debug 2022-12-19 09:38:00 +00:00
fmtabbara 1e10c247bc calculate saturation
tidy

Use NodeId in compute_mixnode_reward_estimation

only call handleCalculation on button click

fix validation tests

tweak calculations

calculate stake saturation

pick up and display errors

pass profit margin and operator cost as args

rebase develop

rebase develop

fix profit margin validation

tidy up

refactor requests for rewards playground

wip
2022-12-19 09:38:00 +00:00
fmtabbara 4584f35a2a get mixnode reward estimation
separarte handleCalculate function into own file

add mix-id to bondedNode state

remove unused imports
2022-12-19 09:38:00 +00:00
fmtabbara 41fa03862e get node uptime 2022-12-19 09:38:00 +00:00
fmtabbara 66303d7ca4 init playground with default values
add more default values

env updates
2022-12-19 09:38:00 +00:00
fmtabbara 480f8a0a53 update validation for rewards playground 2022-12-19 09:38:00 +00:00
fmtabbara ecb0f11bbb add initial rewards calculation
run make file
2022-12-19 09:38:00 +00:00
fmtabbara fe223b5a60 apy playground ui
update calc button style

validator-api-client and wallet: compute mixnode reward estimation
2022-12-19 09:37:45 +00:00
fmtabbara b9e52d22d1 add print to pdf package 2022-12-19 09:36:56 +00:00
fmtabbara ecdf192b47 initial ui for test my node
use svg for node path

adjust layout for overiew page

add stories for test my node

remove placeholder nav item

add top margin to app bar

add print to pdf functionality for node test results
2022-12-19 09:36:56 +00:00
236 changed files with 6467 additions and 12877 deletions
+28 -44
View File
@@ -13,32 +13,10 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- all-binaries: improved error logging ([#2686])
- native client: bring shutdown logic up to the same level as socks5-client
- nym-api, coconut-dkg contract: automatic, time-based dkg epoch state advancement ([#2670])
- all-binaries: standarised argument names (note: old names should still be accepted) ([#2762]
### Fixed
- nym-api: should now correctly use `rewarding.enabled` config flag ([#2753])
[#2686]: https://github.com/nymtech/nym/pull/2686
[#2670]: https://github.com/nymtech/nym/pull/2670
[#2753]: https://github.com/nymtech/nym/pull/2753
[#2762]: https://github.com/nymtech/nym/pull/2762
## [v1.1.4] (2022-12-20)
This release adds multiple Single Use Reply Blocks (SURBs) to allow arbitrarily-sized anonymized replies.
At the moment this is turned off by default, but available for use by application developers.
We will need to wait for network-requesters to upgrade to this new release, after which multi-SURB anonymization will become the default setting for the SOCKS proxy clients.
The release also include some additional work for distributed key generation in the Coconut signing authority nodes.
### Changed
- Feature/dkg contract threshold by @neacsu in https://github.com/nymtech/nym/pull/1885
- Multi-surbs by @jstuczyn in https://github.com/nymtech/nym/pull/2667
- Fix multi-surb backwards compatibility in pre 1.1.4 client config files by @jstuczyn in https://github.com/nymtech/nym/pull/2703
- fix: ignore corrupted surb storage and instead create fresh one by @jstuczyn in https://github.com/nymtech/nym/pull/2711
- socks5: rework waiting in inbound.rs by @octol in https://github.com/nymtech/nym/pull/1880
## [v1.1.3] (2022-12-13)
@@ -53,7 +31,7 @@ The release also include some additional work for distributed key generation in
- network-requester: fix bug where websocket connection disconnect resulted in success error code
- clients: fix a few panics handling the gateway-client
- mixnode, gateway, validator-api: Use mainnet values as defaults for URLs and mixnet contract ([#1884])
- mixnode, gateway, validator-api: Use mainnet values as defaults for URLs and mixnet contract ([#1884])
- socks5: fixed bug where connections sometimes where closed too early
- clients: improve message logging when received message fails to get reconstructed ([#1803])
@@ -73,7 +51,7 @@ The release also include some additional work for distributed key generation in
- gateway: Renamed flag from `enabled/disabled_credentials_mode` to `only-coconut-credentials`
- "Family" feature for node families + layers
- Initial coconut functionality including credentials and distributed key generation
- Initial coconut functionality including credentials and distributed key generation
## [v1.1.1](https://github.com/nymtech/nym/tree/v1.1.1) (2022-11-29)
@@ -109,6 +87,7 @@ The release also include some additional work for distributed key generation in
[#1786]: https://github.com/nymtech/nym/pull/1786
[#1805]: https://github.com/nymtech/nym/pull/1805
## [v1.1.0](https://github.com/nymtech/nym/tree/v1.1.0) (2022-11-09)
### Added
@@ -135,7 +114,7 @@ The release also include some additional work for distributed key generation in
- gateway-client: will attempt to read now as many as 8 websocket messages at once, assuming they're already available on the socket ([#1669])
- moved `Percent` struct to `contracts-common`, change affects explorer-api
- socks5 client: graceful shutdown should fix error on disconnect in nym-connect ([#1591])
- validator-api: changed error serialization on `inclusion_probability`, `stake-saturation` and `reward-estimation` endpoints to provide more accurate information ([#1681])
- validator-api: changed error serialization on `inclusion_probability`, `stake-saturation` and `reward-estimation` endpoints to provide more accurate information ([#1681])
- validator-client: made `fee` argument optional for `execute` and `execute_multiple` ([#1541])
- wasm-client: fixed build errors on MacOS and changed example JS code to use mainnet ([#1585])
- validator-api: changes to internal SQL schema due to the mixnet contract revamp ([#1472])
@@ -163,6 +142,7 @@ The release also include some additional work for distributed key generation in
[#1724]: https://github.com/nymtech/nym/pull/1724
[#1725]: https://github.com/nymtech/nym/pull/1725
## [nym-binaries-1.0.2](https://github.com/nymtech/nym/tree/nym-binaries-1.0.2)
### Added
@@ -216,7 +196,8 @@ The release also include some additional work for distributed key generation in
- gateway, network-statistics: include gateway id in the sent statistical data ([#1478])
- network explorer: tweak how active set probability is shown ([#1503])
- validator-api: rewarder set update fails without panicking on possible nymd queries ([#1520])
- network-requester, socks5 client (nym-connect): send and receive respectively a message error to be displayed about filter check failure ([#1576])
- network-requester, socks5 client (nym-connect): send and receive respectively a message error to be displayed about filter check failure ([#1576])
[#1249]: https://github.com/nymtech/nym/pull/1249
[#1256]: https://github.com/nymtech/nym/pull/1256
@@ -310,9 +291,9 @@ The release also include some additional work for distributed key generation in
- Bump minimist from 1.2.5 to 1.2.6 in /clients/tauri-client [\#1163](https://github.com/nymtech/nym/pull/1163) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump minimist from 1.2.5 to 1.2.6 in /clients/webassembly/js-example [\#1162](https://github.com/nymtech/nym/pull/1162) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump minimist from 1.2.5 to 1.2.6 in /clients/native/examples/js-examples/websocket [\#1160](https://github.com/nymtech/nym/pull/1160) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump minimist from 1.2.5 to 1.2.6 in /docker/typescript_client/upload_contract [\#1159](https://github.com/nymtech/nym/pull/1159) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump minimist from 1.2.5 to 1.2.6 in /docker/typescript\_client/upload\_contract [\#1159](https://github.com/nymtech/nym/pull/1159) ([dependabot[bot]](https://github.com/apps/dependabot))
- Feature/vesting full [\#1158](https://github.com/nymtech/nym/pull/1158) ([fmtabbara](https://github.com/fmtabbara))
- get_current_epoch tauri [\#1156](https://github.com/nymtech/nym/pull/1156) ([durch](https://github.com/durch))
- get\_current\_epoch tauri [\#1156](https://github.com/nymtech/nym/pull/1156) ([durch](https://github.com/durch))
- Cleanup [\#1155](https://github.com/nymtech/nym/pull/1155) ([durch](https://github.com/durch))
- Feature flag reward payments [\#1154](https://github.com/nymtech/nym/pull/1154) ([durch](https://github.com/durch))
- Add Query endpoints for calculating rewards [\#1152](https://github.com/nymtech/nym/pull/1152) ([durch](https://github.com/durch))
@@ -321,7 +302,7 @@ The release also include some additional work for distributed key generation in
- wallet: use Urls rather than Strings for validator urls [\#1148](https://github.com/nymtech/nym/pull/1148) ([octol](https://github.com/octol))
- Change accumulated reward to Option, migrate delegations [\#1147](https://github.com/nymtech/nym/pull/1147) ([durch](https://github.com/durch))
- wallet: fetch validators url remotely if available [\#1146](https://github.com/nymtech/nym/pull/1146) ([octol](https://github.com/octol))
- Fix delegated_free calculation [\#1145](https://github.com/nymtech/nym/pull/1145) ([durch](https://github.com/durch))
- Fix delegated\_free calculation [\#1145](https://github.com/nymtech/nym/pull/1145) ([durch](https://github.com/durch))
- Update Nym wallet dependencies to use `ts-packages` [\#1144](https://github.com/nymtech/nym/pull/1144) ([mmsinclair](https://github.com/mmsinclair))
- wallet: try validators one by one if available [\#1143](https://github.com/nymtech/nym/pull/1143) ([octol](https://github.com/octol))
- Update Network Explorer Packages and add mix node identity key copy [\#1142](https://github.com/nymtech/nym/pull/1142) ([mmsinclair](https://github.com/mmsinclair))
@@ -361,13 +342,14 @@ The release also include some additional work for distributed key generation in
- feature/pedersen-commitments [\#1048](https://github.com/nymtech/nym/pull/1048) ([danielementary](https://github.com/danielementary))
- Feature/reuse init owner [\#970](https://github.com/nymtech/nym/pull/970) ([neacsu](https://github.com/neacsu))
## [v0.12.1](https://github.com/nymtech/nym/tree/v0.12.1) (2021-12-23)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.12.0...v0.12.1)
**Implemented enhancements:**
- Add version check to binaries [\#967](https://github.com/nymtech/nym/issues/967)
- Add version check to binaries [\#967](https://github.com/nymtech/nym/issues/967)
**Fixed bugs:**
@@ -397,7 +379,7 @@ The release also include some additional work for distributed key generation in
- Bugfix/remove mixnode bonding overwrite [\#917](https://github.com/nymtech/nym/pull/917) ([jstuczyn](https://github.com/jstuczyn))
- Fixes crash condition in validator API when calculating last day uptime [\#909](https://github.com/nymtech/nym/pull/909) ([jstuczyn](https://github.com/jstuczyn))
- Bugfix/monitor initial values wait [\#907](https://github.com/nymtech/nym/pull/907) ([jstuczyn](https://github.com/jstuczyn))
- Bug fix: Network Explorer: Add freegeoip API key and split out tasks for country distributions [\#806](https://github.com/nymtech/nym/pull/806) ([mmsinclair](https://github.com/mmsinclair))
- Bug fix: Network Explorer: Add freegeoip API key and split out tasks for country distributions [\#806](https://github.com/nymtech/nym/pull/806) ([mmsinclair](https://github.com/mmsinclair))
- Explorer API: port test now split out address resolution and add units tests [\#755](https://github.com/nymtech/nym/pull/755) ([mmsinclair](https://github.com/mmsinclair))
**Closed issues:**
@@ -412,7 +394,7 @@ The release also include some additional work for distributed key generation in
- help!!! [\#712](https://github.com/nymtech/nym/issues/712)
- UX feature request: show all delegated nodes in wallet [\#711](https://github.com/nymtech/nym/issues/711)
- UX feature request: add current balance on wallet pages [\#710](https://github.com/nymtech/nym/issues/710)
- got sign issue from bot [\#709](https://github.com/nymtech/nym/issues/709)
- got sign issue from bot [\#709](https://github.com/nymtech/nym/issues/709)
- As a wallet user, I would like to be able to log out of the wallet [\#706](https://github.com/nymtech/nym/issues/706)
- As a wallet user, I would like to have a "receive" page where I can see my own wallet address [\#705](https://github.com/nymtech/nym/issues/705)
- Update native client/socks client/mixnode/gateway `upgrade` command [\#689](https://github.com/nymtech/nym/issues/689)
@@ -422,7 +404,7 @@ The release also include some additional work for distributed key generation in
- nym-socks5-client crash after opening Keybase team "Browse all channels" [\#494](https://github.com/nymtech/nym/issues/494)
- Mixed Content problem [\#400](https://github.com/nymtech/nym/issues/400)
- Gateway disk quota [\#137](https://github.com/nymtech/nym/issues/137)
- Simplify message encapsulation with regards to topology [\#127](https://github.com/nymtech/nym/issues/127)
- Simplify message encapsulation with regards to topology [\#127](https://github.com/nymtech/nym/issues/127)
- Create constants for cli argument names [\#115](https://github.com/nymtech/nym/issues/115)
- Using Blake3 as a hash function [\#103](https://github.com/nymtech/nym/issues/103)
- Validator should decide which layer a node is in [\#86](https://github.com/nymtech/nym/issues/86)
@@ -478,10 +460,10 @@ The release also include some additional work for distributed key generation in
- Feature/pre cosmrs updates [\#935](https://github.com/nymtech/nym/pull/935) ([jstuczyn](https://github.com/jstuczyn))
- Feature/client on behalf [\#934](https://github.com/nymtech/nym/pull/934) ([neacsu](https://github.com/neacsu))
- Webpack wallet prod configuration [\#933](https://github.com/nymtech/nym/pull/933) ([tommyv1987](https://github.com/tommyv1987))
- Adding tx_hash to wallet response [\#932](https://github.com/nymtech/nym/pull/932) ([futurechimp](https://github.com/futurechimp))
- Adding tx\_hash to wallet response [\#932](https://github.com/nymtech/nym/pull/932) ([futurechimp](https://github.com/futurechimp))
- Release/1.0.0 pre1 [\#931](https://github.com/nymtech/nym/pull/931) ([durch](https://github.com/durch))
- Feature/identity verification [\#930](https://github.com/nymtech/nym/pull/930) ([jstuczyn](https://github.com/jstuczyn))
- Move cleaned up smart contracts to main code repo [\#929](https://github.com/nymtech/nym/pull/929) ([mfahampshire](https://github.com/mfahampshire))
- Move cleaned up smart contracts to main code repo [\#929](https://github.com/nymtech/nym/pull/929) ([mfahampshire](https://github.com/mfahampshire))
- Feature/mixnet contract further adjustments [\#928](https://github.com/nymtech/nym/pull/928) ([jstuczyn](https://github.com/jstuczyn))
- typo copy change for nodemap [\#926](https://github.com/nymtech/nym/pull/926) ([Aid19801](https://github.com/Aid19801))
- Feature/UI enhancements for Desktop Wallet [\#925](https://github.com/nymtech/nym/pull/925) ([fmtabbara](https://github.com/fmtabbara))
@@ -494,7 +476,7 @@ The release also include some additional work for distributed key generation in
- Feature/faucet page react [\#911](https://github.com/nymtech/nym/pull/911) ([fmtabbara](https://github.com/fmtabbara))
- Feature/mixnet contract refactor [\#910](https://github.com/nymtech/nym/pull/910) ([futurechimp](https://github.com/futurechimp))
- Update README.md [\#905](https://github.com/nymtech/nym/pull/905) ([tommyv1987](https://github.com/tommyv1987))
- BUG: Bond cell denom [\#904](https://github.com/nymtech/nym/pull/904) ([Aid19801](https://github.com/Aid19801))
- BUG: Bond cell denom [\#904](https://github.com/nymtech/nym/pull/904) ([Aid19801](https://github.com/Aid19801))
- Explorer UI tests missing data-testid [\#903](https://github.com/nymtech/nym/pull/903) ([tommyv1987](https://github.com/tommyv1987))
- Fix up Nym-Wallet README.md [\#899](https://github.com/nymtech/nym/pull/899) ([tommyv1987](https://github.com/tommyv1987))
- Feature/batch delegator rewarding [\#898](https://github.com/nymtech/nym/pull/898) ([jstuczyn](https://github.com/jstuczyn))
@@ -512,7 +494,7 @@ The release also include some additional work for distributed key generation in
- Reverted gateway registration handshake to its 0.11.0 version [\#882](https://github.com/nymtech/nym/pull/882) ([jstuczyn](https://github.com/jstuczyn))
- Network Explorer [\#881](https://github.com/nymtech/nym/pull/881) ([mmsinclair](https://github.com/mmsinclair))
- Feature/rewarding interval updates [\#880](https://github.com/nymtech/nym/pull/880) ([jstuczyn](https://github.com/jstuczyn))
- Put client_address and id in the correct order [\#875](https://github.com/nymtech/nym/pull/875) ([neacsu](https://github.com/neacsu))
- Put client\_address and id in the correct order [\#875](https://github.com/nymtech/nym/pull/875) ([neacsu](https://github.com/neacsu))
- remove gateway selection on delegation and undelegation pages [\#873](https://github.com/nymtech/nym/pull/873) ([fmtabbara](https://github.com/fmtabbara))
- Set MSRV on all binaries to 1.56 [\#872](https://github.com/nymtech/nym/pull/872) ([jstuczyn](https://github.com/jstuczyn))
- add native window items \(copy/paste\) via tauri [\#871](https://github.com/nymtech/nym/pull/871) ([fmtabbara](https://github.com/fmtabbara))
@@ -528,7 +510,7 @@ The release also include some additional work for distributed key generation in
- Overflow checks in release [\#846](https://github.com/nymtech/nym/pull/846) ([jstuczyn](https://github.com/jstuczyn))
- fix delegate success overflow [\#842](https://github.com/nymtech/nym/pull/842) ([fmtabbara](https://github.com/fmtabbara))
- Feature NYM wallet webdriverio test [\#841](https://github.com/nymtech/nym/pull/841) ([tommyv1987](https://github.com/tommyv1987))
- Update nym_wallet.yml [\#840](https://github.com/nymtech/nym/pull/840) ([tommyv1987](https://github.com/tommyv1987))
- Update nym\_wallet.yml [\#840](https://github.com/nymtech/nym/pull/840) ([tommyv1987](https://github.com/tommyv1987))
- Feature/vouchers [\#837](https://github.com/nymtech/nym/pull/837) ([aniampio](https://github.com/aniampio))
- Apply readable ids to elements on Nym Wallet [\#836](https://github.com/nymtech/nym/pull/836) ([tommyv1987](https://github.com/tommyv1987))
- Feature/removal of monitor good nodes [\#833](https://github.com/nymtech/nym/pull/833) ([jstuczyn](https://github.com/jstuczyn))
@@ -552,8 +534,8 @@ The release also include some additional work for distributed key generation in
- Created getters for AccountData [\#787](https://github.com/nymtech/nym/pull/787) ([jstuczyn](https://github.com/jstuczyn))
- Feature/migrate hidden delegations [\#786](https://github.com/nymtech/nym/pull/786) ([neacsu](https://github.com/neacsu))
- Feature/persistent gateway storage [\#784](https://github.com/nymtech/nym/pull/784) ([jstuczyn](https://github.com/jstuczyn))
- Replaced unwrap_or_else with unwrap_or_default [\#780](https://github.com/nymtech/nym/pull/780) ([jstuczyn](https://github.com/jstuczyn))
- Add block_height method to Delegation [\#778](https://github.com/nymtech/nym/pull/778) ([durch](https://github.com/durch))
- Replaced unwrap\_or\_else with unwrap\_or\_default [\#780](https://github.com/nymtech/nym/pull/780) ([jstuczyn](https://github.com/jstuczyn))
- Add block\_height method to Delegation [\#778](https://github.com/nymtech/nym/pull/778) ([durch](https://github.com/durch))
- Make fee helpers public [\#777](https://github.com/nymtech/nym/pull/777) ([durch](https://github.com/durch))
- re-enable bonding [\#776](https://github.com/nymtech/nym/pull/776) ([fmtabbara](https://github.com/fmtabbara))
- Explorer-api: add API resource to show the delegations for each mix node [\#774](https://github.com/nymtech/nym/pull/774) ([mmsinclair](https://github.com/mmsinclair))
@@ -562,14 +544,14 @@ The release also include some additional work for distributed key generation in
- Adding deps for building the Tauri wallet under Ubuntu [\#770](https://github.com/nymtech/nym/pull/770) ([futurechimp](https://github.com/futurechimp))
- remove alert [\#767](https://github.com/nymtech/nym/pull/767) ([fmtabbara](https://github.com/fmtabbara))
- Feature/consumable bandwidth [\#766](https://github.com/nymtech/nym/pull/766) ([neacsu](https://github.com/neacsu))
- Update coconut-rs and use hash_to_scalar from there [\#765](https://github.com/nymtech/nym/pull/765) ([neacsu](https://github.com/neacsu))
- Update coconut-rs and use hash\_to\_scalar from there [\#765](https://github.com/nymtech/nym/pull/765) ([neacsu](https://github.com/neacsu))
- Feature/active sets [\#764](https://github.com/nymtech/nym/pull/764) ([jstuczyn](https://github.com/jstuczyn))
- add app alert banner [\#762](https://github.com/nymtech/nym/pull/762) ([fmtabbara](https://github.com/fmtabbara))
- Updated cosmos-sdk [\#761](https://github.com/nymtech/nym/pull/761) ([jstuczyn](https://github.com/jstuczyn))
- Feature/bond blockstamp [\#760](https://github.com/nymtech/nym/pull/760) ([neacsu](https://github.com/neacsu))
- Feature/revert migration code [\#759](https://github.com/nymtech/nym/pull/759) ([neacsu](https://github.com/neacsu))
- Bump next from 11.1.0 to 11.1.1 in /wallet-web [\#758](https://github.com/nymtech/nym/pull/758) ([dependabot[bot]](https://github.com/apps/dependabot))
- Add block_height in the Delegation structure as well [\#757](https://github.com/nymtech/nym/pull/757) ([neacsu](https://github.com/neacsu))
- Add block\_height in the Delegation structure as well [\#757](https://github.com/nymtech/nym/pull/757) ([neacsu](https://github.com/neacsu))
- Feature/add blockstamp [\#756](https://github.com/nymtech/nym/pull/756) ([neacsu](https://github.com/neacsu))
- NetworkMonitorBuilder - starting the monitor after rocket has launched [\#754](https://github.com/nymtech/nym/pull/754) ([jstuczyn](https://github.com/jstuczyn))
- Enabled validators api argument [\#753](https://github.com/nymtech/nym/pull/753) ([jstuczyn](https://github.com/jstuczyn))
@@ -581,7 +563,7 @@ The release also include some additional work for distributed key generation in
- Feature/more reliable uptime calculation [\#747](https://github.com/nymtech/nym/pull/747) ([jstuczyn](https://github.com/jstuczyn))
- Update template toml key [\#746](https://github.com/nymtech/nym/pull/746) ([neacsu](https://github.com/neacsu))
- Feature/cred after handshake [\#745](https://github.com/nymtech/nym/pull/745) ([neacsu](https://github.com/neacsu))
- Reinstate the POST method blind_sign [\#744](https://github.com/nymtech/nym/pull/744) ([neacsu](https://github.com/neacsu))
- Reinstate the POST method blind\_sign [\#744](https://github.com/nymtech/nym/pull/744) ([neacsu](https://github.com/neacsu))
- explorer-api: add pending field to port check response [\#742](https://github.com/nymtech/nym/pull/742) ([mmsinclair](https://github.com/mmsinclair))
- Feature/use delegation rates [\#741](https://github.com/nymtech/nym/pull/741) ([neacsu](https://github.com/neacsu))
- Feature/copy to clipboard [\#740](https://github.com/nymtech/nym/pull/740) ([fmtabbara](https://github.com/fmtabbara))
@@ -618,4 +600,6 @@ The release also include some additional work for distributed key generation in
- Hang coconut issuance off the validator-api [\#679](https://github.com/nymtech/nym/pull/679) ([durch](https://github.com/durch))
- Update hmac and blake3 [\#673](https://github.com/nymtech/nym/pull/673) ([durch](https://github.com/durch))
\* _This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)_
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
Generated
+114 -314
View File
@@ -23,16 +23,6 @@ dependencies = [
"generic-array 0.14.5",
]
[[package]]
name = "aead"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c192eb8f11fc081b0fe4259ba5af04217d4e0faddd02417310a927911abd7c8"
dependencies = [
"crypto-common",
"generic-array 0.14.5",
]
[[package]]
name = "aes"
version = "0.7.5"
@@ -63,7 +53,7 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6"
dependencies = [
"aead 0.4.3",
"aead",
"aes 0.7.5",
"cipher 0.3.0",
"ctr 0.8.0",
@@ -91,12 +81,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "anes"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "ansi_term"
version = "0.12.1"
@@ -426,13 +410,6 @@ dependencies = [
"serde",
]
[[package]]
name = "build-information"
version = "0.1.0"
dependencies = [
"vergen 7.2.1",
]
[[package]]
name = "bumpalo"
version = "3.9.1"
@@ -466,12 +443,6 @@ dependencies = [
"rustc_version 0.4.0",
]
[[package]]
name = "cast"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cc"
version = "1.0.73"
@@ -503,30 +474,6 @@ dependencies = [
"keystream",
]
[[package]]
name = "chacha20"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7fc89c7c5b9e7a02dfe45cd2367bae382f9ed31c61ca8debe5f827c420a2f08"
dependencies = [
"cfg-if 1.0.0",
"cipher 0.4.3",
"cpufeatures",
]
[[package]]
name = "chacha20poly1305"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
dependencies = [
"aead 0.5.1",
"chacha20",
"cipher 0.4.3",
"poly1305",
"zeroize",
]
[[package]]
name = "chrono"
version = "0.4.19"
@@ -541,33 +488,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "ciborium"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f"
dependencies = [
"ciborium-io",
"ciborium-ll",
"serde",
]
[[package]]
name = "ciborium-io"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369"
[[package]]
name = "ciborium-ll"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b"
dependencies = [
"ciborium-io",
"half",
]
[[package]]
name = "cipher"
version = "0.3.0"
@@ -585,7 +505,6 @@ checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e"
dependencies = [
"crypto-common",
"inout",
"zeroize",
]
[[package]]
@@ -605,51 +524,41 @@ version = "3.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "190814073e85d238f31ff738fcb0bf6910cedeb73376c87cd69291028966fd83"
dependencies = [
"atty",
"bitflags",
"clap_lex 0.2.4",
"clap_derive",
"clap_lex",
"indexmap",
"once_cell",
"strsim",
"termcolor",
"textwrap 0.15.0",
]
[[package]]
name = "clap"
version = "4.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"clap_lex 0.3.0",
"once_cell",
"strsim",
"termcolor",
]
[[package]]
name = "clap_complete"
version = "4.0.7"
version = "3.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10861370d2ba66b0f5989f83ebf35db6421713fd92351790e7fdd6c36774c56b"
checksum = "e4179da71abd56c26b54dd0c248cc081c1f43b0a1a7e8448e28e57a29baa993d"
dependencies = [
"clap 4.0.26",
"clap 3.2.8",
]
[[package]]
name = "clap_complete_fig"
version = "4.0.2"
version = "3.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46b30e010e669cd021e5004f3be26cff6b7c08d2a8a0d65b48d43a8cc0efd6c3"
checksum = "ed37b4c0c1214673eba6ad8ea31666626bf72be98ffb323067d973c48b4964b9"
dependencies = [
"clap 4.0.26",
"clap 3.2.8",
"clap_complete",
]
[[package]]
name = "clap_derive"
version = "4.0.21"
version = "3.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
checksum = "759bf187376e1afa7b85b959e6a664a3e7a95203415dba952ad19139e798f902"
dependencies = [
"heck 0.4.0",
"proc-macro-error",
@@ -667,15 +576,6 @@ dependencies = [
"os_str_bytes",
]
[[package]]
name = "clap_lex"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "client-connections"
version = "0.1.0"
@@ -686,7 +586,7 @@ dependencies = [
[[package]]
name = "client-core"
version = "1.1.4"
version = "1.1.3"
dependencies = [
"async-trait",
"client-connections",
@@ -792,7 +692,7 @@ dependencies = [
name = "completions"
version = "0.1.0"
dependencies = [
"clap 4.0.26",
"clap 3.2.8",
"clap_complete",
"clap_complete_fig",
]
@@ -1031,7 +931,7 @@ version = "0.1.0"
dependencies = [
"bip39",
"cfg-if 0.1.10",
"clap 4.0.26",
"clap 3.2.8",
"coconut-interface",
"completions",
"config",
@@ -1080,9 +980,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10"
dependencies = [
"atty",
"cast 0.2.7",
"cast",
"clap 2.34.0",
"criterion-plot 0.4.4",
"criterion-plot",
"csv",
"itertools",
"lazy_static",
@@ -1099,49 +999,13 @@ dependencies = [
"walkdir",
]
[[package]]
name = "criterion"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb"
dependencies = [
"anes",
"atty",
"cast 0.3.0",
"ciborium",
"clap 3.2.8",
"criterion-plot 0.5.0",
"itertools",
"lazy_static",
"num-traits",
"oorandom",
"plotters",
"rayon",
"regex",
"serde",
"serde_derive",
"serde_json",
"tinytemplate",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57"
dependencies = [
"cast 0.2.7",
"itertools",
]
[[package]]
name = "criterion-plot"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
dependencies = [
"cast 0.3.0",
"cast",
"itertools",
]
@@ -1270,12 +1134,11 @@ dependencies = [
[[package]]
name = "crypto-common"
version = "0.1.6"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8"
dependencies = [
"generic-array 0.14.5",
"rand_core 0.6.3",
"typenum",
]
@@ -1603,7 +1466,7 @@ dependencies = [
"bitvec",
"bls12_381 0.6.0",
"bs58",
"criterion 0.3.5",
"criterion",
"ff 0.11.0",
"group 0.11.0",
"lazy_static",
@@ -1791,7 +1654,7 @@ name = "explorer-api"
version = "1.1.1"
dependencies = [
"chrono",
"clap 4.0.26",
"clap 3.2.8",
"contracts-common",
"dotenv",
"humantime-serde",
@@ -1804,9 +1667,6 @@ dependencies = [
"network-defaults",
"okapi",
"pretty_env_logger",
"rand 0.8.5",
"rand_pcg 0.3.1",
"rand_seeder",
"reqwest",
"rocket",
"rocket_cors",
@@ -1838,9 +1698,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
[[package]]
name = "fastrand"
version = "1.8.0"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
dependencies = [
"instant",
]
@@ -3231,72 +3091,6 @@ dependencies = [
"libc",
]
[[package]]
name = "nym-api"
version = "1.1.4"
dependencies = [
"anyhow",
"async-trait",
"bip39",
"bs58",
"build-information",
"cfg-if 1.0.0",
"clap 4.0.26",
"coconut-bandwidth-contract-common",
"coconut-dkg-common",
"coconut-interface",
"config",
"console-subscriber",
"contracts-common",
"cosmwasm-std",
"credential-storage",
"credentials",
"crypto",
"cw-utils",
"cw3",
"dirs",
"dkg",
"dotenv",
"futures",
"gateway-client",
"getset",
"humantime-serde",
"inclusion-probability",
"lazy_static",
"log",
"logging",
"mixnet-contract-common",
"multisig-contract-common",
"nym-api-requests",
"nymcoconut",
"nymsphinx",
"okapi",
"pemstore",
"pin-project",
"pretty_env_logger",
"rand 0.7.3",
"rand 0.8.5",
"reqwest",
"rocket",
"rocket_cors",
"rocket_okapi",
"schemars",
"serde",
"serde_json",
"sqlx 0.6.2",
"tap",
"task",
"thiserror",
"time 0.3.17",
"tokio",
"tokio-stream",
"topology",
"ts-rs",
"url",
"validator-client",
"version-checker",
]
[[package]]
name = "nym-api-requests"
version = "0.1.0"
@@ -3329,13 +3123,13 @@ dependencies = [
[[package]]
name = "nym-cli"
version = "1.1.4"
version = "1.1.3"
dependencies = [
"anyhow",
"base64",
"bip39",
"bs58",
"clap 4.0.26",
"clap 3.2.8",
"clap_complete",
"clap_complete_fig",
"dotenv",
@@ -3359,7 +3153,7 @@ dependencies = [
"bip39",
"bs58",
"cfg-if 1.0.0",
"clap 4.0.26",
"clap 3.2.8",
"comfy-table",
"cosmrs",
"cosmwasm-std",
@@ -3383,10 +3177,9 @@ dependencies = [
[[package]]
name = "nym-client"
version = "1.1.4"
version = "1.1.3"
dependencies = [
"build-information",
"clap 4.0.26",
"clap 3.2.8",
"client-connections",
"client-core",
"coconut-interface",
@@ -3399,7 +3192,6 @@ dependencies = [
"futures",
"gateway-client",
"gateway-requests",
"lazy_static",
"log",
"logging",
"network-defaults",
@@ -3417,20 +3209,20 @@ dependencies = [
"topology",
"url",
"validator-client",
"vergen 5.1.17",
"version-checker",
"websocket-requests",
]
[[package]]
name = "nym-gateway"
version = "1.1.4"
version = "1.1.3"
dependencies = [
"anyhow",
"async-trait",
"bip39",
"bs58",
"build-information",
"clap 4.0.26",
"clap 3.2.8",
"coconut-interface",
"colored",
"completions",
@@ -3443,7 +3235,6 @@ dependencies = [
"futures",
"gateway-requests",
"humantime-serde",
"lazy_static",
"log",
"logging",
"mixnet-client",
@@ -3466,17 +3257,17 @@ dependencies = [
"tokio-util 0.7.3",
"url",
"validator-client",
"vergen 5.1.17",
"version-checker",
]
[[package]]
name = "nym-mixnode"
version = "1.1.4"
version = "1.1.3"
dependencies = [
"anyhow",
"bs58",
"build-information",
"clap 4.0.26",
"clap 3.2.8",
"colored",
"completions",
"config",
@@ -3508,15 +3299,16 @@ dependencies = [
"topology",
"url",
"validator-client",
"vergen 5.1.17",
"version-checker",
]
[[package]]
name = "nym-network-requester"
version = "1.1.4"
version = "1.1.3"
dependencies = [
"async-trait",
"clap 4.0.26",
"clap 3.2.8",
"client-connections",
"completions",
"dirs",
@@ -3545,7 +3337,7 @@ dependencies = [
[[package]]
name = "nym-network-statistics"
version = "1.1.4"
version = "1.1.3"
dependencies = [
"dirs",
"log",
@@ -3559,28 +3351,11 @@ dependencies = [
"tokio",
]
[[package]]
name = "nym-outfox"
version = "0.1.0"
dependencies = [
"blake3",
"chacha20",
"chacha20poly1305",
"criterion 0.4.0",
"curve25519-dalek",
"fastrand",
"getrandom 0.2.6",
"rayon",
"thiserror",
"zeroize",
]
[[package]]
name = "nym-socks5-client"
version = "1.1.4"
version = "1.1.3"
dependencies = [
"build-information",
"clap 4.0.26",
"clap 3.2.8",
"client-connections",
"client-core",
"coconut-interface",
@@ -3593,7 +3368,6 @@ dependencies = [
"futures",
"gateway-client",
"gateway-requests",
"lazy_static",
"log",
"logging",
"network-defaults",
@@ -3614,6 +3388,7 @@ dependencies = [
"topology",
"url",
"validator-client",
"vergen 5.1.17",
"version-checker",
]
@@ -3643,6 +3418,70 @@ dependencies = [
"vesting-contract-common",
]
[[package]]
name = "nym-validator-api"
version = "1.1.3"
dependencies = [
"anyhow",
"async-trait",
"bs58",
"cfg-if 1.0.0",
"clap 3.2.8",
"coconut-bandwidth-contract-common",
"coconut-dkg-common",
"coconut-interface",
"config",
"console-subscriber",
"contracts-common",
"cosmwasm-std",
"credential-storage",
"credentials",
"crypto",
"cw-utils",
"cw3",
"dirs",
"dkg",
"dotenv",
"futures",
"gateway-client",
"getset",
"humantime-serde",
"inclusion-probability",
"log",
"logging",
"mixnet-contract-common",
"multisig-contract-common",
"nym-api-requests",
"nymcoconut",
"nymsphinx",
"okapi",
"pemstore",
"pin-project",
"pretty_env_logger",
"rand 0.7.3",
"rand 0.8.5",
"reqwest",
"rocket",
"rocket_cors",
"rocket_okapi",
"schemars",
"serde",
"serde_json",
"sqlx 0.6.2",
"tap",
"task",
"thiserror",
"time 0.3.17",
"tokio",
"tokio-stream",
"topology",
"ts-rs",
"url",
"validator-client",
"vergen 7.2.1",
"version-checker",
]
[[package]]
name = "nym-wallet-types"
version = "1.0.0"
@@ -3670,7 +3509,7 @@ dependencies = [
"bincode",
"bls12_381 0.6.0",
"bs58",
"criterion 0.3.5",
"criterion",
"digest 0.9.0",
"dkg",
"doc-comment",
@@ -4182,17 +4021,6 @@ dependencies = [
"plotters-backend",
]
[[package]]
name = "poly1305"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
dependencies = [
"cpufeatures",
"opaque-debug 0.3.0",
"universal-hash 0.5.0",
]
[[package]]
name = "polyval"
version = "0.5.3"
@@ -4202,7 +4030,7 @@ dependencies = [
"cfg-if 1.0.0",
"cpufeatures",
"opaque-debug 0.3.0",
"universal-hash 0.4.1",
"universal-hash",
]
[[package]]
@@ -4424,7 +4252,7 @@ dependencies = [
"rand_isaac",
"rand_jitter",
"rand_os",
"rand_pcg 0.1.2",
"rand_pcg",
"rand_xorshift",
"winapi",
]
@@ -4588,24 +4416,6 @@ dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_pcg"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59cad018caf63deb318e5a4586d99a24424a364f40f1e5778c29aca23f4fc73e"
dependencies = [
"rand_core 0.6.3",
]
[[package]]
name = "rand_seeder"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf2890aaef0aa82719a50e808de264f9484b74b442e1a3a0e5ee38243ac40bdb"
dependencies = [
"rand_core 0.6.3",
]
[[package]]
name = "rand_xorshift"
version = "0.1.1"
@@ -6578,16 +6388,6 @@ dependencies = [
"subtle 2.4.1",
]
[[package]]
name = "universal-hash"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5"
dependencies = [
"crypto-common",
"subtle 2.4.1",
]
[[package]]
name = "untrusted"
version = "0.7.1"
@@ -7111,9 +6911,9 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
[[package]]
name = "zeroize"
version = "1.5.7"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"
checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619"
dependencies = [
"zeroize_derive",
]
-2
View File
@@ -30,7 +30,6 @@ members = [
"common/coconut-interface",
"common/commands",
"common/config",
"common/build-information",
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
"common/cosmwasm-smart-contracts/coconut-dkg",
"common/cosmwasm-smart-contracts/contracts-common",
@@ -77,7 +76,6 @@ members = [
"service-providers/network-statistics",
"nym-api",
"nym-api/nym-api-requests",
"nym-outfox",
"tools/nym-cli",
"tools/ts-rs-cli"
]
+1 -2
View File
@@ -1,9 +1,8 @@
[package]
name = "client-core"
version = "1.1.4"
version = "1.1.3"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
edition = "2021"
rust-version = "1.66"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -230,7 +230,7 @@ where
mixnet_message_sender: MixnetMessageSender,
ack_sender: AcknowledgementSender,
shutdown: TaskClient,
) -> Result<GatewayClient, ClientCoreError> {
) -> Result<GatewayClient, ClientCoreError<B>> {
let gateway_id = self.gateway_config.gateway_id.clone();
if gateway_id.is_empty() {
return Err(ClientCoreError::GatewayIdUnknown);
@@ -285,7 +285,7 @@ where
refresh_rate: Duration,
topology_accessor: TopologyAccessor,
shutdown: TaskClient,
) -> Result<(), ClientCoreError> {
) -> Result<(), ClientCoreError<B>> {
let topology_refresher_config = TopologyRefresherConfig::new(
nym_api_urls,
refresh_rate,
@@ -328,17 +328,12 @@ where
async fn setup_persistent_reply_storage(
backend: B,
shutdown: TaskClient,
) -> Result<CombinedReplyStorage, ClientCoreError>
where
<B as ReplyStorageBackend>::StorageError: Sync + Send,
{
) -> Result<CombinedReplyStorage, ClientCoreError<B>> {
let persistent_storage = PersistentReplyStorage::new(backend);
let mem_store = persistent_storage
.load_state_from_backend()
.await
.map_err(|err| ClientCoreError::SurbStorageError {
source: Box::new(err),
})?;
.map_err(|err| ClientCoreError::SurbStorageError { source: err })?;
let store_clone = mem_store.clone();
spawn_future(async move {
@@ -350,10 +345,7 @@ where
Ok(mem_store)
}
pub async fn start_base(mut self) -> Result<BaseClient, ClientCoreError>
where
<B as ReplyStorageBackend>::StorageError: Sync + Send,
{
pub async fn start_base(mut self) -> Result<BaseClient, ClientCoreError<B>> {
info!("Starting nym client");
// channels for inter-component communication
// TODO: make the channels be internally created by the relevant components
@@ -379,7 +371,7 @@ where
// channels responsible for dealing with reply-related fun
let (reply_controller_sender, reply_controller_receiver) =
reply_controller::requests::new_control_channels();
reply_controller::new_control_channels();
let self_address = self.as_mix_recipient();
@@ -445,7 +437,7 @@ where
input_receiver,
sphinx_message_sender.clone(),
reply_storage,
reply_controller_sender.clone(),
reply_controller_sender,
reply_controller_receiver,
shared_lane_queue_lengths.clone(),
client_connection_rx,
@@ -479,7 +471,6 @@ where
received_buffer_request_sender,
},
},
reply_controller_sender,
task_manager,
})
}
@@ -489,8 +480,5 @@ pub struct BaseClient {
pub client_input: ClientInputStatus,
pub client_output: ClientOutputStatus,
// it feels very wrong to put this channel here, but I can't think of any other way of passing it to the native client
pub reply_controller_sender: ReplyControllerSender,
pub task_manager: TaskManager,
}
@@ -14,15 +14,13 @@ use time::OffsetDateTime;
async fn setup_fresh_backend<P: AsRef<Path>>(
db_path: P,
debug_config: &DebugConfig,
) -> Result<fs_backend::Backend, ClientCoreError> {
) -> Result<fs_backend::Backend, ClientCoreError<fs_backend::Backend>> {
info!("creating fresh surb database");
let mut storage_backend = match fs_backend::Backend::init(db_path).await {
Ok(backend) => backend,
Err(err) => {
error!("failed to setup persistent storage backend for our reply needs: {err}");
return Err(ClientCoreError::SurbStorageError {
source: Box::new(err),
});
return Err(ClientCoreError::SurbStorageError { source: err });
}
};
@@ -36,9 +34,7 @@ async fn setup_fresh_backend<P: AsRef<Path>>(
storage_backend
.init_fresh(&mem_store)
.await
.map_err(|err| ClientCoreError::SurbStorageError {
source: Box::new(err),
})?;
.map_err(|err| ClientCoreError::SurbStorageError { source: err })?;
Ok(storage_backend)
}
@@ -67,7 +63,7 @@ fn archive_corrupted_database<P: AsRef<Path>>(db_path: P) -> io::Result<()> {
pub async fn setup_fs_reply_surb_backend<P: AsRef<Path>>(
db_path: P,
debug_config: &DebugConfig,
) -> Result<fs_backend::Backend, ClientCoreError> {
) -> Result<fs_backend::Backend, ClientCoreError<fs_backend::Backend>> {
// if the database file doesnt exist, initialise fresh storage, otherwise attempt to load the existing one
let db_path = db_path.as_ref();
if db_path.exists() {
@@ -1,14 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#[cfg(not(target_arch = "wasm32"))]
mod non_wasm;
#[cfg(target_arch = "wasm32")]
mod wasm;
#[cfg(not(target_arch = "wasm32"))]
pub use non_wasm::*;
#[cfg(target_arch = "wasm32")]
pub use wasm::*;
@@ -1,13 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub use tokio::time::*;
pub type IntervalStream = tokio_stream::wrappers::IntervalStream;
pub(crate) fn get_time_now() -> Instant {
Instant::now()
}
pub(crate) fn new_interval_stream(polling_rate: Duration) -> IntervalStream {
tokio_stream::wrappers::IntervalStream::new(tokio::time::interval(polling_rate))
}
@@ -1,16 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::time::Duration;
use wasm_timer;
pub use wasm_timer::*;
pub type IntervalStream = gloo_timers::future::IntervalStream;
pub(crate) fn get_time_now() -> Instant {
wasm_timer::Instant::now()
}
pub(crate) fn new_interval_stream(polling_rate: Duration) -> IntervalStream {
gloo_timers::future::IntervalStream::new(polling_rate.as_millis() as u32)
}
-2
View File
@@ -3,7 +3,6 @@
pub mod base_client;
pub mod cover_traffic_stream;
pub(crate) mod helpers;
pub mod inbound_messages;
pub mod key_manager;
pub mod mix_traffic;
@@ -11,4 +10,3 @@ pub mod real_messages_control;
pub mod received_buffer;
pub mod replies;
pub mod topology_control;
pub(crate) mod transmission_buffer;
@@ -20,7 +20,6 @@ use nymsphinx::params::{PacketSize, DEFAULT_NUM_MIX_HOPS};
use nymsphinx::preparer::{MessagePreparer, PreparedFragment};
use nymsphinx::Delay;
use rand::{CryptoRng, Rng};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use thiserror::Error;
@@ -279,7 +278,7 @@ where
reply_surb: ReplySurb,
amount: u32,
) -> Result<(), SurbWrappedPreparationError> {
debug!("requesting {amount} reply SURBs from {from}");
debug!("requesting {amount} reply SURBs from {from:?}");
let surbs_request =
ReplyMessage::new_surb_request_message(self.config.sender_address, amount);
@@ -295,11 +294,19 @@ where
)))
}
pub(crate) async fn send_retransmission_reply_chunks(
// the only difference between this method and `try_send_reply_chunks` is that
// here we are not creating acks as acks are already in memory waiting to get cleared.
// we are only updating their existing delays
pub(crate) async fn try_send_retransmission_reply_chunks(
&mut self,
prepared_fragments: Vec<PreparedFragment>,
fragments: Vec<Fragment>,
reply_surbs: Vec<ReplySurb>,
lane: TransmissionLane,
) {
) -> Result<(), SurbWrappedPreparationError> {
let prepared_fragments = self
.prepare_reply_chunks_for_sending(fragments.clone(), reply_surbs)
.await?;
let mut real_messages = Vec::with_capacity(prepared_fragments.len());
for prepared in prepared_fragments {
@@ -308,58 +315,33 @@ where
}
self.forward_messages(real_messages, lane).await;
Ok(())
}
pub(crate) async fn try_send_reply_chunks_on_lane(
pub(crate) async fn try_send_reply_chunks(
&mut self,
target: AnonymousSenderTag,
fragments: Vec<Fragment>,
reply_surbs: Vec<ReplySurb>,
lane: TransmissionLane,
) -> Result<(), SurbWrappedPreparationError> {
// TODO: technically this is performing an unnecessary cloning, but in the grand scheme of things
// is it really that bad?
self.try_send_reply_chunks(
target,
fragments.into_iter().map(|f| (lane, f)).collect(),
reply_surbs,
)
.await
}
pub(crate) async fn try_send_reply_chunks(
&mut self,
target: AnonymousSenderTag,
fragments: Vec<(TransmissionLane, Fragment)>,
reply_surbs: Vec<ReplySurb>,
) -> Result<(), SurbWrappedPreparationError> {
let prepared_fragments = self
.prepare_reply_chunks_for_sending(
fragments.iter().map(|(_, f)| f.clone()).collect(),
reply_surbs,
)
.prepare_reply_chunks_for_sending(fragments.clone(), reply_surbs)
.await?;
let mut pending_acks = Vec::with_capacity(fragments.len());
let mut to_forward: HashMap<_, Vec<_>> = HashMap::new();
let mut real_messages = Vec::with_capacity(fragments.len());
for (raw, prepared) in fragments.into_iter().zip(prepared_fragments.into_iter()) {
let lane = raw.0;
let fragment = raw.1;
let real_message = RealMessage::new(prepared.mix_packet, prepared.fragment_identifier);
let delay = prepared.total_delay;
let pending_ack = PendingAcknowledgement::new_anonymous(fragment, delay, target, false);
let pending_ack = PendingAcknowledgement::new_anonymous(raw, delay, target, false);
let entry = to_forward.entry(lane).or_default();
entry.push(real_message);
real_messages.push(real_message);
pending_acks.push(pending_ack);
}
for (lane, real_messages) in to_forward {
self.forward_messages(real_messages, lane).await;
}
self.forward_messages(real_messages, lane).await;
self.insert_pending_acks(pending_acks);
Ok(())
}
@@ -485,7 +467,7 @@ where
Ok(prepared_fragment)
}
pub(crate) async fn prepare_reply_chunks_for_sending(
async fn prepare_reply_chunks_for_sending(
&mut self,
fragments: Vec<Fragment>,
reply_surbs: Vec<ReplySurb>,
@@ -1,11 +1,9 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use self::sending_delay_controller::SendingDelayController;
use crate::client::mix_traffic::BatchMixMessageSender;
use crate::client::real_messages_control::acknowledgement_control::SentPacketNotificationSender;
use crate::client::topology_control::TopologyAccessor;
use crate::client::transmission_buffer::TransmissionBuffer;
use client_connections::{
ConnectionCommand, ConnectionCommandReceiver, ConnectionId, LaneQueueLengths, TransmissionLane,
};
@@ -31,7 +29,22 @@ use tokio::time;
#[cfg(target_arch = "wasm32")]
use wasm_timer;
use self::{
sending_delay_controller::SendingDelayController, transmission_buffer::TransmissionBuffer,
};
mod sending_delay_controller;
mod transmission_buffer;
#[cfg(not(target_arch = "wasm32"))]
fn get_time_now() -> time::Instant {
time::Instant::now()
}
#[cfg(target_arch = "wasm32")]
fn get_time_now() -> wasm_timer::Instant {
wasm_timer::Instant::now()
}
/// Configurable parameters of the `OutQueueControl`
pub(crate) struct Config {
@@ -122,7 +135,7 @@ where
/// Buffer containing all incoming real messages keyed by transmission lane, that we will send
/// out to the mixnet.
transmission_buffer: TransmissionBuffer<RealMessage>,
transmission_buffer: TransmissionBuffer,
/// Incoming channel for being notified of closed connections, so that we can close lanes
/// corresponding to connections. To avoid sending traffic unnecessary
@@ -149,10 +162,6 @@ impl From<PreparedFragment> for RealMessage {
}
impl RealMessage {
pub(crate) fn packet_size(&self) -> usize {
self.mix_packet.sphinx_packet().len()
}
pub(crate) fn new(mix_packet: MixPacket, fragment_id: FragmentIdentifier) -> Self {
RealMessage {
mix_packet,
@@ -198,7 +207,7 @@ where
real_receiver,
rng,
topology_access,
transmission_buffer: TransmissionBuffer::new(),
transmission_buffer: Default::default(),
client_connection_rx,
lane_queue_lengths,
}
@@ -319,9 +328,7 @@ where
fn pop_next_message(&mut self) -> Option<RealMessage> {
// Pop the next message from the transmission buffer
let (lane, real_next) = self
.transmission_buffer
.pop_next_message_at_random(&mut self.rng)?;
let (lane, real_next) = self.transmission_buffer.pop_next_message_at_random()?;
// Update the published queue length
let lane_length = self.transmission_buffer.lane_length(&lane);
@@ -1,9 +1,14 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::helpers::{get_time_now, Instant};
use super::get_time_now;
use std::time::Duration;
#[cfg(not(target_arch = "wasm32"))]
use tokio::time;
#[cfg(target_arch = "wasm32")]
use wasm_timer;
// The minimum time between increasing the average delay between packets. If we hit the ceiling in
// the available buffer space we want to take somewhat swift action, but we still need to give a
// short time to give the channel a chance reduce pressure.
@@ -34,11 +39,19 @@ pub(crate) struct SendingDelayController {
lower_bound: u32,
/// To make sure we don't change the multiplier to fast, we limit a change to some duration
time_when_changed: Instant,
#[cfg(not(target_arch = "wasm32"))]
time_when_changed: time::Instant,
#[cfg(target_arch = "wasm32")]
time_when_changed: wasm_timer::Instant,
/// If we have a long enough time without any backpressure detected we try reducing the sending
/// delay multiplier
time_when_backpressure_detected: Instant,
#[cfg(not(target_arch = "wasm32"))]
time_when_backpressure_detected: time::Instant,
#[cfg(target_arch = "wasm32")]
time_when_backpressure_detected: wasm_timer::Instant,
}
impl Default for SendingDelayController {
@@ -1,57 +1,38 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::helpers::{get_time_now, Instant};
use crate::client::real_messages_control::real_traffic_stream::RealMessage;
use client_connections::TransmissionLane;
use nymsphinx::chunking::fragment::Fragment;
use rand::{seq::SliceRandom, Rng};
use std::{
collections::{HashMap, HashSet, VecDeque},
time::Duration,
};
#[cfg(not(target_arch = "wasm32"))]
use tokio::time;
#[cfg(target_arch = "wasm32")]
use wasm_timer;
use super::{get_time_now, RealMessage};
// The number of lanes included in the oldest set. Used when we need to prioritize traffic.
const OLDEST_LANE_SET_SIZE: usize = 4;
// As a way of prune connections we also check for timeouts.
const MSG_CONSIDERED_STALE_AFTER_SECS: u64 = 10 * 60;
pub(crate) trait SizedData {
fn data_size(&self) -> usize;
}
impl SizedData for RealMessage {
fn data_size(&self) -> usize {
self.packet_size()
}
}
impl SizedData for Fragment {
fn data_size(&self) -> usize {
// note that raw `Fragment` is smaller than sphinx packet payload
// as it doesn't include surb-ack or the [shared] key materials
self.payload_size()
}
}
#[derive(Default)]
pub(crate) struct TransmissionBuffer<T> {
buffer: HashMap<TransmissionLane, LaneBufferEntry<T>>,
pub(crate) struct TransmissionBuffer {
buffer: HashMap<TransmissionLane, LaneBufferEntry>,
}
impl<T> TransmissionBuffer<T> {
pub(crate) fn new() -> Self {
TransmissionBuffer {
buffer: HashMap::new(),
}
}
impl TransmissionBuffer {
#[allow(unused)]
pub(crate) fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
pub(crate) fn remove(&mut self, lane: &TransmissionLane) -> Option<LaneBufferEntry<T>> {
pub(crate) fn remove(&mut self, lane: &TransmissionLane) -> Option<LaneBufferEntry> {
self.buffer.remove(lane)
}
@@ -76,22 +57,20 @@ impl<T> TransmissionBuffer<T> {
.collect()
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn total_size(&self) -> usize {
self.buffer.values().map(LaneBufferEntry::len).sum()
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn total_size_in_bytes(&self) -> usize
where
T: SizedData,
{
pub(crate) fn total_size_in_bytes(&self) -> usize {
self.buffer
.values()
.map(|lane_buffer_entry| {
lane_buffer_entry
.items
.real_messages
.iter()
.map(|item| item.data_size())
.map(|real_message| real_message.mix_packet.sphinx_packet().len())
.sum::<usize>()
})
.sum()
@@ -113,51 +92,42 @@ impl<T> TransmissionBuffer<T> {
.collect()
}
pub(crate) fn store<I: IntoIterator<Item = T>>(&mut self, lane: &TransmissionLane, items: I) {
pub(crate) fn store(&mut self, lane: &TransmissionLane, real_messages: Vec<RealMessage>) {
if let Some(lane_buffer_entry) = self.buffer.get_mut(lane) {
lane_buffer_entry.extend(items);
lane_buffer_entry.append(real_messages);
} else {
self.buffer
.insert(*lane, LaneBufferEntry::new(items.into_iter().collect()));
.insert(*lane, LaneBufferEntry::new(real_messages));
}
}
pub(crate) fn store_multiple(&mut self, items: Vec<(TransmissionLane, T)>) {
for (lane, item) in items {
self.buffer
.entry(lane)
.or_insert_with(LaneBufferEntry::new_empty)
.push_item(item)
}
}
fn pick_random_lane<R: Rng + ?Sized>(&self, rng: &mut R) -> Option<&TransmissionLane> {
fn pick_random_lane(&self) -> Option<&TransmissionLane> {
let lanes: Vec<&TransmissionLane> = self.buffer.keys().collect();
lanes.choose(rng).copied()
lanes.choose(&mut rand::thread_rng()).copied()
}
fn pick_random_small_lane<R: Rng + ?Sized>(&self, rng: &mut R) -> Option<&TransmissionLane> {
fn pick_random_small_lane(&self) -> Option<&TransmissionLane> {
let lanes: Vec<&TransmissionLane> = self
.buffer
.iter()
.filter(|(_, v)| v.is_small())
.map(|(k, _)| k)
.collect();
lanes.choose(rng).copied()
lanes.choose(&mut rand::thread_rng()).copied()
}
// 2/3 chance to pick from the old lanes
fn pick_random_old_lane<R: Rng + ?Sized>(&self, rng: &mut R) -> Option<TransmissionLane> {
fn pick_random_old_lane(&self) -> Option<TransmissionLane> {
let rand = &mut rand::thread_rng();
if rand.gen_ratio(2, 3) {
let lanes = self.get_oldest_set();
lanes.choose(rand).copied()
} else {
self.pick_random_lane(rng).copied()
self.pick_random_lane().copied()
}
}
fn pop_front_from_lane(&mut self, lane: &TransmissionLane) -> Option<T> {
fn pop_front_from_lane(&mut self, lane: &TransmissionLane) -> Option<RealMessage> {
let real_msgs_queued = self.buffer.get_mut(lane)?;
let real_next = real_msgs_queued.pop_front()?;
real_msgs_queued.messages_transmitted += 1;
@@ -167,48 +137,19 @@ impl<T> TransmissionBuffer<T> {
Some(real_next)
}
pub(crate) fn pop_at_most_n_next_messages_at_random(
&mut self,
n: usize,
) -> Option<Vec<(TransmissionLane, T)>> {
// let start = Instant::now();
if self.buffer.is_empty() {
return None;
}
let rng = &mut rand::thread_rng();
let mut items = Vec::with_capacity(n);
while items.len() < n {
let Some(next) = self.pop_next_message_at_random(rng) else {
break
};
items.push(next)
}
// todo!("time time taken");
Some(items)
}
pub(crate) fn pop_next_message_at_random<R: Rng + ?Sized>(
&mut self,
// turns out the caller always have access to some rng, so no point in instantiating new one
rng: &mut R,
) -> Option<(TransmissionLane, T)> {
pub(crate) fn pop_next_message_at_random(&mut self) -> Option<(TransmissionLane, RealMessage)> {
if self.buffer.is_empty() {
return None;
}
// Very basic heuristic where we prioritize according to small lanes first, the older lanes
// to try to finish lanes when possible, then the rest.
let lane = if let Some(small_lane) = self.pick_random_small_lane(rng) {
let lane = if let Some(small_lane) = self.pick_random_small_lane() {
*small_lane
} else if let Some(old_lane) = self.pick_random_old_lane(rng) {
} else if let Some(old_lane) = self.pick_random_old_lane() {
old_lane
} else {
*self.pick_random_lane(rng)?
*self.pick_random_lane()?
};
let msg = self.pop_front_from_lane(&lane)?;
@@ -230,46 +171,35 @@ impl<T> TransmissionBuffer<T> {
}
}
pub(crate) struct LaneBufferEntry<T> {
pub items: VecDeque<T>,
pub(crate) struct LaneBufferEntry {
pub real_messages: VecDeque<RealMessage>,
pub messages_transmitted: usize,
pub time_for_last_activity: Instant,
#[cfg(not(target_arch = "wasm32"))]
pub time_for_last_activity: time::Instant,
#[cfg(target_arch = "wasm32")]
pub time_for_last_activity: wasm_timer::Instant,
}
impl<T> LaneBufferEntry<T> {
fn new_empty() -> Self {
impl LaneBufferEntry {
fn new(real_messages: Vec<RealMessage>) -> Self {
LaneBufferEntry {
items: VecDeque::new(),
real_messages: real_messages.into(),
messages_transmitted: 0,
time_for_last_activity: get_time_now(),
}
}
fn new(items: VecDeque<T>) -> Self {
LaneBufferEntry {
items,
messages_transmitted: 0,
time_for_last_activity: get_time_now(),
}
}
fn push_item(&mut self, item: T) {
self.items.push_back(item);
// I'm not updating time here on purpose. This method is called just after `new_empty`,
// where the time is already set. Furthermore, this method is called there multiple times at once
}
fn extend<I: IntoIterator<Item = T>>(&mut self, items: I) {
self.items.extend(items);
fn append(&mut self, real_messages: Vec<RealMessage>) {
self.real_messages.append(&mut real_messages.into());
self.time_for_last_activity = get_time_now();
}
fn pop_front(&mut self) -> Option<T> {
self.items.pop_front()
fn pop_front(&mut self) -> Option<RealMessage> {
self.real_messages.pop_front()
}
fn is_small(&self) -> bool {
self.items.len() < 100
self.real_messages.len() < 100
}
fn is_stale(&self) -> bool {
@@ -278,10 +208,10 @@ impl<T> LaneBufferEntry<T> {
}
fn len(&self) -> usize {
self.items.len()
self.real_messages.len()
}
fn is_empty(&self) -> bool {
self.items.is_empty()
self.real_messages.is_empty()
}
}
@@ -4,8 +4,8 @@
use crate::client::real_messages_control::acknowledgement_control::PendingAcknowledgement;
use crate::client::real_messages_control::message_handler::{MessageHandler, PreparationError};
use crate::client::replies::reply_storage::CombinedReplyStorage;
use client_connections::{ConnectionId, TransmissionLane};
use futures::channel::oneshot;
use client_connections::TransmissionLane;
use futures::channel::mpsc;
use futures::StreamExt;
use log::{debug, error, info, trace, warn};
use nymsphinx::addressing::clients::Recipient;
@@ -15,16 +15,116 @@ use nymsphinx::chunking::fragment::{Fragment, FragmentIdentifier};
use rand::{CryptoRng, Rng};
use std::cmp::{max, min};
use std::collections::btree_map::Entry;
use std::collections::{BTreeMap, HashMap};
use std::collections::{BTreeMap, HashMap, VecDeque};
use std::sync::{Arc, Weak};
use std::time::Duration;
use time::OffsetDateTime;
use crate::client::helpers::new_interval_stream;
use crate::client::transmission_buffer::TransmissionBuffer;
pub(crate) use requests::{ReplyControllerMessage, ReplyControllerReceiver, ReplyControllerSender};
#[cfg(not(target_arch = "wasm32"))]
type IntervalStream = tokio_stream::wrappers::IntervalStream;
pub mod requests;
#[cfg(target_arch = "wasm32")]
type IntervalStream = gloo_timers::future::IntervalStream;
pub(crate) fn new_control_channels() -> (ReplyControllerSender, ReplyControllerReceiver) {
let (tx, rx) = mpsc::unbounded();
(tx.into(), rx)
}
#[derive(Debug, Clone)]
pub(crate) struct ReplyControllerSender(mpsc::UnboundedSender<ReplyControllerMessage>);
impl From<mpsc::UnboundedSender<ReplyControllerMessage>> for ReplyControllerSender {
fn from(inner: mpsc::UnboundedSender<ReplyControllerMessage>) -> Self {
ReplyControllerSender(inner)
}
}
impl ReplyControllerSender {
pub(crate) fn send_retransmission_data(
&self,
recipient: AnonymousSenderTag,
timed_out_ack: Weak<PendingAcknowledgement>,
extra_surb_request: bool,
) {
self.0
.unbounded_send(ReplyControllerMessage::RetransmitReply {
recipient,
timed_out_ack,
extra_surb_request,
})
.expect("ReplyControllerReceiver has died!")
}
pub(crate) fn send_reply(
&self,
recipient: AnonymousSenderTag,
message: Vec<u8>,
lane: TransmissionLane,
) {
self.0
.unbounded_send(ReplyControllerMessage::SendReply {
recipient,
message,
lane,
})
.expect("ReplyControllerReceiver has died!")
}
pub(crate) fn send_additional_surbs(
&self,
sender_tag: AnonymousSenderTag,
reply_surbs: Vec<ReplySurb>,
from_surb_request: bool,
) {
self.0
.unbounded_send(ReplyControllerMessage::AdditionalSurbs {
sender_tag,
reply_surbs,
from_surb_request,
})
.expect("ReplyControllerReceiver has died!")
}
pub(crate) fn send_additional_surbs_request(&self, recipient: Recipient, amount: u32) {
self.0
.unbounded_send(ReplyControllerMessage::AdditionalSurbsRequest {
recipient: Box::new(recipient),
amount,
})
.expect("ReplyControllerReceiver has died!")
}
}
pub(crate) type ReplyControllerReceiver = mpsc::UnboundedReceiver<ReplyControllerMessage>;
#[derive(Debug)]
pub(crate) enum ReplyControllerMessage {
RetransmitReply {
recipient: AnonymousSenderTag,
timed_out_ack: Weak<PendingAcknowledgement>,
extra_surb_request: bool,
},
SendReply {
recipient: AnonymousSenderTag,
message: Vec<u8>,
lane: TransmissionLane,
},
AdditionalSurbs {
sender_tag: AnonymousSenderTag,
reply_surbs: Vec<ReplySurb>,
from_surb_request: bool,
},
// Should this also be handled in here? it's technically a completely different side of the pipe
// let's see how it works when combined, might split it before creating PR
AdditionalSurbsRequest {
recipient: Box<Recipient>,
amount: u32,
},
}
pub struct Config {
min_surb_request_size: u32,
@@ -72,7 +172,7 @@ pub struct ReplyController<R> {
// of surbs required to send the message through
// expected_reliability: f32,
request_receiver: ReplyControllerReceiver,
pending_replies: HashMap<AnonymousSenderTag, TransmissionBuffer<Fragment>>,
pending_replies: HashMap<AnonymousSenderTag, VecDeque<Fragment>>,
/// Retransmission packets that have already timed out and are waiting for additional reply SURBs
/// so that they could be sent back to the network. Once we receive more SURBs, we should send them ASAP.
@@ -104,28 +204,17 @@ where
}
}
fn insert_pending_replies<I: IntoIterator<Item = Fragment>>(
/// Inserts the pending replies into the BACK of the queue fn insert_pending_replies<V: Into<VecDeque<Fragment>>>(
fn insert_pending_replies<V: Into<VecDeque<Fragment>>>(
&mut self,
recipient: &AnonymousSenderTag,
fragments: I,
lane: TransmissionLane,
fragments: V,
) {
self.pending_replies
.entry(*recipient)
.or_insert_with(TransmissionBuffer::new)
.store(&lane, fragments)
}
fn re_insert_pending_replies(
&mut self,
recipient: &AnonymousSenderTag,
fragments: Vec<(TransmissionLane, Fragment)>,
) {
// the buffer should ALWAYS exist at this point, if it doesn't, it's a bug...
self.pending_replies
.entry(*recipient)
.or_insert_with(TransmissionBuffer::new)
.store_multiple(fragments)
if let Some(existing) = self.pending_replies.get_mut(recipient) {
existing.append(&mut fragments.into())
} else {
self.pending_replies.insert(*recipient, fragments.into());
}
}
fn re_insert_pending_retransmission(
@@ -155,7 +244,7 @@ where
let pending_queue_size = self
.pending_replies
.get(target)
.map(|pending_queue| pending_queue.total_size())
.map(|pending_queue| pending_queue.len())
.unwrap_or_default();
let retransmission_queue = self
@@ -210,61 +299,42 @@ where
}
trace!("handling reply to {:?}", recipient_tag);
let mut fragments = self.message_handler.split_reply_message(data);
let total_size = fragments.len();
trace!("This reply requires {:?} SURBs", total_size);
let fragments = self.message_handler.split_reply_message(data);
let available_surbs = self
let required_surbs = fragments.len();
trace!("This reply requires {:?} SURBs", required_surbs);
// TODO: edge case:
// we're making a lot of requests and have to request a lot of surbs
// (but at some point we run out of surbs for surb requests)
let (surbs, _surbs_left) = self
.full_reply_storage
.surbs_storage_ref()
.available_surbs(&recipient_tag);
let min_surbs_threshold = self
.full_reply_storage
.surbs_storage_ref()
.min_surb_threshold();
.get_reply_surbs(&recipient_tag, required_surbs);
let max_to_send = if available_surbs > min_surbs_threshold {
min(fragments.len(), available_surbs - min_surbs_threshold)
} else {
0
};
if let Some(reply_surbs) = surbs {
if let Err(err) = self
.message_handler
.try_send_reply_chunks(recipient_tag, fragments, reply_surbs, lane)
.await
{
let err = err.return_unused_surbs(
self.full_reply_storage.surbs_storage_ref(),
&recipient_tag,
);
warn!("failed to send reply to {:?} - {err}", recipient_tag);
if max_to_send > 0 {
let (surbs, _surbs_left) = self
.full_reply_storage
.surbs_storage_ref()
.get_reply_surbs(&recipient_tag, max_to_send);
if let Some(reply_surbs) = surbs {
let to_send = fragments.drain(..max_to_send).collect::<Vec<_>>();
if let Err(err) = self
.message_handler
.try_send_reply_chunks_on_lane(
recipient_tag,
to_send.clone(),
reply_surbs,
lane,
)
.await
{
let err = err.return_unused_surbs(
self.full_reply_storage.surbs_storage_ref(),
&recipient_tag,
);
warn!("failed to send reply to {recipient_tag}: {err}");
self.insert_pending_replies(&recipient_tag, to_send, lane);
}
// TODO: should we buffer that data to try again?
}
}
} else {
// we don't have enough surbs for this reply
self.insert_pending_replies(&recipient_tag, fragments);
// if there's leftover data we didn't send because we didn't have enough (or any) surbs - buffer it
if !fragments.is_empty() {
self.insert_pending_replies(&recipient_tag, fragments, lane);
}
if self.should_request_more_surbs(&recipient_tag) {
self.request_reply_surbs_for_queue_clearing(recipient_tag)
.await;
if self.should_request_more_surbs(&recipient_tag) {
self.request_reply_surbs_for_queue_clearing(recipient_tag)
.await;
}
}
}
@@ -328,18 +398,35 @@ where
};
let mut to_take = Vec::new();
let mut to_remove = Vec::new();
while to_take.len() < max_to_clear {
if let Some((_, data)) = pending.pop_first() {
// no need to do anything if we failed to upgrade the reference,
// it means we got the ack while the data was waiting in the queue
if let Some(upgraded) = data.upgrade() {
to_take.push(upgraded)
// TODO: once rust 1.66.0 is stabilised on 15.12.22, just change it to
// `.pop_front()` to directly take ownership
for (k, data) in pending.iter() {
let upgraded = match data.upgrade() {
Some(upgraded) => upgraded,
None => {
// we got the ack while the data was waiting in the queue
to_remove.push(*k);
continue;
}
} else {
// our map is empty!
};
to_take.push(upgraded);
// we have taken as many entries as we could have
if to_take.len() >= max_to_clear {
break;
}
// TODO: use if upgraded.is_extra_surb_request() to bypass the limit
}
for ack in &to_take {
pending.remove(&ack.inner_fragment_identifier());
}
for id in to_remove {
pending.remove(&id);
}
if to_take.is_empty() {
@@ -360,47 +447,46 @@ where
let to_send_vec = to_take.iter().map(|ack| ack.fragment_data()).collect();
let prepared_fragments = match self
if let Err(err) = self
.message_handler
.prepare_reply_chunks_for_sending(to_send_vec, surbs_for_reply)
.try_send_retransmission_reply_chunks(
to_send_vec,
surbs_for_reply,
TransmissionLane::Retransmission,
)
.await
{
Ok(prepared) => prepared,
Err(err) => {
let err =
err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target);
self.re_insert_pending_retransmission(&target, to_take);
let err = err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target);
self.re_insert_pending_retransmission(&target, to_take);
warn!(
"failed to clear pending retransmission queue for {:?} - {err}",
target
);
return;
}
};
// we can't fail at this point, so drop all references to acks so that timer updates wouldn't blow up
drop(to_take);
self.message_handler
.send_retransmission_reply_chunks(prepared_fragments, TransmissionLane::Retransmission)
.await;
warn!(
"failed to clear pending retransmission queue for {:?} - {err}",
target
);
}
}
fn pop_at_most_pending_replies(
&mut self,
from: &AnonymousSenderTag,
amount: usize,
) -> Option<Vec<(TransmissionLane, Fragment)>> {
) -> Option<VecDeque<Fragment>> {
// if possible, pop all pending replies, if not, pop only entries for which we'd have a reply surb
let total = self.pending_replies.get(from)?.total_size();
let total = self.pending_replies.get(from)?.len();
trace!("pending queue has {total} elements");
if total == 0 {
return None;
}
self.pending_replies
.get_mut(from)?
.pop_at_most_n_next_messages_at_random(amount)
if total < amount {
self.pending_replies.remove(from)
} else {
Some(
self.pending_replies
.get_mut(from)?
.drain(..amount)
.collect(),
)
}
}
async fn try_clear_pending_queue(&mut self, target: AnonymousSenderTag) {
@@ -424,9 +510,9 @@ where
// we're guaranteed to not get more entries than we have reply surbs for
if let Some(to_send) = self.pop_at_most_pending_replies(&target, max_to_clear) {
let to_send_clone = to_send.clone();
let to_send_vec = to_send.iter().cloned().collect::<Vec<_>>();
if to_send_clone.is_empty() {
if to_send_vec.is_empty() {
panic!(
"please let the devs know if you ever see this message (reply_controller.rs)"
);
@@ -435,22 +521,27 @@ where
let (surbs_for_reply, _) = self
.full_reply_storage
.surbs_storage_ref()
.get_reply_surbs(&target, to_send_clone.len());
.get_reply_surbs(&target, to_send_vec.len());
let Some(surbs_for_reply) = surbs_for_reply else {
error!("somehow different task has stolen our reply surbs! - this should have been impossible");
self.re_insert_pending_replies(&target, to_send);
self.insert_pending_replies(&target, to_send);
return;
};
if let Err(err) = self
.message_handler
.try_send_reply_chunks(target, to_send_clone, surbs_for_reply)
.try_send_reply_chunks(
target,
to_send_vec,
surbs_for_reply,
TransmissionLane::General,
)
.await
{
let err =
err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target);
self.re_insert_pending_replies(&target, to_send);
self.insert_pending_replies(&target, to_send);
warn!("failed to clear pending queue for {:?} - {err}", target);
}
} else {
@@ -621,30 +712,6 @@ where
}
}
// to be honest this doesn't make a lot of sense in the context of `connection_id`,
// it should really be asked per tag
fn handle_lane_queue_length(
&self,
connection_id: ConnectionId,
response_channel: oneshot::Sender<usize>,
) {
// TODO: if we ever have duplicate ids for different senders, it means our rng is super weak
// thus I don't think we have to worry about it?
let lane = TransmissionLane::ConnectionId(connection_id);
for buf in self.pending_replies.values() {
if let Some(length) = buf.lane_length(&lane) {
if response_channel.send(length).is_err() {
error!("the requester for lane queue length has dropped the response channel!")
}
return;
}
}
// make sure that if we didn't find that lane, we reply with 0
if response_channel.send(0).is_err() {
error!("the requester for lane queue length has dropped the response channel!")
}
}
async fn handle_request(&mut self, request: ReplyControllerMessage) {
match request {
ReplyControllerMessage::RetransmitReply {
@@ -668,26 +735,19 @@ where
self.handle_received_surbs(sender_tag, reply_surbs, from_surb_request)
.await
}
ReplyControllerMessage::LaneQueueLength {
connection_id,
response_channel,
} => self.handle_lane_queue_length(connection_id, response_channel),
ReplyControllerMessage::AdditionalSurbsRequest { recipient, amount } => {
self.handle_surb_request(*recipient, amount).await
}
}
}
// TODO: modify this method to more accurately determine the amount of surbs it needs to request
// it should take into consideration the average latency, sending rate and queue size.
// it should request as many surbs as it takes to saturate its sending rate before next batch arrives
async fn request_reply_surbs_for_queue_clearing(&mut self, target: AnonymousSenderTag) {
trace!("requesting surbs for queues clearing");
let pending_queue_size = self
.pending_replies
.get(&target)
.map(|pending_queue| pending_queue.total_size())
.map(|pending_queue| pending_queue.len())
.unwrap_or_default();
let retransmission_queue = self
@@ -727,7 +787,7 @@ where
}
let Some(last_received) = self.full_reply_storage.surbs_storage_ref().surbs_last_received_at(pending_reply_target) else {
error!("we have {} pending replies for {pending_reply_target}, but we somehow never received any reply surbs from them!", vals.total_size());
error!("we have {} pending replies for {pending_reply_target}, but we somehow never received any reply surbs from them!", vals.len());
to_remove.push(*pending_reply_target);
continue;
};
@@ -823,20 +883,23 @@ where
}
}
// #[cfg(not(target_arch = "wasm32"))]
// async fn log_status(&self) {
// todo!()
// }
fn create_interval_stream(polling_rate: Duration) -> IntervalStream {
#[cfg(not(target_arch = "wasm32"))]
return tokio_stream::wrappers::IntervalStream::new(tokio::time::interval(polling_rate));
#[cfg(target_arch = "wasm32")]
return gloo_timers::future::IntervalStream::new(polling_rate.as_millis() as u32);
}
pub(crate) async fn run_with_shutdown(&mut self, mut shutdown: task::TaskClient) {
debug!("Started ReplyController with graceful shutdown support");
let polling_rate = Duration::from_secs(5);
let mut stale_inspection = new_interval_stream(polling_rate);
let mut stale_inspection = Self::create_interval_stream(polling_rate);
// this is in the order of hours/days so we don't have to poll it that often
let polling_rate = Duration::from_secs(self.config.max_reply_surb_age.as_secs() / 10);
let mut invalidation_inspection = new_interval_stream(polling_rate);
let mut invalidation_inspection = Self::create_interval_stream(polling_rate);
while !shutdown.is_shutdown() {
tokio::select! {
@@ -1,136 +0,0 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::real_messages_control::acknowledgement_control::PendingAcknowledgement;
use client_connections::{ConnectionId, TransmissionLane};
use futures::channel::{mpsc, oneshot};
use log::error;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::anonymous_replies::requests::AnonymousSenderTag;
use nymsphinx::anonymous_replies::ReplySurb;
use std::sync::Weak;
pub(crate) fn new_control_channels() -> (ReplyControllerSender, ReplyControllerReceiver) {
let (tx, rx) = mpsc::unbounded();
(tx.into(), rx)
}
#[derive(Debug, Clone)]
pub struct ReplyControllerSender(mpsc::UnboundedSender<ReplyControllerMessage>);
impl From<mpsc::UnboundedSender<ReplyControllerMessage>> for ReplyControllerSender {
fn from(inner: mpsc::UnboundedSender<ReplyControllerMessage>) -> Self {
ReplyControllerSender(inner)
}
}
impl ReplyControllerSender {
pub(crate) fn send_retransmission_data(
&self,
recipient: AnonymousSenderTag,
timed_out_ack: Weak<PendingAcknowledgement>,
extra_surb_request: bool,
) {
self.0
.unbounded_send(ReplyControllerMessage::RetransmitReply {
recipient,
timed_out_ack,
extra_surb_request,
})
.expect("ReplyControllerReceiver has died!")
}
pub(crate) fn send_reply(
&self,
recipient: AnonymousSenderTag,
message: Vec<u8>,
lane: TransmissionLane,
) {
self.0
.unbounded_send(ReplyControllerMessage::SendReply {
recipient,
message,
lane,
})
.expect("ReplyControllerReceiver has died!")
}
pub(crate) fn send_additional_surbs(
&self,
sender_tag: AnonymousSenderTag,
reply_surbs: Vec<ReplySurb>,
from_surb_request: bool,
) {
self.0
.unbounded_send(ReplyControllerMessage::AdditionalSurbs {
sender_tag,
reply_surbs,
from_surb_request,
})
.expect("ReplyControllerReceiver has died!")
}
pub(crate) fn send_additional_surbs_request(&self, recipient: Recipient, amount: u32) {
self.0
.unbounded_send(ReplyControllerMessage::AdditionalSurbsRequest {
recipient: Box::new(recipient),
amount,
})
.expect("ReplyControllerReceiver has died!")
}
pub async fn get_lane_queue_length(&self, connection_id: ConnectionId) -> usize {
let (response_tx, response_rx) = oneshot::channel();
self.0
.unbounded_send(ReplyControllerMessage::LaneQueueLength {
connection_id,
response_channel: response_tx,
})
.expect("ReplyControllerReceiver has died!");
match response_rx.await {
Ok(length) => length,
Err(_) => {
error!("The reply controller has dropped our response channel!");
// TODO: should we panic here instead? this message implies something weird and unrecoverable has happened
0
}
}
}
}
pub(crate) type ReplyControllerReceiver = mpsc::UnboundedReceiver<ReplyControllerMessage>;
#[derive(Debug)]
pub(crate) enum ReplyControllerMessage {
RetransmitReply {
recipient: AnonymousSenderTag,
timed_out_ack: Weak<PendingAcknowledgement>,
extra_surb_request: bool,
},
SendReply {
recipient: AnonymousSenderTag,
message: Vec<u8>,
lane: TransmissionLane,
},
AdditionalSurbs {
sender_tag: AnonymousSenderTag,
reply_surbs: Vec<ReplySurb>,
from_surb_request: bool,
},
// this one doesn't belong here either...
LaneQueueLength {
connection_id: ConnectionId,
response_channel: oneshot::Sender<usize>,
},
// Should this also be handled in here? it's technically a completely different side of the pipe
// let's see how it works when combined, might split it before creating PR
AdditionalSurbsRequest {
recipient: Box<Recipient>,
amount: u32,
},
}
+3 -4
View File
@@ -1,13 +1,14 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_storage::ReplyStorageBackend;
use crypto::asymmetric::identity::Ed25519RecoveryError;
use gateway_client::error::GatewayClientError;
use topology::NymTopologyError;
use validator_client::ValidatorClientError;
#[derive(thiserror::Error, Debug)]
pub enum ClientCoreError {
pub enum ClientCoreError<B: ReplyStorageBackend> {
#[error("I/O error: {0}")]
IoError(#[from] std::io::Error),
@@ -39,9 +40,7 @@ pub enum ClientCoreError {
InsufficientNetworkTopology(#[from] NymTopologyError),
#[error("experienced a failure with our reply surb persistent storage: {source}")]
SurbStorageError {
source: Box<dyn std::error::Error + Send + Sync>,
},
SurbStorageError { source: B::StorageError },
#[error("The gateway id is invalid - {0}")]
UnableToCreatePublicKeyFromGatewayId(Ed25519RecoveryError),
+14 -6
View File
@@ -1,6 +1,7 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_storage::ReplyStorageBackend;
use crate::{
client::key_manager::KeyManager,
config::{persistence::key_pathfinder::ClientKeyPathfinder, Config},
@@ -16,10 +17,13 @@ use tap::TapFallible;
use topology::{filter::VersionFilterable, gateway};
use url::Url;
pub(super) async fn query_gateway_details(
pub(super) async fn query_gateway_details<B>(
validator_servers: Vec<Url>,
chosen_gateway_id: Option<String>,
) -> Result<gateway::Node, ClientCoreError> {
) -> Result<gateway::Node, ClientCoreError<B>>
where
B: ReplyStorageBackend,
{
let nym_api = validator_servers
.choose(&mut thread_rng())
.ok_or(ClientCoreError::ListOfNymApisIsEmpty)?;
@@ -51,10 +55,13 @@ pub(super) async fn query_gateway_details(
}
}
async fn register_with_gateway(
async fn register_with_gateway<B>(
gateway: &gateway::Node,
our_identity: Arc<identity::KeyPair>,
) -> Result<Arc<SharedKeys>, ClientCoreError> {
) -> Result<Arc<SharedKeys>, ClientCoreError<B>>
where
B: ReplyStorageBackend,
{
let timeout = Duration::from_millis(1500);
let mut gateway_client = GatewayClient::new_init(
gateway.clients_address(),
@@ -74,12 +81,13 @@ async fn register_with_gateway(
Ok(shared_keys)
}
pub(super) async fn register_with_gateway_and_store_keys<T>(
pub(super) async fn register_with_gateway_and_store_keys<T, B>(
gateway_details: gateway::Node,
config: &Config<T>,
) -> Result<(), ClientCoreError>
) -> Result<(), ClientCoreError<B>>
where
T: NymConfig,
B: ReplyStorageBackend,
{
let mut rng = OsRng;
let mut key_manager = KeyManager::new(&mut rng);
+28 -15
View File
@@ -12,6 +12,7 @@ use tap::TapFallible;
use config::NymConfig;
use crypto::asymmetric::{encryption, identity};
use crate::client::replies::reply_storage::ReplyStorageBackend;
use crate::{
config::{
persistence::key_pathfinder::ClientKeyPathfinder, ClientCoreConfigTrait, Config,
@@ -62,13 +63,13 @@ impl Display for InitResults {
/// Convenience function for setting up the gateway for a client. Depending on the arguments given
/// it will do the sensible thing.
pub async fn setup_gateway<C, T>(
pub async fn setup_gateway<B, C, T>(
register_gateway: bool,
// TODO: this should get refactored to instead take Option<identity::PublicKey>
user_chosen_gateway_id: Option<String>,
config: &Config<T>,
) -> Result<GatewayEndpointConfig, ClientCoreError>
) -> Result<GatewayEndpointConfig, ClientCoreError<B>>
where
B: ReplyStorageBackend,
C: NymConfig + ClientCoreConfigTrait,
T: NymConfig,
{
@@ -78,18 +79,19 @@ where
} else if let Some(user_chosen_gateway_id) = user_chosen_gateway_id {
config_gateway_with_existing_keys(user_chosen_gateway_id, config).await
} else {
reuse_existing_gateway_config::<C>(&id)
reuse_existing_gateway_config::<B, C>(&id)
}
}
/// Get the gateway details by querying the validator-api. Either pick one at random or use
/// the chosen one if it's among the available ones.
/// Saves keys to disk, specified by the paths in `config`.
pub async fn register_with_gateway<T>(
pub async fn register_with_gateway<B, T>(
user_chosen_gateway_id: Option<String>,
config: &Config<T>,
) -> Result<GatewayEndpointConfig, ClientCoreError>
) -> Result<GatewayEndpointConfig, ClientCoreError<B>>
where
B: ReplyStorageBackend,
T: NymConfig,
{
println!("Configuring gateway");
@@ -109,11 +111,12 @@ where
/// create any keys.
/// This assumes that the user knows what they are doing, and that the existing keys are valid for
/// the gateway being used
pub async fn config_gateway_with_existing_keys<T>(
pub async fn config_gateway_with_existing_keys<B, T>(
user_chosen_gateway_id: String,
config: &Config<T>,
) -> Result<GatewayEndpointConfig, ClientCoreError>
) -> Result<GatewayEndpointConfig, ClientCoreError<B>>
where
B: ReplyStorageBackend,
T: NymConfig,
{
println!("Using gateway provided by user, keeping existing keys");
@@ -124,8 +127,11 @@ where
}
/// Read and reuse the existing gateway configuration from a file that was generate earlier.
pub fn reuse_existing_gateway_config<T>(id: &str) -> Result<GatewayEndpointConfig, ClientCoreError>
pub fn reuse_existing_gateway_config<B, T>(
id: &str,
) -> Result<GatewayEndpointConfig, ClientCoreError<B>>
where
B: ReplyStorageBackend,
T: NymConfig + ClientCoreConfigTrait,
{
println!("Not registering gateway, will reuse existing config and keys");
@@ -144,15 +150,19 @@ where
}
/// Get the client address by loading the keys from stored files.
pub fn get_client_address_from_stored_keys<T>(
pub fn get_client_address_from_stored_keys<B, T>(
config: &Config<T>,
) -> Result<Recipient, ClientCoreError>
) -> Result<Recipient, ClientCoreError<B>>
where
T: config::NymConfig,
B: ReplyStorageBackend,
{
fn load_identity_keys(
fn load_identity_keys<B>(
pathfinder: &ClientKeyPathfinder,
) -> Result<identity::KeyPair, ClientCoreError> {
) -> Result<identity::KeyPair, ClientCoreError<B>>
where
B: ReplyStorageBackend,
{
let identity_keypair: identity::KeyPair =
pemstore::load_keypair(&pemstore::KeyPairPath::new(
pathfinder.private_identity_key().to_owned(),
@@ -162,9 +172,12 @@ where
Ok(identity_keypair)
}
fn load_sphinx_keys(
fn load_sphinx_keys<B>(
pathfinder: &ClientKeyPathfinder,
) -> Result<encryption::KeyPair, ClientCoreError> {
) -> Result<encryption::KeyPair, ClientCoreError<B>>
where
B: ReplyStorageBackend,
{
let sphinx_keypair: encryption::KeyPair =
pemstore::load_keypair(&pemstore::KeyPairPath::new(
pathfinder.private_encryption_key().to_owned(),
+1 -1
View File
@@ -8,7 +8,7 @@ edition = "2021"
[dependencies]
bip39 = "1.0.1"
cfg-if = "0.1"
clap = { version = "4.0", features = ["cargo", "derive"] }
clap = { version = "3.2", features = ["cargo", "derive"] }
rand = "0.7.3"
serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0"
+3 -3
View File
@@ -31,7 +31,7 @@ cfg_if::cfg_if! {
#[tokio::main]
async fn main() -> Result<()> {
let args = Cli::parse();
setup_env(args.config_env_file.as_ref());
setup_env(args.config_env_file.clone());
let bin_name = "nym-credential-client";
match args.command {
@@ -42,8 +42,8 @@ cfg_if::cfg_if! {
let state = deposit(&r.nymd_url, &r.mnemonic, r.amount).await?;
get_credential(&state, shared_storage).await?;
}
Command::Completions(c) => c.generate(&mut crate::Cli::command(), bin_name),
Command::GenerateFigSpec => fig_generate(&mut crate::Cli::command(), bin_name)
Command::Completions(c) => c.generate(&mut crate::Cli::into_app(), bin_name),
Command::GenerateFigSpec => fig_generate(&mut crate::Cli::into_app(), bin_name)
}
Ok(())
+5 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-client"
version = "1.1.4"
version = "1.1.3"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client"
edition = "2021"
@@ -20,9 +20,8 @@ futures = "0.3" # bunch of futures stuff, however, now that I think about it, it
# and the single instance of abortable we have should really be refactored anyway
url = "2.2"
clap = { version = "4.0", features = ["cargo", "derive"] }
clap = { version = "3.2", features = ["cargo", "derive"] }
dirs = "4.0"
lazy_static = "1.4.0"
log = "0.4" # self explanatory
pretty_env_logger = "0.4" # for formatting log messages
rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use
@@ -34,7 +33,6 @@ tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] }
tokio-tungstenite = "0.14" # websocket
## internal
build-information = { path = "../../common/build-information" }
client-core = { path = "../client-core", features = ["fs-surb-storage"] }
client-connections = { path = "../../common/client-connections" }
coconut-interface = { path = "../../common/coconut-interface", optional = true }
@@ -60,3 +58,6 @@ coconut = ["coconut-interface", "credentials", "credentials/coconut", "gateway-r
[dev-dependencies]
serde_json = "1.0" # for the "textsend" example
[build-dependencies]
vergen = { version = "5", default-features = false, features = ["build", "git", "rustc", "cargo"] }
@@ -1,4 +1,4 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use vergen::{vergen, Config};
File diff suppressed because it is too large Load Diff
-4
View File
@@ -13,7 +13,6 @@ use client_core::client::base_client::{
use client_core::client::inbound_messages::InputMessage;
use client_core::client::key_manager::KeyManager;
use client_core::client::received_buffer::{ReceivedBufferMessage, ReconstructedMessagesReceiver};
use client_core::client::replies::reply_controller::requests::ReplyControllerSender;
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use futures::channel::mpsc;
use gateway_client::bandwidth::BandwidthController;
@@ -88,7 +87,6 @@ impl SocketClient {
client_input: ClientInput,
client_output: ClientOutput,
self_address: &Recipient,
reply_controller_sender: ReplyControllerSender,
shutdown: task::TaskClient,
) {
info!("Starting websocket listener...");
@@ -109,7 +107,6 @@ impl SocketClient {
received_buffer_request_sender,
self_address,
shared_lane_queue_lengths,
reply_controller_sender,
);
websocket::Listener::new(config.get_listening_port()).start(websocket_handler, shutdown);
@@ -157,7 +154,6 @@ impl SocketClient {
client_input,
client_output,
&self_address,
started_client.reply_controller_sender,
started_client.task_manager.subscribe(),
);
+14 -18
View File
@@ -8,7 +8,6 @@ use crate::{
};
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::identity;
use nymsphinx::addressing::clients::Recipient;
use serde::Serialize;
use std::fmt::Display;
@@ -22,7 +21,7 @@ pub(crate) struct Init {
/// Id of the gateway we are going to connect to.
#[clap(long)]
gateway: Option<identity::PublicKey>,
gateway: Option<String>,
/// Force register gateway. WARNING: this will overwrite any existing keys for the given id,
/// potentially causing loss of access.
@@ -30,14 +29,12 @@ pub(crate) struct Init {
force_register_gateway: bool,
/// Comma separated list of rest endpoints of the nymd validators
#[cfg(feature = "coconut")]
#[clap(long, value_delimiter = ',')]
nymd_validators: Option<Vec<url::Url>>,
#[clap(long)]
nymd_validators: Option<String>,
/// Comma separated list of rest endpoints of the API validators
#[clap(long, alias = "api_validators", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
#[clap(long)]
api_validators: Option<String>,
/// Whether to not start the websocket
#[clap(long)]
@@ -49,11 +46,11 @@ pub(crate) struct Init {
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hide = true)]
#[clap(long, hidden = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hide = true)]
#[clap(long, hidden = true)]
no_cover: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
@@ -70,14 +67,13 @@ pub(crate) struct Init {
impl From<Init> for OverrideConfig {
fn from(init_config: Init) -> Self {
OverrideConfig {
nym_apis: init_config.nym_apis,
nymd_validators: init_config.nymd_validators,
api_validators: init_config.api_validators,
disable_socket: init_config.disable_socket,
port: init_config.port,
fastmode: init_config.fastmode,
no_cover: init_config.no_cover,
#[cfg(feature = "coconut")]
nymd_validators: init_config.nymd_validators,
#[cfg(feature = "coconut")]
enabled_credentials_mode: init_config.enabled_credentials_mode,
}
@@ -131,16 +127,16 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> {
let register_gateway = !already_init || user_wants_force_register;
// Attempt to use a user-provided gateway, if possible
let user_chosen_gateway_id = args.gateway;
let user_chosen_gateway_id = args.gateway.clone();
// Load and potentially override config
let mut config = override_config(Config::new(id), OverrideConfig::from(args.clone()));
// Setup gateway by either registering a new one, or creating a new config from the selected
// one but with keys kept, or reusing the gateway configuration.
let gateway = client_core::init::setup_gateway::<Config, _>(
let gateway = client_core::init::setup_gateway::<_, Config, _>(
register_gateway,
user_chosen_gateway_id.map(|id| id.to_base58_string()),
user_chosen_gateway_id,
config.get_base(),
)
.await
@@ -156,14 +152,14 @@ pub(crate) async fn execute(args: &Init) -> Result<(), ClientError> {
let address = client_core::init::get_client_address_from_stored_keys(config.get_base())?;
let init_results = InitResults::new(&config, &address);
println!("{init_results}");
println!("{}", init_results);
// Output summary to a json file, if specified
if args.output_json {
client_core::init::output_to_json(&init_results, "client_init_results.json");
}
println!("\nThe address of this client is: {address}\n");
println!("\nThe address of this client is: {}\n", address);
Ok(())
}
+54 -27
View File
@@ -1,30 +1,54 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::error::Error;
use crate::client::config::{Config, SocketType};
use build_information::BinaryBuildInformation;
use clap::CommandFactory;
use clap::{Parser, Subcommand};
use completions::{fig_generate, ArgShell};
use lazy_static::lazy_static;
use std::error::Error;
pub(crate) mod init;
pub(crate) mod run;
pub(crate) mod upgrade;
lazy_static! {
pub static ref PRETTY_BUILD_INFORMATION: String =
BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print();
fn long_version() -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
env!("VERGEN_BUILD_TIMESTAMP"),
"Build Version:",
env!("VERGEN_BUILD_SEMVER"),
"Commit SHA:",
env!("VERGEN_GIT_SHA"),
"Commit Date:",
env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
"Commit Branch:",
env!("VERGEN_GIT_BRANCH"),
"rustc Version:",
env!("VERGEN_RUSTC_SEMVER"),
"rustc Channel:",
env!("VERGEN_RUSTC_CHANNEL"),
"cargo Profile:",
env!("VERGEN_CARGO_PROFILE"),
)
}
// Helper for passing LONG_VERSION to clap
fn pretty_build_info_static() -> &'static str {
&PRETTY_BUILD_INFORMATION
fn long_version_static() -> &'static str {
Box::leak(long_version().into_boxed_str())
}
#[derive(Parser)]
#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)]
#[clap(author = "Nymtech", version, long_version = long_version_static(), about)]
pub(crate) struct Cli {
/// Path pointing to an env file that configures the client.
#[clap(short, long)]
@@ -52,14 +76,13 @@ pub(crate) enum Commands {
// Configuration that can be overridden.
pub(crate) struct OverrideConfig {
nym_apis: Option<Vec<url::Url>>,
nymd_validators: Option<String>,
api_validators: Option<String>,
disable_socket: bool,
port: Option<u16>,
fastmode: bool,
no_cover: bool,
#[cfg(feature = "coconut")]
nymd_validators: Option<Vec<url::Url>>,
#[cfg(feature = "coconut")]
enabled_credentials_mode: bool,
}
@@ -71,21 +94,34 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Syn
Commands::Init(m) => init::execute(m).await?,
Commands::Run(m) => run::execute(m).await?,
Commands::Upgrade(m) => upgrade::execute(m),
Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name),
Commands::Completions(s) => s.generate(&mut Cli::into_app(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut Cli::into_app(), bin_name),
}
Ok(())
}
pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Config {
if let Some(nym_apis) = args.nym_apis {
config.get_base_mut().set_custom_nym_apis(nym_apis);
if let Some(raw_validators) = args.nymd_validators {
config
.get_base_mut()
.set_custom_validators(config::parse_validators(&raw_validators));
} else if std::env::var(network_defaults::var_names::CONFIGURED).is_ok() {
let raw_validators = std::env::var(network_defaults::var_names::NYMD_VALIDATOR)
.expect("nymd validator not set");
config
.get_base_mut()
.set_custom_validators(config::parse_validators(&raw_validators));
}
if let Some(raw_validators) = args.api_validators {
config
.get_base_mut()
.set_custom_nym_apis(config::parse_validators(&raw_validators));
} else if std::env::var(network_defaults::var_names::CONFIGURED).is_ok() {
let raw_validators = std::env::var(network_defaults::var_names::API_VALIDATOR)
.expect("api validator not set");
config
.get_base_mut()
.set_custom_nym_apis(config::parse_urls(&raw_validators));
.set_custom_nym_apis(config::parse_validators(&raw_validators));
}
if args.disable_socket {
@@ -98,15 +134,6 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
#[cfg(feature = "coconut")]
{
if let Some(nymd_validators) = args.nymd_validators {
config.get_base_mut().set_custom_validators(nymd_validators);
} else if std::env::var(network_defaults::var_names::CONFIGURED).is_ok() {
let raw_validators = std::env::var(network_defaults::var_names::NYMD_VALIDATOR)
.expect("nymd validator not set");
config
.get_base_mut()
.set_custom_validators(config::parse_urls(&raw_validators));
}
if args.enabled_credentials_mode {
config.get_base_mut().with_disabled_credentials(false)
}
+10 -15
View File
@@ -1,4 +1,4 @@
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::error::Error;
@@ -11,7 +11,6 @@ use crate::{
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::identity;
use log::*;
use version_checker::is_minor_version_compatible;
@@ -22,19 +21,17 @@ pub(crate) struct Run {
id: String,
/// Comma separated list of rest endpoints of the nymd validators
#[cfg(feature = "coconut")]
#[clap(long, value_delimiter = ',')]
nymd_validators: Option<Vec<url::Url>>,
#[clap(long)]
nymd_validators: Option<String>,
/// Comma separated list of rest endpoints of the API validators
#[clap(long, alias = "api_validators", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
#[clap(long)]
api_validators: Option<String>,
/// Id of the gateway we want to connect to. If overridden, it is user's responsibility to
/// ensure prior registration happened
#[clap(long)]
gateway: Option<identity::PublicKey>,
gateway: Option<String>,
/// Whether to not start the websocket
#[clap(long)]
@@ -46,11 +43,11 @@ pub(crate) struct Run {
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hide = true)]
#[clap(long, hidden = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hide = true)]
#[clap(long, hidden = true)]
no_cover: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
@@ -63,14 +60,12 @@ pub(crate) struct Run {
impl From<Run> for OverrideConfig {
fn from(run_config: Run) -> Self {
OverrideConfig {
nym_apis: run_config.nym_apis,
nymd_validators: run_config.nymd_validators,
api_validators: run_config.api_validators,
disable_socket: run_config.disable_socket,
port: run_config.port,
fastmode: run_config.fastmode,
no_cover: run_config.no_cover,
#[cfg(feature = "coconut")]
nymd_validators: run_config.nymd_validators,
#[cfg(feature = "coconut")]
enabled_credentials_mode: run_config.enabled_credentials_mode,
}
+2 -1
View File
@@ -1,3 +1,4 @@
use client_core::client::replies::reply_storage::fs_backend;
use client_core::error::ClientCoreError;
#[derive(thiserror::Error, Debug)]
@@ -6,7 +7,7 @@ pub enum ClientError {
IoError(#[from] std::io::Error),
#[error("client-core error: {0}")]
ClientCoreError(#[from] ClientCoreError),
ClientCoreError(#[from] ClientCoreError<fs_backend::Backend>),
#[error("Failed to load config for: {0}")]
FailedToLoadConfig(String),
+1 -1
View File
@@ -18,7 +18,7 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
println!("{}", banner());
let args = commands::Cli::parse();
setup_env(args.config_env_file.as_ref());
setup_env(args.config_env_file.clone());
commands::execute(&args).await
}
+73 -63
View File
@@ -2,9 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
use client_connections::{
ConnectionCommand, ConnectionCommandSender, ConnectionId, LaneQueueLengths, TransmissionLane,
ConnectionCommand, ConnectionCommandSender, LaneQueueLengths, TransmissionLane,
};
use client_core::client::replies::reply_controller::requests::ReplyControllerSender;
use client_core::client::{
inbound_messages::{InputMessage, InputMessageSender},
received_buffer::{
@@ -17,9 +16,7 @@ use log::*;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::anonymous_replies::requests::AnonymousSenderTag;
use nymsphinx::receiver::ReconstructedMessage;
use std::time::Duration;
use tokio::net::TcpStream;
use tokio::time::Instant;
use tokio_tungstenite::{
accept_async,
tungstenite::{protocol::Message as WsMessage, Error as WsError},
@@ -44,7 +41,6 @@ pub(crate) struct HandlerBuilder {
buffer_requester: ReceivedBufferRequestSender,
self_full_address: Recipient,
lane_queue_lengths: LaneQueueLengths,
reply_controller_sender: ReplyControllerSender,
}
impl HandlerBuilder {
@@ -54,7 +50,6 @@ impl HandlerBuilder {
buffer_requester: ReceivedBufferRequestSender,
self_full_address: &Recipient,
lane_queue_lengths: LaneQueueLengths,
reply_controller_sender: ReplyControllerSender,
) -> Self {
Self {
msg_input,
@@ -62,7 +57,6 @@ impl HandlerBuilder {
buffer_requester,
self_full_address: *self_full_address,
lane_queue_lengths,
reply_controller_sender,
}
}
@@ -76,7 +70,6 @@ impl HandlerBuilder {
socket: None,
received_response_type: Default::default(),
lane_queue_lengths: self.lane_queue_lengths.clone(),
reply_controller_sender: self.reply_controller_sender.clone(),
}
}
}
@@ -89,7 +82,6 @@ pub(crate) struct Handler {
socket: Option<WebSocketStream<TcpStream>>,
received_response_type: ReceivedResponseType,
lane_queue_lengths: LaneQueueLengths,
reply_controller_sender: ReplyControllerSender,
}
impl Drop for Handler {
@@ -105,48 +97,6 @@ impl Drop for Handler {
}
impl Handler {
async fn get_lane_queue_length(&self, connection_id: ConnectionId) -> Option<ServerResponse> {
let req_start = Instant::now();
// get the base queue length
// Note that this does _NOT_ take into account the packets that have been received but not
// yet reach `OutQueueControl`, so it might be a tad low.
let conn_lane = TransmissionLane::ConnectionId(connection_id);
let Ok(base_length) = self
.lane_queue_lengths
.lock()
.map(|guard| guard.get(&conn_lane).unwrap_or_default()) else {
// I'd argue we should panic here as this error it not recoverable
error!("The lane queue length lock is poisoned!!");
return None
};
// get the number of pending replies waiting for reply surbs
let reply_queue_length = self
.reply_controller_sender
.get_lane_queue_length(connection_id)
.await;
let queue_length = base_length + reply_queue_length;
let time_taken = req_start.elapsed();
let msg =
format!("it took {time_taken:?} to get lane length for connection {connection_id}. The length is: {queue_length} = {base_length} (already queued up) + {reply_queue_length} (waiting for reply SURBs)");
if time_taken > Duration::from_millis(1) {
info!("{msg}");
} else if time_taken > Duration::from_millis(10) {
warn!("{msg}");
} else if time_taken > Duration::from_millis(50) {
error!("{msg}");
}
Some(ServerResponse::LaneQueueLength {
lane: connection_id,
queue_length,
})
}
async fn handle_send(
&mut self,
recipient: Recipient,
@@ -171,11 +121,27 @@ impl Handler {
.expect("InputMessageReceiver has stopped receiving!");
// Only reply back with a `LaneQueueLength` if the sender providided a connection id
let TransmissionLane::ConnectionId(connection_id) = lane else {
return None
let connection_id = match lane {
TransmissionLane::General
| TransmissionLane::ReplySurbRequest
| TransmissionLane::Retransmission
| TransmissionLane::AdditionalReplySurbs => return None,
TransmissionLane::ConnectionId(id) => id,
};
self.get_lane_queue_length(connection_id).await
// on receiving a send, we reply back the current lane queue length for that connection id.
// Note that this does _NOT_ take into account the packets that have been received but not
// yet reach `OutQueueControl`, so it might be a tad low.
if let Ok(lane_queue_lengths) = self.lane_queue_lengths.lock() {
let queue_length = lane_queue_lengths.get(&lane).unwrap_or(0);
return Some(ServerResponse::LaneQueueLength {
lane: connection_id,
queue_length,
});
}
log::warn!("Failed to get the lane queue length lock, not responding back with the current queue length");
None
}
async fn handle_send_anonymous(
@@ -202,11 +168,27 @@ impl Handler {
.expect("InputMessageReceiver has stopped receiving!");
// Only reply back with a `LaneQueueLength` if the sender providided a connection id
let TransmissionLane::ConnectionId(connection_id) = lane else {
return None
let connection_id = match lane {
TransmissionLane::General
| TransmissionLane::ReplySurbRequest
| TransmissionLane::Retransmission
| TransmissionLane::AdditionalReplySurbs => return None,
TransmissionLane::ConnectionId(id) => id,
};
self.get_lane_queue_length(connection_id).await
// on receiving a send, we reply back the current lane queue length for that connection id.
// Note that this does _NOT_ take into account the packets that have been received but not
// yet reach `OutQueueControl`, so it might be a tad low.
if let Ok(lane_queue_lengths) = self.lane_queue_lengths.lock() {
let queue_length = lane_queue_lengths.get(&lane).unwrap_or(0);
return Some(ServerResponse::LaneQueueLength {
lane: connection_id,
queue_length,
});
}
log::warn!("Failed to get the lane queue length lock, not responding back with the current queue length");
None
}
async fn handle_reply(
@@ -229,11 +211,27 @@ impl Handler {
.expect("InputMessageReceiver has stopped receiving!");
// Only reply back with a `LaneQueueLength` if the sender providided a connection id
let TransmissionLane::ConnectionId(connection_id) = lane else {
return None
let connection_id = match lane {
TransmissionLane::General
| TransmissionLane::ReplySurbRequest
| TransmissionLane::Retransmission
| TransmissionLane::AdditionalReplySurbs => return None,
TransmissionLane::ConnectionId(id) => id,
};
self.get_lane_queue_length(connection_id).await
// on receiving a send, we reply back the current lane queue length for that connection id.
// Note that this does _NOT_ take into account the packets that have been received but not
// yet reach `OutQueueControl`, so it might be a tad low.
if let Ok(lane_queue_lengths) = self.lane_queue_lengths.lock() {
let queue_length = lane_queue_lengths.get(&lane).unwrap_or(0);
return Some(ServerResponse::LaneQueueLength {
lane: connection_id,
queue_length,
});
}
log::warn!("Failed to get the lane queue length lock, not responding back with the current queue length");
None
}
fn handle_self_address(&self) -> ServerResponse {
@@ -247,8 +245,20 @@ impl Handler {
None
}
async fn handle_get_lane_queue_length(&self, connection_id: u64) -> Option<ServerResponse> {
self.get_lane_queue_length(connection_id).await
fn handle_get_lane_queue_length(&self, connection_id: u64) -> Option<ServerResponse> {
let Ok(lane_queue_lengths) = self.lane_queue_lengths.lock() else {
log::warn!(
"Failed to get the lane queue length lock, not responding back with the current queue length"
);
return None;
};
let lane = TransmissionLane::ConnectionId(connection_id);
let queue_length = lane_queue_lengths.get(&lane).unwrap_or(0);
Some(ServerResponse::LaneQueueLength {
lane: connection_id,
queue_length,
})
}
async fn handle_request(&mut self, request: ClientRequest) -> Option<ServerResponse> {
@@ -277,7 +287,7 @@ impl Handler {
ClientRequest::SelfAddress => Some(self.handle_self_address()),
ClientRequest::ClosedConnection(id) => self.handle_closed_connection(id),
ClientRequest::GetLaneQueueLength(id) => self.handle_get_lane_queue_length(id).await,
ClientRequest::GetLaneQueueLength(id) => self.handle_get_lane_queue_length(id),
}
}
+5 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "nym-socks5-client"
version = "1.1.4"
version = "1.1.3"
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"
@@ -11,10 +11,9 @@ name = "nym_socks5"
path = "src/lib.rs"
[dependencies]
clap = { version = "4.0", features = ["cargo", "derive"] }
clap = { version = "3.2", features = ["cargo", "derive"] }
dirs = "4.0"
futures = "0.3"
lazy_static = "1.4.0"
log = "0.4"
pin-project = "1.0"
pretty_env_logger = "0.4"
@@ -27,7 +26,6 @@ tokio = { version = "1.21.2", features = ["rt-multi-thread", "net", "signal"] }
url = "2.2"
# internal
build-information = { path = "../../common/build-information" }
client-core = { path = "../client-core", features = ["fs-surb-storage"] }
client-connections = { path = "../../common/client-connections" }
coconut-interface = { path = "../../common/coconut-interface", optional = true }
@@ -53,3 +51,6 @@ version-checker = { path = "../../common/version-checker" }
[features]
coconut = ["coconut-interface", "credentials", "gateway-requests/coconut", "gateway-client/coconut", "credentials/coconut", "client-core/coconut"]
eth = []
[build-dependencies]
vergen = { version = "5", default-features = false, features = ["build", "git", "rustc", "cargo"] }
+8
View File
@@ -0,0 +1,8 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use vergen::{vergen, Config};
fn main() {
vergen(Config::default()).expect("failed to extract build metadata")
}
+17 -23
View File
@@ -8,7 +8,6 @@ use crate::{
};
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::identity;
use nymsphinx::addressing::clients::Recipient;
use serde::Serialize;
use std::fmt::Display;
@@ -22,20 +21,19 @@ pub(crate) struct Init {
/// Address of the socks5 provider to send messages to.
#[clap(long)]
provider: Recipient,
provider: String,
/// Specifies whether this client is going to use an anonymous sender tag for communication with the service provider.
/// While this is going to hide its actual address information, it will make the actual communication
/// slower and consume nearly double the bandwidth as it will require sending reply SURBs.
///
/// Note that some service providers might not support this.
// the alias here is included for backwards compatibility (1.1.4 and before)
#[clap(long, alias = "use_anonymous_sender_tag")]
use_reply_surbs: bool,
#[clap(long)]
use_anonymous_sender_tag: bool,
/// Id of the gateway we are going to connect to.
#[clap(long)]
gateway: Option<identity::PublicKey>,
gateway: Option<String>,
/// Force register gateway. WARNING: this will overwrite any existing keys for the given id,
/// potentially causing loss of access.
@@ -43,14 +41,12 @@ pub(crate) struct Init {
force_register_gateway: bool,
/// Comma separated list of rest endpoints of the nymd validators
#[cfg(feature = "coconut")]
#[clap(long, value_delimiter = ',')]
nymd_validators: Option<Vec<url::Url>>,
#[clap(long)]
nymd_validators: Option<String>,
/// Comma separated list of rest endpoints of the API validators
#[clap(long, alias = "api_validators", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
#[clap(long)]
api_validators: Option<String>,
/// Port for the socket to listen on in all subsequent runs
#[clap(short, long)]
@@ -58,11 +54,11 @@ pub(crate) struct Init {
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hide = true)]
#[clap(long, hidden = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hide = true)]
#[clap(long, hidden = true)]
no_cover: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
@@ -79,14 +75,12 @@ pub(crate) struct Init {
impl From<Init> for OverrideConfig {
fn from(init_config: Init) -> Self {
OverrideConfig {
nym_apis: init_config.nym_apis,
nymd_validators: init_config.nymd_validators,
api_validators: init_config.api_validators,
port: init_config.port,
use_anonymous_replies: init_config.use_reply_surbs,
use_anonymous_sender_tag: init_config.use_anonymous_sender_tag,
fastmode: init_config.fastmode,
no_cover: init_config.no_cover,
#[cfg(feature = "coconut")]
nymd_validators: init_config.nymd_validators,
#[cfg(feature = "coconut")]
enabled_credentials_mode: init_config.enabled_credentials_mode,
}
@@ -141,19 +135,19 @@ pub(crate) async fn execute(args: &Init) -> Result<(), Socks5ClientError> {
let register_gateway = !already_init || user_wants_force_register;
// Attempt to use a user-provided gateway, if possible
let user_chosen_gateway_id = args.gateway;
let user_chosen_gateway_id = args.gateway.clone();
// Load and potentially override config
let mut config = override_config(
Config::new(id, &provider_address.to_string()),
Config::new(id, provider_address),
OverrideConfig::from(args.clone()),
);
// Setup gateway by either registering a new one, or creating a new config from the selected
// one but with keys kept, or reusing the gateway configuration.
let gateway = client_core::init::setup_gateway::<Config, _>(
let gateway = client_core::init::setup_gateway::<_, Config, _>(
register_gateway,
user_chosen_gateway_id.map(|id| id.to_base58_string()),
user_chosen_gateway_id,
config.get_base(),
)
.await
+56 -31
View File
@@ -1,31 +1,55 @@
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::error::Error;
use crate::client::config::Config;
use build_information::BinaryBuildInformation;
use clap::CommandFactory;
use clap::{Parser, Subcommand};
use completions::{fig_generate, ArgShell};
use config::parse_urls;
use lazy_static::lazy_static;
use std::error::Error;
use config::parse_validators;
pub mod init;
pub(crate) mod run;
pub(crate) mod upgrade;
lazy_static! {
pub static ref PRETTY_BUILD_INFORMATION: String =
BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print();
fn long_version() -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
env!("VERGEN_BUILD_TIMESTAMP"),
"Build Version:",
env!("VERGEN_BUILD_SEMVER"),
"Commit SHA:",
env!("VERGEN_GIT_SHA"),
"Commit Date:",
env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
"Commit Branch:",
env!("VERGEN_GIT_BRANCH"),
"rustc Version:",
env!("VERGEN_RUSTC_SEMVER"),
"rustc Channel:",
env!("VERGEN_RUSTC_CHANNEL"),
"cargo Profile:",
env!("VERGEN_CARGO_PROFILE"),
)
}
// Helper for passing LONG_VERSION to clap
fn pretty_build_info_static() -> &'static str {
&PRETTY_BUILD_INFORMATION
fn long_version_static() -> &'static str {
Box::leak(long_version().into_boxed_str())
}
#[derive(Parser)]
#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)]
#[clap(author = "Nymtech", version, long_version = long_version_static(), about)]
pub(crate) struct Cli {
/// Path pointing to an env file that configures the client.
#[clap(short, long)]
@@ -55,14 +79,13 @@ pub(crate) enum Commands {
// Configuration that can be overridden.
pub(crate) struct OverrideConfig {
nym_apis: Option<Vec<url::Url>>,
nymd_validators: Option<String>,
api_validators: Option<String>,
port: Option<u16>,
use_anonymous_replies: bool,
use_anonymous_sender_tag: bool,
fastmode: bool,
no_cover: bool,
#[cfg(feature = "coconut")]
nymd_validators: Option<Vec<url::Url>>,
#[cfg(feature = "coconut")]
enabled_credentials_mode: bool,
}
@@ -74,22 +97,33 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Syn
Commands::Init(m) => init::execute(m).await?,
Commands::Run(m) => run::execute(m).await?,
Commands::Upgrade(m) => upgrade::execute(m),
Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name),
Commands::Completions(s) => s.generate(&mut Cli::into_app(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut Cli::into_app(), bin_name),
}
Ok(())
}
pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Config {
if let Some(nym_apis) = args.nym_apis {
config.get_base_mut().set_custom_nym_apis(nym_apis);
if let Some(raw_validators) = args.nymd_validators {
config
.get_base_mut()
.set_custom_validators(parse_validators(&raw_validators));
} else if let Ok(raw_validators) = std::env::var(network_defaults::var_names::NYMD_VALIDATOR) {
config
.get_base_mut()
.set_custom_validators(parse_validators(&raw_validators));
}
if let Some(raw_validators) = args.api_validators {
config
.get_base_mut()
.set_custom_nym_apis(parse_validators(&raw_validators));
} else if let Ok(raw_validators) = std::env::var(network_defaults::var_names::API_VALIDATOR) {
config
.get_base_mut()
.set_custom_nym_apis(parse_urls(&raw_validators));
.set_custom_nym_apis(parse_validators(&raw_validators));
}
if args.use_anonymous_replies {
if args.use_anonymous_sender_tag {
config = config.with_anonymous_replies(true)
}
@@ -99,15 +133,6 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
#[cfg(feature = "coconut")]
{
if let Some(nymd_validators) = args.nymd_validators {
config.get_base_mut().set_custom_validators(nymd_validators);
} else if let Ok(raw_validators) =
std::env::var(network_defaults::var_names::NYMD_VALIDATOR)
{
config
.get_base_mut()
.set_custom_validators(parse_urls(&raw_validators));
}
if args.enabled_credentials_mode {
config.get_base_mut().with_disabled_credentials(false)
}
+13 -19
View File
@@ -9,9 +9,7 @@ use crate::{
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::identity;
use log::*;
use nymsphinx::addressing::clients::Recipient;
use version_checker::is_minor_version_compatible;
#[derive(Args, Clone)]
@@ -29,27 +27,25 @@ pub(crate) struct Run {
/// slower and consume nearly double the bandwidth as it will require sending reply SURBs.
///
/// Note that some service providers might not support this.
// the alias here is included for backwards compatibility (1.1.4 and before)
#[clap(long, alias = "use_anonymous_sender_tag")]
use_anonymous_replies: bool,
#[clap(long)]
use_anonymous_sender_tag: bool,
/// Address of the socks5 provider to send messages to.
#[clap(long)]
provider: Option<Recipient>,
provider: Option<String>,
/// Id of the gateway we want to connect to. If overridden, it is user's responsibility to
/// ensure prior registration happened
#[clap(long)]
gateway: Option<identity::PublicKey>,
gateway: Option<String>,
/// Comma separated list of rest endpoints of the nymd validators
#[cfg(feature = "coconut")]
#[clap(long, value_delimiter = ',')]
nymd_validators: Option<Vec<url::Url>>,
#[clap(long)]
nymd_validators: Option<String>,
/// Comma separated list of rest endpoints of the Nym APIs
#[clap(long, value_delimiter = ',')]
nym_apis: Option<Vec<url::Url>>,
#[clap(long)]
nym_apis: Option<String>,
/// Port for the socket to listen on
#[clap(short, long)]
@@ -57,11 +53,11 @@ pub(crate) struct Run {
/// Mostly debug-related option to increase default traffic rate so that you would not need to
/// modify config post init
#[clap(long, hide = true)]
#[clap(long, hidden = true)]
fastmode: bool,
/// Disable loop cover traffic and the Poisson rate limiter (for debugging only)
#[clap(long, hide = true)]
#[clap(long, hidden = true)]
no_cover: bool,
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
@@ -74,14 +70,12 @@ pub(crate) struct Run {
impl From<Run> for OverrideConfig {
fn from(run_config: Run) -> Self {
OverrideConfig {
nym_apis: run_config.nym_apis,
nymd_validators: run_config.nymd_validators,
api_validators: run_config.nym_apis,
port: run_config.port,
use_anonymous_replies: run_config.use_anonymous_replies,
use_anonymous_sender_tag: run_config.use_anonymous_sender_tag,
fastmode: run_config.fastmode,
no_cover: run_config.no_cover,
#[cfg(feature = "coconut")]
nymd_validators: run_config.nymd_validators,
#[cfg(feature = "coconut")]
enabled_credentials_mode: run_config.enabled_credentials_mode,
}
+2 -1
View File
@@ -1,4 +1,5 @@
use crate::socks::types::SocksProxyError;
use client_core::client::replies::reply_storage::fs_backend;
use client_core::error::ClientCoreError;
use socks5_requests::ConnectionId;
@@ -8,7 +9,7 @@ pub enum Socks5ClientError {
IoError(#[from] std::io::Error),
#[error("client-core error: {0}")]
ClientCoreError(#[from] ClientCoreError),
ClientCoreError(#[from] ClientCoreError<fs_backend::Backend>),
#[error("SOCKS proxy error")]
SocksProxyError(SocksProxyError),
+1 -1
View File
@@ -18,7 +18,7 @@ async fn main() -> Result<(), Box<dyn Error + Send + Sync>> {
println!("{}", banner());
let args = commands::Cli::parse();
setup_env(args.config_env_file.as_ref());
setup_env(args.config_env_file.clone());
commands::execute(&args).await
}
File diff suppressed because it is too large Load Diff
-11
View File
@@ -1,11 +0,0 @@
[package]
name = "build-information"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[build-dependencies]
vergen = { version = "7", default-features = false, features = ["build", "git", "rustc", "cargo"] }
-86
View File
@@ -1,86 +0,0 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
// TODO: at a later date this crate should probably also expose `ContractBuildInformation`
// and be used by our smart contracts
pub struct BinaryBuildInformation {
// VERGEN_BUILD_TIMESTAMP
/// Provides the build timestamp, for example `2021-02-23T20:14:46.558472672+00:00`.
pub build_timestamp: &'static str,
// VERGEN_BUILD_SEMVER
/// Provides the build version, for example `0.1.0-9-g46f83e1`.
pub build_version: &'static str,
// VERGEN_GIT_SHA
/// Provides the hash of the commit that was used for the build, for example `46f83e112520533338245862d366f6a02cef07d4`.
pub commit_sha: &'static str,
// VERGEN_GIT_COMMIT_TIMESTAMP
/// Provides the timestamp of the commit that was used for the build, for example `2021-02-23T08:08:02-05:00`.
pub commit_timestamp: &'static str,
// VERGEN_GIT_BRANCH
/// Provides the name of the git branch that was used for the build, for example `master`.
pub commit_branch: &'static str,
// VERGEN_RUSTC_SEMVER
/// Provides the rustc version that was used for the build, for example `1.52.0-nightly`.
pub rustc_version: &'static str,
// VERGEN_RUSTC_CHANNEL
/// Provides the rustc channel that was used for the build, for example `nightly`.
pub rustc_channel: &'static str,
// VERGEN_CARGO_PROFILE
/// Provides the cargo profile that was used for the build, for example `debug`.
pub cargo_profile: &'static str,
}
impl BinaryBuildInformation {
// explicitly require the build_version to be passed as it's binary specific
pub const fn new(build_version: &'static str) -> Self {
BinaryBuildInformation {
build_timestamp: env!("VERGEN_BUILD_TIMESTAMP"),
build_version,
commit_sha: env!("VERGEN_GIT_SHA"),
commit_timestamp: env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
commit_branch: env!("VERGEN_GIT_BRANCH"),
rustc_version: env!("VERGEN_RUSTC_SEMVER"),
rustc_channel: env!("VERGEN_RUSTC_CHANNEL"),
cargo_profile: env!("VERGEN_CARGO_PROFILE"),
}
}
pub fn pretty_print(&self) -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
self.build_timestamp,
"Build Version:",
self.build_version,
"Commit SHA:",
self.commit_sha,
"Commit Date:",
self.commit_timestamp,
"Commit Branch:",
self.commit_branch,
"rustc Version:",
self.rustc_version,
"rustc Channel:",
self.rustc_channel,
"cargo Profile:",
self.cargo_profile,
)
}
}
+2 -1
View File
@@ -1,9 +1,10 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use futures::channel::mpsc;
use std::collections::HashMap;
use futures::channel::mpsc;
pub type ConnectionId = u64;
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
@@ -366,8 +366,8 @@ impl Client {
&self,
mix_id: MixId,
request_body: &ComputeRewardEstParam,
) -> Result<RewardEstimationResponse, NymAPIError> {
self.post_nym_api(
) -> Result<RewardEstimationResponse, ValidatorAPIError> {
self.post_validator_api(
&[
routes::API_VERSION,
routes::STATUS_ROUTES,
+1 -1
View File
@@ -10,7 +10,7 @@ bip39 = "1.0.1"
bs58 = "0.4"
comfy-table = "6.0.0"
cfg-if = "1.0.0"
clap = { version = "4.0", features = ["derive"] }
clap = { version = "3.2", features = ["derive"] }
handlebars = "3.0.1"
humantime-serde = "1.0"
k256 = { version = "0.10", features = ["ecdsa", "sha256"] }
+1 -1
View File
@@ -32,7 +32,7 @@ pub struct ClientArgs {
pub fn get_network_details(args: &ClientArgs) -> Result<NymNetworkDetails, ContextError> {
// let the network defaults crate handle setting up the env vars if the file arg is set, otherwise
// it will default to what is already in env vars, falling back to mainnet
setup_env(args.config_env_file.as_ref());
setup_env(args.config_env_file.clone());
// override the env vars with user supplied arguments, if set
if let Some(nymd_url) = args.nymd_url.as_ref() {
+3 -3
View File
@@ -6,6 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = { version = "4.0", features = ["derive"] }
clap_complete = "4.0"
clap_complete_fig = "4.0"
clap = { version = "3.2", features = ["derive"] }
clap_complete = "3.2"
clap_complete_fig = "3.2"
+3 -3
View File
@@ -1,5 +1,5 @@
use clap::builder::Command;
use clap::clap_derive::ValueEnum;
use clap::clap_derive::ArgEnum;
use clap::Args;
use clap_complete::generator::generate;
use clap_complete::Shell as ClapShell;
@@ -14,7 +14,7 @@ pub fn fig_generate(command: &mut Command, name: &str) {
)
}
#[derive(ValueEnum, Copy, Clone)]
#[derive(ArgEnum, Copy, Clone)]
pub enum Shell {
Bash,
Elvish,
@@ -25,7 +25,7 @@ pub enum Shell {
#[derive(Args, Copy, Clone)]
pub struct ArgShell {
#[clap(value_enum, value_name = "SHELL")]
#[clap(arg_enum, value_name = "SHELL")]
shell: Shell,
}
+4 -5
View File
@@ -118,14 +118,13 @@ pub trait NymConfig: Default + Serialize + DeserializeOwned {
}
}
// this function is only used for parsing values from the network defaults and thus the "expect" there are fine
pub fn parse_urls(raw: &str) -> Vec<url::Url> {
pub fn parse_validators(raw: &str) -> Vec<url::Url> {
raw.split(',')
.map(|raw_url| {
raw_url
.map(|raw_validator| {
raw_validator
.trim()
.parse()
.expect("one of the provided nym api urls is invalid")
.expect("one of the provided validator api urls is invalid")
})
.collect()
}
@@ -56,6 +56,7 @@ impl Family {
self.proxy.as_ref()
}
#[allow(dead_code)]
pub fn label(&self) -> &str {
&self.label
}
@@ -7,7 +7,6 @@ pub use ed25519_dalek::{Verifier, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATUR
use nymsphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH};
use pemstore::traits::{PemStorableKey, PemStorableKeyPair};
use std::fmt::{self, Display, Formatter};
use std::str::FromStr;
use thiserror::Error;
#[cfg(feature = "rand")]
@@ -142,14 +141,6 @@ impl PublicKey {
}
}
impl FromStr for PublicKey {
type Err = Ed25519RecoveryError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
PublicKey::from_base58_string(s)
}
}
#[cfg(feature = "serde")]
impl Serialize for PublicKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+1 -1
View File
@@ -289,7 +289,7 @@ impl ValidatorDetails {
}
}
pub fn setup_env(config_env_file: Option<&PathBuf>) {
pub fn setup_env(config_env_file: Option<PathBuf>) {
match std::env::var(var_names::CONFIGURED) {
// if the configuration is not already set in the env vars
Err(std::env::VarError::NotPresent) => {
@@ -10,7 +10,6 @@ use nymsphinx_types::Destination;
use serde::de::{Error as SerdeError, Unexpected, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt::{self, Formatter};
use std::str::FromStr;
use thiserror::Error;
// Not entirely sure whether this is the correct place for those, but let's see how it's going
@@ -226,14 +225,6 @@ impl std::fmt::Display for Recipient {
}
}
impl FromStr for Recipient {
type Err = RecipientFormattingError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Recipient::try_from_base58_string(s)
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -208,11 +208,6 @@ impl Fragment {
}
}
/// Gets the size of payload contained in this `Fragment`.
pub fn payload_size(&self) -> usize {
self.payload.len()
}
/// Extracts id of this `Fragment`.
pub fn id(&self) -> i32 {
self.header.id
File diff suppressed because it is too large Load Diff
@@ -1,12 +1,12 @@
{
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.5",
"@nomiclabs/hardhat-etherscan": "^3.1.0",
"@nomiclabs/hardhat-etherscan": "^3.0.3",
"@nomiclabs/hardhat-waffle": "^2.0.3",
"chai": "^4.3.6",
"ethereum-waffle": "^3.4.4",
"ethers": "^5.6.1",
"hardhat": "^2.11.2",
"hardhat": "^2.9.2",
"solidity-coverage": "^0.7.20"
},
"dependencies": {
File diff suppressed because it is too large Load Diff
@@ -16,7 +16,7 @@
},
"dependencies": {
"@types/node": "^14.14.22",
"nodemon": "^2.0.20",
"nodemon": "^2.0.7",
"@nymproject/nym-validator-client" : "0.18.0",
"save-dev": "0.0.1-security",
"tasktimer": "^3.0.0",
+1 -4
View File
@@ -7,7 +7,7 @@ edition = "2021"
[dependencies]
chrono = { version = "0.4.19", features = ["serde"] }
clap = { version = "4.0", features = ["cargo", "derive"] }
clap = { version = "3.2", features = ["cargo", "derive"] }
humantime-serde = "1.0"
isocountry = "0.3.2"
itertools = "0.10.3"
@@ -25,9 +25,6 @@ thiserror = "1.0.29"
tokio = {version = "1.21.2", features = ["full"] }
maxminddb = "0.23.0"
dotenv = "0.15.0"
rand = "0.8.5"
rand_seeder = "0.2.3"
rand_pcg = "0.3.1"
mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet-contract" }
contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" }
+30 -2
View File
@@ -8,7 +8,7 @@ use dotenv::dotenv;
use log::info;
use logging::setup_logging;
use network_defaults::setup_env;
use task::{wait_for_signal, TaskManager};
use task::TaskManager;
mod buy_terms;
pub(crate) mod cache;
@@ -35,7 +35,7 @@ async fn main() {
dotenv().ok();
setup_logging();
let args = commands::Cli::parse();
setup_env(args.config_env_file.as_ref());
setup_env(args.config_env_file);
let mut explorer_api = ExplorerApi::new();
explorer_api.run().await;
}
@@ -88,3 +88,31 @@ impl ExplorerApi {
log::info!("Stopping explorer API");
}
}
#[cfg(unix)]
async fn wait_for_signal() {
use tokio::signal::unix::{signal, SignalKind};
let mut sigterm = signal(SignalKind::terminate()).expect("Failed to setup SIGTERM channel");
let mut sigquit = signal(SignalKind::quit()).expect("Failed to setup SIGQUIT channel");
tokio::select! {
_ = tokio::signal::ctrl_c() => {
log::info!("Received SIGINT");
},
_ = sigterm.recv() => {
log::info!("Received SIGTERM");
}
_ = sigquit.recv() => {
log::info!("Received SIGQUIT");
}
}
}
#[cfg(not(unix))]
async fn wait_for_signal() {
tokio::select! {
_ = tokio::signal::ctrl_c() => {
log::info!("Received SIGINT");
},
}
}
-1
View File
@@ -40,7 +40,6 @@ pub(crate) struct PrettyDetailedMixNodeBond {
pub estimated_delegators_apy: f64,
pub operating_cost: Coin,
pub profit_margin_percent: Percent,
pub family_id: Option<u16>,
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)]
-1
View File
@@ -6,7 +6,6 @@ use std::time::Duration;
pub(crate) mod http;
pub(crate) mod location;
pub(crate) mod models;
pub(crate) mod utils;
pub(crate) const CACHE_REFRESH_RATE: Duration = Duration::from_secs(30);
pub(crate) const CACHE_ENTRY_TTL: Duration = Duration::from_secs(60);
-4
View File
@@ -13,7 +13,6 @@ use tokio::sync::{RwLock, RwLockReadGuard};
use crate::helpers::best_effort_small_dec_to_f64;
use validator_client::models::MixNodeBondAnnotated;
use super::utils::family_numerical_id;
use crate::mix_node::models::{MixnodeStatus, PrettyDetailedMixNodeBond};
use crate::mix_nodes::location::{Location, LocationCache, LocationCacheItem};
use crate::mix_nodes::CACHE_ENTRY_TTL;
@@ -141,8 +140,6 @@ impl ThreadsafeMixNodesCache {
let denom = &node.mixnode_details.original_pledge().denom;
let rewarding_info = &node.mixnode_details.rewarding_details;
let family_id = node.family.as_ref().map(family_numerical_id);
PrettyDetailedMixNodeBond {
mix_id,
location: location.and_then(|l| l.location.clone()),
@@ -160,7 +157,6 @@ impl ThreadsafeMixNodesCache {
estimated_delegators_apy: best_effort_small_dec_to_f64(node.estimated_delegators_apy),
operating_cost: rewarding_info.cost_params.interval_operating_cost.clone(),
profit_margin_percent: rewarding_info.cost_params.profit_margin_percent,
family_id,
}
}
-13
View File
@@ -1,15 +1,9 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use mixnet_contract_common::families::FamilyHead;
use rand::Rng;
use rand_pcg::Pcg64;
use rand_seeder::Seeder;
use crate::mix_nodes::location::GeoLocation;
use isocountry::CountryCode;
#[allow(dead_code)]
pub(crate) fn map_2_letter_to_3_letter_country_code(geo: &GeoLocation) -> String {
match CountryCode::for_alpha2(&geo.country_code) {
Ok(three_letter_country_code) => three_letter_country_code.alpha3().to_string(),
@@ -22,10 +16,3 @@ pub(crate) fn map_2_letter_to_3_letter_country_code(geo: &GeoLocation) -> String
}
}
}
// We don't need numerical IDs anywhere, so to avoid modifying the contract storage again and
// since this is for explorer ergonomics, it will generate a deterministic random u16 based on the family Identity.
pub(crate) fn family_numerical_id(fh: &FamilyHead) -> u16 {
let mut rng: Pcg64 = Seeder::from(fh.identity()).make_rng();
rng.gen()
}
+1 -6
View File
@@ -4,8 +4,6 @@ import Select, { SelectChangeEvent } from '@mui/material/Select';
import { Filters } from './Filters/Filters';
import { useIsMobile } from '../hooks/useIsMobile';
const fieldsHeight = '42.25px';
type TableToolBarProps = {
onChangeSearch: (arg: string) => void;
onChangePageSize: (event: SelectChangeEvent<string>) => void;
@@ -37,7 +35,7 @@ export const TableToolbar: React.FC<TableToolBarProps> = ({
}}
>
<Box sx={{ display: 'flex', flexDirection: isMobile ? 'column-reverse' : 'row', alignItems: 'middle' }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between', height: fieldsHeight }}>
<Box sx={{ display: 'flex', justifyContent: 'space-between' }}>
{childrenBefore}
<Select
labelId="simple-select-label"
@@ -67,9 +65,6 @@ export const TableToolbar: React.FC<TableToolBarProps> = ({
sx={{
width: isMobile ? '100%' : 200,
marginBottom: isMobile ? 2 : 0,
'& > :not(style)': {
height: fieldsHeight,
},
}}
value={searchTerm}
data-testid="search-box"
+9 -5
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-gateway"
version = "1.1.4"
version = "1.1.3"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
@@ -19,14 +19,13 @@ anyhow = "1.0.53"
async-trait = { version = "0.1.51" }
bip39 = "1.0.1"
bs58 = "0.4.0"
clap = { version = "4.0", features = ["cargo", "derive"] }
clap = { version = "3.2", features = ["cargo", "derive"] }
colored = "2.0"
dashmap = "4.0"
dirs = "4.0"
dotenv = "0.15.0"
futures = "0.3"
humantime-serde = "1.0.1"
lazy_static = "1.4.0"
log = "0.4"
once_cell = "1.7.2"
pretty_env_logger = "0.4"
@@ -52,7 +51,6 @@ tokio-util = { version = "0.7.3", features = ["codec"] }
url = { version = "2.2", features = ["serde"] }
# internal
build-information = { path = "../common/build-information" }
coconut-interface = { path = "../common/coconut-interface", optional = true }
credentials = { path = "../common/credentials" }
config = { path = "../common/config" }
@@ -87,4 +85,10 @@ sqlx = { version = "0.5", features = [
"sqlite",
"macros",
"migrate",
] }
] }
vergen = { version = "5", default-features = false, features = [
"build",
"git",
"rustc",
"cargo",
] }
+3
View File
@@ -1,5 +1,6 @@
use sqlx::{Connection, SqliteConnection};
use std::env;
use vergen::{vergen, Config};
#[tokio::main]
async fn main() {
@@ -22,4 +23,6 @@ async fn main() {
// for some strange reason we need to add a leading `/` to the windows path even though it's
// not a valid windows path... but hey, it works...
println!("cargo:rustc-env=DATABASE_URL=sqlite:///{}", &database_path);
vergen(Config::default()).expect("failed to extract build metadata")
}
+18 -27
View File
@@ -1,4 +1,4 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{
@@ -8,9 +8,6 @@ use crate::{
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::{encryption, identity};
use std::net::IpAddr;
use std::path::PathBuf;
use validator_client::nymd;
#[derive(Args, Clone)]
pub struct Init {
@@ -20,11 +17,11 @@ pub struct Init {
/// The custom host on which the gateway will be running for receiving sphinx packets
#[clap(long)]
host: IpAddr,
host: String,
/// The wallet address you will use to bond this gateway, e.g. nymt1z9egw0knv47nmur0p8vk4rcx59h9gg4zuxrrr9
#[clap(long)]
wallet_address: nymd::AccountId,
wallet_address: String,
/// The port on which the gateway will be listening for sphinx packets
#[clap(long)]
@@ -36,27 +33,23 @@ pub struct Init {
/// The host that will be reported to the directory server
#[clap(long)]
// TODO: could this be changed to `Option<url::Url>`?
announce_host: Option<String>,
/// Path to sqlite database containing all gateway persistent data
#[clap(long)]
datastore: Option<PathBuf>,
datastore: Option<String>,
/// Comma separated list of endpoints of nym APIs
#[clap(long, alias = "validator_apis", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
#[clap(long)]
nym_apis: Option<String>,
/// Comma separated list of endpoints of the validator
#[cfg(feature = "coconut")]
#[clap(long, alias = "validators", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nymd_validators: Option<Vec<url::Url>>,
#[clap(long)]
validators: Option<String>,
/// Cosmos wallet mnemonic needed for double spending protection
#[clap(long)]
mnemonic: Option<bip39::Mnemonic>,
mnemonic: Option<String>,
/// Set this gateway to work only with coconut credentials; that would disallow clients to
/// bypass bandwidth credential requirement
@@ -70,7 +63,7 @@ pub struct Init {
/// URL where a statistics aggregator is running. The default value is a Nym aggregator server
#[clap(long)]
statistics_service_url: Option<url::Url>,
statistics_service_url: Option<String>,
}
impl From<Init> for OverrideConfig {
@@ -83,15 +76,14 @@ impl From<Init> for OverrideConfig {
datastore: init_config.datastore,
announce_host: init_config.announce_host,
nym_apis: init_config.nym_apis,
validators: init_config.validators,
mnemonic: init_config.mnemonic,
#[cfg(feature = "coconut")]
only_coconut_credentials: init_config.only_coconut_credentials,
enabled_statistics: init_config.enabled_statistics,
statistics_service_url: init_config.statistics_service_url,
#[cfg(feature = "coconut")]
nymd_validators: init_config.nymd_validators,
#[cfg(feature = "coconut")]
only_coconut_credentials: init_config.only_coconut_credentials,
}
}
}
@@ -167,19 +159,18 @@ mod tests {
async fn create_gateway_with_in_mem_storage() {
let args = Init {
id: "foo-id".to_string(),
host: "1.1.1.1".parse().unwrap(),
wallet_address: "n1z9egw0knv47nmur0p8vk4rcx59h9gg4zjx9ede".parse().unwrap(),
host: "foo-host".to_string(),
wallet_address: "n1z9egw0knv47nmur0p8vk4rcx59h9gg4zjx9ede".to_string(),
mix_port: Some(42),
clients_port: Some(43),
announce_host: Some("foo-announce-host".to_string()),
datastore: Some("/foo-datastore".parse().unwrap()),
datastore: Some("foo-datastore".to_string()),
nym_apis: None,
validators: None,
mnemonic: None,
statistics_service_url: None,
enabled_statistics: None,
#[cfg(feature = "coconut")]
nymd_validators: None,
#[cfg(feature = "coconut")]
only_coconut_credentials: false,
};
std::env::set_var(BECH32_PREFIX, "n");
+37 -34
View File
@@ -1,20 +1,19 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::{process, str::FromStr};
use crate::{config::Config, Cli};
use clap::CommandFactory;
use clap::Subcommand;
use colored::Colorize;
use completions::{fig_generate, ArgShell};
use config::parse_validators;
use crypto::bech32_address_validation;
use network_defaults::mainnet::read_var_if_not_default;
use network_defaults::var_names::{
API_VALIDATOR, BECH32_PREFIX, CONFIGURED, STATISTICS_SERVICE_DOMAIN_ADDRESS,
API_VALIDATOR, BECH32_PREFIX, CONFIGURED, NYMD_VALIDATOR, STATISTICS_SERVICE_DOMAIN_ADDRESS,
};
use std::net::IpAddr;
use std::path::PathBuf;
use std::process;
use validator_client::nymd::{self};
pub(crate) mod init;
pub(crate) mod node_details;
@@ -48,19 +47,18 @@ pub(crate) enum Commands {
// Configuration that can be overridden.
pub(crate) struct OverrideConfig {
host: Option<IpAddr>,
wallet_address: Option<nymd::AccountId>,
host: Option<String>,
wallet_address: Option<String>,
mix_port: Option<u16>,
clients_port: Option<u16>,
datastore: Option<PathBuf>,
datastore: Option<String>,
announce_host: Option<String>,
enabled_statistics: Option<bool>,
statistics_service_url: Option<url::Url>,
nym_apis: Option<Vec<url::Url>>,
mnemonic: Option<bip39::Mnemonic>,
statistics_service_url: Option<String>,
nym_apis: Option<String>,
validators: Option<String>,
mnemonic: Option<String>,
#[cfg(feature = "coconut")]
nymd_validators: Option<Vec<url::Url>>,
#[cfg(feature = "coconut")]
only_coconut_credentials: bool,
}
@@ -74,8 +72,8 @@ pub(crate) async fn execute(args: Cli) {
Commands::Run(m) => run::execute(m).await,
Commands::Sign(m) => sign::execute(m),
Commands::Upgrade(m) => upgrade::execute(m).await,
Commands::Completions(s) => s.generate(&mut crate::Cli::command(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::command(), bin_name),
Commands::Completions(s) => s.generate(&mut crate::Cli::into_app(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::into_app(), bin_name),
}
}
@@ -105,8 +103,12 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
config = config.with_enabled_statistics(enabled_statistics);
}
if let Some(url) = args.statistics_service_url {
config = config.with_custom_statistics_service_url(url);
if let Some(raw_url) = args.statistics_service_url {
config = config.with_custom_statistics_service_url(
raw_url
.parse()
.expect("the provided statistics service url is invalid!"),
);
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(raw_url) = read_var_if_not_default(STATISTICS_SERVICE_DOMAIN_ADDRESS) {
config = config.with_custom_statistics_service_url(
@@ -117,18 +119,26 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
}
}
if let Some(nym_apis) = args.nym_apis {
config = config.with_custom_nym_apis(nym_apis);
if let Some(raw_validators) = args.nym_apis {
config = config.with_custom_nym_apis(parse_validators(&raw_validators));
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(raw_validators) = read_var_if_not_default(API_VALIDATOR) {
config = config.with_custom_nym_apis(::config::parse_urls(&raw_validators))
config = config.with_custom_nym_apis(::config::parse_validators(&raw_validators))
}
}
if let Some(ref raw_validators) = args.validators {
config = config.with_custom_validator_nymd(parse_validators(raw_validators));
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(raw_validators) = read_var_if_not_default(NYMD_VALIDATOR) {
config = config.with_custom_validator_nymd(::config::parse_validators(&raw_validators))
}
}
if let Some(wallet_address) = args.wallet_address {
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(wallet_address.as_ref());
config = config.with_wallet_address(wallet_address);
let trimmed = wallet_address.trim();
validate_bech32_address_or_exit(trimmed);
config = config.with_wallet_address(trimmed);
}
if let Some(datastore_path) = args.datastore {
@@ -136,20 +146,13 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi
}
if let Some(cosmos_mnemonic) = args.mnemonic {
config = config.with_cosmos_mnemonic(cosmos_mnemonic);
config = config.with_cosmos_mnemonic(
bip39::Mnemonic::from_str(&cosmos_mnemonic).expect("Provided mnemonic is invalid"),
);
}
#[cfg(feature = "coconut")]
{
use network_defaults::var_names::NYMD_VALIDATOR;
if let Some(nymd_validators) = args.nymd_validators {
config = config.with_custom_validator_nymd(nymd_validators);
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(raw_validators) = read_var_if_not_default(NYMD_VALIDATOR) {
config = config.with_custom_validator_nymd(::config::parse_urls(&raw_validators))
}
}
config = config.with_only_coconut_credentials(args.only_coconut_credentials);
}
+15 -23
View File
@@ -1,4 +1,4 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::{
@@ -8,9 +8,6 @@ use crate::{
use clap::Args;
use config::NymConfig;
use log::*;
use std::net::IpAddr;
use std::path::PathBuf;
use validator_client::nymd;
#[derive(Args, Clone)]
pub struct Run {
@@ -20,11 +17,11 @@ pub struct Run {
/// The custom host on which the gateway will be running for receiving sphinx packets
#[clap(long)]
host: Option<IpAddr>,
host: Option<String>,
/// The wallet address you will use to bond this gateway, e.g. nymt1z9egw0knv47nmur0p8vk4rcx59h9gg4zuxrrr9
#[clap(long)]
wallet_address: Option<nymd::AccountId>,
wallet_address: Option<String>,
/// The port on which the gateway will be listening for sphinx packets
#[clap(long)]
@@ -36,27 +33,23 @@ pub struct Run {
/// The host that will be reported to the directory server
#[clap(long)]
// TODO: could this be changed to `Option<url::Url>`?
announce_host: Option<String>,
/// Path to sqlite database containing all gateway persistent data
#[clap(long)]
datastore: Option<PathBuf>,
datastore: Option<String>,
/// Comma separated list of endpoints of nym APIs
#[clap(long, alias = "validator_apis", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nym_apis: Option<Vec<url::Url>>,
/// Comma separated list of endpoints of the nym APIs
#[clap(long)]
nym_apis: Option<String>,
/// Comma separated list of endpoints of the validator
#[cfg(feature = "coconut")]
#[clap(long, alias = "validators", value_delimiter = ',')]
// the alias here is included for backwards compatibility (1.1.4 and before)
nymd_validators: Option<Vec<url::Url>>,
#[clap(long)]
validators: Option<String>,
/// Cosmos wallet mnemonic
#[clap(long)]
mnemonic: Option<bip39::Mnemonic>,
mnemonic: Option<String>,
/// Set this gateway to work only with coconut credentials; that would disallow clients to
/// bypass bandwidth credential requirement
@@ -70,7 +63,7 @@ pub struct Run {
/// URL where a statistics aggregator is running. The default value is a Nym aggregator server
#[clap(long)]
statistics_service_url: Option<url::Url>,
statistics_service_url: Option<String>,
}
impl From<Run> for OverrideConfig {
@@ -83,15 +76,14 @@ impl From<Run> for OverrideConfig {
datastore: run_config.datastore,
announce_host: run_config.announce_host,
nym_apis: run_config.nym_apis,
validators: run_config.validators,
mnemonic: run_config.mnemonic,
#[cfg(feature = "coconut")]
only_coconut_credentials: run_config.only_coconut_credentials,
enabled_statistics: run_config.enabled_statistics,
statistics_service_url: run_config.statistics_service_url,
#[cfg(feature = "coconut")]
nymd_validators: run_config.nymd_validators,
#[cfg(feature = "coconut")]
only_coconut_credentials: run_config.only_coconut_credentials,
}
}
}
+15 -14
View File
@@ -1,9 +1,8 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::commands::validate_bech32_address_or_exit;
use crate::{
commands::version_check,
commands::{validate_bech32_address_or_exit, version_check},
config::{persistence::pathfinder::GatewayPathfinder, Config},
};
use anyhow::{anyhow, Result};
@@ -11,10 +10,9 @@ use clap::{ArgGroup, Args};
use config::NymConfig;
use crypto::asymmetric::identity;
use log::error;
use validator_client::nymd;
#[derive(Args, Clone)]
#[clap(group(ArgGroup::new("sign").required(true).args(&["wallet_address", "text"])))]
#[clap(group(ArgGroup::new("sign").required(true).args(&["address", "text"])))]
pub struct Sign {
/// The id of the mixnode you want to sign with
#[clap(long)]
@@ -22,7 +20,7 @@ pub struct Sign {
/// Signs your blockchain address with your identity key
#[clap(long)]
wallet_address: Option<nymd::AccountId>,
address: Option<String>,
/// Signs an arbitrary piece of text with your identity key
#[clap(long)]
@@ -31,7 +29,7 @@ pub struct Sign {
enum SignedTarget {
Text(String),
Address(nymd::AccountId),
Address(String),
}
impl TryFrom<Sign> for SignedTarget {
@@ -40,7 +38,7 @@ impl TryFrom<Sign> for SignedTarget {
fn try_from(args: Sign) -> Result<Self, Self::Error> {
if let Some(text) = args.text {
Ok(SignedTarget::Text(text))
} else if let Some(address) = args.wallet_address {
} else if let Some(address) = args.address {
Ok(SignedTarget::Address(address))
} else {
// This is unreachable, and hopefully clap will support it explicitly by outputting an
@@ -60,12 +58,15 @@ pub fn load_identity_keys(pathfinder: &GatewayPathfinder) -> identity::KeyPair {
identity_keypair
}
fn print_signed_address(private_key: &identity::PrivateKey, wallet_address: nymd::AccountId) {
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(wallet_address.as_ref());
fn print_signed_address(private_key: &identity::PrivateKey, raw_address: &str) {
let trimmed = raw_address.trim();
validate_bech32_address_or_exit(trimmed);
let signature = private_key.sign_text(trimmed);
let signature = private_key.sign_text(wallet_address.as_ref());
println!("The base58-encoded signature on '{wallet_address}' is: {signature}",);
println!(
"The base58-encoded signature on '{}' is: {}",
trimmed, signature
);
}
fn print_signed_text(private_key: &identity::PrivateKey, text: &str) {
@@ -112,6 +113,6 @@ pub fn execute(args: &Sign) {
match signed_target {
SignedTarget::Text(text) => print_signed_text(identity_keypair.private_key(), &text),
SignedTarget::Address(addr) => print_signed_address(identity_keypair.private_key(), addr),
SignedTarget::Address(addr) => print_signed_address(identity_keypair.private_key(), &addr),
}
}
+1 -1
View File
@@ -103,7 +103,7 @@ fn minor_0_12_upgrade(
print_start_upgrade(config_version, &to_version);
let upgraded_config = config.with_custom_version(to_version.to_string());
let upgraded_config = config.with_custom_version(to_version.to_string().as_ref());
upgraded_config.save_to_file(None).unwrap_or_else(|err| {
eprintln!("failed to overwrite config file! - {err}");
+21 -15
View File
@@ -4,6 +4,7 @@
use crate::config::template::config_template;
use config::defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
use config::NymConfig;
use log::error;
use network_defaults::mainnet::{API_VALIDATOR, NYMD_VALIDATOR, STATISTICS_SERVICE_DOMAIN_ADDRESS};
use serde::{Deserialize, Serialize};
use std::net::IpAddr;
@@ -11,7 +12,6 @@ use std::path::PathBuf;
use std::str::FromStr;
use std::time::Duration;
use url::Url;
use validator_client::nymd;
pub mod persistence;
mod template;
@@ -149,7 +149,6 @@ impl Config {
self
}
#[cfg(feature = "coconut")]
pub fn with_custom_validator_nymd(mut self, validator_nymd_urls: Vec<Url>) -> Self {
self.gateway.validator_nymd_urls = validator_nymd_urls;
self
@@ -160,8 +159,16 @@ impl Config {
self
}
pub fn with_listening_address(mut self, listening_address: IpAddr) -> Self {
self.gateway.listening_address = listening_address;
pub fn with_listening_address<S: Into<String>>(mut self, listening_address: S) -> Self {
let listening_address_string = listening_address.into();
if let Ok(ip_addr) = listening_address_string.parse() {
self.gateway.listening_address = ip_addr;
} else {
error!(
"failed to change listening address. the provided value ({}) was invalid",
listening_address_string
);
}
self
}
@@ -185,18 +192,18 @@ impl Config {
self
}
pub fn with_custom_persistent_store(mut self, store_dir: PathBuf) -> Self {
self.gateway.persistent_storage = store_dir;
pub fn with_custom_persistent_store<S: Into<String>>(mut self, store_dir: S) -> Self {
self.gateway.persistent_storage = PathBuf::from(store_dir.into());
self
}
pub fn with_custom_version<S: Into<String>>(mut self, version: S) -> Self {
self.gateway.version = version.into();
pub fn with_custom_version(mut self, version: &str) -> Self {
self.gateway.version = version.to_string();
self
}
pub fn with_wallet_address(mut self, wallet_address: nymd::AccountId) -> Self {
self.gateway.wallet_address = Some(wallet_address);
pub fn with_wallet_address(mut self, wallet_address: &str) -> Self {
self.gateway.wallet_address = wallet_address.to_string();
self
}
@@ -295,8 +302,8 @@ impl Config {
&self.gateway.version
}
pub fn get_wallet_address(&self) -> Option<nymd::AccountId> {
self.gateway.wallet_address.clone()
pub fn get_wallet_address(&self) -> &str {
&self.gateway.wallet_address
}
}
@@ -370,8 +377,7 @@ pub struct Gateway {
persistent_storage: PathBuf,
/// The Cosmos wallet address that will control this gateway
// the only reason this is an Option is because of the lack of existence of a sane default value
wallet_address: Option<nymd::AccountId>,
wallet_address: String,
}
impl Gateway {
@@ -417,7 +423,7 @@ impl Default for Gateway {
cosmos_mnemonic: bip39::Mnemonic::from_str("exact antique hybrid width raise anchor puzzle degree fee quit long crack net vague hip despair write put useless civil mechanic broom music day").unwrap(),
nym_root_directory: Config::default_root_directory(),
persistent_storage: Default::default(),
wallet_address: None,
wallet_address: "nymXXXXXXXX".to_string(),
}
}
}
+44 -11
View File
@@ -1,28 +1,24 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use build_information::BinaryBuildInformation;
use clap::{crate_version, Parser};
use lazy_static::lazy_static;
use logging::setup_logging;
use network_defaults::setup_env;
use once_cell::sync::OnceCell;
mod commands;
mod config;
mod node;
lazy_static! {
pub static ref PRETTY_BUILD_INFORMATION: String =
BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print();
}
static LONG_VERSION: OnceCell<String> = OnceCell::new();
// Helper for passing LONG_VERSION to clap
fn pretty_build_info_static() -> &'static str {
&PRETTY_BUILD_INFORMATION
// Helper for passing LONG_ABOUT to clap
fn long_version_static() -> &'static str {
LONG_VERSION.get().expect("Failed to get long about text")
}
#[derive(Parser)]
#[clap(author = "Nymtech", version, about, long_version = pretty_build_info_static())]
#[clap(author = "Nymtech", version, about, long_version = long_version_static())]
struct Cli {
/// Path pointing to an env file that configures the gateway.
#[clap(short, long)]
@@ -36,9 +32,12 @@ struct Cli {
async fn main() {
setup_logging();
println!("{}", banner());
LONG_VERSION
.set(long_version())
.expect("Failed to set long about text");
let args = Cli::parse();
setup_env(args.config_env_file.as_ref());
setup_env(args.config_env_file.clone());
commands::execute(args).await;
}
@@ -59,6 +58,37 @@ fn banner() -> String {
)
}
fn long_version() -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
env!("VERGEN_BUILD_TIMESTAMP"),
"Build Version:",
env!("VERGEN_BUILD_SEMVER"),
"Commit SHA:",
env!("VERGEN_GIT_SHA"),
"Commit Date:",
env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
"Commit Branch:",
env!("VERGEN_GIT_BRANCH"),
"rustc Version:",
env!("VERGEN_RUSTC_SEMVER"),
"rustc Channel:",
env!("VERGEN_RUSTC_CHANNEL"),
"cargo Profile:",
env!("VERGEN_CARGO_PROFILE")
)
}
#[cfg(test)]
mod tests {
use super::*;
@@ -66,6 +96,9 @@ mod tests {
#[test]
fn verify_cli() {
LONG_VERSION
.set(long_version())
.expect("Failed to set long about text");
Cli::command().debug_assert();
}
}
+9 -15
View File
@@ -1,20 +1,19 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use self::storage::PersistentStorage;
use crate::commands::sign::load_identity_keys;
use crate::commands::validate_bech32_address_or_exit;
use crate::config::persistence::pathfinder::GatewayPathfinder;
use crate::config::Config;
use crate::node::client_handling::active_clients::ActiveClientsStore;
use crate::node::client_handling::websocket;
use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler;
use crate::node::statistics::collector::GatewayStatisticsCollector;
use crate::node::storage::Storage;
use colored::Colorize;
use crypto::asymmetric::{encryption, identity};
use log::*;
use mixnet_client::forwarder::{MixForwardingSender, PacketForwarder};
#[cfg(feature = "coconut")]
use network_defaults::NymNetworkDetails;
use rand::seq::SliceRandom;
use rand::thread_rng;
use statistics_common::collector::StatisticsSender;
@@ -22,15 +21,16 @@ use std::net::SocketAddr;
use std::process;
use std::sync::Arc;
use crate::config::persistence::pathfinder::GatewayPathfinder;
#[cfg(feature = "coconut")]
use crate::node::client_handling::websocket::connection_handler::coconut::CoconutVerifier;
#[cfg(feature = "coconut")]
use credentials::coconut::utils::obtain_aggregate_verification_key;
#[cfg(feature = "coconut")]
use network_defaults::NymNetworkDetails;
#[cfg(feature = "coconut")]
use validator_client::{Client, CoconutApiClient};
use self::storage::PersistentStorage;
pub(crate) mod client_handling;
pub(crate) mod mixnet_handling;
pub(crate) mod statistics;
@@ -117,15 +117,9 @@ where
fn generate_owner_signature(&self) -> String {
let pathfinder = GatewayPathfinder::new_from_config(&self.config);
let identity_keypair = load_identity_keys(&pathfinder);
let Some(address) = self.config.get_wallet_address() else {
let error_message = "Error: gateway hasn't set its wallet address".red();
println!("{error_message}");
println!("Exiting...");
process::exit(1);
};
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(address.as_ref());
let verification_code = identity_keypair.private_key().sign_text(address.as_ref());
let address = self.config.get_wallet_address();
validate_bech32_address_or_exit(address);
let verification_code = identity_keypair.private_key().sign_text(address);
verification_code
}
+5 -3
View File
@@ -3,7 +3,7 @@
[package]
name = "nym-mixnode"
version = "1.1.4"
version = "1.1.3"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
@@ -18,7 +18,7 @@ rust-version = "1.58.1"
[dependencies]
anyhow = "1.0.40"
bs58 = "0.4.0"
clap = { version = "4.0", features = ["cargo", "derive"] }
clap = { version = "3.2", features = ["cargo", "derive"] }
colored = "2.0"
cupid = "0.6.1"
dirs = "4.0"
@@ -38,7 +38,6 @@ toml = "0.5.8"
url = { version = "2.2", features = ["serde"] }
## internal
build-information = { path = "../common/build-information" }
config = { path="../common/config" }
crypto = { path="../common/crypto" }
completions = { path="../common/completions" }
@@ -58,3 +57,6 @@ tokio = { version="1.21.2", features = ["rt-multi-thread", "net", "signal", "tes
nymsphinx-types = { path = "../common/nymsphinx/types" }
nymsphinx-params = { path = "../common/nymsphinx/params" }
[build-dependencies]
vergen = { version = "5", default-features = false, features = ["build", "git", "rustc", "cargo"] }
+8
View File
@@ -0,0 +1,8 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use vergen::{vergen, Config};
fn main() {
vergen(Config::default()).expect("failed to extract build metadata")
}
+24 -46
View File
@@ -1,6 +1,3 @@
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::config::Config;
use crate::node::node_description::NodeDescription;
use clap::Args;
@@ -14,32 +11,9 @@ pub(crate) struct Describe {
/// The id of the mixnode you want to describe
#[clap(long)]
id: String,
/// Human readable name of this node
#[clap(long)]
name: Option<String>,
/// Description of this node
#[clap(long)]
description: Option<String>,
/// Link associated with this node, for example `https://mixnode.yourdomain.com`
#[clap(long)]
link: Option<String>,
/// Physical location of this node, for example `City: London, Country: UK`
#[clap(long)]
location: Option<String>,
}
fn read_user_input() -> String {
io::stdout().flush().unwrap();
let mut buf = String::new();
io::stdin().read_line(&mut buf).unwrap();
buf.trim().to_string()
}
pub(crate) fn execute(args: Describe) {
pub(crate) fn execute(args: &Describe) {
// ensure that the mixnode has in fact been initialized
match Config::load_from_file(Some(&args.id)) {
Ok(cfg) => cfg,
@@ -49,29 +23,33 @@ pub(crate) fn execute(args: Describe) {
}
};
// get input from the user
print!("name: ");
io::stdout().flush().unwrap();
let mut name_buf = String::new();
io::stdin().read_line(&mut name_buf).unwrap();
let name = name_buf.trim().to_string();
print!("description: ");
io::stdout().flush().unwrap();
let mut desc_buf = String::new();
io::stdin().read_line(&mut desc_buf).unwrap();
let description = desc_buf.trim().to_string();
let example_url = "https://mixnode.yourdomain.com".bright_cyan();
let example_location = "City: London, Country: UK";
// get input from the user if not provided via the arguments
let name = args.name.unwrap_or_else(|| {
print!("name: ");
read_user_input()
});
print!("link, e.g. {}: ", example_url);
io::stdout().flush().unwrap();
let mut link_buf = String::new();
io::stdin().read_line(&mut link_buf).unwrap();
let link = link_buf.trim().to_string();
let description = args.description.unwrap_or_else(|| {
print!("description: ");
read_user_input()
});
let link = args.link.unwrap_or_else(|| {
print!("link, e.g. {example_url}: ");
read_user_input()
});
let location = args.location.unwrap_or_else(|| {
print!("location, e.g. {example_location}: ");
read_user_input()
});
print!("location, e.g. {}: ", example_location);
io::stdout().flush().unwrap();
let mut location_buf = String::new();
io::stdin().read_line(&mut location_buf).unwrap();
let location = location_buf.trim().to_string();
let node_description = NodeDescription {
name,
+9 -11
View File
@@ -1,15 +1,14 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::OverrideConfig;
use crate::config::Config;
use crate::node::MixNode;
use crate::{commands::override_config, config::persistence::pathfinder::MixNodePathfinder};
use clap::Args;
use config::NymConfig;
use crypto::asymmetric::{encryption, identity};
use std::net::IpAddr;
use validator_client::nymd;
use super::OverrideConfig;
#[derive(Args, Clone)]
pub(crate) struct Init {
@@ -19,11 +18,11 @@ pub(crate) struct Init {
/// The host on which the mixnode will be running
#[clap(long)]
host: IpAddr,
host: String,
/// The wallet address you will use to bond this mixnode, e.g. nymt1z9egw0knv47nmur0p8vk4rcx59h9gg4zuxrrr9
#[clap(long)]
wallet_address: nymd::AccountId,
wallet_address: String,
/// The port on which the mixnode will be listening for mix packets
#[clap(long)]
@@ -41,10 +40,9 @@ pub(crate) struct Init {
#[clap(long)]
announce_host: Option<String>,
/// Comma separated list of nym-api endpoints of the validators
// the alias here is included for backwards compatibility (1.1.4 and before)
#[clap(long, alias = "validators", value_delimiter = ',')]
nym_apis: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the validators
#[clap(long)]
validators: Option<String>,
}
impl From<Init> for OverrideConfig {
@@ -57,7 +55,7 @@ impl From<Init> for OverrideConfig {
verloc_port: init_config.verloc_port,
http_api_port: init_config.http_api_port,
announce_host: init_config.announce_host,
nym_apis: init_config.nym_apis,
validators: init_config.validators,
}
}
}
+24 -22
View File
@@ -1,17 +1,19 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::process;
use crate::{config::Config, Cli};
use clap::CommandFactory;
use clap::Subcommand;
use colored::Colorize;
use completions::{fig_generate, ArgShell};
use config::defaults::mainnet::read_var_if_not_default;
use config::defaults::var_names::{API_VALIDATOR, BECH32_PREFIX, CONFIGURED};
use config::{
defaults::var_names::{API_VALIDATOR, BECH32_PREFIX, CONFIGURED},
parse_validators,
};
use crypto::bech32_address_validation;
use std::net::IpAddr;
use std::process;
use validator_client::nymd;
mod describe;
mod init;
@@ -50,27 +52,27 @@ pub(crate) enum Commands {
// Configuration that can be overridden.
struct OverrideConfig {
id: String,
host: Option<IpAddr>,
wallet_address: Option<nymd::AccountId>,
host: Option<String>,
wallet_address: Option<String>,
mix_port: Option<u16>,
verloc_port: Option<u16>,
http_api_port: Option<u16>,
announce_host: Option<String>,
nym_apis: Option<Vec<url::Url>>,
validators: Option<String>,
}
pub(crate) async fn execute(args: Cli) {
let bin_name = "nym-mixnode";
match args.command {
match &args.command {
Commands::Describe(m) => describe::execute(m),
Commands::Init(m) => init::execute(&m),
Commands::Run(m) => run::execute(&m).await,
Commands::Sign(m) => sign::execute(&m),
Commands::Upgrade(m) => upgrade::execute(&m),
Commands::NodeDetails(m) => node_details::execute(&m),
Commands::Completions(s) => s.generate(&mut crate::Cli::command(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::command(), bin_name),
Commands::Init(m) => init::execute(m),
Commands::Run(m) => run::execute(m).await,
Commands::Sign(m) => sign::execute(m),
Commands::Upgrade(m) => upgrade::execute(m),
Commands::NodeDetails(m) => node_details::execute(m),
Commands::Completions(s) => s.generate(&mut crate::Cli::into_app(), bin_name),
Commands::GenerateFigSpec => fig_generate(&mut crate::Cli::into_app(), bin_name),
}
}
@@ -93,11 +95,11 @@ fn override_config(mut config: Config, args: OverrideConfig) -> Config {
config = config.with_http_api_port(port);
}
if let Some(nym_apis) = args.nym_apis {
config = config.with_custom_nym_apis(nym_apis);
if let Some(ref raw_validators) = args.validators {
config = config.with_custom_nym_apis(parse_validators(raw_validators));
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(raw_validators) = read_var_if_not_default(API_VALIDATOR) {
config = config.with_custom_nym_apis(::config::parse_urls(&raw_validators))
config = config.with_custom_nym_apis(::config::parse_validators(&raw_validators))
}
}
@@ -108,10 +110,10 @@ fn override_config(mut config: Config, args: OverrideConfig) -> Config {
config = config.announce_address_from_listening_address()
}
if let Some(wallet_address) = args.wallet_address {
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(wallet_address.as_ref());
config = config.with_wallet_address(wallet_address);
if let Some(ref wallet_address) = args.wallet_address {
let trimmed = wallet_address.trim();
validate_bech32_address_or_exit(trimmed);
config = config.with_wallet_address(trimmed);
}
config
+8 -10
View File
@@ -1,14 +1,13 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::OverrideConfig;
use crate::commands::{override_config, version_check};
use crate::config::Config;
use crate::node::MixNode;
use clap::Args;
use config::NymConfig;
use std::net::IpAddr;
use validator_client::nymd;
use super::OverrideConfig;
#[derive(Args, Clone)]
pub(crate) struct Run {
@@ -18,11 +17,11 @@ pub(crate) struct Run {
/// The custom host on which the mixnode will be running
#[clap(long)]
host: Option<IpAddr>,
host: Option<String>,
/// The wallet address you will use to bond this mixnode, e.g. nymt1z9egw0knv47nmur0p8vk4rcx59h9gg4zuxrrr9
#[clap(long)]
wallet_address: Option<nymd::AccountId>,
wallet_address: Option<String>,
/// The port on which the mixnode will be listening for mix packets
#[clap(long)]
@@ -40,10 +39,9 @@ pub(crate) struct Run {
#[clap(long)]
announce_host: Option<String>,
/// Comma separated list of nym-api endpoints of the validators
// the alias here is included for backwards compatibility (1.1.4 and before)
#[clap(long, alias = "validators", value_delimiter = ',')]
nym_apis: Option<Vec<url::Url>>,
/// Comma separated list of rest endpoints of the validators
#[clap(long)]
validators: Option<String>,
}
impl From<Run> for OverrideConfig {
@@ -56,7 +54,7 @@ impl From<Run> for OverrideConfig {
verloc_port: run_config.verloc_port,
http_api_port: run_config.http_api_port,
announce_host: run_config.announce_host,
nym_apis: run_config.nym_apis,
validators: run_config.validators,
}
}
}
+15 -14
View File
@@ -1,4 +1,4 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::convert::TryFrom;
@@ -11,21 +11,19 @@ use clap::{ArgGroup, Args};
use config::NymConfig;
use crypto::asymmetric::identity;
use log::error;
use validator_client::nymd;
use super::version_check;
#[derive(Args, Clone)]
#[clap(group(ArgGroup::new("sign").required(true).args(&["wallet_address", "text"])))]
#[clap(group(ArgGroup::new("sign").required(true).args(&["address", "text"])))]
pub(crate) struct Sign {
/// The id of the mixnode you want to sign with
#[clap(long)]
id: String,
/// Signs your blockchain address with your identity key
// the alias here is included for backwards compatibility (1.1.4 and before)
#[clap(long, alias = "address")]
wallet_address: Option<nymd::AccountId>,
#[clap(long)]
address: Option<String>,
/// Signs an arbitrary piece of text with your identity key
#[clap(long)]
@@ -34,7 +32,7 @@ pub(crate) struct Sign {
enum SignedTarget {
Text(String),
Address(nymd::AccountId),
Address(String),
}
impl TryFrom<Sign> for SignedTarget {
@@ -43,7 +41,7 @@ impl TryFrom<Sign> for SignedTarget {
fn try_from(args: Sign) -> Result<Self, Self::Error> {
if let Some(text) = args.text {
Ok(SignedTarget::Text(text))
} else if let Some(address) = args.wallet_address {
} else if let Some(address) = args.address {
Ok(SignedTarget::Address(address))
} else {
// This is unreachable, and hopefully clap will support it explicitly by outputting an
@@ -54,12 +52,15 @@ impl TryFrom<Sign> for SignedTarget {
}
}
fn print_signed_address(private_key: &identity::PrivateKey, wallet_address: nymd::AccountId) {
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(wallet_address.as_ref());
fn print_signed_address(private_key: &identity::PrivateKey, raw_address: &str) {
let trimmed = raw_address.trim();
validate_bech32_address_or_exit(trimmed);
let signature = private_key.sign_text(trimmed);
let signature = private_key.sign_text(wallet_address.as_ref());
println!("The base58-encoded signature on '{wallet_address}' is: {signature}",);
println!(
"The base58-encoded signature on '{}' is: {}",
trimmed, signature
);
}
fn print_signed_text(private_key: &identity::PrivateKey, text: &str) {
@@ -106,6 +107,6 @@ pub(crate) fn execute(args: &Sign) {
match signed_target {
SignedTarget::Text(text) => print_signed_text(identity_keypair.private_key(), &text),
SignedTarget::Address(addr) => print_signed_address(identity_keypair.private_key(), addr),
SignedTarget::Address(addr) => print_signed_address(identity_keypair.private_key(), &addr),
}
}
+16 -10
View File
@@ -13,7 +13,6 @@ use std::path::PathBuf;
use std::str::FromStr;
use std::time::Duration;
use url::Url;
use validator_client::nymd;
pub mod persistence;
mod template;
@@ -161,8 +160,16 @@ impl Config {
self
}
pub fn with_listening_address(mut self, listening_address: IpAddr) -> Self {
self.mixnode.listening_address = listening_address;
pub fn with_listening_address<S: Into<String>>(mut self, listening_address: S) -> Self {
let listening_address_string = listening_address.into();
if let Ok(ip_addr) = listening_address_string.parse() {
self.mixnode.listening_address = ip_addr
} else {
error!(
"failed to change listening address. the provided value ({}) was invalid",
listening_address_string
)
}
self
}
@@ -196,8 +203,8 @@ impl Config {
self
}
pub fn with_wallet_address(mut self, wallet_address: nymd::AccountId) -> Self {
self.mixnode.wallet_address = Some(wallet_address);
pub fn with_wallet_address(mut self, wallet_address: &str) -> Self {
self.mixnode.wallet_address = wallet_address.to_string();
self
}
@@ -310,8 +317,8 @@ impl Config {
self.verloc.retry_timeout
}
pub fn get_wallet_address(&self) -> Option<nymd::AccountId> {
self.mixnode.wallet_address.clone()
pub fn get_wallet_address(&self) -> &str {
&self.mixnode.wallet_address
}
}
@@ -370,8 +377,7 @@ struct MixNode {
nym_root_directory: PathBuf,
/// The Cosmos wallet address that will control this mixnode
// the only reason this is an Option is because of the lack of existence of a sane default value
wallet_address: Option<nymd::AccountId>,
wallet_address: String,
}
impl MixNode {
@@ -408,7 +414,7 @@ impl Default for MixNode {
public_sphinx_key_file: Default::default(),
nym_api_urls: vec![Url::from_str(API_VALIDATOR).expect("Invalid default API URL")],
nym_root_directory: Config::default_root_directory(),
wallet_address: None,
wallet_address: "nymXXXXXXXX".to_string(),
}
}
}
+39 -10
View File
@@ -1,11 +1,10 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#[macro_use]
extern crate rocket;
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use ::config::defaults::setup_env;
use build_information::BinaryBuildInformation;
use clap::{crate_version, Parser};
use lazy_static::lazy_static;
use logging::setup_logging;
@@ -15,17 +14,16 @@ mod config;
mod node;
lazy_static! {
pub static ref PRETTY_BUILD_INFORMATION: String =
BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print();
pub static ref LONG_VERSION: String = long_version();
}
// Helper for passing LONG_VERSION to clap
fn pretty_build_info_static() -> &'static str {
&PRETTY_BUILD_INFORMATION
fn long_version_static() -> &'static str {
&LONG_VERSION
}
#[derive(Parser)]
#[clap(author = "Nymtech", version, about, long_version = pretty_build_info_static())]
#[clap(author = "Nymtech", version, about, long_version = long_version_static())]
struct Cli {
/// Path pointing to an env file that configures the mixnode.
#[clap(short, long)]
@@ -41,7 +39,7 @@ async fn main() {
println!("{}", banner());
let args = Cli::parse();
setup_env(args.config_env_file.as_ref());
setup_env(args.config_env_file.clone());
commands::execute(args).await;
}
@@ -62,6 +60,37 @@ fn banner() -> String {
)
}
fn long_version() -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
env!("VERGEN_BUILD_TIMESTAMP"),
"Build Version:",
env!("VERGEN_BUILD_SEMVER"),
"Commit SHA:",
env!("VERGEN_GIT_SHA"),
"Commit Date:",
env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
"Commit Branch:",
env!("VERGEN_GIT_BRANCH"),
"rustc Version:",
env!("VERGEN_RUSTC_SEMVER"),
"rustc Channel:",
env!("VERGEN_RUSTC_CHANNEL"),
"cargo Profile:",
env!("VERGEN_CARGO_PROFILE")
)
}
#[cfg(test)]
mod tests {
use super::*;
+4 -14
View File
@@ -18,7 +18,6 @@ use crate::node::node_description::NodeDescription;
use crate::node::node_statistics::SharedNodeStats;
use crate::node::packet_delayforwarder::{DelayForwarder, PacketDelayForwardSender};
use ::crypto::asymmetric::{encryption, identity};
use colored::Colorize;
use config::NymConfig;
use log::{error, info, warn};
use mixnode_common::verloc::{self, AtomicVerlocResult, VerlocMeasurer};
@@ -88,15 +87,9 @@ impl MixNode {
fn generate_owner_signature(&self) -> String {
let pathfinder = MixNodePathfinder::new_from_config(&self.config);
let identity_keypair = Self::load_identity_keys(&pathfinder);
let Some(address) = self.config.get_wallet_address() else {
let error_message = "Error: mixnode hasn't set its wallet address".red();
println!("{error_message}");
println!("Exiting...");
process::exit(1);
};
// perform extra validation to ensure we have correct prefix
validate_bech32_address_or_exit(address.as_ref());
let verification_code = identity_keypair.private_key().sign_text(address.as_ref());
let address = self.config.get_wallet_address();
validate_bech32_address_or_exit(address);
let verification_code = identity_keypair.private_key().sign_text(address);
verification_code
}
@@ -125,10 +118,7 @@ impl MixNode {
);
println!(
"You are bonding to wallet address: {}\n\n",
self.config
.get_wallet_address()
.map(|addr| addr.to_string())
.unwrap_or_else(|| "UNSPECIFIED".to_string())
self.config.get_wallet_address()
);
}
+9 -6
View File
@@ -2,8 +2,8 @@
# SPDX-License-Identifier: Apache-2.0
[package]
name = "nym-api"
version = "1.1.4"
name = "nym-validator-api"
version = "1.1.3"
authors = [
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
"Jędrzej Stuczyński <andrew@nymtech.net>",
@@ -17,15 +17,13 @@ rust-version = "1.56"
[dependencies]
async-trait = "0.1.52"
bs58 = {version = "0.4.0", optional = true }
bip39 = "1"
cfg-if = "1.0"
clap = { version = "4.0", features = ["cargo", "derive"] }
clap = { version = "3.2", features = ["cargo"] }
console-subscriber = { version = "0.1.1", optional = true } # validator-api needs to be built with RUSTFLAGS="--cfg tokio_unstable"
dirs = "4.0"
dotenv = "0.15.0"
futures = "0.3.24"
humantime-serde = "1.0"
lazy_static = "1.4.0"
log = "0.4.17"
pin-project = "1.0"
pretty_env_logger = "0.4.0"
@@ -65,7 +63,6 @@ rocket_okapi = { version = "0.8.0-rc.2", features = ["swagger"] }
schemars = { version = "0.8", features = ["preserve_order"] }
## internal
build-information = { path = "../common/build-information" }
coconut-bandwidth-contract-common = { path = "../common/cosmwasm-smart-contracts/coconut-bandwidth-contract" }
coconut-dkg-common = { path = "../common/cosmwasm-smart-contracts/coconut-dkg", optional = true }
coconut-interface = { path = "../common/coconut-interface", optional = true }
@@ -118,6 +115,12 @@ sqlx = { version = "0.6.2", features = [
"macros",
"migrate",
] }
vergen = { version = "7", default-features = false, features = [
"build",
"git",
"rustc",
"cargo",
] }
[dev-dependencies]
cw3 = "0.13.4"
+3
View File
@@ -1,5 +1,6 @@
use sqlx::{Connection, SqliteConnection};
use std::env;
use vergen::{vergen, Config};
#[tokio::main]
async fn main() {
@@ -22,4 +23,6 @@ async fn main() {
// for some strange reason we need to add a leading `/` to the windows path even though it's
// not a valid windows path... but hey, it works...
println!("cargo:rustc-env=DATABASE_URL=sqlite:///{}", &database_path);
vergen(Config::default()).expect("failed to extract build metadata")
}
+2
View File
@@ -446,6 +446,8 @@ impl Config {
self.network_monitor.credentials_database_path.clone()
}
// TODO: Remove if still unused
#[allow(dead_code)]
pub fn get_rewarding_enabled(&self) -> bool {
self.rewarding.enabled
}
+262 -141
View File
@@ -1,4 +1,4 @@
// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#[macro_use]
@@ -6,7 +6,6 @@ extern crate rocket;
use crate::config::Config;
use crate::contract_cache::ValidatorCacheRefresher;
use crate::epoch_operations::RewardedSetUpdater;
use crate::network_monitor::NetworkMonitorBuilder;
use crate::node_status_api::uptime_updater::HistoricalUptimeUpdater;
use crate::nymd_client::Client;
@@ -16,12 +15,9 @@ use ::config::defaults::setup_env;
use ::config::defaults::var_names::{CONFIGURED, MIXNET_CONTRACT_ADDRESS, MIX_DENOM};
use ::config::NymConfig;
use anyhow::Result;
use build_information::BinaryBuildInformation;
use clap::Parser;
use clap::{crate_version, App, Arg, ArgMatches};
use contract_cache::ValidatorCache;
use lazy_static::lazy_static;
use log::{info, warn};
use logging::setup_logging;
use node_status_api::NodeStatusCache;
use okapi::openapi3::OpenApi;
use rocket::fairing::AdHoc;
@@ -30,21 +26,27 @@ use rocket::{Ignite, Rocket};
use rocket_cors::{AllowedHeaders, AllowedOrigins, Cors};
use rocket_okapi::mount_endpoints_and_merged_docs;
use rocket_okapi::swagger_ui::make_swagger_ui;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::Arc;
use std::time::Duration;
use std::{fs, process};
use task::{wait_for_signal, TaskManager};
use task::TaskManager;
use tokio::sync::Notify;
use validator_client::nymd::{self, SigningNymdClient};
#[cfg(feature = "coconut")]
use url::Url;
use validator_client::nymd::SigningNymdClient;
use crate::epoch_operations::RewardedSetUpdater;
#[cfg(feature = "coconut")]
use coconut::{
comm::QueryCommunicationChannel,
dkg::controller::{init_keypair, DkgController},
InternalSignRequest,
};
use logging::setup_logging;
#[cfg(feature = "coconut")]
use rand::rngs::OsRng;
use validator_client::nymd::bip32::secp256k1::elliptic_curve::rand_core::OsRng;
pub(crate) mod config;
pub(crate) mod contract_cache;
@@ -58,92 +60,150 @@ mod swagger;
#[cfg(feature = "coconut")]
mod coconut;
lazy_static! {
pub static ref PRETTY_BUILD_INFORMATION: String =
BinaryBuildInformation::new(env!("CARGO_PKG_VERSION")).pretty_print();
const ID: &str = "id";
const CONFIG_ENV_FILE: &str = "config-env-file";
const MONITORING_ENABLED: &str = "enable-monitor";
const REWARDING_ENABLED: &str = "enable-rewarding";
const MIXNET_CONTRACT_ARG: &str = "mixnet-contract";
const MNEMONIC_ARG: &str = "mnemonic";
const WRITE_CONFIG_ARG: &str = "save-config";
const NYMD_VALIDATOR_ARG: &str = "nymd-validator";
const ENABLED_CREDENTIALS_MODE_ARG_NAME: &str = "enabled-credentials-mode";
#[cfg(feature = "coconut")]
const ANNOUNCE_ADDRESS: &str = "announce-address";
#[cfg(feature = "coconut")]
const COCONUT_ENABLED: &str = "enable-coconut";
const REWARDING_MONITOR_THRESHOLD_ARG: &str = "monitor-threshold";
const MIN_MIXNODE_RELIABILITY_ARG: &str = "min_mixnode_reliability";
const MIN_GATEWAY_RELIABILITY_ARG: &str = "min_gateway_reliability";
fn long_version() -> String {
format!(
r#"
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
{:<20}{}
"#,
"Build Timestamp:",
env!("VERGEN_BUILD_TIMESTAMP"),
"Build Version:",
env!("VERGEN_BUILD_SEMVER"),
"Commit SHA:",
env!("VERGEN_GIT_SHA"),
"Commit Date:",
env!("VERGEN_GIT_COMMIT_TIMESTAMP"),
"Commit Branch:",
env!("VERGEN_GIT_BRANCH"),
"rustc Version:",
env!("VERGEN_RUSTC_SEMVER"),
"rustc Channel:",
env!("VERGEN_RUSTC_CHANNEL"),
"cargo Profile:",
env!("VERGEN_CARGO_PROFILE")
)
}
// Helper for passing LONG_VERSION to clap
fn pretty_build_info_static() -> &'static str {
&PRETTY_BUILD_INFORMATION
}
fn parse_args() -> ArgMatches {
let build_details = long_version();
let base_app = App::new("Nym API")
.version(crate_version!())
.long_version(&*build_details)
.author("Nymtech")
.arg(
Arg::with_name(CONFIG_ENV_FILE)
.help("Path pointing to an env file that configures the Nym API")
.long(CONFIG_ENV_FILE)
.short('c')
.takes_value(true)
)
.arg(
Arg::with_name(ID)
.help("Id of the nym-api we want to run")
.long(ID)
.takes_value(true)
)
.arg(
Arg::with_name(MONITORING_ENABLED)
.help("specifies whether a network monitoring is enabled on this API")
.long(MONITORING_ENABLED)
.short('m')
)
.arg(
Arg::with_name(REWARDING_ENABLED)
.help("specifies whether a network rewarding is enabled on this API")
.long(REWARDING_ENABLED)
.short('r')
.requires_all(&[MONITORING_ENABLED, MNEMONIC_ARG])
)
.arg(
Arg::with_name(NYMD_VALIDATOR_ARG)
.help("Endpoint to nymd instance from which the monitor will grab nodes to test")
.long(NYMD_VALIDATOR_ARG)
.takes_value(true)
)
.arg(Arg::with_name(MIXNET_CONTRACT_ARG)
.long(MIXNET_CONTRACT_ARG)
.help("Address of the mixnet contract managing the network")
.takes_value(true),
)
.arg(Arg::with_name(MNEMONIC_ARG)
.long(MNEMONIC_ARG)
.help("Mnemonic of the network monitor used for rewarding operators")
.takes_value(true)
)
.arg(
Arg::with_name(WRITE_CONFIG_ARG)
.help("specifies whether a config file based on provided arguments should be saved to a file")
.long(WRITE_CONFIG_ARG)
.short('w')
)
.arg(
Arg::with_name(REWARDING_MONITOR_THRESHOLD_ARG)
.help("Specifies the minimum percentage of monitor test run data present in order to distribute rewards for given interval.")
.takes_value(true)
.long(REWARDING_MONITOR_THRESHOLD_ARG)
)
.arg(
Arg::with_name(MIN_MIXNODE_RELIABILITY_ARG)
.long(MIN_MIXNODE_RELIABILITY_ARG)
.help("Mixnodes with reliability lower the this get blacklisted by network monitor, get no traffic and cannot be selected into a rewarded set.")
.takes_value(true)
)
.arg(
Arg::with_name(MIN_GATEWAY_RELIABILITY_ARG)
.long(MIN_GATEWAY_RELIABILITY_ARG)
.help("Gateways with reliability lower the this get blacklisted by network monitor, get no traffic and cannot be selected into a rewarded set.")
.takes_value(true)
)
.arg(
Arg::with_name(ENABLED_CREDENTIALS_MODE_ARG_NAME)
.long(ENABLED_CREDENTIALS_MODE_ARG_NAME)
.help("Set this nym api to work in a enabled credentials that would attempt to use gateway with the bandwidth credential requirement")
);
// explicitly defined custom parser (as opposed to just using
// #[arg(value_parser = clap::value_parser!(u8).range(0..100))]
// for better error message
fn threshold_in_range(s: &str) -> Result<u8, String> {
let threshold: usize = s
.parse()
.map_err(|_| format!("`{s}` isn't a valid threshold number"))?;
if threshold > 100 {
Err(format!("{threshold} is not within the range 0-100"))
} else {
Ok(threshold as u8)
}
}
#[derive(Parser)]
#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)]
struct ApiArgs {
/// Path pointing to an env file that configures the Nym API.
#[clap(short, long)]
config_env_file: Option<std::path::PathBuf>,
/// Id of the nym-api we want to run
#[clap(long)]
id: Option<String>,
/// Specifies whether network monitoring is enabled on this API
#[clap(short = 'm', long)]
enable_monitor: bool,
/// Specifies whether network rewarding is enabled on this API
#[clap(short = 'r', long, requires = "enable_monitor", requires = "mnemonic")]
enable_rewarding: bool,
/// Endpoint to nymd instance from which the monitor will grab nodes to test
#[clap(long)]
nymd_validator: Option<url::Url>,
/// Address of the mixnet contract managing the network
#[clap(long)]
mixnet_contract: Option<nymd::AccountId>,
/// Mnemonic of the network monitor used for rewarding operators
// even though we're currently converting the mnemonic to string (and then back to the concrete type)
// at least we're getting immediate validation when passing the arguments
#[clap(long)]
mnemonic: Option<bip39::Mnemonic>,
/// Specifies whether a config file based on provided arguments should be saved to a file
#[clap(short = 'w', long)]
save_config: bool,
/// Specifies the minimum percentage of monitor test run data present in order to distribute rewards for given interval.
#[clap(long, value_parser = threshold_in_range)]
monitor_threshold: Option<u8>,
/// Mixnodes with reliability lower the this get blacklisted by network monitor, get no traffic and cannot be selected into a rewarded set.
#[clap(long, value_parser = threshold_in_range)]
min_mixnode_reliability: Option<u8>,
/// Gateways with reliability lower the this get blacklisted by network monitor, get no traffic and cannot be selected into a rewarded set.
#[clap(long, value_parser = threshold_in_range)]
min_gateway_reliability: Option<u8>,
/// Set this nym api to work in a enabled credentials that would attempt to use gateway with the bandwidth credential requirement
#[clap(long)]
enabled_credentials_mode: bool,
/// Announced address where coconut clients will connect.
#[cfg(feature = "coconut")]
#[clap(long)]
announce_address: Option<url::Url>,
/// Flag to indicate whether coconut signer authority is enabled on this API
#[cfg(feature = "coconut")]
#[clap(long, requires = "mnemonic", requires = "announce-address")]
enable_coconut: bool,
let base_app = base_app
.arg(
Arg::with_name(ANNOUNCE_ADDRESS)
.help("Announced address where coconut clients will connect.")
.long(ANNOUNCE_ADDRESS)
.takes_value(true),
)
.arg(
Arg::with_name(COCONUT_ENABLED)
.help("Flag to indicate whether coconut signer authority is enabled on this API")
.requires_all(&[MNEMONIC_ARG, ANNOUNCE_ADDRESS])
.long(COCONUT_ENABLED),
);
base_app.get_matches()
}
async fn wait_for_interrupt(mut shutdown: TaskManager) {
@@ -158,55 +218,122 @@ async fn wait_for_interrupt(mut shutdown: TaskManager) {
log::info!("Stopping nym API");
}
fn override_config(mut config: Config, args: ApiArgs) -> Config {
if let Some(id) = args.id {
fs::create_dir_all(Config::default_config_directory(Some(&id)))
#[cfg(unix)]
async fn wait_for_signal() {
use tokio::signal::unix::{signal, SignalKind};
let mut sigterm = signal(SignalKind::terminate()).expect("Failed to setup SIGTERM channel");
let mut sigquit = signal(SignalKind::quit()).expect("Failed to setup SIGQUIT channel");
tokio::select! {
_ = tokio::signal::ctrl_c() => {
log::info!("Received SIGINT");
},
_ = sigterm.recv() => {
log::info!("Received SIGTERM");
}
_ = sigquit.recv() => {
log::info!("Received SIGQUIT");
}
}
}
#[cfg(not(unix))]
async fn wait_for_signal() {
tokio::select! {
_ = tokio::signal::ctrl_c() => {
log::info!("Received SIGINT");
},
}
}
fn override_config(mut config: Config, matches: &ArgMatches) -> Config {
if let Some(id) = matches.value_of(ID) {
fs::create_dir_all(Config::default_config_directory(Some(id)))
.expect("Could not create config directory");
fs::create_dir_all(Config::default_data_directory(Some(&id)))
fs::create_dir_all(Config::default_data_directory(Some(id)))
.expect("Could not create data directory");
config = config.with_id(&id);
config = config.with_id(id);
}
config = config
.with_network_monitor_enabled(args.enable_monitor)
.with_rewarding_enabled(args.enable_rewarding)
.with_disabled_credentials_mode(!args.enabled_credentials_mode);
if let Some(nymd_validator) = args.nymd_validator {
config = config.with_custom_nymd_validator(nymd_validator);
if matches.is_present(MONITORING_ENABLED) {
config = config.with_network_monitor_enabled(true)
}
if let Some(mixnet_contract) = args.mixnet_contract {
config = config.with_custom_mixnet_contract(mixnet_contract.to_string())
if matches.is_present(REWARDING_ENABLED) {
config = config.with_rewarding_enabled(true)
}
#[cfg(feature = "coconut")]
if matches.is_present(COCONUT_ENABLED) {
config = config.with_coconut_signer_enabled(true)
}
#[cfg(feature = "coconut")]
if let Some(announce_address) = matches.value_of(ANNOUNCE_ADDRESS) {
config = config.with_announce_address(
Url::parse(announce_address).expect("Could not parse announce address"),
);
}
if let Some(raw_validator) = matches.value_of(NYMD_VALIDATOR_ARG) {
let parsed = match raw_validator.parse() {
Err(err) => {
error!("Passed validator argument is invalid - {err}");
process::exit(1)
}
Ok(url) => url,
};
config = config.with_custom_nymd_validator(parsed);
}
if let Some(mixnet_contract) = matches.value_of(MIXNET_CONTRACT_ARG) {
config = config.with_custom_mixnet_contract(mixnet_contract)
} else if std::env::var(CONFIGURED).is_ok() {
if let Some(mixnet_contract) = read_var_if_not_default(MIXNET_CONTRACT_ADDRESS) {
config = config.with_custom_mixnet_contract(mixnet_contract)
}
}
if let Some(mnemonic) = args.mnemonic {
config = config.with_mnemonic(mnemonic.to_string())
if let Some(mnemonic) = matches.value_of(MNEMONIC_ARG) {
config = config.with_mnemonic(mnemonic)
}
if let Some(monitor_threshold) = args.monitor_threshold {
if let Some(monitor_threshold) = matches
.value_of(REWARDING_MONITOR_THRESHOLD_ARG)
.map(|t| t.parse::<u8>())
{
let monitor_threshold =
monitor_threshold.expect("Provided monitor threshold is not a number!");
assert!(
monitor_threshold <= 100,
"Provided monitor threshold is greater than 100!"
);
config = config.with_minimum_interval_monitor_threshold(monitor_threshold)
}
if let Some(reliability) = args.min_mixnode_reliability {
config = config.with_min_mixnode_reliability(reliability)
if let Some(reliability) = matches
.value_of(MIN_MIXNODE_RELIABILITY_ARG)
.map(|t| t.parse::<u8>())
{
config = config.with_min_mixnode_reliability(
reliability.expect("Provided reliability is not a u8 number!"),
)
}
if let Some(reliability) = args.min_gateway_reliability {
config = config.with_min_gateway_reliability(reliability)
if let Some(reliability) = matches
.value_of(MIN_GATEWAY_RELIABILITY_ARG)
.map(|t| t.parse::<u8>())
{
config = config.with_min_gateway_reliability(
reliability.expect("Provided reliability is not a u8 number!"),
)
}
#[cfg(feature = "coconut")]
if let Some(announce_address) = args.announce_address {
config = config
.with_announce_address(announce_address)
.with_coconut_signer_enabled(args.enable_coconut);
if matches.is_present(ENABLED_CREDENTIALS_MODE_ARG_NAME) {
config = config.with_disabled_credentials_mode(false)
}
if args.save_config {
if matches.is_present(WRITE_CONFIG_ARG) {
info!("Saving the configuration to a file");
if let Err(err) = config.save_to_file(None) {
error!("Failed to write config to a file - {err}");
@@ -363,11 +490,11 @@ fn get_servers() -> Vec<rocket_okapi::okapi::openapi3::Server> {
}]
}
async fn run_nym_api(args: ApiArgs) -> Result<()> {
async fn run_nym_api(matches: ArgMatches) -> Result<()> {
let system_version = env!("CARGO_PKG_VERSION");
// try to load config from the file, if it doesn't exist, use default values
let id = args.id.as_deref();
let id = matches.value_of(ID);
let (config, _already_inited) = match Config::load_from_file(id) {
Ok(cfg) => (cfg, true),
Err(_) => {
@@ -376,14 +503,14 @@ async fn run_nym_api(args: ApiArgs) -> Result<()> {
.into_string()
.unwrap();
warn!(
"Could not load the configuration file from {config_path}. Either the file did not exist or was malformed. Using the default values instead",
"Could not load the configuration file from {}. Either the file did not exist or was malformed. Using the default values instead",
config_path
);
(Config::new(), false)
}
};
let save_to_file = args.save_config;
let config = override_config(config, args);
let config = override_config(config, &matches);
#[cfg(feature = "coconut")]
if !_already_inited {
@@ -391,16 +518,9 @@ async fn run_nym_api(args: ApiArgs) -> Result<()> {
}
// if we just wanted to write data to the config, exit
if save_to_file {
info!("Saving the configuration to a file");
if let Err(err) = config.save_to_file(None) {
error!("Failed to write config to a file - {err}");
process::exit(1)
} else {
return Ok(());
}
if matches.is_present(WRITE_CONFIG_ARG) {
return Ok(());
}
let mix_denom = std::env::var(MIX_DENOM).expect("mix denom not set");
let signing_nymd_client = Client::new_signing(&config);
@@ -464,13 +584,11 @@ async fn run_nym_api(args: ApiArgs) -> Result<()> {
tokio::spawn(async move { validator_cache_refresher.run(shutdown_listener).await });
// spawn rewarded set updater
if config.get_rewarding_enabled() {
let mut rewarded_set_updater =
RewardedSetUpdater::new(signing_nymd_client, validator_cache.clone(), storage)
.await?;
let shutdown_listener = shutdown.subscribe();
tokio::spawn(async move { rewarded_set_updater.run(shutdown_listener).await.unwrap() });
}
let mut rewarded_set_updater =
RewardedSetUpdater::new(signing_nymd_client, validator_cache.clone(), storage).await?;
let shutdown_listener = shutdown.subscribe();
tokio::spawn(async move { rewarded_set_updater.run(shutdown_listener).await.unwrap() });
validator_cache_listener
} else {
// Spawn the validator cache refresher.
@@ -540,7 +658,10 @@ async fn main() -> Result<()> {
}}
setup_logging();
let args = ApiArgs::parse();
setup_env(args.config_env_file.as_ref());
let args = parse_args();
let config_env_file = args
.value_of(CONFIG_ENV_FILE)
.map(|s| PathBuf::from_str(s).expect("invalid env config file"));
setup_env(config_env_file);
run_nym_api(args).await
}
+3 -3
View File
@@ -2161,9 +2161,9 @@ json-stringify-safe@5.0.1:
integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==
json5@^2.2.1:
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
version "2.2.1"
resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
kleur@^3.0.3:
version "3.0.3"
-13
View File
@@ -30,19 +30,6 @@ module.exports = {
use: ['@svgr/webpack'],
});
config.module.rules.unshift({
test: /\.ya?ml$/,
type: 'json',
use: [
{
loader: 'yaml-loader',
options: {
asJSON: true,
},
},
],
});
config.resolve.extensions = ['.tsx', '.ts', '.js'];
config.resolve.plugins = [new TsconfigPathsPlugin()];
@@ -1,10 +0,0 @@
/**
* This is a mock for Tauri's API package (@tauri-apps/api/notification), to prevent stories from being excluded, because they either use
* or import dependencies that use Tauri.
*/
module.exports = {
isPermissionGranted: () => undefined,
requestPermission: () => undefined,
sendNotification: () => undefined,
};
+1 -9
View File
@@ -1,18 +1,10 @@
## UNRELEASED
## [nym-connect-v1.1.4](https://github.com/nymtech/nym/tree/nym-connect-v1.1.4) (2022-12-20)
This release contains the new opt-in Test & Earn program, and it uses a stress-tested directory of network requesters to improve reliability. It also has some bugfixes, performance improvements, and better error handling.
- nym-connect: send status messages from socks5 task to tauri backend by @octol in https://github.com/nymtech/nym/pull/1882
- socks5: rework waiting in inbound.rs by @octol in https://github.com/nymtech/nym/pull/1880
- Test&Earn by @mmsinclair in https://github.com/nymtech/nym/pull/2729
## [nym-connect-v1.1.3](https://github.com/nymtech/nym/tree/nym-connect-v1.1.3) (2022-12-13)
- socks5-client: added support for socks4a.
## [nym-connect-v1.1.2](https://github.com/nymtech/nym/tree/nym-connect-v1.1.2) (2022-12-06)
## [nym-connect-v1.1.2](https://github.com/nymtech/nym/tree/nym-connect-v1.1.2) (2022-11-29)
- socks5-client: fix error with client failing and disconnecting unnecessarily.
+114 -289
View File
@@ -14,6 +14,12 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "adler32"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]]
name = "aes"
version = "0.7.5"
@@ -407,13 +413,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "build-information"
version = "0.1.0"
dependencies = [
"vergen 7.4.4",
]
[[package]]
name = "bumpalo"
version = "3.11.0"
@@ -470,11 +469,12 @@ dependencies = [
[[package]]
name = "cargo_toml"
version = "0.13.0"
version = "0.11.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa0e3586af56b3bfa51fca452bd56e8dbbbd5d8d81cbf0b7e4e35b695b537eb8"
checksum = "a4419e9adae9fd7e231b60d50467481bf8181ddeef6ed54683b23ae925c74c9c"
dependencies = [
"serde",
"serde_derive",
"toml",
]
@@ -573,33 +573,35 @@ dependencies = [
[[package]]
name = "clap"
version = "4.0.26"
version = "3.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e"
checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"clap_lex",
"indexmap",
"once_cell",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_complete"
version = "4.0.7"
version = "3.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10861370d2ba66b0f5989f83ebf35db6421713fd92351790e7fdd6c36774c56b"
checksum = "3f7a2e0a962c45ce25afce14220bc24f9dade0a1787f185cecf96bfba7847cd8"
dependencies = [
"clap",
]
[[package]]
name = "clap_complete_fig"
version = "4.0.2"
version = "3.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46b30e010e669cd021e5004f3be26cff6b7c08d2a8a0d65b48d43a8cc0efd6c3"
checksum = "ed37b4c0c1214673eba6ad8ea31666626bf72be98ffb323067d973c48b4964b9"
dependencies = [
"clap",
"clap_complete",
@@ -607,9 +609,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.0.21"
version = "3.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
dependencies = [
"heck 0.4.0",
"proc-macro-error",
@@ -620,9 +622,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.3.0"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
@@ -637,7 +639,7 @@ dependencies = [
[[package]]
name = "client-core"
version = "1.1.4"
version = "1.1.3"
dependencies = [
"async-trait",
"client-connections",
@@ -752,17 +754,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colored"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
dependencies = [
"atty",
"lazy_static",
"winapi",
]
[[package]]
name = "colored"
version = "2.0.0"
@@ -1325,14 +1316,13 @@ dependencies = [
]
[[package]]
name = "dbus"
version = "0.9.6"
name = "deflate"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f8bcdd56d2e5c4ed26a529c5a9029f5db8290d433497506f958eae3be148eb6"
checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4"
dependencies = [
"libc",
"libdbus-sys",
"winapi",
"adler32",
"byteorder",
]
[[package]]
@@ -1481,12 +1471,6 @@ dependencies = [
"dtoa",
]
[[package]]
name = "dunce"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c"
[[package]]
name = "dyn-clone"
version = "1.0.9"
@@ -1588,16 +1572,7 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2953d1df47ac0eb70086ccabf0275aa8da8591a28bd358ee2b52bd9f9e3ff9e9"
dependencies = [
"enum-iterator-derive 0.8.1",
]
[[package]]
name = "enum-iterator"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45a0ac4aeb3a18f92eaf09c6bb9b3ac30ff61ca95514fc58cbead1c9a6bf5401"
dependencies = [
"enum-iterator-derive 1.1.0",
"enum-iterator-derive",
]
[[package]]
@@ -1611,17 +1586,6 @@ dependencies = [
"syn",
]
[[package]]
name = "enum-iterator-derive"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "828de45d0ca18782232dfb8f3ea9cc428e8ced380eb26a520baaacfc70de39ce"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "env_logger"
version = "0.7.1"
@@ -1668,16 +1632,6 @@ dependencies = [
"instant",
]
[[package]]
name = "fern"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bdd7b0849075e79ee9a1836df22c717d1eba30451796fdc631b04565dd11e2a"
dependencies = [
"colored 1.9.3",
"log",
]
[[package]]
name = "ff"
version = "0.10.1"
@@ -2666,12 +2620,12 @@ dependencies = [
[[package]]
name = "ico"
version = "0.2.0"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "031530fe562d8c8d71c0635013d6d155bbfe8ba0aa4b4d2d24ce8af6b71047bd"
checksum = "6a4b3331534254a9b64095ae60d3dc2a8225a7a70229cd5888be127cdc1f6804"
dependencies = [
"byteorder",
"png",
"png 0.11.0",
]
[[package]]
@@ -2748,6 +2702,15 @@ dependencies = [
"cfb",
]
[[package]]
name = "inflate"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5f9f47468e9a76a6452271efadc88fe865a82be91fe75e6c0c57b87ccea59d4"
dependencies = [
"adler32",
]
[[package]]
name = "inout"
version = "0.1.3"
@@ -2786,9 +2749,9 @@ checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b"
[[package]]
name = "itertools"
version = "0.10.5"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
checksum = "d8bf247779e67a9082a4790b45e71ac7cfd1321331a5c856a74a9faebdab78d0"
dependencies = [
"either",
]
@@ -2830,9 +2793,9 @@ dependencies = [
[[package]]
name = "jni"
version = "0.20.0"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c"
checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec"
dependencies = [
"cesu8",
"combine",
@@ -2951,15 +2914,6 @@ version = "0.2.132"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
[[package]]
name = "libdbus-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c185b5b7ad900923ef3a8ff594083d4d9b5aea80bb4f32b8342363138c0d456b"
dependencies = [
"pkg-config",
]
[[package]]
name = "libgit2-sys"
version = "0.14.0+1.5.0"
@@ -3020,12 +2974,6 @@ dependencies = [
"safemem",
]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "lioness"
version = "0.1.2"
@@ -3055,7 +3003,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
"serde",
]
[[package]]
@@ -3087,19 +3034,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
[[package]]
name = "mac-notification-sys"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e72d50edb17756489e79d52eb146927bec8eba9dd48faadf9ef08bca3791ad5"
dependencies = [
"cc",
"dirs-next",
"objc-foundation",
"objc_id",
"time 0.3.17",
]
[[package]]
name = "malloc_buf"
version = "0.0.6"
@@ -3321,17 +3255,6 @@ dependencies = [
"wasm-timer",
]
[[package]]
name = "notify-rust"
version = "4.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "368e89ea58df747ce88be669ae44e79783c1d30bfd540ad0fc520b3f41f0b3b0"
dependencies = [
"dbus",
"mac-notification-sys",
"tauri-winrt-notification",
]
[[package]]
name = "num-derive"
version = "0.3.3"
@@ -3353,6 +3276,17 @@ dependencies = [
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
dependencies = [
"autocfg 1.1.0",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.1"
@@ -3423,28 +3357,21 @@ dependencies = [
name = "nym-connect"
version = "1.1.4"
dependencies = [
"anyhow",
"bip39",
"chrono",
"client-core",
"config",
"crypto",
"dirs",
"eyre",
"fern",
"fix-path-env",
"futures",
"itertools",
"log",
"logging",
"nym-socks5-client",
"pretty_env_logger",
"rand 0.8.5",
"reqwest",
"rust-embed",
"serde",
"serde_json",
"serde_repr",
"tap",
"task",
"tauri",
@@ -3458,14 +3385,12 @@ dependencies = [
"topology",
"ts-rs",
"url",
"yaml-rust",
]
[[package]]
name = "nym-socks5-client"
version = "1.1.4"
version = "1.1.3"
dependencies = [
"build-information",
"clap",
"client-connections",
"client-core",
@@ -3477,7 +3402,6 @@ dependencies = [
"futures",
"gateway-client",
"gateway-requests",
"lazy_static",
"log",
"logging",
"network-defaults",
@@ -3498,6 +3422,7 @@ dependencies = [
"topology",
"url",
"validator-client",
"vergen",
"version-checker",
]
@@ -3687,9 +3612,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.16.0"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0"
[[package]]
name = "opaque-debug"
@@ -4140,6 +4065,18 @@ dependencies = [
"xml-rs",
]
[[package]]
name = "png"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0b0cabbbd20c2d7f06dbf015e06aad59b6ca3d9ed14848783e98af9aaf19925"
dependencies = [
"bitflags",
"deflate",
"inflate",
"num-iter",
]
[[package]]
name = "png"
version = "0.17.6"
@@ -4284,15 +4221,6 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
[[package]]
name = "quick-xml"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11bafc859c6815fbaffbbbf4229ecb767ac913fecb27f9ad4343662e9ef099ea"
dependencies = [
"memchr",
]
[[package]]
name = "quote"
version = "1.0.21"
@@ -4545,9 +4473,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.7.0"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"aho-corasick",
"memchr",
@@ -4607,7 +4535,6 @@ dependencies = [
"serde_urlencoded",
"tokio",
"tokio-native-tls",
"tokio-socks",
"tower-service",
"url",
"wasm-bindgen",
@@ -4677,41 +4604,6 @@ dependencies = [
"opaque-debug 0.3.0",
]
[[package]]
name = "rust-embed"
version = "6.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "283ffe2f866869428c92e0d61c2f35dfb4355293cdfdc48f49e895c15f1333d1"
dependencies = [
"rust-embed-impl",
"rust-embed-utils",
"walkdir",
]
[[package]]
name = "rust-embed-impl"
version = "6.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31ab23d42d71fb9be1b643fe6765d292c5e14d46912d13f3ae2815ca048ea04d"
dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn",
"walkdir",
]
[[package]]
name = "rust-embed-utils"
version = "7.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1669d81dfabd1b5f8e2856b8bbe146c6192b0ba22162edc738ac0a5de18f054"
dependencies = [
"globset",
"sha2 0.10.6",
"walkdir",
]
[[package]]
name = "rustc_version"
version = "0.3.3"
@@ -5567,27 +5459,6 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strum"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7ac893c7d471c8a21f31cfe213ec4f6d9afeed25537c772e08ef3f005f8729e"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "339f799d8b549e3744c7ac7feb216383e4005d94bdb22561b3ab8f3b808ae9fb"
dependencies = [
"heck 0.3.3",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "subtle"
version = "1.0.0"
@@ -5660,9 +5531,9 @@ dependencies = [
[[package]]
name = "tao"
version = "0.15.7"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1fa15735311b4816d030ff54da58560b047daca0970e1031aed5502e84231a8"
checksum = "43336f5d1793543ba96e2a1e75f3a5c7dcd592743be06a0ab3a190f4fcb4b934"
dependencies = [
"bitflags",
"cairo-rs",
@@ -5695,12 +5566,12 @@ dependencies = [
"once_cell",
"parking_lot 0.12.1",
"paste",
"png",
"png 0.17.6",
"raw-window-handle",
"scopeguard",
"serde",
"unicode-segmentation",
"uuid 1.2.2",
"uuid 1.1.2",
"windows 0.39.0",
"windows-implement",
"x11-dl",
@@ -5737,9 +5608,9 @@ dependencies = [
[[package]]
name = "tauri"
version = "1.2.2"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8ea1d785ab2164373703817bff144c4610a69ad3f659becaca0e1ea004b98d8"
checksum = "efbf22abd61d95ca9b2becd77f9db4c093892f73e8a07d21d8b0b2bf71a7bcea"
dependencies = [
"anyhow",
"attohttpc",
@@ -5757,7 +5628,6 @@ dependencies = [
"http",
"ignore",
"minisign-verify",
"notify-rust",
"objc",
"once_cell",
"open",
@@ -5782,7 +5652,7 @@ dependencies = [
"time 0.3.17",
"tokio",
"url",
"uuid 1.2.2",
"uuid 1.1.2",
"webkit2gtk",
"webview2-com",
"windows 0.39.0",
@@ -5791,9 +5661,9 @@ dependencies = [
[[package]]
name = "tauri-build"
version = "1.2.1"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8807c85d656b2b93927c19fe5a5f1f1f348f96c2de8b90763b3c2d561511f9b4"
checksum = "0991fb306849897439dbd4a72e4cbed2413e2eb26cb4b3ba220b94edba8b4b88"
dependencies = [
"anyhow",
"cargo_toml",
@@ -5807,16 +5677,16 @@ dependencies = [
[[package]]
name = "tauri-codegen"
version = "1.2.1"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14388d484b6b1b5dc0f6a7d6cc6433b3b230bec85eaa576adcdf3f9fafa49251"
checksum = "356fa253e40ae4d6ff02075011f2f2bb4066f5c9d8c1e16ca6912d7b75903ba6"
dependencies = [
"base64",
"brotli",
"ico",
"json-patch",
"plist",
"png",
"png 0.17.6",
"proc-macro2",
"quote",
"regex",
@@ -5827,15 +5697,15 @@ dependencies = [
"tauri-utils",
"thiserror",
"time 0.3.17",
"uuid 1.2.2",
"uuid 1.1.2",
"walkdir",
]
[[package]]
name = "tauri-macros"
version = "1.2.1"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "069319e5ecbe653a799b94b0690d9f9bf5d00f7b1d3989aa331c524d4e354075"
checksum = "d6051fd6940ddb22af452340d03c66a3e2f5d72e0788d4081d91e31528ccdc4d"
dependencies = [
"heck 0.4.0",
"proc-macro2",
@@ -5847,29 +5717,30 @@ dependencies = [
[[package]]
name = "tauri-runtime"
version = "0.12.1"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c507d954d08ac8705d235bc70ec6975b9054fb95ff7823af72dbb04186596f3b"
checksum = "d49439a5ea47f474572b854972f42eda2e02a470be5ca9609cc83bb66945abe2"
dependencies = [
"gtk",
"http",
"http-range",
"infer",
"rand 0.8.5",
"raw-window-handle",
"serde",
"serde_json",
"tauri-utils",
"thiserror",
"uuid 1.2.2",
"uuid 1.1.2",
"webview2-com",
"windows 0.39.0",
]
[[package]]
name = "tauri-runtime-wry"
version = "0.12.2"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36b1c5764a41a13176a4599b5b7bd0881bea7d94dfe45e1e755f789b98317e30"
checksum = "28dce920995fd49907aa9bea7249ed1771454f11f7611924c920a1f75fb614d4"
dependencies = [
"cocoa",
"gtk",
@@ -5878,7 +5749,7 @@ dependencies = [
"raw-window-handle",
"tauri-runtime",
"tauri-utils",
"uuid 1.2.2",
"uuid 1.1.2",
"webkit2gtk",
"webview2-com",
"windows 0.39.0",
@@ -5887,16 +5758,15 @@ dependencies = [
[[package]]
name = "tauri-utils"
version = "1.2.1"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5abbc109a6eb45127956ffcc26ef0e875d160150ac16cfa45d26a6b2871686f1"
checksum = "1e8fdae6f29cef959809a3c3afef510c5b715a446a597ab8b791497585363f39"
dependencies = [
"brotli",
"ctor",
"glob",
"heck 0.4.0",
"html5ever",
"infer",
"json-patch",
"kuchiki",
"memchr",
@@ -5913,17 +5783,6 @@ dependencies = [
"windows 0.39.0",
]
[[package]]
name = "tauri-winrt-notification"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c58de036c4d2e20717024de2a3c4bf56c301f07b21bc8ef9b57189fce06f1f3b"
dependencies = [
"quick-xml",
"strum",
"windows 0.39.0",
]
[[package]]
name = "tempfile"
version = "3.3.0"
@@ -6054,6 +5913,12 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7b3e525a49ec206798b40326a44121291b530c963cfb01018f63e135bac543d"
[[package]]
name = "thin-slice"
version = "0.1.1"
@@ -6190,18 +6055,6 @@ dependencies = [
"webpki 0.22.0",
]
[[package]]
name = "tokio-socks"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0"
dependencies = [
"either",
"futures-util",
"thiserror",
"tokio",
]
[[package]]
name = "tokio-stream"
version = "0.1.10"
@@ -6493,9 +6346,9 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
[[package]]
name = "uuid"
version = "1.2.2"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f"
dependencies = [
"getrandom 0.2.7",
]
@@ -6510,7 +6363,7 @@ dependencies = [
"coconut-bandwidth-contract-common",
"coconut-dkg-common",
"coconut-interface",
"colored 2.0.0",
"colored",
"config",
"contracts-common",
"cosmrs",
@@ -6558,7 +6411,7 @@ dependencies = [
"anyhow",
"cfg-if",
"chrono",
"enum-iterator 0.8.1",
"enum-iterator",
"getset",
"git2",
"rustc_version 0.4.0",
@@ -6566,23 +6419,6 @@ dependencies = [
"thiserror",
]
[[package]]
name = "vergen"
version = "7.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efadd36bc6fde40c6048443897d69511a19161c0756cb704ed403f8dfd2b7d1c"
dependencies = [
"anyhow",
"cfg-if",
"enum-iterator 1.1.3",
"getset",
"git2",
"rustc_version 0.4.0",
"rustversion",
"thiserror",
"time 0.3.17",
]
[[package]]
name = "version-checker"
version = "0.1.0"
@@ -6619,7 +6455,7 @@ dependencies = [
"schemars",
"serde",
"thiserror",
"vergen 5.1.17",
"vergen",
"vesting-contract-common",
]
@@ -6798,9 +6634,9 @@ dependencies = [
[[package]]
name = "webkit2gtk"
version = "0.18.2"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8f859735e4a452aeb28c6c56a852967a8a76c8eb1cc32dbf931ad28a13d6370"
checksum = "29952969fb5e10fe834a52eb29ad0814ccdfd8387159b0933edf1344a1c9cdcc"
dependencies = [
"bitflags",
"cairo-rs",
@@ -7175,16 +7011,15 @@ dependencies = [
[[package]]
name = "wry"
version = "0.23.4"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c1ad8e2424f554cc5bdebe8aa374ef5b433feff817aebabca0389961fc7ef98"
checksum = "ff5c1352b4266fdf92c63479d2f58ab4cd29dc4e78fbc1b62011ed1227926945"
dependencies = [
"base64",
"block",
"cocoa",
"core-graphics",
"crossbeam-channel",
"dunce",
"gdk",
"gio",
"glib",
@@ -7200,7 +7035,6 @@ dependencies = [
"serde",
"serde_json",
"sha2 0.10.6",
"soup2",
"tao",
"thiserror",
"url",
@@ -7267,15 +7101,6 @@ version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "zeroize"
version = "1.5.7"
@@ -7299,9 +7124,9 @@ dependencies = [
[[package]]
name = "zip"
version = "0.6.3"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "537ce7411d25e54e8ae21a7ce0b15840e7bfcff15b51d697ec3266cc76bdf080"
checksum = "bf225bcf73bb52cbb496e70475c7bd7a3f769df699c0020f6c7bd9a96dcf0b8d"
dependencies = [
"byteorder",
"crc32fast",
+4 -8
View File
@@ -1,12 +1,11 @@
{
"name": "@nym/nym-connect",
"version": "1.1.4",
"version": "1.1.3",
"main": "index.js",
"license": "MIT",
"scripts": {
"prewebpack:dev": "yarn --cwd .. build",
"webpack:dev": "yarn webpack serve --config webpack.dev.js",
"webpack:dev:onlyThis": "yarn webpack serve --config webpack.dev.js",
"webpack:prod": "yarn webpack --progress --config webpack.prod.js",
"tauri:dev": "RUST_DEBUG=1 yarn tauri dev",
"tauri:build": "yarn tauri build",
@@ -31,7 +30,7 @@
"@mui/material": "^5.2.2",
"@mui/styles": "^5.2.2",
"@nymproject/react": "^1.0.0",
"@tauri-apps/api": "^1.2.0",
"@tauri-apps/api": "^1.1.0",
"@tauri-apps/tauri-forage": "^1.0.0-beta.2",
"clsx": "^1.1.1",
"luxon": "^2.3.0",
@@ -40,7 +39,6 @@
"react-dom": "^17.0.2",
"react-error-boundary": "^3.1.3",
"react-hook-form": "^7.14.2",
"react-markdown": "^8.0.4",
"react-router-dom": "^5.2.0",
"semver": "^6.3.0",
"yup": "^0.32.9"
@@ -51,12 +49,11 @@
"@babel/preset-env": "^7.15.0",
"@babel/preset-react": "^7.14.5",
"@babel/preset-typescript": "^7.15.0",
"@mdx-js/loader": "^2.1.5",
"@nymproject/eslint-config-react-typescript": "^1.0.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
"@storybook/react": "^6.5.8",
"@svgr/webpack": "^6.1.1",
"@tauri-apps/cli": "^1.2.2",
"@tauri-apps/cli": "^1.1.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.0.0",
"@types/jest": "^27.0.1",
@@ -108,7 +105,6 @@
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.5.0",
"webpack-favicons": "^1.3.8",
"webpack-merge": "^5.8.0",
"yaml-loader": "^0.8.0"
"webpack-merge": "^5.8.0"
}
}
-11
View File
@@ -1,11 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Nym Connect</title>
</head>
<body style="background: rgb(29, 33, 37);">
<div id="root-growth"></div>
</body>
</html>
+1 -1
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Nym Connect</title>
<title>nym-connect</title>
</head>
<body>
<div id="root"></div>
-11
View File
@@ -1,11 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Nym Wallet Logs</title>
</head>
<body>
<div id="root-log"></div>
</body>
</html>
+7 -14
View File
@@ -13,40 +13,33 @@ rust-version = "1.58"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies]
tauri-build = { version = "^1.2.1", features = [] }
tauri-build = { version = "^1.1.1", features = [] }
tauri-codegen = "^1.2.1"
tauri-macros = "^1.2.1"
tauri-codegen = "^1.1.1"
tauri-macros = "^1.1.1"
[dependencies]
anyhow = "1.0"
bip39 = "1.0"
chrono = "0.4"
dirs = "4.0"
eyre = "0.6.5"
fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs", branch = "release"}
futures = "0.3"
fern = { version = "0.6.1", features = ["colored"] }
itertools = "0.10.5"
log = { version = "0.4", features = ["serde"] }
log = "0.4"
pretty_env_logger = "0.4.0"
rand = "0.8"
reqwest = { version = "0.11", features = ["json", "socks"] }
rust-embed = { version = "6.4.2", features = ["include-exclude"] }
reqwest = { version = "0.11", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_repr = "0.1"
tap = "1.0.1"
tauri = { version = "^1.2.2", features = ["clipboard-write-text", "macos-private-api", "notification-all", "shell-open", "system-tray", "updater", "window-close", "window-minimize", "window-start-dragging"] }
tauri = { version = "^1.1.1", features = ["clipboard-write-text", "macos-private-api", "shell-open", "system-tray", "updater", "window-close", "window-minimize", "window-start-dragging"] }
tendermint-rpc = "0.23.0"
thiserror = "1.0"
tokio = { version = "1.21.2", features = ["sync", "time"] }
url = "2.2"
yaml-rust = "0.4"
client-core = { path = "../../clients/client-core" }
config-common = { path = "../../common/config", package = "config" }
crypto = { path = "../../common/crypto" }
logging = { path = "../../common/logging"}
nym-socks5-client = { path = "../../clients/socks5" }
task = { path = "../../common/task" }
+2 -9
View File
@@ -44,13 +44,6 @@ impl Config {
}
}
#[allow(unused)]
pub fn new_with_port<S: Into<String>>(id: S, provider_mix_address: S, port: u16) -> Self {
Config {
socks5: Socks5Config::new(id, provider_mix_address).with_port(port),
}
}
pub fn get_socks5(&self) -> &Socks5Config {
&self.socks5
}
@@ -130,11 +123,11 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
if let Ok(raw_validators) = std::env::var(config_common::defaults::var_names::API_VALIDATOR) {
config
.get_base_mut()
.set_custom_nym_apis(config_common::parse_urls(&raw_validators));
.set_custom_nym_apis(config_common::parse_validators(&raw_validators));
}
// Setup gateway by either registering a new one, or reusing exiting keys
let gateway = client_core::init::setup_gateway::<Socks5Config, _>(
let gateway = client_core::init::setup_gateway::<_, Socks5Config, _>(
register_gateway,
Some(chosen_gateway_id),
config.get_base(),
+2 -13
View File
@@ -1,3 +1,4 @@
use client_core::client::replies::reply_storage::fs_backend;
use client_core::error::ClientCoreError;
use serde::{Serialize, Serializer};
use thiserror::Error;
@@ -26,11 +27,6 @@ pub enum BackendError {
source: tauri::Error,
},
#[error("{source}")]
TauriApiError {
#[from]
source: tauri::api::Error,
},
#[error("{source}")]
SerdeJsonError {
#[from]
source: serde_json::Error,
@@ -38,12 +34,7 @@ pub enum BackendError {
#[error("{source}")]
ClientCoreError {
#[from]
source: ClientCoreError,
},
#[error("{source}")]
ApiClientError {
#[from]
source: crate::operations::growth::api_client::ApiClientError,
source: ClientCoreError<fs_backend::Backend>,
},
#[error("Could not send disconnect signal to the SOCKS5 client")]
@@ -66,8 +57,6 @@ pub enum BackendError {
CouldNotGetConfigFilename,
#[error("Could not load existing gateway configuration")]
CouldNotLoadExistingGatewayConfiguration(std::io::Error),
#[error("Unable to open a new window")]
NewWindowError,
}
impl Serialize for BackendError {

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