Compare commits

...

1058 Commits

Author SHA1 Message Date
durch 1060888945 wallet tracing POC 2023-01-05 17:30:25 +01:00
Jędrzej Stuczyński 5f4926dd49 feature: use clap derive for nym-api + use stricter validation for other binaries (#2772)
* fixed all uses of deprecated clap methods

* updated all uses of clap to 4.0

* unified obtaining build information

* moved around the imports

* Moved all nym-api arguments to ApiArgs and simplified parsing

* Using common shutdown signal code

* Using clap for parsing Vec<Url>

* stricter validation of socks5-client arguments

* ibid for the native client

* ibid for the gateway

* ibid for the mixnode

* clippy
2023-01-05 10:32:57 +00:00
dependabot[bot] 1f132a4eaa build(deps): bump got and nodemon (#1624)
Bumps [got](https://github.com/sindresorhus/got) and [nodemon](https://github.com/remy/nodemon). These dependencies needed to be updated together.

Removes `got`

Updates `nodemon` from 2.0.12 to 2.0.19
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](https://github.com/remy/nodemon/compare/v2.0.12...v2.0.19)

---
updated-dependencies:
- dependency-name: got
  dependency-type: indirect
- dependency-name: nodemon
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:21:05 +00:00
dependabot[bot] 097d2d51cc build(deps): bump undici, hardhat and @nomiclabs/hardhat-etherscan (#1634)
Bumps [undici](https://github.com/nodejs/undici), [hardhat](https://github.com/nomiclabs/hardhat) and [@nomiclabs/hardhat-etherscan](https://github.com/nomiclabs/hardhat). These dependencies needed to be updated together.

Updates `undici` from 4.16.0 to 5.10.0
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v4.16.0...v5.10.0)

Updates `hardhat` from 2.9.2 to 2.11.2
- [Release notes](https://github.com/nomiclabs/hardhat/releases)
- [Commits](https://github.com/nomiclabs/hardhat/compare/hardhat@2.9.2...hardhat@2.11.2)

Updates `@nomiclabs/hardhat-etherscan` from 3.0.3 to 3.1.0
- [Release notes](https://github.com/nomiclabs/hardhat/releases)
- [Commits](https://github.com/nomiclabs/hardhat/compare/@nomiclabs/hardhat-etherscan@3.0.3...@nomiclabs/hardhat-etherscan@3.1.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-type: indirect
- dependency-name: hardhat
  dependency-type: direct:development
- dependency-name: "@nomiclabs/hardhat-etherscan"
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:20:56 +00:00
dependabot[bot] a2078d997b Bump loader-utils from 1.4.0 to 1.4.2 (#1763)
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.2.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.2/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.2)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:20:37 +00:00
dependabot[bot] 558d4b899d Bump deep-object-diff from 1.1.7 to 1.1.9 (#1765)
Bumps [deep-object-diff](https://github.com/mattphillips/deep-object-diff) from 1.1.7 to 1.1.9.
- [Release notes](https://github.com/mattphillips/deep-object-diff/releases)
- [Commits](https://github.com/mattphillips/deep-object-diff/commits)

---
updated-dependencies:
- dependency-name: deep-object-diff
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:20:24 +00:00
dependabot[bot] 4fcb98e839 Bump decode-uri-component in /contracts/basic-bandwidth-generation (#1838)
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:20:11 +00:00
dependabot[bot] 702bb202a3 Bump decode-uri-component from 0.2.0 to 0.2.2 (#1840)
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:59 +00:00
dependabot[bot] 71ff2c04a0 Bump express in /clients/native/examples/js-examples/websocket (#1849)
Bumps [express](https://github.com/expressjs/express) from 4.17.1 to 4.18.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

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

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:46 +00:00
dependabot[bot] cb30384eaf Bump qs and express in /clients/native/examples/js-examples/websocket (#1850)
Bumps [qs](https://github.com/ljharb/qs) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `qs` from 6.7.0 to 6.11.0
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.7.0...v6.11.0)

Updates `express` from 4.17.1 to 4.18.2
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: indirect
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:38 +00:00
dependabot[bot] e911c2fbc0 Bump qs and express in /clients/webassembly/js-example (#1851)
Bumps [qs](https://github.com/ljharb/qs) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `qs` from 6.7.0 to 6.11.0
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.7.0...v6.11.0)

Updates `express` from 4.17.1 to 4.18.2
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: indirect
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:27 +00:00
dependabot[bot] bb005a39f5 Bump qs, body-parser and express (#1852)
Bumps [qs](https://github.com/ljharb/qs), [qs](https://github.com/ljharb/qs), [body-parser](https://github.com/expressjs/body-parser) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `qs` from 6.10.1 to 6.11.0
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.10.1...v6.11.0)

Updates `qs` from 6.5.2 to 6.11.0
- [Release notes](https://github.com/ljharb/qs/releases)
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.10.1...v6.11.0)

Updates `body-parser` from 1.19.0 to 1.20.1
- [Release notes](https://github.com/expressjs/body-parser/releases)
- [Changelog](https://github.com/expressjs/body-parser/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/body-parser/compare/1.19.0...1.20.1)

Updates `express` from 4.17.1 to 4.18.2
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

---
updated-dependencies:
- dependency-name: qs
  dependency-type: indirect
- dependency-name: qs
  dependency-type: indirect
- dependency-name: body-parser
  dependency-type: indirect
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:19 +00:00
dependabot[bot] ea72c37083 Bump express in /contracts/basic-bandwidth-generation (#1853)
Bumps [express](https://github.com/expressjs/express) from 4.17.1 to 4.18.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

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

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:19:10 +00:00
dependabot[bot] a24dd8b9bc build(deps): bump json5 from 2.2.1 to 2.2.3 in /nym-api/tests (#2768)
Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3)

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

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:11:01 +00:00
dependabot[bot] b006c01397 build(deps): bump json5 from 2.2.1 to 2.2.3 in /testnet-faucet (#2769)
Bumps [json5](https://github.com/json5/json5) from 2.2.1 to 2.2.3.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v2.2.1...v2.2.3)

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

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:10:38 +00:00
dependabot[bot] f7f2a51458 build(deps): bump json5 from 1.0.1 to 1.0.2 (#2770)
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

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

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-05 10:10:04 +00:00
Jon Häggblad 408396c900 client-core: remove generic parameter for ClientCoreError (#2765)
* client-core: remove generic parameter for ClientCoreError

* fix compilation
2023-01-04 15:41:11 +01:00
Jędrzej Stuczyński a97c913bb1 Fixed missing feature lock for coconut-exlusive fields (#2767) 2023-01-04 14:00:55 +00:00
Jędrzej Stuczyński dba5a9caef Renamed 'nym-validator-api' package name to 'nym-api' (#2766) 2023-01-04 13:00:37 +00:00
Pierre Dommerc 3e39573feb feat(wallet-buy): pass wallet address as url param (#2752) 2023-01-04 13:26:09 +01:00
Jędrzej Stuczyński ac312e9109 feature: standarise arguments (#2762)
* Renamed "address" argument in "sign" command to "wallet-address"

* Ability to optionally describe mixnode with command line arguments

* renamed 'validators' arguments to 'nym-apis' in mixnode binary

* cleaned up gateway validator-related url arguments

* fixup! Renamed "address" argument in "sign" command to "wallet-address"

* renamed 'use_anonymous_sender_tag' to 'use_anonymous_replies'

* 'nymd_endpoints => 'nymd_validators'

* more consistency for nymd_validators and nym_apis urls arguments

* updated changelog
2023-01-04 09:59:08 +00:00
Jędrzej Stuczyński 8a2a7dc0ce bugfix: don't start rewarding unless rewarding.enabled is explicitly set to true (#2753)
* start rewarded set updater based on config flag

* removed dead code annotation

* updated changelog
2023-01-04 09:44:32 +00:00
Fouad 9684b7ffbd merge resolve 2022-12-22 15:45:02 +01:00
farbanas 29f48efe49 feat: release v1.1.5 of nym-wallet 2022-12-22 12:13:44 +01:00
Drazen Urch bdc285dbbb Add numeric family ids to explorer-api (#2707) 2022-12-21 23:37:32 +01:00
benedetta davico a02a1b0385 Merge pull request #2728 from nymtech/feat/2722-ne-ui
make fields match button height
2022-12-21 15:09:32 +01:00
Jędrzej Stuczyński 32ad93c57e Feature/multi surb transmission lanes (#2723)
* Preserve information about original transmission lanes when buffering reply packets

* Attempting to send partial data in 'handle_send_reply' if we don't have enough surbs immediately

* Display logging of reply surb request target

* promoted reply_controller to a directory

* moved channels and messages to separate file

* simplifications due to rust 1.66

* Using a shoarthand for obtaining connection_id

* made TransmissionBuffer generic

* Moved transmissaion buffer to a higher level directory + defined wasm helpers

* Using transmission buffer in reply controller

* Using the pending replies size in lane lenghts queries

* fixed an out of bounds use of fragments

* Fixed dropped channel in getting lane queue length

* Fixed an edge case failure for reply retransmissions

* measuring (and logging) time it takes to obtain lane lenghts

* decreased logging level

* Removed non-wasm lock on total_size
2022-12-20 19:38:49 +00:00
farbanas c4a68dbbe6 chore: formatting 2022-12-20 15:28:51 +01:00
fmtabbara 1140503eba merge 1.1.4 to develop 2022-12-20 13:49:10 +00:00
farbanas b9fed9f455 updating changelogs 2022-12-20 12:33:20 +01:00
farbanas 5e45f7d3a5 updating changelogs 2022-12-20 12:28:13 +01:00
farbanas 1133acd8bd update nym-connect and nym-wallet version 2022-12-20 12:14:05 +01:00
farbanas 08e6f3c4b7 update binaries version 2022-12-20 12:10:21 +01:00
farbanas 0ed546b739 fix: remove clear all settings button 2022-12-20 12:04:24 +01:00
Drazen Urch b4f2233d2b Outfox and Lion (#2730) 2022-12-20 11:29:28 +01:00
Mark Sinclair d8369eb4c9 Test and earn
- add logging and clear local storage menu items
- bump nym-connect version
- add app version number
- add reset trigger when clearing SP storage
- bump tauri version (nym-connect and nym-wallet)
- fix webpack config for prod builds
- new selector for services, with an advanced section for service providers
2022-12-19 18:18:08 +00:00
fmtabbara db3d379219 update buy NYM text 2022-12-19 15:07:49 +00:00
Gala a746738d48 make fields match button height 2022-12-19 13:40:26 +01:00
Jon Häggblad c67f0fb7f8 Merge remote-tracking branch 'origin/release/v1.1.4' into develop 2022-12-19 12:39:11 +01:00
Fouad 7c12a3422c Feature/node settings apy playground (#1677)
* initial ui for test my node

use svg for node path

add stories for test my node

* add initial rewards calculation

* update validation for rewards playground

* init playground with default values

* get node uptime

* get mixnode reward estimation

* calculate saturation

calculate stake saturation

* Make ComputeRewardEstParam derive Debug

* set active set to be always true

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
2022-12-19 11:22:51 +00:00
Gala f047209baf Merge pull request #2691 from nymtech/2129-buy-2-secc
ui and copy changes
2022-12-19 10:43:03 +01:00
Gala cc5a69d4f1 Merge branch 'release/v1.1.4' into 2129-buy-2-secc 2022-12-19 10:40:01 +01:00
Gala 776d27a899 Merge pull request #2694 from nymtech/2687-remove-warning
remove warning error message
2022-12-19 10:35:25 +01:00
Gala 829dbb1695 Merge pull request #2689 from nymtech/2139-buy-secc-1
adding bity icon and wallet address
2022-12-19 10:33:47 +01:00
Jon Häggblad 52156e0c38 validator-client: fix typo in error message 2022-12-19 09:22:30 +01:00
Jon Häggblad 901275fd63 wallet: rewrite some abci errors on the fly (#2716)
* wallet: rewrite some abci errors on the fly

* changelog: update

* Tidy
2022-12-19 09:22:25 +01:00
Jon Häggblad 6c4f0bc2f4 validator-client: fix typo in error message 2022-12-19 09:12:33 +01:00
Jon Häggblad 052a9a71c2 client: tweak shutdown order (#2724)
* clients: slightly tweak shutdown

* tweak log
2022-12-16 17:03:39 +01:00
Jon Häggblad da094f0208 wallet: rewrite some abci errors on the fly (#2716)
* wallet: rewrite some abci errors on the fly

* changelog: update

* Tidy
2022-12-16 12:02:23 +01:00
Bogdan-Ștefan Neacşu 254302ec38 Feature/auto dkg advance (#2714)
* Add dkg epoch

* Make epoch state advancement dependent only on time

* Nym api tries advancing the dkg epoch state

* Update the time table a bit

It still needs to be changed before production, as the sign-up timeframe
needs to be something like a few days.

* Update changelog

* Fix tests

* Fix clippy after rustc update
2022-12-16 12:21:39 +02:00
Jon Häggblad a0a73421d0 fix clippy for new rustc 2022-12-16 11:19:53 +01:00
Jon Häggblad b7be48a1b3 Merge remote-tracking branch 'origin/release/v1.1.4' into develop 2022-12-16 11:09:31 +01:00
Jon Häggblad 870c4f73a8 socks5: send additional status messages available for the frontend (#2715)
* socks5: send network-requester error in status channel

* Minor tidy

* task-manager: send status msg to indicate ready

* changelog: add note

* coconut/tests: fix clippy for rustc 1.66
2022-12-16 00:24:45 +01:00
Jon Häggblad c2c883e840 client: create websocket handler builder (#2700)
* client: create websocket handler builder

* rustfmt
2022-12-16 00:23:58 +01:00
Jędrzej Stuczyński 4d7e21e0f2 fix: ignore corrupted surb storage and instead create fresh one (#2711)
* checking for correct surb  metadata on db load

* archiving corrupted database on load and attempting to start fresh session instead

* checking for data corruption by looking at flush timestamp

* Moving public import to separate section
2022-12-15 15:45:54 +00:00
Jędrzej Stuczyński c0ffbb0cb2 Fix multi-surb backwards compatibility in pre 1.1.4 client config files (#2703)
* Defaulting to 'false' value for 'send_anonymously' in socks5 config if not present

* Created method to change all empty core client config fields to their default values

* Using default values for surb reply storage in 'run' command if left unset
2022-12-15 11:21:40 +00:00
Bogdan-Ștefan Neacşu 5e600de932 Modify wasm specific make targets (#2693) 2022-12-15 12:22:43 +02:00
Jon Häggblad eb07ec8580 client: sort out shutdown procedure and harmonize with socks5-client (#2695)
* common/task: rename ShutdownNotifier to TaskManager

* nym-client: return boxed error

* nym-client: enable graceful shutdown

* nym-client: task wait on shutdown to instead exit on closed channel

* Fix build

* Fix unused

* changelog: update
2022-12-14 17:13:00 +01:00
Dave Hrycyszyn f6a79ce7c3 Renaming validator-api to nym-api (#1863)
* Renaming validator-api to nym-api

* nym-api: simplified crate name

* Added nym-api rename to changelog

* Changed some output messages

* Renamed validator-api-requests to nym-api requests

* Removing more references to validator-api-requests

* Additional lockfile name changes after full build

* Removing mistakenly added merge files

* ibid

* ibid

* Getting rid of ref to validator_api deep inside validator-client

* Fixing file storage paths

* Renaming struct function names referring to validator_api

* Simplifying struct init

* Fixed up all other instances of nym_api.

* Renaming validatorApi to nymApi in TypeScript client for consistency

v

* Found a few more Rust instances

* Changed examples in TypeScript SDK

* Found one more instance of the use of validator instead of nym apis

* Aliasing config key name for deserialization to preserve compatibility with old configs
2022-12-14 15:05:01 +00:00
Gala 80c81fa3d7 using a plain string 2022-12-14 14:52:33 +01:00
Gala 27e6539e98 remove message only for gateways 2022-12-14 14:48:49 +01:00
Gala a2d10d9956 remove warning error message 2022-12-14 14:12:16 +01:00
Fouad 4ece8b7e8f Feature/nym connect experimental software text (#2692)
* use experimental text
2022-12-14 13:04:54 +00:00
Bogdan-Ștefan Neacşu bb557985c0 DKG resharing unit test (#2668) 2022-12-14 14:47:59 +02:00
Fouad 3ebb24b2c8 get version number from tauri and display (#2684)
* get version number from tauri and display

* update internal version numbers
2022-12-14 12:12:34 +00:00
Gala 142a2bb26b copy 2022-12-14 13:05:54 +01:00
Gala 677d8c7fce text size 2022-12-14 12:30:10 +01:00
Gala 3563ad67b2 ui and copy changes 2022-12-14 12:21:36 +01:00
Gala c11a4c23fa adding bity icon and wallet address 2022-12-14 11:16:08 +01:00
Jędrzej Stuczyński 97b01db23e Chore/more error macros (#2686)
* cleaned up MixProcessingError

* Added Error impl to (hopefully) all error enums in the codebase

* Replaced all occurences of error("{0}") with error(transparent)

* Changelog entry
2022-12-13 17:42:11 +00:00
farbanas a020f2ad1c Merge branch 'release/v1.1.3' into develop 2022-12-13 15:19:04 +01:00
Fran Arbanas 4b0f3cc093 Merge pull request #1874 from nymtech/bug-fix/hide-display-mnemonic
Bug fix/hide display mnemonic
2022-12-13 15:17:29 +01:00
farbanas 568ba1f4d9 Merge branch 'release/v1.1.3' into develop 2022-12-13 13:24:21 +01:00
farbanas 5456b16e3b updated changelogs 2022-12-13 13:23:27 +01:00
farbanas 3b5eab5342 bumped everything by one patch version 2022-12-13 13:15:51 +01:00
Jędrzej Stuczyński a7d8613c9d Multi-surbs (#2667)
* Feature/multi surbs (#1796)

* bunch of wip with focus on serialization

* Being able to send normal data (NO SURBS yet) to yourself again

* Fixed RepliableMessage deserialization

* Recovering data from surb messages

* Extracted common code in sphinx payload construction

* Cleanup within received buffer

* requesting, sending and using additional reply surbs

* Following discussion with @simonwicky, removing sender proof and decreasing size of sender tag

* Made sender tag more easily configurable

* Refactoring of message creation

* Propagating reply surb acks but not retransmitting them yet

* Surb retransmissions

* requesting additional surbs from the retransmission flow

* correctly determining the point of requesting additional surbs

* Ability to use socks5 (and network requester) with surbs

* Improved surbs retranmsission reliability

* naive way of not over-requesting surbs

* wip on tag storage

* Improved error propagation for message construction

* Requesting more surbs for stale entries

* Better controlling the point of having to request additional surbs

* Using pseudorandom sender tag instead of a hardcoded one

* First cleanup round in MessageHandler

* Error cleanup and if simplification

* Assigned a more permanent name to the ReplyController

* Removed PendingReply redundant type

* Made socks5 client less eager to over-send reply surbs

* 'anonymous' field on socks5 client to decide whether to use surbs or attach address

* Dead code and import removal in client-core

* Updating ClientRequest variants

* Adjusted decision threshold for requesting more surbs

* Native client cleanup

* Made socks5 client usage of surbs configurable

* Restored statistics in network requester

* Validator-api compiles once again

* Further improved surb request logic

* boxing the recipient in controller requests

* Removal of hardcoded values in favour of propagating them from the config

* more validation during surb requests

* Fixed ClientRequest::Send deserialization

* Added length checks for request deserialization

* post-merge formatting

* Unit tests once again compile and pass

* controlling retransmission_reply_surb_request_size from config

* More Recipient boxing action

* Requesting additional reply surbs for retransmission BEFORE dipping below the threshold

* Making clippy generally happier

* Wasm client compiles (but might not yet work correctly)

* Feature/use expect instead of panicking (#1797)

* Implementation of 'Debug' on 'RealMessage'

* expect with failed channel name instead of throwing empty panics

* Introduced Debug trait constraint in ProxyRunner

* Derive Debug for socks5_requests::Message

* Fix decrypting stored received msg (#1786)

* Fix decrypting stored received msg

* rustfmt

* Moving binary message recovery to separate function

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

* real_traffic_stream: reduce frequency of status print (#1794)

* Properly defined unnamed errors

* Dealing with previously ignored errors

* logging improvements

* Removed old example code

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>

* Missing changelog entry for multi-surbs (#1802)

* Making anonymous sender tag human readable (#1801)

* Created wrapper with string serialization for AnonymousSenderTag

* Using Display implementation of AnonymousSenderTag for logs

* Using Display implementation of MessageRecoveryError when logging (#1803)

* Using Display implementation of MessageRecoveryError when logging

* Updated changelog

* Defined socks5 client startup flag to enable reply-surb communication (#1804)

* Feature/persistent surbs data (#1835)

* prototyping wip

* Implemented ReplyStorageBackend trait for the sql-backed storage

* Storing correct surb threshold

* using correct database path

* Starting surb persistent storage in native and socks5 clients

* loading or creating fresh surb storage in socks5 and native clients

* making clippy happier + fixing config templates

* Creating status table on database rotation

* Completed the 'Empty' ReplyStorageBackend

* feature locking wasm-incompatible bits and pieces

* Feature/develop resync (#1844)

* Network-requester: throttle inbound connections (#1789)

* Return and handle ClientRequest::LaneQueueLenghts

* Pass lane queue lengths to inbound future

* Remove unused self reference

* Request lane queue lengths periodically for all open connections

* Add timeouts

* Rename to ConnectionCommandSender and Receiver

* Rename to client_connection_tx/rx

* Fix wasm build

* Replace bool with enum

* rust: bump required version to 1.65 in some crates that need it

* Add step to release GH actions (#1792)

* feat: add a release step to nym contracts GH action

* feat: add shrinking the size of wasm

* Possibilty to change gateway ws listener (#1779)

* add: set gatewayListener

* Update types.ts

* Update worker.ts

* Update contracts-build.yml

* real_traffic_stream: reduce frequency of status print (#1794)

* Update wallet and connect lock files (#1793)

* client-core: add warning when delay multiplier is larger than 1

* Fix decrypting stored received msg (#1786)

* Fix decrypting stored received msg

* rustfmt

* Moving binary message recovery to separate function

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

* Feature/use expect instead of panicking (#1797)

* Implementation of 'Debug' on 'RealMessage'

* expect with failed channel name instead of throwing empty panics

* Introduced Debug trait constraint in ProxyRunner

* Derive Debug for socks5_requests::Message

* Make connection_id optional in ClientRequest::Send (#1798)

* changelog: add missing entry for fixing message decrypt in gateway-client

* websocket-requests: fix length check before deserialize (#1799)

* Fix export dkg contract addr (#1800)

* Export dkg contract for mainnet when no config file present

* Remove redundant env files

* nym-cli: improve error reporting/handling and changed `vesting-schedule` queries to use query client instead of signing client

* Feature/gateway client protocol version (#1795)

* Introducing concept of gateway protocol version

* Remove version-based gateway filtering

* Fixed the unit test

* grammar

* Set build on latest release on schedule event

* Added nightly build workflow on second latest release

* socks5: if any task panics, signal all other tasks to shutdown (#1805)

* socks5: signal shutdown on error

* Mark as success

* Tidy

* Reduce wait to 5 sec

* Replace unwrap with expect

* Two more unwraps

* Update changelog

* client-core: less frequent status logging (#1806)

* Feature/nym connect UI updates (#1784)

* create custom titlebar

* create help page

* create generic modal component

* create separate connection time component

* link to shipyard docs

* move timer to separate component and update connection status component usage

* use separate component for copying ip and port details

* only show infomodal once after connection

* set service provider on tauri side

* Emit events when stopped

* listen and unlisten for tauri events

* connect: add trace log to get_services

* Add back CI notifications

* Update README

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com>

* Use default serde value for upgrade (#1807)

* fix ui overflow bug (#1808)

* update nym connect error text (#1809)

* set flag to false

* Fix wait_for_signal_and_error on win (#1811)

* Add socks5-client changes to nym-connect changelog

* Fix links in nym-connect changelog

* More entries in nym-connect CHANGELOG

* Fix typo in changelog

* Update CHANGELOG.md

* Experiment/client refactoring (#1814)

* experimenting with extracting more common client code

* drying up the wasm client

* allowing some dead code for the time being

* fixed formatting in nym-connect

* made socks5 client inside nym-connect immutable

* made clippy a bit happier

* hidden away target locking for recv timeout

* New transactions for increasing amount of pledged tokens

* unit tests

* Added an option to pledge extra tokens through the vesting contract

* Introduced wallet endpoints for new operations

* Using updated pledge cap in the vesting contract

* Bumping version numbers

* Changelog for v1.1.1

* Bumping final version numbers for 1.1.1

* Bumping nym-cli version, missed it last time

* socks5-client: SOCKS4a support (#1822)

* socks5-client: SOCKS4a support

* Tidy

* Fix a few errors in socks5 client and network-requester (#1823)

* Fix two unwraps in socks5 and network-requester

* Make sure client task never sends shutdown signal

* Fix panic on getting socks version

* wip

* connecting to the back and making the requests work

* display details modal

* logs removal

* Feature/pledge more (#1679)

* New transactions for increasing amount of pledged tokens

* unit tests

* Added an option to pledge extra tokens through the vesting contract

* Introduced wallet endpoints for new operations

* Using updated pledge cap in the vesting contract

* Changelog update

* nym-connect: update lock file

* avoid mix tokens pools

* amount error

* envs/mainnet: update to latest mixnet contract and nymd validator url

* validator-api: add missing shortform for --config-env-file (#1830)

* gateway-client: handle shutdown listener (#1829)

* WIP

* WIP: try another approach

* WIP

* Reworked

* Tidy

* fix

* validator-api: remove storage dependency in contract cache (#1685)

* validator-api: remove storage dependency in contract cache

* validator-client: update detailed routes

* contract_cache: forward to new endpoints for compat

* Move reward_estimate

* client: add --no-cover and update --fastmode (#1831)

* adding a oversaturaded bonding more modal

* common/task: extract out spawn_with_report_error (#1837)

* stop panic on failed buffer request

* Compilable wasm client

* Enabled hard error on lack of gateway-client protocol version

* Missing generic parameter for ClientCoreError in BackendError

* Removed unused imports

* Additional wasm feature locking

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
Co-authored-by: Fran Arbanas <arbanasfran@gmail.com>
Co-authored-by: cgi-bin/ <6095048+sven-hash@users.noreply.github.com>
Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com>
Co-authored-by: Bogdan-Ștefan Neacşu <bogdan@nymtech.net>
Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
Co-authored-by: Raphaël Walther <raphael@nymtech.net>
Co-authored-by: Fouad <fmtabbara@hotmail.co.uk>
Co-authored-by: Gala <calero.vg@gmail.com>
Co-authored-by: Dave Hrycyszyn <futurechimp@users.noreply.github.com>

* Making native client wait for shutdown

* Marking dead test code

* Feature/multi surbs invalidation (#1858)

* Cleaned up RealMessagesController constructor

* introduced config field for maximum_reply_surb_age

* Handling edge-case reply-surb failures

* invalidating old reply surbs

* Removing old reply keys from cache

* Invalidating old reply keys

* missing config changes

* logging created tag details

* Fixed clippy warning in test code

* Saving reply key timestamp on data flush (#1867)

* Remove panic if ReconstructedMessagesReceiver is closed (#1868)

Instead log error and return because presumably the shutdown procedure has started

* Feature/multi surbs basic wasm interface (#1846)

* Added builder to wasm client

* missing wasm_bindgen macros

* Added constructor macro on GatewayEndpointConfig

* Attempting to use updated wasm client api

* Removing dead code

* Exposed other messages types in wasm client

* cleanup in js-example

* Changed 'self_address' to be a method call

* Removed needless borrow when cloning an Arc

* Improving arguments in 'on_message' callback

* fixed wasm-client dependency/features

* Reverted hard requirement for gateway protocol presence (#1875)

* Feature/prioritise surb retransmission (#1883)

* Improved error messages + removed redundant variants

* Improved estimation of 'expected_forward_delay'

* Removed old wasm-specific startup code

* Removed old unused reply-related code

* hacky and temporary way of buffering retransmission data

* offloading retransmission reply handling to ReplyController

* fixed linter errors + rebuffering retransmission data on failure

* Removed unused fields from wasm client debug config

* Chore/v1.2.0 update (#2666)

* Network-requester: throttle inbound connections (#1789)

* Return and handle ClientRequest::LaneQueueLenghts

* Pass lane queue lengths to inbound future

* Remove unused self reference

* Request lane queue lengths periodically for all open connections

* Add timeouts

* Rename to ConnectionCommandSender and Receiver

* Rename to client_connection_tx/rx

* Fix wasm build

* Replace bool with enum

* rust: bump required version to 1.65 in some crates that need it

* Add step to release GH actions (#1792)

* feat: add a release step to nym contracts GH action

* feat: add shrinking the size of wasm

* Possibilty to change gateway ws listener (#1779)

* add: set gatewayListener

* Update types.ts

* Update worker.ts

* Update contracts-build.yml

* real_traffic_stream: reduce frequency of status print (#1794)

* Update wallet and connect lock files (#1793)

* client-core: add warning when delay multiplier is larger than 1

* Fix decrypting stored received msg (#1786)

* Fix decrypting stored received msg

* rustfmt

* Moving binary message recovery to separate function

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

* Feature/use expect instead of panicking (#1797)

* Implementation of 'Debug' on 'RealMessage'

* expect with failed channel name instead of throwing empty panics

* Introduced Debug trait constraint in ProxyRunner

* Derive Debug for socks5_requests::Message

* Make connection_id optional in ClientRequest::Send (#1798)

* changelog: add missing entry for fixing message decrypt in gateway-client

* websocket-requests: fix length check before deserialize (#1799)

* Fix export dkg contract addr (#1800)

* Export dkg contract for mainnet when no config file present

* Remove redundant env files

* nym-cli: improve error reporting/handling and changed `vesting-schedule` queries to use query client instead of signing client

* Feature/gateway client protocol version (#1795)

* Introducing concept of gateway protocol version

* Remove version-based gateway filtering

* Fixed the unit test

* grammar

* Set build on latest release on schedule event

* feat(wallet): buy page bootstrap

* feat(wallet-buy): tutorial

* feat(explorer-api): add route to fetch nym terms&cdts

* Revert "feat(explorer-api): add route to fetch nym terms&cdts"

This reverts commit 876f752697d89061b1904e1ddd1d5bcb7045dc5c.

* feat(wallet-buy-nym): buy page new ui

* fix(wallet-buy-nym): signature output

* feat(wallet-buy-nym): update signature modal ui

* Added nightly build workflow on second latest release

* socks5: if any task panics, signal all other tasks to shutdown (#1805)

* socks5: signal shutdown on error

* Mark as success

* Tidy

* Reduce wait to 5 sec

* Replace unwrap with expect

* Two more unwraps

* Update changelog

* client-core: less frequent status logging (#1806)

* Feature/nym connect UI updates (#1784)

* create custom titlebar

* create help page

* create generic modal component

* create separate connection time component

* link to shipyard docs

* move timer to separate component and update connection status component usage

* use separate component for copying ip and port details

* only show infomodal once after connection

* set service provider on tauri side

* Emit events when stopped

* listen and unlisten for tauri events

* connect: add trace log to get_services

* Add back CI notifications

* Update README

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com>

* Use default serde value for upgrade (#1807)

* fix ui overflow bug (#1808)

* feat(wallet): add link to nym exchange interface

* update nym connect error text (#1809)

* refactor(wallet): clean code

* set flag to false

* Fix wait_for_signal_and_error on win (#1811)

* Use config URLs in clients before the env values (#1813)

* Add socks5-client changes to nym-connect changelog

* Fix links in nym-connect changelog

* More entries in nym-connect CHANGELOG

* Fix typo in changelog

* Update CHANGELOG.md

* Experiment/client refactoring (#1814)

* experimenting with extracting more common client code

* drying up the wasm client

* allowing some dead code for the time being

* fixed formatting in nym-connect

* made socks5 client inside nym-connect immutable

* made clippy a bit happier

* hidden away target locking for recv timeout

* New transactions for increasing amount of pledged tokens

* unit tests

* Added an option to pledge extra tokens through the vesting contract

* Introduced wallet endpoints for new operations

* Using updated pledge cap in the vesting contract

* Feature/dkg integration tests (#1815)

* DKG contract e2e test

* Refactor to the same format as other contracts

* Vk share tests

* State tests

* Dealings tests

* Dealer tests

* Api dkg tests

* Fix path to contract after refactor

* Fix test target clippy

* Bumping version numbers

* Changelog for v1.1.1

* Bumping final version numbers for 1.1.1

* Bumping nym-cli version, missed it last time

* socks5-client: SOCKS4a support (#1822)

* socks5-client: SOCKS4a support

* Tidy

* Fix a few errors in socks5 client and network-requester (#1823)

* Fix two unwraps in socks5 and network-requester

* Make sure client task never sends shutdown signal

* Fix panic on getting socks version

* wip

* connecting to the back and making the requests work

* display details modal

* logs removal

* Feature/pledge more (#1679)

* New transactions for increasing amount of pledged tokens

* unit tests

* Added an option to pledge extra tokens through the vesting contract

* Introduced wallet endpoints for new operations

* Using updated pledge cap in the vesting contract

* Changelog update

* Feature/pledge more (#1679)

* New transactions for increasing amount of pledged tokens

* unit tests

* Added an option to pledge extra tokens through the vesting contract

* Introduced wallet endpoints for new operations

* Using updated pledge cap in the vesting contract

* Changelog update

* Fix a few errors in socks5 client and network-requester (backport) (#1824)

* Fix two unwraps in socks5 and network-requester

* Make sure client task never sends shutdown signal

* nym-connect: update lock file

* fix(wallet): typo

* avoid mix tokens pools

* fix(wallet): typo

* fix(wallet): buy tutorial ui responsivness

* amount error

* envs/mainnet: update to latest mixnet contract and nymd validator url

* validator-api: add missing shortform for --config-env-file (#1830)

* gateway-client: handle shutdown listener (#1829)

* WIP

* WIP: try another approach

* WIP

* Reworked

* Tidy

* fix

* validator-api: remove storage dependency in contract cache (#1685)

* validator-api: remove storage dependency in contract cache

* validator-client: update detailed routes

* contract_cache: forward to new endpoints for compat

* Move reward_estimate

* Node family management (#1670)

* Family management messages

* Add family queries

* Add queries to client

* Layer assignment message

* Paged family queries, annotate mixnodes with family

* Add layer assignments to epoch operations

* Remove family layer peristence

* Add NotImplemented error for kick

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

* Fixed layer distribution skewness check (#1766)

* client: add --no-cover and update --fastmode (#1831)

* adding a oversaturaded bonding more modal

* Use better naming on gateway credential handling (#1834)

* Fix comment in configuration file (#1836)

* common/task: extract out spawn_with_report_error (#1837)

* nym-connect/changelog: add note about disconnect fix

* Feature/simplify credential binary (#1841)

* Expose name of standard directories

* Use one command instead of two

* nym-connect: append error to failed message (#1839)

* nym-connect: append error to failed message

* changelog: add note

* Fix clippy

* remove extra checks to display vesting schedule(#1826)

* Set explorer to use rpc.nymtech.net

* update versions for platfrom, nym-connect and nym-wallet to v1.1.2

* changed nym-connect version to 1.1.1

* Modifying changelog for v1.1.2

* changed nym-connect version to 1.1.2

* update nym-connect CHANGELOG

* Updated changelog for wallet

* Feature/wallet content updates (#1825)

* fix up balance screen

* fix up app bar and nym logo alignment

* fix up delegation action icon font weight

* fix up bond page

* Corrected env variable name in workflows

* Use config URLs in clients before the env values (#1813)

* Feature/dkg integration tests (#1815)

* DKG contract e2e test

* Refactor to the same format as other contracts

* Vk share tests

* State tests

* Dealings tests

* Dealer tests

* Api dkg tests

* Fix path to contract after refactor

* Fix test target clippy

* Node family management (#1670)

* Family management messages

* Add family queries

* Add queries to client

* Layer assignment message

* Paged family queries, annotate mixnodes with family

* Add layer assignments to epoch operations

* Remove family layer peristence

* Add NotImplemented error for kick

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

* Fixed layer distribution skewness check (#1766)

* Use better naming on gateway credential handling (#1834)

* Fix comment in configuration file (#1836)

* nym-connect/changelog: add note about disconnect fix

* Feature/simplify credential binary (#1841)

* Expose name of standard directories

* Use one command instead of two

* Fix clippy

* feat(wallet): buy page bootstrap

* feat(wallet-buy): tutorial

* feat(explorer-api): add route to fetch nym terms&cdts

* Revert "feat(explorer-api): add route to fetch nym terms&cdts"

This reverts commit 876f752697d89061b1904e1ddd1d5bcb7045dc5c.

* feat(wallet-buy-nym): buy page new ui

* fix(wallet-buy-nym): signature output

* feat(wallet-buy-nym): update signature modal ui

* feat(wallet): add link to nym exchange interface

* refactor(wallet): clean code

* fix(wallet): typo

* fix(wallet): typo

* fix(wallet): buy tutorial ui responsivness

* update versions for platfrom, nym-connect and nym-wallet to v1.1.2

* changed nym-connect version to 1.1.1

* Modifying changelog for v1.1.2

* changed nym-connect version to 1.1.2

* update nym-connect CHANGELOG

* Updated changelog for wallet

* Resolve merge conflicts

* Update qa-qwerty.env

* Fixed URL to branch

* changed ubuntu-latest on GH actions to ubuntu-20.04

* docs: updated changelog for contracts release v1.1.2 and updated versions of mixnet and vesting contracts as well

* Add ignore to dkg expensive tests (#1856)

* introduce minimize button in custom title bar (#1843)

* refresh balance after sending tokens (#1857)

* Feature/fix client multi cred consume (#1859)

* Mark consumed credentials in the db

* Add signature log

* Fix wasm mock Storage trait

* Fix clippy

* Feature/verify bte proof (#1866)

* Update lock file

* Include bte public key verification

* Wallet - Buy, copy changes (#1855)

* use mix_id for account to get correct pending cost event (#1869)

* use mix_id for account to get correct pending cost event

* Properly add consumed to table (#1870)

* nym-connect: update Cargo.lock to 1.1.2

* Clients: save init results to JSON (#1865)

* clients: output results of init to json

* Remove leftover dbg

* Tidy

* Fix nym-connect

* Client: dedup setup gateway during init (#1871)

* clients: dedup gateway setup logic

* nym-connect: extract out print_save_config

* Feature/dkg state to disk (#1872)

* Add PersistentState

* Save and load state to/from disk

* If in progress, don't continually write the same state

* Fix tests and add serde one

* Update changelog

* Fix clippy

* network-requester: return error on socket close (#1876)

* network-requester: return error when the socket closes

* changelog: add note

* clients: further deduplicate init code (#1873)

* client-core: move init helpers to module

* WIP

* socks5: return error instead of terminate in init

* Extract out reuse_existing_gateway_config

* rustfmt

* Remove comment out code

* nym-connect: use setup_gateway

* Linebreak

* changelog: update

* Tweak log

* rustfmt

* client: pick from old lanes probabilisticlly (#1877)

* Pick from old lanes probabilisticly

* changelog: update

* clients: dont panic in base client gateway client handling (#1878)

* client-core: fix some panics related to gateway-client

* changelog: update

* fix

* changelog: fix wording

* Use default mainnet values when nothing is specified (#1884)

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
Co-authored-by: Fran Arbanas <arbanasfran@gmail.com>
Co-authored-by: cgi-bin/ <6095048+sven-hash@users.noreply.github.com>
Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com>
Co-authored-by: Bogdan-Ștefan Neacşu <bogdan@nymtech.net>
Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
Co-authored-by: Raphaël Walther <raphael@nymtech.net>
Co-authored-by: pierre <dommerc.pierre@gmail.com>
Co-authored-by: Fouad <fmtabbara@hotmail.co.uk>
Co-authored-by: Gala <calero.vg@gmail.com>
Co-authored-by: Dave Hrycyszyn <futurechimp@users.noreply.github.com>
Co-authored-by: Drazen Urch <drazen@urch.eu>
Co-authored-by: durch <durch@users.noreply.github.com>
Co-authored-by: Tommy Verrall <60836166+tommyv1987@users.noreply.github.com>

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
Co-authored-by: Fran Arbanas <arbanasfran@gmail.com>
Co-authored-by: cgi-bin/ <6095048+sven-hash@users.noreply.github.com>
Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com>
Co-authored-by: Bogdan-Ștefan Neacşu <bogdan@nymtech.net>
Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
Co-authored-by: Raphaël Walther <raphael@nymtech.net>
Co-authored-by: Fouad <fmtabbara@hotmail.co.uk>
Co-authored-by: Gala <calero.vg@gmail.com>
Co-authored-by: Dave Hrycyszyn <futurechimp@users.noreply.github.com>
Co-authored-by: pierre <dommerc.pierre@gmail.com>
Co-authored-by: Drazen Urch <drazen@urch.eu>
Co-authored-by: durch <durch@users.noreply.github.com>
Co-authored-by: Tommy Verrall <60836166+tommyv1987@users.noreply.github.com>
2022-12-13 12:11:30 +00:00
Jon Häggblad c720481a45 socks5: rework waiting in inbound.rs (#1880)
* socks5: rework waiting in inbound.rs

* changelog: add note

* out queue control: reduce old set size to 4
2022-12-13 11:39:02 +01:00
Jon Häggblad e18946efe1 nym-connect: send status messages from socks5 task to tauri backend (#1882)
* nym-connect: send status messages from socks5 task to tauri backend

* common/tasks: fix spawn for wasm

* Tidy up some names

* make status channel bounded in case there is no one listening
2022-12-13 10:53:01 +01:00
Bogdan-Ștefan Neacşu 47ca0d0358 Feature/dkg contract threshold (#1885)
* Save threshold in dkg contract

* Simplify the mock db for tests

* Add unit test
2022-12-13 11:52:18 +02:00
Bogdan-Ștefan Neacşu 00f17c376a Use default mainnet values when nothing is specified (#1884) 2022-12-12 16:34:56 +02:00
Jon Häggblad 5283329914 changelog: fix wording 2022-12-09 22:35:37 +01:00
Jon Häggblad 29dd121282 clients: dont panic in base client gateway client handling (#1878)
* client-core: fix some panics related to gateway-client

* changelog: update

* fix
2022-12-09 21:43:37 +01:00
Jon Häggblad cd1d9d1a0d client: pick from old lanes probabilisticlly (#1877)
* Pick from old lanes probabilisticly

* changelog: update
2022-12-09 18:44:40 +01:00
Jon Häggblad b694e675e6 clients: further deduplicate init code (#1873)
* client-core: move init helpers to module

* WIP

* socks5: return error instead of terminate in init

* Extract out reuse_existing_gateway_config

* rustfmt

* Remove comment out code

* nym-connect: use setup_gateway

* Linebreak

* changelog: update

* Tweak log

* rustfmt
2022-12-09 16:12:30 +01:00
Jon Häggblad 39cb6f6ec0 network-requester: return error on socket close (#1876)
* network-requester: return error when the socket closes

* changelog: add note
2022-12-09 15:04:47 +01:00
fmtabbara 7a52124d53 content updates 2022-12-09 13:29:06 +00:00
fmtabbara 2ec5616453 text update 2022-12-09 13:07:59 +00:00
Bogdan-Ștefan Neacşu ebaf99fadb Feature/dkg state to disk (#1872)
* Add PersistentState

* Save and load state to/from disk

* If in progress, don't continually write the same state

* Fix tests and add serde one

* Update changelog

* Fix clippy
2022-12-09 13:00:27 +02:00
fmtabbara c534c4b91d remove fixed height for mnemonic input 2022-12-09 10:28:49 +00:00
Jon Häggblad 85515fe16e Client: dedup setup gateway during init (#1871)
* clients: dedup gateway setup logic

* nym-connect: extract out print_save_config
2022-12-08 22:59:11 +01:00
Jon Häggblad ec60966a85 Clients: save init results to JSON (#1865)
* clients: output results of init to json

* Remove leftover dbg

* Tidy

* Fix nym-connect
2022-12-08 19:39:11 +01:00
Jon Häggblad d1df407bac nym-connect: update Cargo.lock to 1.1.2 2022-12-08 16:58:41 +01:00
Bogdan-Ștefan Neacşu 9ff4051b0f Properly add consumed to table (#1870) 2022-12-08 17:47:41 +02:00
Fouad fea9ec0f9f use mix_id for account to get correct pending cost event (#1869)
* use mix_id for account to get correct pending cost event
2022-12-08 15:42:26 +00:00
Pierre Dommerc d48d094672 Wallet - Buy, copy changes (#1855) 2022-12-08 15:54:33 +01:00
Bogdan-Ștefan Neacşu e1b511e788 Feature/verify bte proof (#1866)
* Update lock file

* Include bte public key verification
2022-12-08 14:06:24 +02:00
Bogdan-Ștefan Neacşu 1500d27ce5 Feature/fix client multi cred consume (#1859)
* Mark consumed credentials in the db

* Add signature log

* Fix wasm mock Storage trait

* Fix clippy
2022-12-08 11:06:31 +02:00
Fouad a0eba073ec refresh balance after sending tokens (#1857) 2022-12-07 17:17:58 +00:00
Fouad 2c3e716ba1 introduce minimize button in custom title bar (#1843) 2022-12-07 17:17:30 +00:00
Bogdan-Ștefan Neacşu b76051832f Add ignore to dkg expensive tests (#1856) 2022-12-07 13:53:28 +02:00
farbanas c966680bba Merge branch 'release/v1.1.2' into develop 2022-12-07 12:36:55 +01:00
farbanas 7f7d30c9b5 docs: updated changelog for contracts release v1.1.2 and updated versions of mixnet and vesting contracts as well 2022-12-07 12:36:24 +01:00
farbanas b08dace119 changed ubuntu-latest on GH actions to ubuntu-20.04 2022-12-07 12:23:33 +01:00
Jon Häggblad 58255857e5 Merge remote-tracking branch 'origin/release/v1.1.2' into develop 2022-12-07 12:14:15 +01:00
fmtabbara bd1d88e9e8 fix display mnemonic bug 2022-12-07 10:40:43 +00:00
Raphaël Walther edf38e6356 Fixed URL to branch 2022-12-07 10:40:43 +01:00
Tommy Verrall e258f62a26 Update qa-qwerty.env 2022-12-07 08:11:11 +01:00
durch 940427776c Resolve merge conflicts 2022-12-06 20:30:57 +01:00
Dave Hrycyszyn 2f7d9254b8 Updated changelog for wallet 2022-12-06 19:13:08 +01:00
farbanas 67321d7d04 update nym-connect CHANGELOG 2022-12-06 19:13:07 +01:00
farbanas e38a20fb58 changed nym-connect version to 1.1.2 2022-12-06 19:12:30 +01:00
Dave Hrycyszyn 8e45e3e995 Modifying changelog for v1.1.2 2022-12-06 19:12:27 +01:00
farbanas 2f63d916b6 changed nym-connect version to 1.1.1 2022-12-06 19:12:07 +01:00
farbanas 0b465e1f09 update versions for platfrom, nym-connect and nym-wallet to v1.1.2 2022-12-06 19:12:02 +01:00
pierre f93aab2f5b fix(wallet): buy tutorial ui responsivness 2022-12-06 19:09:38 +01:00
pierre 7ff06cfe3e fix(wallet): typo 2022-12-06 19:09:38 +01:00
pierre 8c7e7dfcd1 fix(wallet): typo 2022-12-06 19:09:38 +01:00
pierre 31ca88fd7f refactor(wallet): clean code 2022-12-06 19:09:38 +01:00
pierre 51b29a9dcf feat(wallet): add link to nym exchange interface 2022-12-06 19:09:38 +01:00
pierre d58c2da463 feat(wallet-buy-nym): update signature modal ui 2022-12-06 19:09:38 +01:00
pierre 5644726a7b fix(wallet-buy-nym): signature output 2022-12-06 19:09:38 +01:00
pierre e9ba34ba52 feat(wallet-buy-nym): buy page new ui 2022-12-06 19:09:38 +01:00
pierre a33e848d6d Revert "feat(explorer-api): add route to fetch nym terms&cdts"
This reverts commit 876f752697d89061b1904e1ddd1d5bcb7045dc5c.
2022-12-06 19:09:38 +01:00
pierre 3da9d2944b feat(explorer-api): add route to fetch nym terms&cdts 2022-12-06 19:09:38 +01:00
pierre e2c9f69ab9 feat(wallet-buy): tutorial 2022-12-06 19:09:38 +01:00
pierre 8a21f183f9 feat(wallet): buy page bootstrap 2022-12-06 19:09:38 +01:00
Bogdan-Ștefan Neacșu cb2a89dceb Fix clippy 2022-12-06 19:09:38 +01:00
Bogdan-Ștefan Neacşu 502e23b42c Feature/simplify credential binary (#1841)
* Expose name of standard directories

* Use one command instead of two
2022-12-06 19:09:38 +01:00
Jon Häggblad 2676c68b77 nym-connect/changelog: add note about disconnect fix 2022-12-06 19:09:36 +01:00
Bogdan-Ștefan Neacşu c5252f348d Fix comment in configuration file (#1836) 2022-12-06 19:09:15 +01:00
Bogdan-Ștefan Neacşu bd8cea3ba3 Use better naming on gateway credential handling (#1834) 2022-12-06 19:09:13 +01:00
Jędrzej Stuczyński 7ddc8e80e6 Fixed layer distribution skewness check (#1766) 2022-12-06 19:08:10 +01:00
Drazen Urch 03a974ec34 Node family management (#1670)
* Family management messages

* Add family queries

* Add queries to client

* Layer assignment message

* Paged family queries, annotate mixnodes with family

* Add layer assignments to epoch operations

* Remove family layer peristence

* Add NotImplemented error for kick

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2022-12-06 19:08:07 +01:00
Bogdan-Ștefan Neacşu 5c841de6ae Feature/dkg integration tests (#1815)
* DKG contract e2e test

* Refactor to the same format as other contracts

* Vk share tests

* State tests

* Dealings tests

* Dealer tests

* Api dkg tests

* Fix path to contract after refactor

* Fix test target clippy
2022-12-06 19:06:31 +01:00
Bogdan-Ștefan Neacşu 9a8218905e Use config URLs in clients before the env values (#1813) 2022-12-06 19:06:31 +01:00
Raphaël Walther f6fca0ad37 Corrected env variable name in workflows 2022-12-06 15:45:32 +01:00
Fouad 9a8c5c3708 Feature/wallet content updates (#1825)
* fix up balance screen

* fix up app bar and nym logo alignment

* fix up delegation action icon font weight

* fix up bond page
2022-12-06 14:11:04 +00:00
Dave Hrycyszyn c39afd0b65 Updated changelog for wallet 2022-12-06 13:58:59 +00:00
farbanas 31be7a6170 update nym-connect CHANGELOG 2022-12-06 14:42:12 +01:00
farbanas fee780489c changed nym-connect version to 1.1.2 2022-12-06 14:08:33 +01:00
Dave Hrycyszyn 957c6fbba0 Modifying changelog for v1.1.2 2022-12-06 13:04:31 +00:00
farbanas 7e56a7a8b2 changed nym-connect version to 1.1.1 2022-12-06 13:53:35 +01:00
farbanas b273df297a update versions for platfrom, nym-connect and nym-wallet to v1.1.2 2022-12-06 13:50:45 +01:00
Dave Hrycyszyn d4979c1f0a Merge branch 'feature/buy' into release/v1.1.2 2022-12-06 12:35:26 +00:00
Raphaël Walther 52136d727b Set explorer to use rpc.nymtech.net 2022-12-06 11:00:33 +01:00
Fouad edd5c363bb remove extra checks to display vesting schedule(#1826) 2022-12-06 09:37:11 +00:00
Bogdan-Ștefan Neacșu 1171f18399 Fix clippy 2022-12-06 10:48:32 +02:00
Jon Häggblad 028bee804b nym-connect: append error to failed message (#1839)
* nym-connect: append error to failed message

* changelog: add note
2022-12-05 15:58:59 +01:00
Bogdan-Ștefan Neacşu 2515646075 Feature/simplify credential binary (#1841)
* Expose name of standard directories

* Use one command instead of two
2022-12-05 16:58:36 +02:00
Jon Häggblad 74d34aeebc nym-connect/changelog: add note about disconnect fix 2022-12-05 14:53:05 +01:00
Jon Häggblad a16c566719 common/task: extract out spawn_with_report_error (#1837) 2022-12-05 14:44:44 +01:00
Bogdan-Ștefan Neacşu d495aefb0d Fix comment in configuration file (#1836) 2022-12-05 15:03:01 +02:00
Gala 667d5f3033 Merge pull request #1828 from nymtech/feat-508-bond-more
Feat 508 bond more
2022-12-05 13:13:57 +01:00
Bogdan-Ștefan Neacşu ce4fd0588c Use better naming on gateway credential handling (#1834) 2022-12-05 14:02:30 +02:00
Gala b51aac6047 Merge branch 'develop' into feat-508-bond-more 2022-12-05 12:18:13 +01:00
Gala a21be84833 adding a oversaturaded bonding more modal 2022-12-05 12:13:14 +01:00
Jon Häggblad 49f7c48b1b client: add --no-cover and update --fastmode (#1831) 2022-12-05 11:14:41 +01:00
Jędrzej Stuczyński 29c073d25c Fixed layer distribution skewness check (#1766) 2022-12-05 09:28:32 +00:00
Drazen Urch 7e3bc2d6bb Node family management (#1670)
* Family management messages

* Add family queries

* Add queries to client

* Layer assignment message

* Paged family queries, annotate mixnodes with family

* Add layer assignments to epoch operations

* Remove family layer peristence

* Add NotImplemented error for kick

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2022-12-05 09:36:06 +01:00
Jon Häggblad 6943271942 validator-api: remove storage dependency in contract cache (#1685)
* validator-api: remove storage dependency in contract cache

* validator-client: update detailed routes

* contract_cache: forward to new endpoints for compat

* Move reward_estimate
2022-12-02 14:40:19 +01:00
Jon Häggblad a872b478d2 gateway-client: handle shutdown listener (#1829)
* WIP

* WIP: try another approach

* WIP

* Reworked

* Tidy

* fix
2022-12-02 12:36:06 +01:00
Jon Häggblad 11051ba929 validator-api: add missing shortform for --config-env-file (#1830) 2022-12-02 09:23:34 +01:00
Jon Häggblad 10e28c6e5c envs/mainnet: update to latest mixnet contract and nymd validator url 2022-12-01 23:09:37 +01:00
Gala 78af0bff71 amount error 2022-12-01 16:47:46 +01:00
pierre e15183029b fix(wallet): buy tutorial ui responsivness 2022-12-01 16:39:27 +01:00
pierre 39ab252941 fix(wallet): typo 2022-12-01 16:00:42 +01:00
Gala 3d2dee3e1c avoid mix tokens pools 2022-12-01 15:46:58 +01:00
pierre 4ccd4d258a fix(wallet): typo 2022-12-01 15:40:09 +01:00
Jon Häggblad 25212f23ad nym-connect: update lock file 2022-12-01 14:40:27 +01:00
Jon Häggblad ab4e39e1b3 Fix a few errors in socks5 client and network-requester (backport) (#1824)
* Fix two unwraps in socks5 and network-requester

* Make sure client task never sends shutdown signal
2022-12-01 14:25:59 +01:00
Jędrzej Stuczyński 66e5119114 Feature/pledge more (#1679)
* New transactions for increasing amount of pledged tokens

* unit tests

* Added an option to pledge extra tokens through the vesting contract

* Introduced wallet endpoints for new operations

* Using updated pledge cap in the vesting contract

* Changelog update
2022-12-01 12:51:32 +00:00
Gala 96c0256154 Merge branch 'develop' into feat-508-bond-more 2022-12-01 13:46:21 +01:00
Jędrzej Stuczyński 033333bb52 Feature/pledge more (#1679)
* New transactions for increasing amount of pledged tokens

* unit tests

* Added an option to pledge extra tokens through the vesting contract

* Introduced wallet endpoints for new operations

* Using updated pledge cap in the vesting contract

* Changelog update
2022-12-01 12:44:20 +00:00
Gala bf207abe55 logs removal 2022-12-01 13:25:32 +01:00
Gala 4069b0349d display details modal 2022-12-01 13:15:16 +01:00
Gala bca20e1dfd connecting to the back and making the requests work 2022-12-01 12:57:28 +01:00
Gala 1bc94d8fd4 Merge branch 'feature/pledge-more' into feat-508-bond-more 2022-12-01 11:47:44 +01:00
Gala a269bd8289 wip 2022-12-01 11:46:58 +01:00
Jon Häggblad eedf3d996a Merge remote-tracking branch 'origin/release/v1.1.1' into release/v1.1.3 2022-12-01 11:38:36 +01:00
Jon Häggblad 52d06785fb Fix a few errors in socks5 client and network-requester (#1823)
* Fix two unwraps in socks5 and network-requester

* Make sure client task never sends shutdown signal

* Fix panic on getting socks version
2022-12-01 11:20:31 +01:00
Jon Häggblad 1507938c65 socks5-client: SOCKS4a support (#1822)
* socks5-client: SOCKS4a support

* Tidy
2022-12-01 09:19:17 +01:00
Dave Hrycyszyn 41b37984a4 Bumping nym-cli version, missed it last time 2022-11-29 17:51:37 +00:00
Dave Hrycyszyn b541d1a034 Merge branch 'master' into develop 2022-11-29 17:40:30 +00:00
Dave Hrycyszyn e4f34833ef Bumping final version numbers for 1.1.1 2022-11-29 17:22:33 +00:00
Dave Hrycyszyn 5044764a80 Changelog for v1.1.1 2022-11-29 17:21:05 +00:00
Dave Hrycyszyn c178438f06 Bumping version numbers 2022-11-29 17:18:57 +00:00
Bogdan-Ștefan Neacşu 5d51f4dc71 Feature/dkg integration tests (#1815)
* DKG contract e2e test

* Refactor to the same format as other contracts

* Vk share tests

* State tests

* Dealings tests

* Dealer tests

* Api dkg tests

* Fix path to contract after refactor

* Fix test target clippy
2022-11-29 18:32:37 +02:00
Jędrzej Stuczyński bc25288d08 Using updated pledge cap in the vesting contract 2022-11-29 16:18:21 +00:00
Jędrzej Stuczyński 3a001e2f9f Introduced wallet endpoints for new operations 2022-11-29 16:08:55 +00:00
Jędrzej Stuczyński 09cad3c589 Added an option to pledge extra tokens through the vesting contract 2022-11-29 16:08:11 +00:00
Jędrzej Stuczyński ab0180c5ce unit tests 2022-11-29 16:08:11 +00:00
Jędrzej Stuczyński a77f364466 New transactions for increasing amount of pledged tokens 2022-11-29 16:03:54 +00:00
Jon Häggblad a9be8a6abd Merge remote-tracking branch 'origin/release/v1.1.2' into develop 2022-11-29 16:49:33 +01:00
Jędrzej Stuczyński 8de9f36b69 Experiment/client refactoring (#1814)
* experimenting with extracting more common client code

* drying up the wasm client

* allowing some dead code for the time being

* fixed formatting in nym-connect

* made socks5 client inside nym-connect immutable

* made clippy a bit happier

* hidden away target locking for recv timeout
2022-11-29 15:48:12 +00:00
Fouad 22f3c8aa40 Update CHANGELOG.md 2022-11-29 14:57:04 +00:00
Jon Häggblad de2e721ba7 Fix typo in changelog 2022-11-29 15:36:54 +01:00
Jon Häggblad b94fbcb6db More entries in nym-connect CHANGELOG 2022-11-29 15:36:14 +01:00
Jon Häggblad 7735f64c6d Fix links in nym-connect changelog 2022-11-29 15:29:59 +01:00
Jon Häggblad 3857313808 Add socks5-client changes to nym-connect changelog 2022-11-29 15:19:34 +01:00
Jon Häggblad 9d60de0091 Merge remote-tracking branch 'origin/release/v1.1.2' into release/v1.1.3 2022-11-29 12:57:48 +01:00
Bogdan-Ștefan Neacşu ca7c5d80ce Use config URLs in clients before the env values (#1813) 2022-11-29 13:52:08 +02:00
Jon Häggblad 24e2eee547 Merge remote-tracking branch 'origin/release/v1.1.2' into develop 2022-11-29 12:47:52 +01:00
Gala bdb724e9ca Merge pull request #1812 from nymtech/no-display-maintenance
No display maintenance banner
2022-11-29 09:51:55 +01:00
Jon Häggblad 89b35c1483 Fix wait_for_signal_and_error on win (#1811) 2022-11-29 09:43:08 +01:00
Gala 76ef50dc17 Merge branch 'develop' into no-display-maintenance 2022-11-29 09:32:55 +01:00
Gala f663623768 set flag to false 2022-11-29 09:32:22 +01:00
pierre 731780993f refactor(wallet): clean code 2022-11-28 16:01:08 +01:00
Fouad 822a3b70b7 update nym connect error text (#1809) 2022-11-28 14:37:06 +00:00
Jon Häggblad 136202f329 Merge remote-tracking branch 'origin/release/v1.1.2' into develop 2022-11-28 13:49:46 +01:00
pierre c02bcb460f feat(wallet): add link to nym exchange interface 2022-11-28 13:36:17 +01:00
Fouad 66257669fc fix ui overflow bug (#1808) 2022-11-28 12:26:11 +00:00
Jon Häggblad c605a9dd9a Merge remote-tracking branch 'origin/release/v1.1.1' into release/v1.1.2 2022-11-28 13:05:58 +01:00
Bogdan-Ștefan Neacşu f3e226b2bf Use default serde value for upgrade (#1807) 2022-11-28 13:27:48 +02:00
Fouad d004db8037 Feature/nym connect UI updates (#1784)
* create custom titlebar

* create help page

* create generic modal component

* create separate connection time component

* link to shipyard docs

* move timer to separate component and update connection status component usage

* use separate component for copying ip and port details

* only show infomodal once after connection

* set service provider on tauri side

* Emit events when stopped

* listen and unlisten for tauri events

* connect: add trace log to get_services

* Add back CI notifications

* Update README

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com>
2022-11-28 11:22:11 +00:00
Jon Häggblad 018bf8c241 client-core: less frequent status logging (#1806) 2022-11-28 12:14:27 +01:00
Jon Häggblad 65a69b2cba socks5: if any task panics, signal all other tasks to shutdown (#1805)
* socks5: signal shutdown on error

* Mark as success

* Tidy

* Reduce wait to 5 sec

* Replace unwrap with expect

* Two more unwraps

* Update changelog
2022-11-28 10:49:00 +01:00
Raphaël Walther d25848e6f8 Added nightly build workflow on second latest release 2022-11-28 10:41:17 +01:00
pierre bdb6aa848e feat(wallet-buy-nym): update signature modal ui 2022-11-28 10:35:15 +01:00
pierre 32b535d67f fix(wallet-buy-nym): signature output 2022-11-28 10:35:15 +01:00
pierre 9e1109a577 feat(wallet-buy-nym): buy page new ui 2022-11-28 10:35:15 +01:00
pierre 247a7ba1dc Revert "feat(explorer-api): add route to fetch nym terms&cdts"
This reverts commit 876f752697d89061b1904e1ddd1d5bcb7045dc5c.
2022-11-28 10:35:15 +01:00
pierre 77d10358d4 feat(explorer-api): add route to fetch nym terms&cdts 2022-11-28 10:35:15 +01:00
pierre fb2a61bed3 feat(wallet-buy): tutorial 2022-11-28 10:35:15 +01:00
pierre 4c2c101e57 feat(wallet): buy page bootstrap 2022-11-28 10:35:15 +01:00
Raphaël Walther 0084ba221b Set build on latest release on schedule event 2022-11-25 16:03:43 +01:00
Jędrzej Stuczyński 186896bb37 Feature/gateway client protocol version (#1795)
* Introducing concept of gateway protocol version

* Remove version-based gateway filtering

* Fixed the unit test

* grammar
2022-11-25 13:29:42 +00:00
Mark Sinclair df90ff8658 nym-cli: improve error reporting/handling and changed vesting-schedule queries to use query client instead of signing client 2022-11-25 13:16:44 +00:00
Bogdan-Ștefan Neacşu bff079a3f8 Fix export dkg contract addr (#1800)
* Export dkg contract for mainnet when no config file present

* Remove redundant env files
2022-11-25 14:18:07 +02:00
Jon Häggblad e2ba85c9bf websocket-requests: fix length check before deserialize (#1799) 2022-11-25 10:54:12 +01:00
Jon Häggblad cb7e57b5f8 changelog: add missing entry for fixing message decrypt in gateway-client 2022-11-25 10:54:12 +01:00
Jon Häggblad 17f89aecd5 Make connection_id optional in ClientRequest::Send (#1798) 2022-11-25 10:54:12 +01:00
Jędrzej Stuczyński 0be6fe5079 Feature/use expect instead of panicking (#1797)
* Implementation of 'Debug' on 'RealMessage'

* expect with failed channel name instead of throwing empty panics

* Introduced Debug trait constraint in ProxyRunner

* Derive Debug for socks5_requests::Message
2022-11-25 10:54:12 +01:00
Jon Häggblad 358687f43a Fix decrypting stored received msg (#1786)
* Fix decrypting stored received msg

* rustfmt

* Moving binary message recovery to separate function

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2022-11-25 10:54:12 +01:00
Jon Häggblad fb31dbee16 client-core: add warning when delay multiplier is larger than 1 2022-11-25 10:54:12 +01:00
Jon Häggblad bb98d796a8 Update wallet and connect lock files (#1793) 2022-11-25 10:54:12 +01:00
Jon Häggblad 30dc929e40 real_traffic_stream: reduce frequency of status print (#1794) 2022-11-25 10:54:12 +01:00
Mark Sinclair f1378c3488 Update contracts-build.yml 2022-11-25 10:54:12 +01:00
cgi-bin/ 39ca9c22af Possibilty to change gateway ws listener (#1779)
* add: set gatewayListener

* Update types.ts

* Update worker.ts
2022-11-25 10:54:12 +01:00
Fran Arbanas 4ff741ed9a Add step to release GH actions (#1792)
* feat: add a release step to nym contracts GH action

* feat: add shrinking the size of wasm
2022-11-25 10:54:12 +01:00
Jon Häggblad c9779df2a4 rust: bump required version to 1.65 in some crates that need it 2022-11-25 10:54:12 +01:00
Jon Häggblad c6d624a3b3 Network-requester: throttle inbound connections (#1789)
* Return and handle ClientRequest::LaneQueueLenghts

* Pass lane queue lengths to inbound future

* Remove unused self reference

* Request lane queue lengths periodically for all open connections

* Add timeouts

* Rename to ConnectionCommandSender and Receiver

* Rename to client_connection_tx/rx

* Fix wasm build

* Replace bool with enum
2022-11-25 10:54:12 +01:00
Jon Häggblad 9c361385a7 websocket-requests: fix length check before deserialize (#1799) 2022-11-24 23:45:25 +01:00
Jon Häggblad a9983003d4 changelog: add missing entry for fixing message decrypt in gateway-client 2022-11-24 23:29:37 +01:00
Jon Häggblad e645d14005 Make connection_id optional in ClientRequest::Send (#1798) 2022-11-24 23:13:51 +01:00
Jędrzej Stuczyński cbf9db91ab Feature/use expect instead of panicking (#1797)
* Implementation of 'Debug' on 'RealMessage'

* expect with failed channel name instead of throwing empty panics

* Introduced Debug trait constraint in ProxyRunner

* Derive Debug for socks5_requests::Message
2022-11-24 17:02:31 +00:00
Jon Häggblad 8304146195 Fix decrypting stored received msg (#1786)
* Fix decrypting stored received msg

* rustfmt

* Moving binary message recovery to separate function

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2022-11-24 10:26:09 +01:00
Jon Häggblad c5c16cd6b0 client-core: add warning when delay multiplier is larger than 1 2022-11-23 21:00:48 +01:00
Jon Häggblad 258fa41271 Update wallet and connect lock files (#1793) 2022-11-23 20:59:12 +01:00
Jon Häggblad 0a41834fbe real_traffic_stream: reduce frequency of status print (#1794) 2022-11-23 16:56:09 +01:00
Mark Sinclair 9637afea85 Update contracts-build.yml 2022-11-23 15:51:21 +00:00
cgi-bin/ c8b454a085 Possibilty to change gateway ws listener (#1779)
* add: set gatewayListener

* Update types.ts

* Update worker.ts
2022-11-23 15:14:43 +00:00
Fran Arbanas 81f7457e0e Add step to release GH actions (#1792)
* feat: add a release step to nym contracts GH action

* feat: add shrinking the size of wasm
2022-11-23 15:13:18 +00:00
Jon Häggblad 63ae568cc2 rust: bump required version to 1.65 in some crates that need it 2022-11-23 15:52:58 +01:00
Jon Häggblad f3c1ff02e2 Network-requester: throttle inbound connections (#1789)
* Return and handle ClientRequest::LaneQueueLenghts

* Pass lane queue lengths to inbound future

* Remove unused self reference

* Request lane queue lengths periodically for all open connections

* Add timeouts

* Rename to ConnectionCommandSender and Receiver

* Rename to client_connection_tx/rx

* Fix wasm build

* Replace bool with enum
2022-11-23 12:03:58 +01:00
Bogdan-Ștefan Neacşu f4fb0d6d6c Remove required deposit from signers (#1791) 2022-11-23 12:10:24 +02:00
Jon Häggblad 236594f0c6 Fix clippy::derive-partial-eq-without-eq (#1790) 2022-11-23 10:09:50 +01:00
Jon Häggblad e873845178 Fix some client send unwraps encountered during use (#1787) 2022-11-23 10:09:22 +01:00
Raphaël Walther 2e2f2bb702 atty is unmaintained 2022-11-22 15:28:08 +01:00
Bogdan-Ștefan Neacşu 1cec2ddff0 Remove debugging transaction (#1788) 2022-11-22 14:33:35 +02:00
Bogdan-Ștefan Neacşu 2db1bc8efa Feature/dkg publish vk (#1747)
* Save to disk coconut keypair

* Check verification keys of the other signers

* Post verification key to chain

* Add multisig propose/vote for vks

* Execute the proposal

* Parse announce address argument

* Gateway uses chain data

* Network requester uses chain data

* Native&socks5 clients use chain data

* Credential client signature uses chain data

* Remove redundant api endpoints

* Undo debugging logging

* Fix some tests

* Fix clippy

* Fix wasm client and contract test

* More contract clippy

* Update CHANGELOG

* Use a bigger expiry period then the testing one
2022-11-22 11:16:02 +02:00
Jon Häggblad f1deebc0f1 ci: check formatting first, and add all targets to coconut clippy step 2022-11-22 09:29:32 +01:00
Jon Häggblad 9063a86d26 client: log and handle error when cant load reply key storage (#1785)
* client: log and handle error when cant load reply key storage

* clippy
2022-11-22 01:15:50 +01:00
Jon Häggblad d82fd620ad Update blake2 and ed25519 deps (#1762) 2022-11-22 01:09:12 +01:00
Jon Häggblad fa95d15eac socks5-client: throttle connection inbound from application until data is sent (#1783)
* socks5: throttle send

* client-connections: add additional methods

* WIP

* Update

* Input message sender bounded

* WIP

* Remove the delay that is no longer needed

* rustfmt

* clippy

* Fix wasm build

* clippy

* Try to use MixProxySender/Reader type alias

* Extract out wait function

* Wait on every msg

* changelog: add note

* rustfmt
2022-11-21 23:52:30 +01:00
Bogdan-Ștefan Neacşu b71a8708db Feature/dkg dealing (#1708)
* Reintroduce epoch states

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

* Use admin address for sensible txs

* Validator-api watch contract and handle events

* Handle dealing exchange

* Dealing exchange

* Recover raw verification keys for 5 dkgs

* Test coconut with dkg keys

* Split dealing storage

* Finish dkg task when it achieved its purpose

* Temporary fix for clippy

* Fix clippy

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2022-11-21 18:00:47 +02:00
Bogdan-Ștefan Neacşu fea6f44a57 Feature/dkg (#1678)
* Port code without epoch and blacklisting

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

* Add dkg contract to validator client

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

* Introduce publisher

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

* Fix mock testing client

* Apply fmt to contract

* Get data from attributes

* Minor fixes

* Fix wasm client

* Add pem files for dkg keys

* Save/load dkg keys in/from pem files

* Get dealer old or fresh dealer index

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2022-11-21 17:28:26 +02:00
Raphaël Walther 23e97e9643 Set schedule for nightly build on release 2022-11-21 16:23:36 +01:00
Raphaël Walther 3f5bfcc696 Cleaned 2022-11-21 16:20:44 +01:00
Raphaël Walther f568673fbc Debugging workflow 2022-11-21 16:13:46 +01:00
Jon Häggblad f6576939d9 Merge remote-tracking branch 'origin/release/v1.1.1' into develop 2022-11-21 16:09:29 +01:00
Raphaël Walther ce17196d48 Debugging workflow 2022-11-21 16:04:12 +01:00
Raphaël Walther 6dde8ecd0a Debugging 2022-11-21 15:49:55 +01:00
Jon Häggblad 1db5e6af05 Merge remote-tracking branch 'origin/release/v1.1.0' into release/v1.1.1 2022-11-21 15:45:18 +01:00
Bogdan-Ștefan Neacşu c4ee964557 Setup with 1 epoch and full test that skips key update (#1647)
* Setup with 1 epoch and full test that skips key update

* Remove a bunch of epoch code

* Remove unnecessary map from one element vector

* Remove tau, epoch and lambda_t

* Removed lambda_t completely

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2022-11-21 16:34:50 +02:00
Raphaël Walther 9337821712 Removed extra spaces in sed expression 2022-11-21 15:07:50 +01:00
Raphaël Walther 279ba7034c Typo 2022-11-21 14:53:30 +01:00
Jon Häggblad 1859ca0a30 client-core: expose lane queue length state to other components (#1777)
* client-core: publish lane queue lengths

* client-connections: rename to LaneQueueLenghts plural

* Fix clippy

* Fix wasm build

* rustfmt

* clippy
2022-11-21 11:21:28 +01:00
Mark Sinclair e30fd270a1 Publish @nymproject/sdk v1.1.4 2022-11-18 15:32:57 +00:00
Jon Häggblad 3ae16fbf1d network-requester: make arguments to run into flags (#1776) 2022-11-18 15:22:33 +01:00
Mark Sinclair e3cda93919 WASM client: update crate version so that the client works with mainnet 2022-11-18 13:06:03 +00:00
benedetta davico 87fb4daeda Release/v1.1.1 nym wallet (#1775)
* fix undelegating with vesting tokens

* update version number

* update tauri conf version

* fix(wallet): explorer links

* refactor(explorer): rename mixnodeidentitykey to mixid

* fix(wallet): broken explorer links

Co-authored-by: fmtabbara <fmtabbara@hotmail.co.uk>
Co-authored-by: pierre <dommerc.pierre@gmail.com>
2022-11-18 12:38:16 +00:00
Dave Hrycyszyn 9f56796bf6 Removing unused nym-chitchat experiment 2022-11-18 12:28:21 +00:00
Jon Häggblad 09b51226c2 client: add LaneQueueLength to ServerResponse (#1772)
* client: add LaneQueueLength to ServerResponse

* fix test compilation

* changlog: add note
2022-11-18 10:24:28 +01:00
Jędrzej Stuczyński 6946151b25 Made vesting_contract_address argument peroperly optional (#1769)
* Made vesting_contract_address argument peroperly optional

* Updated changelog
2022-11-17 17:13:58 +00:00
Jon Häggblad a4aee465fa Merge pull request #1758 from nymtech/jon/fix/deserialize-length-check
Fix deserialize length check
2022-11-17 16:09:54 +01:00
Jon Häggblad 0d71ac5e75 websocket-requests: fix lints in file 2022-11-17 15:32:12 +01:00
Jon Häggblad ce14e40968 websocket-requests: fix deserialize length check 2022-11-17 15:32:12 +01:00
Pierre Dommerc d108edb424 fix(nym-cli): typo in sign command json output (#1768) 2022-11-17 15:15:45 +01:00
Tommy Verrall 18f5623b05 Merge pull request #1759 from nymtech/feature/mixnet-contract-migratemsg
Added migration code for updating vesting contract address
2022-11-17 12:48:57 +01:00
Mark Sinclair 8e92801929 Reduce logging in explorer api 2022-11-16 16:45:59 +00:00
Gala 3fc1bc4e7c Merge pull request #1764 from nymtech/no-display-maintenance
Update banner
2022-11-16 17:25:40 +01:00
Gala 72de726762 another text update 2022-11-16 16:08:47 +00:00
Gala cb9dfa8188 update banner text 2022-11-16 16:03:27 +00:00
Mark Sinclair f102ed53a7 Merge remote-tracking branch 'origin/release/v1.1.0' into develop
# Conflicts:
#	.github/workflows/network-explorer-api.yml
2022-11-16 15:54:08 +00:00
Raphaël Walther a803c7f25e Set output 2022-11-16 16:06:03 +01:00
Gala f20b620cbb turn maintenance banner display false 2022-11-16 15:04:24 +00:00
Raphaël Walther d771d15959 Corrected reference 2022-11-16 15:50:53 +01:00
Raphaël Walther 49e6f387ff Hardcoded branch name 2022-11-16 15:12:50 +01:00
Raphaël Walther 9568c0ba1d Upgraded checkout action 2022-11-16 14:50:46 +01:00
Gala 0b7b705e56 Merge pull request #1602 from nymtech/327-nym-connect-colours
Nym Connect: Various ui updates
2022-11-16 14:30:41 +01:00
Raphaël Walther 5daea675e7 Sent errors through the pipe 2022-11-16 14:28:45 +01:00
Gala ebd18586a8 Merge branch '327-nym-connect-colours' of github.com:nymtech/nym into 327-nym-connect-colours 2022-11-16 13:14:40 +00:00
Gala 585610295f Merge branch 'develop' into 327-nym-connect-colours 2022-11-16 13:14:17 +00:00
Raphaël Walther 91653d13c6 Added echo 2022-11-16 14:03:34 +01:00
Mark Sinclair b84486c0f4 GitHub Actions: install packages needed for build 2022-11-16 11:56:26 +00:00
Mark Sinclair b6a765481a GitHub Actions: add workflow to build network explorer api 2022-11-16 11:43:53 +00:00
Mark Sinclair 8f52f34bc4 GitHub Actions: add workflow to build network explorer api 2022-11-16 11:43:17 +00:00
Raphaël Walther 39798de1e8 Fixed dependency 2022-11-16 11:40:28 +01:00
Raphaël Walther c650587e4c Fixed typo 2022-11-16 11:35:06 +01:00
Raphaël Walther 660d5d8b05 Added missing property 2022-11-16 11:18:12 +01:00
Raphaël Walther 79f9db91ae Fixed typo 2022-11-16 11:16:07 +01:00
Raphaël Walther 43822f27a8 Switched to job outputs 2022-11-16 11:13:36 +01:00
Raphaël Walther e500d154dd Fixed issue with environment variable 2022-11-16 10:37:28 +01:00
Raphaël Walther 3ceb00fae1 Added matrix 2022-11-16 10:24:49 +01:00
Raphaël Walther d019343fd9 Added nightly build on latest release 2022-11-16 10:10:59 +01:00
Raphaël Walther f55a55b784 Cleaned workflows 2022-11-16 10:10:14 +01:00
Raphaël Walther 0ea8da79c8 Enabled yanked crates warning 2022-11-16 09:24:58 +01:00
Jon Häggblad 0e12251773 Update some deps suggested by cargo deny (#1761)
* Update yanked cpufeatures dependency

* Update yanked textwrap version

* Updated yanked crossbeam-channel version

* Update client-core dep to 1.1.0
2022-11-16 09:10:40 +01:00
Jon Häggblad f886326014 wallet_storage: fix clippy (#1757) 2022-11-16 07:43:49 +01:00
Jess c73c2beb33 Update CHANGELOG.md 2022-11-15 19:04:38 +00:00
benedettadavico b7aa84cd5a updating mainnet mixnet conract address 2022-11-15 19:54:28 +01:00
Raphaël Walther b6b40163c6 Added security audit for whole tree 2022-11-15 17:43:51 +01:00
Jędrzej Stuczyński f46c0142e7 Updated changelog 2022-11-15 16:28:15 +00:00
Jędrzej Stuczyński 8774b22d84 Added migration code for updating vesting contract address 2022-11-15 16:06:03 +00:00
Mark Sinclair c74a880838 Update README for SDK 2022-11-14 15:58:00 +00:00
Mark Sinclair ccbb254b1a Add wildcard glob for all files to SDK npm package.json 2022-11-14 15:36:30 +00:00
Dave Hrycyszyn 2bd0cfc870 Moving towards a publishable npm sdk package 2022-11-14 15:08:58 +00:00
Gala aeaf31ed59 Merge pull request #1756 from nymtech/feature-457-banner
Feature 457 banner
2022-11-14 14:04:07 +01:00
Gala 05820cfca7 mantenance banner text update 2022-11-14 12:58:49 +00:00
Gala 0469d5b602 adding a comment and different alignment 2022-11-11 11:53:49 +01:00
Jon Häggblad d912844543 Client: multiplex connection data streams (#1720)
* WIP: QA network details

* Initial implementation to multiplex socks5-client sends

* Introduce TransmissionLane enum

* WIP

* WIP: client requests connection id

* WIP

* mulitplex somewhat done

* Remove closed lanes

* WIP: connection handling over ws

* Remove unused published active connections shared data

* Start on status timer

* Max number of connections, and prune

* Some tidy

* Remove commented out code and tweak log

* Tidy

* Tweak log output

* Rename to TransmissionBuffer

* Use number of msg sent instead of time to rank age of lanes

* Create client-connections crate

* Remove waker call that probably are not needed

* Extract out some types from real traffic stream module

* Revert to develop qa.env

* Tweak comments, tidy for getting ready to merge

* Update changelog

* wasm client compile fixes

* rustfmt
2022-11-11 11:04:49 +01:00
Gala 64757ebc83 adding missing spaces 2022-11-11 07:16:13 +01:00
Gala ba55affe0a reducing ne banner height 2022-11-10 20:43:09 +01:00
Gala e9f826e705 adding a mintenance banner 2022-11-10 20:11:59 +01:00
Fouad bfbd509e4b Update/last minute release updates (#1753)
* fix vesting update bond settings

* style and text updates

* show tx fee when updating node settings

* allow cost param update with vesting tokens
2022-11-10 16:22:09 +00:00
Mark Sinclair b68fb4f5dd Merge branch 'release/v1.1.0' into develop 2022-11-10 15:06:36 +00:00
Dave Hrycyszyn 7461fe88d0 Merge remote-tracking branch 'origin/feature/nym-sdk' into develop 2022-11-10 14:09:49 +00:00
Jon Häggblad 510d0333a1 Add -c for --config-env-file (#1748)
* Add -c for --config-env-file

* changelog: add note
2022-11-10 13:38:55 +01:00
Jon Häggblad cea4887080 Fix clippy in beta toolchain (#1749) 2022-11-10 13:38:40 +01:00
Jon Häggblad 8f1cb67bf7 Update client-core to 1.1.0 2022-11-10 09:44:20 +01:00
Jon Häggblad 09b9601c7e Update client-core to 1.1.0 2022-11-10 09:38:38 +01:00
Mark Sinclair 2a1dd138e0 GH Actions: Install same dependencies as build..yml 2022-11-09 18:21:28 +00:00
Mark Sinclair 89925e49e8 GH Actions: Install same dependencies as build..yml 2022-11-09 18:20:45 +00:00
Mark Sinclair 96fc7208a2 Merge branch 'release/v1.1.0' into develop 2022-11-09 15:27:56 +00:00
Mark Sinclair 9874daa061 Release v1.1.0: bump versions and update CHANGELOGs (#1746)
* Bump version of nym-cli to 1.1.0 and move CHANGELOG to standalone file

* Bump version of nym-connect to v1.1.0 and update CHANGELOG

* Bump version of nym-wallet to v1.1.0 and update CHANGELOG

* Bump version of explorer-api to v1.1.0

* Bump versions of binaries (native-client, socks5-client, mixnode, gateway, network-requester) to v1.1.0

* Bump version of validator-api to v1.1.0

* Bump version of mixnet contract to v1.1.0 (vesting contract already v1.1.0 from #1472)

* Bump Nym Platform version to v1.1.0 and update CHANGELOG

* Update CHANGELOG.md

* Update CHANGELOG.md

* Updated changelog with v2-related changes

* Update CHANGELOG.md

Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
Co-authored-by: Fouad <fmtabbara@hotmail.co.uk>
Co-authored-by: Pierre Dommerc <dommerc.pierre@gmail.com>
Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
Co-authored-by: Jess <31625607+jessgess@users.noreply.github.com>
2022-11-09 15:04:41 +00:00
Fouad baa61c07d5 Bug fix/ne snag list (#1741)
* use uncapped saturation

* display uncapped saturation

update profit margin tooltip

update operating cost

update rewards tooltip

update stake saturation tooltip

update reward tooltips

update profit margin tooltip

* allow full gateway field to be clickable

use uncapped saturation on mixnode details page
2022-11-09 12:39:14 +00:00
Jon Häggblad b8cb683da0 Add qwerty qa net env file 2022-11-09 11:27:28 +01:00
Jon Häggblad 62e9c8236a Remove log from vesting-contract (#1745)
* Remove log from vesting-contract

* rustfmt
2022-11-09 11:04:32 +01:00
Jon Häggblad d79c25861b Merge pull request #1740 from nymtech/develop-with-release-1.1.0-merged-in
Merge release/v1.1.0 into develop
2022-11-09 11:02:12 +01:00
Jon Häggblad b89ec2e0be clippy 2022-11-09 10:43:53 +01:00
Jon Häggblad 269f50bdd4 rustfmt 2022-11-09 10:25:39 +01:00
durch e3c02dc80a Actually save updated pledge cap 2022-11-09 10:22:14 +01:00
Drazen Urch 65a9320d35 Set default pledge cap to 10% (#1739)
* Set default pledge cap to 10%

* fix clippy beta lints
2022-11-09 10:22:08 +01:00
durch cf268ffcd5 Actually save updated pledge cap 2022-11-09 10:19:21 +01:00
Mark Sinclair bdcfe42a1e Add docs and diagrams 2022-11-08 17:47:10 +00:00
Mark Sinclair 51e30b2a89 Add "attach file" to chat demo
Uses custom binary payload, that includes headers with the file and mime-type, so the receiving browser can save the file correctly.
2022-11-08 17:47:10 +00:00
Mark Sinclair 76d4d0e7cb Add makefile 2022-11-08 17:47:10 +00:00
Mark Sinclair 9df432b8a2 Add arbitrary text headers to binary payload helpers 2022-11-08 17:47:10 +00:00
Mark Sinclair 4021059e76 Send all chat messages with new payload 2022-11-08 17:47:10 +00:00
Mark Sinclair 43ef098aad Add utilities to handle text and binary payloads for mixnet messages 2022-11-08 17:47:10 +00:00
Mark Sinclair bf1d2a12bc Fix html file 2022-11-08 17:47:10 +00:00
Mark Sinclair c3f214ffad Change to sync build 2022-11-08 17:47:10 +00:00
Mark Sinclair 324fb6afe7 Build SDK in dependencies 2022-11-08 17:47:10 +00:00
Mark Sinclair ace020b5cf Upgrade favicons (to upgrade sharp) 2022-11-08 17:47:10 +00:00
Mark Sinclair 4b8fa4805e Tweak dependency build script 2022-11-08 17:47:10 +00:00
Mark Sinclair eb18b49f3e Add a typescript version of the old js-example with basic HTML 2022-11-08 17:47:10 +00:00
Mark Sinclair 2dc45fda1e Tweak dependency build script 2022-11-08 17:47:10 +00:00
Mark Sinclair c2a113f1b3 Remove bootstrap async load, as it isn't needed when loading the wasm from a worker 2022-11-08 17:47:10 +00:00
Mark Sinclair f805eebce7 UI tweaks 2022-11-08 17:47:10 +00:00
Mark Sinclair ad81160760 Build dependencies 2022-11-08 17:47:10 +00:00
Mark Sinclair 0931236a98 Add README and example structure 2022-11-08 17:47:05 +00:00
Drazen Urch b28ff17c30 Set default pledge cap to 10% (#1739)
* Set default pledge cap to 10%

* fix clippy beta lints
2022-11-07 14:40:52 +01:00
Jon Häggblad 9b14e00653 Fix merge error 2022-11-07 13:55:36 +01:00
Jon Häggblad ec8b5e6e9d Merge remote-tracking branch 'origin/release/v1.1.0' into develop 2022-11-07 10:13:33 +01:00
Raphaël Walther d4584c305a Set cron 2022-11-04 15:50:08 +01:00
Raphaël Walther afc53d4379 Added audit notification 2022-11-04 15:12:29 +01:00
Raphaël Walther 4278e88d3c Added audit notification 2022-11-04 14:55:47 +01:00
Raphaël Walther e12a34ce6b Added audit notification 2022-11-04 11:58:23 +01:00
Raphaël Walther 1de64f7b52 Added audit notification 2022-11-04 11:42:31 +01:00
Raphaël Walther 66dbe09e66 Added audit notification 2022-11-04 11:22:54 +01:00
Raphaël Walther dcce269921 Added audit notification 2022-11-04 09:56:00 +01:00
Jędrzej Stuczyński c043f0096a Notify about sent packet after actually pushing it through mix_tx (#1735) 2022-11-03 15:11:58 +00:00
Fouad a7cd7a58f2 Bugfix/delegations sort by no bonded node (#1737)
* use sorting function

* create hardcoded examples in  storybook
2022-11-03 13:44:09 +00:00
Jędrzej Stuczyński fe6da046dc Fixed beta clippy warnings (#1736) 2022-11-03 10:13:16 +00:00
Gala 8bbdb94b13 Merge pull request #1733 from nymtech/417-inputs-label
Wallet: make input's label always shrink
2022-11-02 16:42:17 +01:00
Pierre Dommerc e32601ab86 feat(wallet): normalize decimal places in ui (#1731) 2022-11-02 15:48:49 +01:00
Gala 161138bdff Merge branch 'release/v1.1.0' into 417-inputs-label 2022-11-02 14:26:03 +01:00
Fouad 0529e84a31 add account how to links (#1732) 2022-11-02 13:15:48 +00:00
Gala 95f98016de make label always shrink 2022-11-02 13:49:29 +01:00
Fouad 4967bbb5bd Feature/delegations without bonded node (#1727)
* refactor delegations list to include separate delegation and pending delegation item

* show tooltip on delegation with unbonded node

* feat(wallet): add operating cost in delegations list

* add additional state to check for unbonding event

* disable actions when pending unbond event

* add request and type guard for pending unbond event

* add mixnode_is_unbonding to delegation item type

Co-authored-by: pierre <dommerc.pierre@gmail.com>
2022-11-02 10:46:45 +00:00
Fouad 2952144d32 add profit margin percent to response (#1729)
* add profit margin percent to response

* use display percentage function

* fix profit margin display

* fix up filters
2022-11-01 13:02:34 +00:00
Jędrzej Stuczyński 80c21b3ed9 (chore) setting up a common/logging crate (#1730) 2022-11-01 11:46:47 +00:00
Jędrzej Stuczyński 1f0d5f8ad0 Feature/vesting contract version query (#1726)
* Introduced vesting contract query for build information

* Fixed import paths

* Changelog
2022-10-31 17:37:16 +00:00
Jędrzej Stuczyński 49ce56c367 Jedrzej/feature/version field in framed sphinx packets (#1723)
* introduced PacketVersion into FramedSphinxPacket

* Using legacy mode by default in mixnodes and gateways

* fixed unit tests
2022-10-31 16:56:37 +00:00
Pierre Dommerc 4ab6f4c3a9 refactor(explorer-api): route ping use mix_id as param (#1728) 2022-10-31 16:58:30 +01:00
Jędrzej Stuczyński 3727370b9e Improved error propagation for fallible validator api queries (#1681)
* Improved error propagation for fallible validator api queries

* Updated changelog
2022-10-31 15:28:54 +00:00
Jędrzej Stuczyński b3272097f9 Jedrzej/bugfix/historical uptimes recording (#1721)
* Removed commented out type alias

* typos

* Using the same  underlying timer for uptime updater

* Updating uptimes at 23:00 UTC each day

* Changelog
2022-10-31 12:19:14 +00:00
Jon Häggblad ebc13c4327 client: make channel to mix traffic controller bounded and add backpressure handling v1.1 (#1725)
* clients: change mix traffic channel to bounded

* clients: dynamically adjust sending delay in steps

* rustfmt

* wasm-client: update channel

* client: introduce SendingDelayController

* client-core: downgrade two debug statements to trace

* sending delay controller: tweak parameters

* wasm-client: add tokio dependency

* client-core: rework delay controller

* Revert "client-core: downgrade two debug statements to trace"

This reverts commit e0a7772fafac7bff0e4a2c50ba25e94b52b794e6.

* Remove outdated comment

* Remove WIP comments

* changelog: add note

* out queue controller: simplify with just send

* client-core: document constants

* client: move creating mix msg channel to mix traffic controller

* client-core: downgrade a warning log msg to debug

* changelog: update
2022-10-31 12:21:02 +01:00
Jon Häggblad ec3a6b3e27 socks5: wait to close buffer (v1.1 branch) (#1724)
* socks5: wait to close buffer

This is the fix proposed by @simonwicky in
https://github.com/nymtech/nym/issues/1701

* socks5: fix typo in patch

* socks5: fix tests

* socks5: add type for returned data and index

* socks5: make closed_at_index an Option

* changelog: add note

* changelog: update
2022-10-31 11:56:31 +01:00
Pierre Dommerc 19f3c76f72 Feature/explorer operating cost (#1719)
* feat(explorer): operating cost
2022-10-28 16:24:52 +02:00
Pierre Dommerc 90cc239999 Feature/ne gateway details (#1722)
* create gateway details page

* adding uptime chart

* adding loading state for gateways

* adding link style

* fixing gateways pagination

* remove gateway name and desc

* adding correct toolpit text and cleaning

* fix build

* PR requested changes

* fix build

* requested changes

* fix build a rever console utility addition

Co-authored-by: Gala <calero.vg@gmail.com>
2022-10-28 15:12:37 +02:00
Jędrzej Stuczyński c1bd5db902 comment regarding ts-rs compilation warning 2022-10-28 14:00:54 +01:00
Pierre Dommerc fb1649bab5 fix(explorer): gateway list location column (#1718)
* fix(explorer): gateway list location column

* fix(explorer): gateway list columns width
2022-10-28 12:17:23 +01:00
Jędrzej Stuczyński b21ca41e16 Adding staking supply scale factor in rewarding params update (#1716) 2022-10-28 12:17:17 +01:00
Pierre Dommerc 8656abcbde fix(explorer): minoxde details page (#1715)
* fix(explorer): minoxde details page

* feat(explorer): add mix_id column in mixnodes list
2022-10-27 17:16:30 +02:00
Jon Häggblad 99b30c2570 client: additional error handling in client + socks5-client + network-requester (#1713)
* client: add error type to native client, and start handling them

* client: handle two more error cases

* changelog: add note

* socks5: add error type and start handle run errors

* network-requester: add some error types

* rustfmt

* changelog: update note

* network-requester: remove unused import
2022-10-27 16:00:26 +02:00
Jon Häggblad 2c5d31e685 client: make channel to mix traffic controller bounded and add backpressure handling (#1703)
* clients: change mix traffic channel to bounded

* clients: dynamically adjust sending delay in steps

* rustfmt

* wasm-client: update channel

* client: introduce SendingDelayController

* client-core: downgrade two debug statements to trace

* sending delay controller: tweak parameters

* wasm-client: add tokio dependency

* client-core: rework delay controller

* Revert "client-core: downgrade two debug statements to trace"

This reverts commit e0a7772fafac7bff0e4a2c50ba25e94b52b794e6.

* Remove outdated comment

* Remove WIP comments

* changelog: add note

* out queue controller: simplify with just send

* client-core: document constants

* client: move creating mix msg channel to mix traffic controller

* client-core: downgrade a warning log msg to debug
2022-10-27 15:23:25 +02:00
Tommy Verrall 3ae9ea5de6 Merge pull request #1709 from nymtech/fix/explorerapi-geoip-lookup
fix(explorer-api): geoip lookup
2022-10-27 12:47:36 +02:00
Jon Häggblad cf65bc1295 socks5: wait to close buffer (#1702)
* socks5: wait to close buffer

This is the fix proposed by @simonwicky in
https://github.com/nymtech/nym/issues/1701

* socks5: fix typo in patch

* socks5: fix tests

* socks5: add type for returned data and index

* socks5: make closed_at_index an Option

* changelog: add note
2022-10-27 12:42:01 +02:00
Jędrzej Stuczyński 8bcec241a2 Moves Percent tests to the crate with the type definition (#1714) 2022-10-27 11:33:33 +01:00
Jędrzej Stuczyński 306e9b9dc2 Bugfix/correct staking supply accounting (#1706)
* Added staking_supply_scale_factor field on RewardingParams

* Scaling the amount of tokens released to the circulating/staking supplies
2022-10-27 10:51:09 +01:00
Jędrzej Stuczyński 2d5f851252 Workaround for clippy #9612 issue 2022-10-27 10:47:13 +01:00
Fouad d36e349cc6 Display routing scores for bonded gateway (#1693)
* access gateway report from node status api

* Create 4 response types for gateway and mixnode uptime and status

* Add the three remaining validator-client functions

* display gatways routing scores

* handle undefined gateway report

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
2022-10-27 10:34:11 +01:00
Jon Häggblad 4990a4745f Add two more sphinx extended packet sizes (8kb and 16kb) (#1694)
* Rename to ExtendedPacketSize32

* Add two more extended packet sizes

* Update config handling for new packet sizes

* Update wasm-client

* Changelog: update

* wasm-client: fix ref

* Switch use enum instead of string for config
2022-10-27 10:52:57 +02:00
Jędrzej Stuczyński 5ce087dafe Chore/remove unwraps (#1707)
* Disallowing the use of unwraps and expects in vesting and mixnet contracts

* Removed dodgy unwraps from the mixnet contract

* Removed dodgy unwraps from the vesting contract

* Removed unwraps/expects from common contracts crate

* ...but adding the unwraps in tests
2022-10-26 16:48:06 +01:00
Dave Hrycyszyn caf03a09c8 Adding in wss fix for web version 2022-10-26 16:34:09 +01:00
Jon Häggblad 0d399f7d70 connect: tidy error enum (#1712) 2022-10-26 17:26:31 +02:00
Jon Häggblad 56cf181770 validator-api: use response type for history and report endpoints (#1711) 2022-10-26 17:26:17 +02:00
Tommy Verrall f0aa2feb76 Merge pull request #1710 from nymtech/fix/explorer-table-ui
fix(explorer): mixnode location overflow
2022-10-26 17:13:29 +02:00
pierre 4df927cc3d fix(explorer): mixnode location overflow 2022-10-26 16:51:25 +02:00
Dave Hrycyszyn 5db47b8931 Optimizing for fat wasm 2022-10-26 15:40:03 +01:00
Dave Hrycyszyn 27c1b29615 Removing accidental yarn lockfile 2022-10-26 15:38:54 +01:00
Dave Hrycyszyn c80c8ef899 Bumping version number of wasm client package 2022-10-26 14:36:33 +01:00
pierre 3f4373eb98 feat(explorer-api): add debug logs 2022-10-26 12:29:01 +02:00
pierre cf10bb12ef feat(explorer-api): use mixnode port in ip lookup 2022-10-26 12:23:33 +02:00
pierre cb1e93e58d fix(explorer-api): geoip lookup 2022-10-26 12:06:47 +02:00
pierre d0cd22c4da Revert "fix(explorer-api): geoip, ip address from domain"
This reverts commit a721e97c06.
2022-10-26 11:57:04 +02:00
pierre a721e97c06 fix(explorer-api): geoip, ip address from domain 2022-10-26 11:52:54 +02:00
Drazen Urch f4f98027a0 Add per account pledge caps (#1687)
* Add per account pledge caps

* Address PR comments

* Update CHANGELOG

* No cap if no locked

* Fail account creation if taking account already exists

* Delegated free should be counted from vesting period start
2022-10-26 10:51:40 +02:00
Dave Hrycyszyn dee27e805d Adding a README for the nym-api 2022-10-25 12:25:09 +01:00
Dave Hrycyszyn 6f7dc36e5c Removing unused attribute 2022-10-25 11:45:02 +01:00
Dave Hrycyszyn ef50f361ba Adding funding notice 2022-10-25 11:45:02 +01:00
Pierre Dommerc 3c55b28e69 feat(explorer-api): auto update geoip database (#1684)
* feat(explorer-api): auto update geoip database

* feat(explorer-api): read dotenv file

* fix(explorer-api): gitignore

* feat: move geoipupdate service to root compose file
2022-10-24 18:17:50 +02:00
Jędrzej Stuczyński f1624e658e Feature/adjusting epoch events (#1696)
* Added (not yet using) source height for pending events

* Fixed existing unit tests

* Emitting source height for resolved pending events

* Removed unused attribute keys

* Emitting initial total unit reward at time of delegation

* Updated ts types

* regenerated corresponding typescript types

* missed changes

* Piggybacking on breaking change to remove serde aliases
2022-10-24 09:30:51 +01:00
Jon Häggblad fc44f2fe1c Fix typo in Makefile 2022-10-21 22:11:04 +02:00
Fouad cc26e4043c only display general settings for mixnodes (#1700)
* only display general settings for mixnodes
2022-10-21 12:21:55 +01:00
Jon Häggblad bb242080cf Update qa.env mixnet contract address 2022-10-21 12:34:44 +02:00
Jon Häggblad 3ebaf48aa3 Makefile: add wasm-client (#1699) 2022-10-21 11:35:20 +02:00
Fouad 2d7a55daba fix duplicate delegations (#1697) 2022-10-21 09:55:58 +01:00
Fouad 5f36742ce6 fix up operating cost (#1698) 2022-10-21 09:51:19 +01:00
Fouad 8547e770da Display interval timings (#1690)
* make reusable Alert component

* get current interval

* display next interval and epoch times

* display pending events
2022-10-20 17:11:02 +01:00
Gala 862178c9c5 Merge pull request #1688 from nymtech/ne-changes
Network Explorer: narrowing columns and re-orden them
2022-10-20 17:24:16 +02:00
Jędrzej Stuczyński 33a339ae2c Feature/multi node simulator (#1692)
* simple multi-node simulator

* Extending simulator with multi-node feature + testing against known good values

* Mixnet contract test fixes

* comment explaining the epsilon choice
2022-10-19 17:52:00 +01:00
Pierre Dommerc 5d583548ec feat(wallet): new account howto modals (#1689) 2022-10-19 11:18:09 +02:00
Fouad ba979c2e60 Feature/operator costs (#1680)
* add new operator cost field

* change uptime label to routing score

* update validation for operator cost

* fix profit margin type
2022-10-19 09:56:22 +01:00
Jędrzej Stuczyński dbb674f042 Fixes rewarding-epoch emitted events + unit tests for reward recalculation (#1691) 2022-10-18 12:59:27 +01:00
Jędrzej Stuczyński c3bea668d5 Renamed the type alias NodeId to MixId and fixed some usages (#1682)
* Renamed the type alias NodeId to MixId and fixed some usages

* fix(wallet): bonding context

* fix(wallet): remove ip field (type error)

Co-authored-by: pierre <dommerc.pierre@gmail.com>
2022-10-17 17:25:40 +01:00
Gala e0dd9b533e create theme variables 2022-10-17 17:17:20 +02:00
Gala 5ab3f95b8f cleaning 2022-10-17 15:36:42 +02:00
Gala 46097c80fe Merge branch 'develop' into ne-changes 2022-10-17 14:30:59 +02:00
Gala ab0eb35906 columns re-order and narrowing 2022-10-17 14:28:41 +02:00
Gala 8bb3b066ba nav width 2022-10-17 14:28:00 +02:00
Jon Häggblad 6a3ac6b9be client-core: fix clippy (#1686)
* client-core: fix clippy in beta toolchain

* nym-connect: update Cargo.lock
2022-10-17 10:58:38 +02:00
Pierre Dommerc da95e4e903 Wallet - bonding, new node stats component (#1535)
* feature(wallet-bonding): add bond more skeleton

* fix(wallet-bonding): post godzilla merge

fix: post rebase

feature(wallet-bonding): wip

* feat(wallet-bonding): add node stats component

feat(wallet-bonding): add node stats component

* feat(wallet-bonding): fix tooltip icon size

* fix(wallet-bonding): node stats fix responsiveness

fix(wallet-bonding): post godzilla merge

* feat(wallet): fetch active set probabilities

* feat(wallet): operation mixnode avg uptime

* fix: typo

* fix(wallet): theme colors

fix(wallet): theme colors

* fix(wallet): destructuring

* feat(wallet): request total reward data

* refactor(wallet): clean code

* fix(wallet): typo, better error logging

* fix(wallet): some nym decimal values

* fix(wallet): deal with unym nym values

* fix(wallet): routing score chart

* feat(wallet): new node stats design

* feat(wallet): new node stats design

* fix(wallet): increase component width

* fix(wallet): some vertical alignements
2022-10-14 10:40:53 +02:00
Fouad 732235afc0 update account wording (#1683) 2022-10-13 14:44:28 +01:00
Jędrzej Stuczyński 27a81df79e Require authorisation to reconcile pending events (#1676) 2022-10-11 12:32:39 +01:00
Jon Häggblad 03d654214f wallet: remove leftover debug log 2022-10-10 18:30:58 +02:00
Jon Häggblad a9dcd8e6c7 validator-api: add operating cost and profit margin to compute reward est (#1672)
* validator-api: add oper cost and profit margin to compute reward est

* changelog: add note

* rustfmt

* rustfmt
2022-10-10 18:13:23 +02:00
Jędrzej Stuczyński a43d183b4f Feature/wasm client updates (#1673)
* Compiles but runtime time fails

* wip

* Beginning of clean-up - creation of config to keep things together

* Removed unused module

* Removed hardcoded constants

* Easier way of sending binary messages

* WIP cleanup before machine switch

* Upgrade wasm-bindgen to 0.2.83

* Fixed compilation warnings for wasm client

* all clients compiling without warnings

* disabling topology refresh in wasm

* Added a config option to disable loop cover traffic stream

* config changes

* Make webassembly work in a web worker
- `wasm-timer` modified to work in web worker
- add worker target to webpack
- add client to call from HTML
- update README to build WASM for bundling (this does not build ES modules)

* Restored topology refreshing

* correctly polling items in the wasm delay_queue

* Allow client to read up to 8 messages at once from gateway connection (#1669)

* Allow client to read up to 8 messages at once from gateway connection

* Importing tokio::select in wasm32 target

* Updated changelog

* missing imports

* Introduced disable_main_poisson_packet_distribution to force real_traffic_stream to disable poisson sending (#1664)

* Introduced disable_main_poisson_packet_distribution to force real_traffic_stream to disable poisson sending

* Updated changelog

* Adjusting default settings

* Introduced a client-configurable option to force it to use extended packet size

* local adjustments

* Removed warning associated with receiving extended packets

* Minimal v2-required changes

* Updated changelog

* explicitly allowing clippy drop_non_drop

Co-authored-by: Mark Sinclair <mmsinclair@gmail.com>
2022-10-10 16:27:51 +01:00
Jędrzej Stuczyński 54d97fdbec Introduced a client-configurable option to force it to use extended packet size (#1671)
* Introduced a client-configurable option to force it to use extended packet size

* cargo fmt

* Removed warning associated with receiving extended packets

* Updated changelog
2022-10-10 15:07:30 +01:00
Gala 69e5abaed9 Merge pull request #1516 from nymtech/340-ne-content
NE: Change mentions of "Uptime" to "Routing Score"
2022-10-10 14:35:33 +02:00
Gala e3284f30a8 Merge pull request #1665 from nymtech/348-bonding-settings
Wallet: Bonded node settings
2022-10-10 14:09:26 +02:00
Gala 46d2d1f88b Merge branch 'develop' into 340-ne-content 2022-10-10 13:55:04 +02:00
Gala 8f11b39e95 consistency 2022-10-10 12:32:43 +02:00
Gala 2192777485 prevent build fail 2022-10-10 12:06:35 +02:00
Gala 11b8c52b30 pr refactoring suggestion 2022-10-10 12:03:38 +02:00
Gala 99cfdab601 using Consoles and some refactor 2022-10-10 11:48:22 +02:00
Jędrzej Stuczyński 11a67adc04 Introduced disable_main_poisson_packet_distribution to force real_traffic_stream to disable poisson sending (#1664)
* Introduced disable_main_poisson_packet_distribution to force real_traffic_stream to disable poisson sending

* Updated changelog
2022-10-10 10:10:01 +01:00
Jędrzej Stuczyński 65f75c5fe5 Allow client to read up to 8 messages at once from gateway connection (#1669)
* Allow client to read up to 8 messages at once from gateway connection

* Importing tokio::select in wasm32 target

* Updated changelog
2022-10-10 09:44:47 +01:00
Jędrzej Stuczyński 68c2cf5f95 Feature-locked TestingResolveAllPendingEvents transaction (#1667) 2022-10-07 11:25:35 +01:00
Jędrzej Stuczyński 1dd89ea1aa Try to use up to date list of nodes when performing rewarding (#1668) 2022-10-07 11:15:49 +01:00
Jędrzej Stuczyński 6593605834 Exposed all debug fields in client configs 2022-10-07 10:37:36 +01:00
Jędrzej Stuczyński 9d4c62cad6 Added a config option to disable loop cover traffic stream (#1666)
* Added a config option to disable loop cover traffic stream

* Updated changelog
2022-10-07 10:35:25 +01:00
Gala f72a38a5a8 use ts type predicates 2022-10-06 15:53:14 +02:00
durch cc641052b3 Force add Makefile 2022-10-06 15:33:13 +02:00
Gala 545c8b76a7 use location state instead of a query 2022-10-06 15:31:13 +02:00
durch be07e4997e Add wasm-opt to build 2022-10-06 15:16:14 +02:00
Gala 139a0dca2f now is the refactor : ) 2022-10-06 15:12:58 +02:00
Gala e9c0b9bef3 navigation refactor from CR 2022-10-06 15:12:33 +02:00
Gala 9b28de4a06 use iconbutton 2022-10-06 14:22:12 +02:00
Gala f0c50556ad don't update not used files 2022-10-06 12:37:57 +02:00
Gala f50af85fb1 cleaning up a bit the code 2022-10-06 12:20:08 +02:00
Mark Sinclair 25f1fb2eb8 Wrap up Bity order signature and verification into simple structs, so it is easy for them to use (#1661) 2022-10-06 11:00:49 +01:00
Gala 27ab849018 unbonf new flow 2022-10-06 11:50:19 +02:00
Jędrzej Stuczyński 803f7117ea Removes humantime_serde serialization of epoch_length (#1662) 2022-10-06 09:05:07 +01:00
Gala 611d37e46f update with develop 2022-10-05 15:47:17 +02:00
Gala 99b35f8d01 wip unbonding page 2022-10-05 15:38:47 +02:00
Gala f35bfc63e2 connect also info settings and adding schemas for both forms 2022-10-05 15:35:22 +02:00
Gala 1be85dced6 bonded node param set settings and validate first 2022-10-05 15:22:08 +02:00
Pierre Dommerc 7a3253e025 fix: typescript generate types (#1660) 2022-10-05 13:53:03 +02:00
Mark Sinclair 8a3351bf82 common commands - add prefix and account id to the signature verification helper (#1659) 2022-10-05 12:47:29 +01:00
Jon Häggblad 55e45a0d88 validator-client: remove left-over log::trace 2022-10-05 11:41:53 +02:00
Pierre Dommerc 5a55c320cb fix(wallet): reward types (#1658) 2022-10-04 17:38:42 +02:00
Gala ba64c57283 use react useForm 2022-10-04 15:53:19 +02:00
Pierre Dommerc 739b2f88f9 Wallet - update of bonding flow part 1 (#1528) 2022-10-04 13:46:51 +02:00
Gala ce269e60e4 Merge branch 'develop' into 348-bonding-settings 2022-10-04 12:45:04 +02:00
Gala ad9ea03683 Merge branch 'node-settings-copy' into 348-bonding-settings 2022-10-04 12:44:33 +02:00
Gala 47cae50e68 profit margin only for mixnode 2022-10-04 11:51:34 +02:00
Gala 2a04234c26 wip scroll bar styles 2022-10-03 14:45:01 +02:00
Pierre Dommerc c582d6dcba config(wallet): use new mixnet contract address for qa (#1656) 2022-10-03 13:38:56 +02:00
Gala ef8f6ed07b some ui changes at the navigation 2022-09-29 17:54:31 +03:00
Gala c644956576 wip 2022-09-29 17:08:31 +03:00
Gala c329724f8c Merge branch 'develop' into node-settings-copy 2022-09-29 15:44:52 +03:00
Gala a96383e714 wip 2022-09-28 09:52:57 +03:00
Jędrzej Stuczyński 49b3a5aa90 Made config.toml values in validator-api take precedence over mainnet defaults (#1645)
* Made config.toml values in validator-api take precedence over mainnet defaults

* Updated mixnode and gateway configs with similar priority adjustments

* Changelog
2022-09-23 16:59:42 +01:00
Jędrzej Stuczyński 879ce3f2d5 Feature/field renaming (#1654)
* Replaced serde renames to aliases

Ideally I would have removed all serde macros, but then it would have broken existing QA deployments - perhaps we should do it later

* Renamed 'node_id' in Delegation to 'mix_id'

* Further renamings of 'node_id' to 'mix_id' in various places
2022-09-23 15:01:39 +01:00
Pierre Dommerc 996f0bf732 feature(explorer-api): rewrite geoip2 location service (#1651) 2022-09-23 14:53:56 +02:00
Jędrzej Stuczyński b289a3570a Prefixing all mixnet contract events with a v2_ prefix (#1652) 2022-09-23 12:33:29 +01:00
Gala 1b689edb43 Merge pull request #1653 from nymtech/ne-stak-sat-filter
NE: fix upper saturation value used on filters
2022-09-23 11:37:47 +02:00
Jon Häggblad 95c5b70eb7 Remove the old deprecated parts of network-defaults (#1646)
* network-defaults: remove all the old crap and simplity

* validator-client: remove commented out code
2022-09-23 11:32:23 +02:00
Jędrzej Stuczyński a5b4504b0a Emitting information about prior delegation data before rewarding (#1650)
* Emitting information about prior delegation data before rewarding

* Cargo fmt
2022-09-23 09:32:37 +01:00
Gala 995a61b7ea fix upper saturation value use on filters 2022-09-23 10:20:51 +02:00
Drazen Urch 0adf4df094 Fig and shell completions (#1638)
* Fig and shell completions lib

* Complete all the things
2022-09-22 17:26:37 +02:00
Gala 6eb482fc4b CR: use a parameter instead of cardcoded value 2022-09-22 16:54:07 +02:00
Gala f9be735d4f various ui updates 2022-09-22 16:54:06 +02:00
Gala 8c877d64d6 Merge pull request #1649 from nymtech/fix-validator-url-access
NE: Fix validators url
2022-09-22 15:32:34 +02:00
Gala 9ae1f046c4 avoid destructuring 2022-09-22 15:13:33 +02:00
Gala 7dc776f98a wip fixing conflicts 2022-09-22 13:16:39 +02:00
Gala 9717bcbb17 WIP: Merge branch 'develop' into 348-bonding-settings 2022-09-22 12:22:24 +02:00
Gala f401266d1b Merge pull request #1644 from nymtech/ne-transition-v1-v2
NE: Adding a workaround for v1 to v2 transition
2022-09-22 10:47:32 +02:00
Gala 0fd178a304 Merge branch 'develop' into 327-nym-connect-colours 2022-09-22 10:37:06 +02:00
Gala 1878b50752 Merge branch 'develop' into ne-transition-v1-v2 2022-09-22 10:34:16 +02:00
Gala 8bd7b69bf9 Merge pull request #1597 from nymtech/305-ui-fixes-inputs
Wallet: address Figma differences on modals, dialogs and inputs
2022-09-22 10:33:28 +02:00
Gala cf2ede1040 adding a temporaly solution for transition v1 to v2 2022-09-21 17:57:19 +02:00
Gala af1bf57f24 anothe conflict fix 2022-09-21 17:41:31 +02:00
Gala 0de6a0f1ca Merge branch 'develop' into 305-ui-fixes-inputs 2022-09-21 17:41:07 +02:00
Gala 978cbc4f00 fix conflicts 2022-09-21 17:03:56 +02:00
Gala ebb06d4beb Merge branch 'develop' - wip fixing clonflicts 2022-09-21 17:03:47 +02:00
Gala 03974f9cb3 Merge pull request #1628 from nymtech/409-ne-filters-info
NE & Wallet: NE TableToolbar ui and Wallet new display when no delegations
2022-09-21 16:52:21 +02:00
Jędrzej Stuczyński d322f5e91b Removed the concept of exiting validator API after X consecutive failures (#1643) 2022-09-21 15:20:33 +01:00
Gala 0dee6d9db7 spacing between title and content on pages 2022-09-21 16:05:03 +02:00
Gala 05bd6d6a9a signup mnemonic change 2022-09-21 16:04:06 +02:00
Jędrzej Stuczyński c43dbf6f4d Feature/remove deprecated routes (#1642)
* Removed deprecated routes in validator-api

* Removed deprecated routes in explorer-api
2022-09-21 14:54:51 +01:00
Dave Hrycyszyn 848ace1e0b Using the pre-built package in the chat demo 2022-09-21 13:28:41 +01:00
Mark Sinclair f98d9d89bc GitHub Actions - add input to manual dispatch
Adds `RUST_FLAGS="--cfg tokio_unstable"` when the input is true to add the tokio console to the validator api
2022-09-21 12:24:09 +01:00
Jon Häggblad b9015c1321 Update to latest set of selection chance buckets (#1626)
* Update to latest set of selection chance buckets

* Fixup after rebase

* Lock file update

* storybook update

* update storybook

Co-authored-by: Gala <calero.vg@gmail.com>
2022-09-21 12:38:42 +02:00
Fouad 59b0fe2f94 change input placeholders to labels (#1575)
* change input placeholders to labels

* use back button on 'show mnemonic' modal
2022-09-21 11:28:30 +01:00
Gala bf98c1b369 Merge branch 'develop' into 409-ne-filters-info 2022-09-21 12:01:01 +02:00
Gala d7e3b2c6f2 update branch 2022-09-21 11:57:54 +02:00
Gala 7302b64be7 Merge pull request #1617 from nymtech/309-figma-diff-mnemonic
Wallet: Figma diff, change mnemonic textfield
2022-09-21 11:55:15 +02:00
Gala d5365a7602 Merge pull request #1524 from nymtech/317-forms-menus-titles-ui
317 forms menus titles UI
2022-09-21 11:54:53 +02:00
Jędrzej Stuczyński 524d563077 Added additional log statement to show config file save location 2022-09-21 10:12:53 +01:00
Jon Häggblad e44ddc419c clippy: fix warnings in beta toolchain (#1639) 2022-09-21 09:25:22 +02:00
Jon Häggblad be20e17ebb ci: add libudev-dev to nightly linux build 2022-09-21 08:52:41 +02:00
Dave Hrycyszyn 7b76beab76 Switch from deprecated substr() to slice() 2022-09-20 16:00:18 +01:00
Bogdan-Ștefan Neacşu 9ed013b418 Add library to communicate with ledger (#1640)
* Add library to communicate with ledger

* Update changelog

* Install libudev-dev on linux
2022-09-20 17:57:14 +03:00
Dave Hrycyszyn 33ae43b86d Removing commented code 2022-09-20 15:44:56 +01:00
Dave Hrycyszyn 2c1ad1388d removing surb noise display 2022-09-20 15:35:53 +01:00
Jędrzej Stuczyński 136666d759 Feature/rewarding revamp (#1472)
* Query for node stake saturation

* Queries for currently pending events

* Rewarded set query

* Moved ContractState to common types

since it's being returned as a result of one of the queries on the mixnet contract and thus it needs to be accessible outside the contract itself

* Cleaend up storage initialisation

* started restoring unit tests

* Removed attached 1ucoin for cross-contract execute msgs

* wip

* query for rewarding details of a mix node

* Changes for mixnodes and gateways

* Furher progress on v2 changelog(-ish) description

* wip

* first version of the description

* mixnode bonding queries tests and fixes

* ibid for storage

* MixnodeEventType enum + created events for missing mixnode txs

* tests for adding new mixnode

* Additional mixnode-related tests + bug fixes

* Display for Percent

* Bunch of tests for try_reward_mixnode

* More tests and fixes

* ibid

* tests for updating rewarding params + important bug fix

* Started removing unused imports

* rewarding queries tests + undelegation bugfix

* A lot of todo()-ing and commenting out unimplemented code

* implements https://github.com/nymtech/team-core/issues/113

* Delegation tests + fixes

* Emiting events by top level interval txs + incorporating limit

* question

* Missing events emissions

* removed some code duplication

* wip

* pending delegation tests

* Vesting contract update

* More tests (and fixes) for pending events txs

* Restored gateway tx tests

* Another cleanup iteration

* removed redundant comment

* Unit tests, fixes and simplifcations for interval-related txs

* Unit tests for helper functions

* Interval queries unit tests

* Test for correct contract initialisation

* Another round of cleanup

* Work on mixnet_query_client trait

* mixnet_signing_client trait

* Removed redundant methods

* Slowly restoring validator client functionality

* Added deprecated query for mix details by identity

* wip restoration of validator-api

* Work on deprecating validator API routes

* Further validator-api routes

* Restored rest of status api routes

* Resolved all todos in ValidatorApiStorage

There's still bunch left in StorageManager though

* Changed NodeId from u64 to u32

* Updating sql code

* Network monitor internals

* Changed behaviour of full_epoch_id and updated epoch operations

* Fixed sql queries

* [most likely] finished updating rest of the validator API

* Post rebasing fixes

* Feature/rewarding revamp explorer api changes (#1511)

* Changed cache to allow for non-string keys

* Helper method for best-effort conversion of pubkey to nodeid

* Updated validator-api client routes

* Updated routes to use mix-id indexing

* Introduction of deprecated routes callable by identity key

* Fixed mixnode compatibility by changing read node details fields (#1512)

* Fixed bond to topology conversion for client compatibility (#1513)

* Updated 'verify_gateway_owner' to use correct nymd_client method for obtaining gateway details (#1515)

* Updated constructor for ValidatorCacheInner

* Fixed wasm client topology construction

* Run cargo fmt on the entire codebase

* Feature/rewarding revamp wallet backend changes (#1529)

* Updated mixnode-related ts types

* Updated nym-wallet-types

* Updated 'get_contract_settings' and commented out code of other tauri commands

* 'update_contract_settings'

* 'bond_gateway'

* unbond_gateway'

* Utility commands for the transition period

* 'bond_mixnode'

* 'unbond_mixnode'

* Ability to update mixnode cost paramaters

* Mixnode config update

* Updated mixnode_bond_details

It also returns a different underlying type now

* Updated 'gateway_bond_details'

* Obtaining pending operator rewards

* Improved way of obtaining number of mixnode delegators

* simplified error handling in 'fetch_mix_node_description'

* mixnode and gateway ownership queries

* updated get_number_of_mixnode_delegators to use mix_id since we have the conversion utils helper

* mixnode delegation

* undelegating

* Obtaining pending delegator rewards

* Command for obtaining current interval details

* Queries to handle paging for pending events

* Additional level of indirection to pending events to incorporate event id into response

* Wallet compatible pending event types

* Commands fo obtaining pending events

* Re-implemented pending delegation events

* Further work on delegation

* Removed unused imports

* Commands for withdrawing rewards

* Admin-related simulations

* mixnet-related simulation commands

* Validator-api related routes

* Bond-related vesting operations

* Vesting simulations

* Vesting handler for UpdateMixnodeCostParams

* Vesting reward claiming

* Vesting queries

* claim_locked_and_unlocked_delegator_reward

* The massive delegation query

* cleanup

* updated typescript requests

* sorted the new type exports in ts-rs-cli

* Regenerated typescript types

* temporarily ignoring unreachable code in vesting migration

* Updated missed test fixture

* Fixed missing coconut-specific import

* cargo fmt

* Exporting reward-related types

* utility to convert stringified decimal to cosmjs Decimal

* deriving Eq alongside PartialEq

* wip - typescript fixes

* using default operating cost when bonding mixnode

* Using default operating cost when updating mixnode cost params

* most delegation fixes

* Wrapping delegation with node identity

* Added MultiIndex on owner and identity key to unbonded mixnodes

* Support for queries for unbonded nodes by owner or by identity key

* Cargo fmt + ts types update

* feature locking unused imports

* fix(nym-wallet): typing and error (#1548)

* post-rebase fixes

* Changed storage key for new delegations map in vesting contract

* fix(wallet): typing issues (#1562)

* fix(wallet): error UI feedback (#1565)

* clean(wallet): remove useless files (with flamethrowers 🔥) (#1567)

* Changed default_mixnode_cost_params to allow accepting f32 instead

* Revert "Changed default_mixnode_cost_params to allow accepting f32 instead"

This reverts commit fb62a0014f.

* Fixed APY calculation for 0 pledge value

* Don't send rewarding transactions for empty rewarded set

* Fixed mixnode rewarding in validator API

* fix(nym-wallet): profit margin (#1574)

* Correctly assigning Delegate event type to PendingEpochEventData::Delegate

* Replaced 'history' in with 'pending_events' in DelegationWithEverything

* Updated typescript side of things

* Removed todo!() from vesting contract migration since its going to be dealt with differently

* fix(nym-wallet): stake saturation and delegations (#1578)

* fix(nym-wallet): stake saturation percentage

* fix(nym-wallet): stake saturation percentage

* Correctly assigning Delegate event type to PendingEpochEventData::Delegate

* fix(nym-wallet): get rid of delegation history

* Replaced 'history' in with 'pending_events' in DelegationWithEverything

* Updated typescript side of things

* Correctly assigning Delegate event type to PendingEpochEventData::Delegate

* Replaced 'history' in with 'pending_events' in DelegationWithEverything

* Updated typescript side of things

* fix(nym-wallet): welcome back pending events and delegation menu

* fix(nym-wallet): stake saturation percentage

* fix(nym-wallet): stake saturation percentage

* fix(nym-wallet): get rid of delegation history

* Updated typescript side of things

* fix(nym-wallet): welcome back pending events and delegation menu

* fix(nym-wallet): fix clippy

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

* Updated vesting contract migration to update the mixnet contract address

* feat(wallet): add confirmation/warning modal for unbonding

* Post rebasing fixes

* commented out all code

* Bunch of work in progres, but working simulator

* Removing redundant fields + increased precision to 9decimal places

* deserialization of Percent with value validation

* wip

* Further moving things around + mixnode bonding

* Mixnode unbonding

* Starting restoration on contract state

* Revamping interval

* More work on epoch/interval

* progress on mixnode rewarding

* Moved MixNodeRewarding to rewards storage

* wip on delegations

* Removed concept of periods and historical records and moved cummulative reward ratio directly to delegation

* more wip delegation

* Full delegation flow

* mixnode config updates

* Mixnode cost function updates

* Work on moving mixnode unbonding to post-epoch actions

* Unbonding

* Processing undelegation

* changing cost params

* Uncommented existing gateways features

without much changes so far, however, things like unbonding should probably also go to epoch queue

* ExecuteMsg cleanup

* unit tests for withdrawing rewards against known values

* Transactions for withdrawing rewards

* Transactions for updating various parameters

* First round of post-tx cleanup

* Moved all storage keys to constants.rs

* Using correct initial gateway pledge amount

* Renamed sybil_resistance_percent to sybil_resistance with percent being implicit from the typ

* Starting with contract queries

* Keeping minimal details of unbonded mixnoces

* Checking for owner address rather than rewarding validator when updating rewarding params

* Mixnode-related queries

* Gateway-related queries

* Query for paged unbonded mixnodes

* Delegations queries

* Query for current interval details

* Removed 'fixed' dependency from the mixnet common

* wip on implementing rewards-related queries

* Pending rewards queries

* Query for node stake saturation

* Queries for currently pending events

* Rewarded set query

* Moved ContractState to common types

since it's being returned as a result of one of the queries on the mixnet contract and thus it needs to be accessible outside the contract itself

* Cleaend up storage initialisation

* started restoring unit tests

* Removed attached 1ucoin for cross-contract execute msgs

* wip

* query for rewarding details of a mix node

* Changes for mixnodes and gateways

* Furher progress on v2 changelog(-ish) description

* wip

* first version of the description

* mixnode bonding queries tests and fixes

* ibid for storage

* MixnodeEventType enum + created events for missing mixnode txs

* tests for adding new mixnode

* Additional mixnode-related tests + bug fixes

* Display for Percent

* Bunch of tests for try_reward_mixnode

* More tests and fixes

* ibid

* tests for updating rewarding params + important bug fix

* Started removing unused imports

* rewarding queries tests + undelegation bugfix

* A lot of todo()-ing and commenting out unimplemented code

* implements https://github.com/nymtech/team-core/issues/113

* Delegation tests + fixes

* Emiting events by top level interval txs + incorporating limit

* question

* Missing events emissions

* removed some code duplication

* wip

* pending delegation tests

* Vesting contract update

* More tests (and fixes) for pending events txs

* Restored gateway tx tests

* Another cleanup iteration

* removed redundant comment

* Unit tests, fixes and simplifcations for interval-related txs

* Unit tests for helper functions

* Interval queries unit tests

* Test for correct contract initialisation

* Another round of cleanup

* Work on mixnet_query_client trait

* mixnet_signing_client trait

* Removed redundant methods

* Slowly restoring validator client functionality

* Added deprecated query for mix details by identity

* wip restoration of validator-api

* Work on deprecating validator API routes

* Further validator-api routes

* Restored rest of status api routes

* Resolved all todos in ValidatorApiStorage

There's still bunch left in StorageManager though

* Changed NodeId from u64 to u32

* Updating sql code

* Network monitor internals

* Changed behaviour of full_epoch_id and updated epoch operations

* Fixed sql queries

* [most likely] finished updating rest of the validator API

* Post rebasing fixes

* Feature/rewarding revamp explorer api changes (#1511)

* Changed cache to allow for non-string keys

* Helper method for best-effort conversion of pubkey to nodeid

* Updated validator-api client routes

* Updated routes to use mix-id indexing

* Introduction of deprecated routes callable by identity key

* Fixed mixnode compatibility by changing read node details fields (#1512)

* Fixed bond to topology conversion for client compatibility (#1513)

* Updated 'verify_gateway_owner' to use correct nymd_client method for obtaining gateway details (#1515)

* Updated constructor for ValidatorCacheInner

* Fixed wasm client topology construction

* Run cargo fmt on the entire codebase

* Feature/rewarding revamp wallet backend changes (#1529)

* Updated mixnode-related ts types

* Updated nym-wallet-types

* Updated 'get_contract_settings' and commented out code of other tauri commands

* 'update_contract_settings'

* 'bond_gateway'

* unbond_gateway'

* Utility commands for the transition period

* 'bond_mixnode'

* 'unbond_mixnode'

* Ability to update mixnode cost paramaters

* Mixnode config update

* Updated mixnode_bond_details

It also returns a different underlying type now

* Updated 'gateway_bond_details'

* Obtaining pending operator rewards

* Improved way of obtaining number of mixnode delegators

* simplified error handling in 'fetch_mix_node_description'

* mixnode and gateway ownership queries

* updated get_number_of_mixnode_delegators to use mix_id since we have the conversion utils helper

* mixnode delegation

* undelegating

* Obtaining pending delegator rewards

* Command for obtaining current interval details

* Queries to handle paging for pending events

* Additional level of indirection to pending events to incorporate event id into response

* Wallet compatible pending event types

* Commands fo obtaining pending events

* Re-implemented pending delegation events

* Further work on delegation

* Removed unused imports

* Commands for withdrawing rewards

* Admin-related simulations

* mixnet-related simulation commands

* Validator-api related routes

* Bond-related vesting operations

* Vesting simulations

* Vesting handler for UpdateMixnodeCostParams

* Vesting reward claiming

* Vesting queries

* claim_locked_and_unlocked_delegator_reward

* The massive delegation query

* cleanup

* updated typescript requests

* sorted the new type exports in ts-rs-cli

* Regenerated typescript types

* temporarily ignoring unreachable code in vesting migration

* Updated missed test fixture

* Fixed missing coconut-specific import

* cargo fmt

* Exporting reward-related types

* utility to convert stringified decimal to cosmjs Decimal

* deriving Eq alongside PartialEq

* wip - typescript fixes

* using default operating cost when bonding mixnode

* Using default operating cost when updating mixnode cost params

* most delegation fixes

* Wrapping delegation with node identity

* Added MultiIndex on owner and identity key to unbonded mixnodes

* Support for queries for unbonded nodes by owner or by identity key

* Cargo fmt + ts types update

* feature locking unused imports

* fix(nym-wallet): typing and error (#1548)

* post-rebase fixes

* Changed storage key for new delegations map in vesting contract

* fix(wallet): typing issues (#1562)

* fix(wallet): error UI feedback (#1565)

* clean(wallet): remove useless files (with flamethrowers 🔥) (#1567)

* Changed default_mixnode_cost_params to allow accepting f32 instead

* Revert "Changed default_mixnode_cost_params to allow accepting f32 instead"

This reverts commit fb62a0014f.

* Fixed APY calculation for 0 pledge value

* Don't send rewarding transactions for empty rewarded set

* Fixed mixnode rewarding in validator API

* fix(nym-wallet): profit margin (#1574)

* Correctly assigning Delegate event type to PendingEpochEventData::Delegate

* Replaced 'history' in with 'pending_events' in DelegationWithEverything

* Updated typescript side of things

* Removed todo!() from vesting contract migration since its going to be dealt with differently

* fix(nym-wallet): stake saturation and delegations (#1578)

* fix(nym-wallet): stake saturation percentage

* fix(nym-wallet): stake saturation percentage

* Correctly assigning Delegate event type to PendingEpochEventData::Delegate

* fix(nym-wallet): get rid of delegation history

* Replaced 'history' in with 'pending_events' in DelegationWithEverything

* Updated typescript side of things

* Correctly assigning Delegate event type to PendingEpochEventData::Delegate

* Replaced 'history' in with 'pending_events' in DelegationWithEverything

* Updated typescript side of things

* fix(nym-wallet): welcome back pending events and delegation menu

* fix(nym-wallet): stake saturation percentage

* fix(nym-wallet): stake saturation percentage

* fix(nym-wallet): get rid of delegation history

* Updated typescript side of things

* fix(nym-wallet): welcome back pending events and delegation menu

* fix(nym-wallet): fix clippy

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>

* Updated vesting contract migration to update the mixnet contract address

* feat(wallet): add confirmation/warning modal for unbonding

* Post rebasing fixes

* Removed deprecation on GetMixnodeDetailsByIdentity

* Fixed nym-cli

* Removed needless borrow

* Updated colorMap and textMap

Co-authored-by: durch <durch@users.noreply.github.com>
Co-authored-by: Mark Sinclair <mmsinclair@gmail.com>
Co-authored-by: Pierre Dommerc <dommerc.pierre@gmail.com>
2022-09-20 14:44:57 +01:00
Gala 16ccbd9e48 CR: use a parameter instead of cardcoded value 2022-09-20 13:30:09 +02:00
Gala bd0ea45f35 Merge branch 'develop' into 327-nym-connect-colours 2022-09-20 13:17:15 +02:00
Gala 4648967e93 fix build and refactor from CR 2022-09-20 12:43:51 +02:00
Gala 824e980647 Merge branch 'develop' into 305-ui-fixes-inputs 2022-09-20 11:49:33 +02:00
Jon Häggblad ecbf5296a5 validator-api: guard against funny numbers in apy calc (#1636) 2022-09-19 14:37:09 +02:00
Jon Häggblad f3454409f8 Upgrade nym-connect to tauri 1.1.1 (#1635) 2022-09-19 11:34:33 +02:00
Gala 7d2e90b69f Merge pull request #1625 from nymtech/407-ne-filters-granularity
NE: 407 filters granularity
2022-09-19 11:28:26 +02:00
Gala bb2732bcc6 Merge pull request #1619 from nymtech/413-ne-content
NE: Display raw bond instead of self %
2022-09-19 11:16:16 +02:00
Gala d196993993 fix build 2022-09-19 11:08:16 +02:00
Gala b4fe8af890 refactor from CR 2022-09-19 11:04:26 +02:00
Gala 1c8ab2395d Merge branch 'develop' into 409-ne-filters-info 2022-09-19 10:24:18 +02:00
Jon Häggblad 065fe812ae Rename crate to nym-wallet-recovery-cli (#1633)
* Rename to nym-wallet-recovery-cli

* Rename crate name too

* Rename workspace member too

* Cargo.lock
2022-09-19 10:22:37 +02:00
Gala 02e75ea5cd display different content when user doesn't have delegations 2022-09-16 12:24:32 +02:00
Jon Häggblad 2aa18fb77c nym-wallet: add log window (#1618)
* Add a second entry point to the webpack config for the logging window

* tauri operations to show a log window

* LogViewer react component

* Upgrade tauri and use default tauri app menu for MacOS and add `Help` menu with `Show log` entry to show the logging window

* wip

* Proof of concept

* Fix format inside debug with ferm

* Put new menubar and log behind env variable flag

* Remove unused deps

* rustfmt

* Add changelog note

* Fix up imports

* Remove old code

* Improve log viewer

* Remove old code

* Add color to output, even if tauri hides it

* Remove redundant level from tauri log msg

* Since menu bar visible by default, change feature flag name

* Fix up webpack config so correct chunks get injected into entry points and remove inline CSS causing CSP issue

Co-authored-by: Mark Sinclair <mmsinclair@gmail.com>
2022-09-16 09:38:52 +01:00
Jon Häggblad 8a0e7fb9d6 validator-api: add missing clap argument (#1629) 2022-09-15 22:31:31 +02:00
Dave Hrycyszyn 13c2ca4a78 Noted a correct npm publish command 2022-09-15 16:28:56 +01:00
Dave Hrycyszyn 6af84535fa Formatting 2022-09-15 16:27:44 +01:00
Mark Sinclair c8699cbe8d wasm-client: fix up dependencies and feature flags so that wasm-pack build works (#1585)
* wasm-client: fix up dependencies and feature flags so that wasm-pack build works

* Update CHANGELOG
2022-09-15 16:11:49 +01:00
Drazen Urch 974163da97 Reduce iterations when delegator last_claimed_height is 0 (#1609)
* Reduce iterations when delegator last_claimed_height is 0

* Fix typo
2022-09-15 17:10:35 +02:00
Raphaël Walther 7290e479db Notification test 2022-09-15 17:01:49 +02:00
Raphaël Walther c7b728318c Notification test 2022-09-15 16:57:25 +02:00
Dave Hrycyszyn 5c6d31bcb5 README fix 2022-09-15 15:48:58 +01:00
Dave Hrycyszyn 3823292ba8 Bumping version number to 1.0.0 2022-09-15 15:48:42 +01:00
Bogdan-Ștefan Neacşu 3eeda4a421 Apply fix for socket_state too (#1627) 2022-09-15 17:35:41 +03:00
Gala ebb3f6eebb fixing the build 2022-09-15 16:06:14 +02:00
Gala 2c15d22e1e Merge branch 'develop' into 409-ne-filters-info 2022-09-15 15:55:58 +02:00
Gala f1dca2c9a8 styling the mobile view 2022-09-15 14:50:33 +02:00
Gala d039c25b55 create a custom label for stake sat 2022-09-15 14:27:52 +02:00
Drazen Urch 16ef1c547b Remove eth feature, and BBBC related code (#1612)
* Remove eth feature, and BBBC related code

* Burn some more, especially clients
2022-09-15 13:58:44 +02:00
Dave Hrycyszyn e804b014a8 Cargo lock excluding webassembly client 2022-09-15 12:25:36 +01:00
Dave Hrycyszyn e406a05694 Re-excluding clients/webassembly which breaks cargo build --all 2022-09-15 12:24:04 +01:00
Gala 057b3456a7 more granulatity on filters 2022-09-15 12:49:27 +02:00
Dave Hrycyszyn 5ac124e159 Adding the webassembly client to the main build
This gives type hinting in editors. I can no longer remember why we
didn't set it up like this a long time ago, but it builds and tests
fine. Feel free to revert if it causes any problems.
2022-09-15 11:33:16 +01:00
Jon Häggblad f29c6a0550 Merge pull request #1622 from nymtech/jon/fix/shutdown-in-gateway-client
gateway-client: fix shutdown
2022-09-14 17:00:48 +02:00
Jon Häggblad 242a6d13af gateway-client: fix shutdown 2022-09-14 16:24:05 +02:00
Gala dee2c50b50 ne toolbar changes 2022-09-14 16:04:39 +02:00
Gala a394c9b59a PR requested changes 2022-09-14 14:48:30 +02:00
Gala 17768bab0b Merge branch 'develop' into 317-forms-menus-titles-ui 2022-09-14 14:11:10 +02:00
Gala 7816b4c839 some refactor 2022-09-14 13:58:04 +02:00
Gala e7ed48e55e trying to fix the build 2022-09-14 13:35:22 +02:00
Gala 63855f6ca4 display pledge_amount instead of self on mix nodes page 2022-09-14 13:13:08 +02:00
Dave Hrycyszyn 2f53e40355 Switching to mainnet validator API 2022-09-14 11:49:06 +01:00
Dave Hrycyszyn bb9753cda6 Switching webassembly client to sync web assembly (async loading doens't work) 2022-09-14 11:49:06 +01:00
Dave Hrycyszyn 95d0afdeb6 Whitespace fix 2022-09-14 11:49:06 +01:00
mx fbe02fa7fb added new blockstream endpoint to example allowed.list (#1611)
* added new blockstream endpoint to example allowed.list

* updated changelog
2022-09-14 11:07:19 +01:00
dependabot[bot] 46e206e8f0 build(deps): bump terser from 4.8.0 to 4.8.1 (#1468)
Bumps [terser](https://github.com/terser/terser) from 4.8.0 to 4.8.1.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-14 11:07:05 +01:00
dependabot[bot] 55bdcecffb Bump parse-url from 6.0.0 to 6.0.5 (#1497)
Bumps [parse-url](https://github.com/IonicaBizau/parse-url) from 6.0.0 to 6.0.5.
- [Release notes](https://github.com/IonicaBizau/parse-url/releases)
- [Commits](https://github.com/IonicaBizau/parse-url/compare/6.0.0...6.0.5)

---
updated-dependencies:
- dependency-name: parse-url
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-14 11:05:39 +01:00
dependabot[bot] 2ee4b8fec6 Bump @openzeppelin/contracts in /contracts/basic-bandwidth-generation (#1545)
Bumps [@openzeppelin/contracts](https://github.com/OpenZeppelin/openzeppelin-contracts) from 4.5.0 to 4.7.3.
- [Release notes](https://github.com/OpenZeppelin/openzeppelin-contracts/releases)
- [Changelog](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CHANGELOG.md)
- [Commits](https://github.com/OpenZeppelin/openzeppelin-contracts/compare/v4.5.0...v4.7.3)

---
updated-dependencies:
- dependency-name: "@openzeppelin/contracts"
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-14 11:05:07 +01:00
dependabot[bot] 67900956f8 Bump terser in /clients/native/examples/js-examples/websocket (#1620)
Bumps [terser](https://github.com/terser/terser) from 5.12.1 to 5.15.0.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/compare/v5.12.1...v5.15.0)

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

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-14 11:04:14 +01:00
dependabot[bot] 29166c1d6a Bump terser from 5.10.0 to 5.15.0 in /testnet-faucet (#1621)
Bumps [terser](https://github.com/terser/terser) from 5.10.0 to 5.15.0.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/compare/v5.10.0...v5.15.0)

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

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-14 11:03:56 +01:00
Gala 27d566dd47 some styling 2022-09-14 11:46:06 +02:00
Gala bfa0144594 text change 2022-09-14 11:38:10 +02:00
Gala 8924f9642f wip 2022-09-14 11:35:22 +02:00
Dave Hrycyszyn db24170752 Fixing npm audit in js example code 2022-09-14 10:32:39 +01:00
Gala 58541defad Merge branch 'develop' into 309-figma-diff-mnemonic 2022-09-14 11:29:55 +02:00
Gala c513014913 taking advantage to deal with some other differences 2022-09-14 11:27:41 +02:00
Gala 5985ba5182 Merge branch 'develop' into 305-ui-fixes-inputs 2022-09-14 10:08:17 +02:00
Jon Häggblad fc90d5a389 ci: more cargo clean for windows
Not ideal, we need runners with more disk space
2022-09-14 08:31:05 +02:00
Raphaël Walther af1a83fe83 Test for notification 2022-09-13 19:35:22 +02:00
Raphaël Walther e12b69e58f Test for notification 2022-09-13 19:28:46 +02:00
Raphaël Walther d38614b15c Test for notification 2022-09-13 19:22:09 +02:00
Raphaël Walther 627d12239e Added keybase team variable (#1537)
* Added keybase team variable

* Amended notification
2022-09-13 18:13:18 +01:00
Gala 1af1370f23 display raw bond instead of self % 2022-09-13 17:00:37 +02:00
Gala ade15d3c60 change mnemonic textfield 2022-09-13 14:53:04 +02:00
Gala 1241a81514 changing alert behaviour 2022-09-13 13:49:42 +02:00
Gala 08a190c1cb Merge branch 'develop' into 348-bonding-settings 2022-09-13 12:44:11 +02:00
Mark Sinclair 124103d51b Mixnet and vesting contracts v1.0.2 (#1616) 2022-09-13 09:47:18 +01:00
Drazen Urch 6154b0c24c Fix claim -> undelegate (#1613)
* Fix claim -> undelegate

* Fix ordering

* Changelog
2022-09-13 09:38:23 +01:00
Pierre Dommerc b43657f42d feat(wallet): add tauri ops to sign and verify (#1606)
* Fix compile error

* Expose signing wallet for signing client

* Add stub tauri operation to sign a message with the current account

* feat(wallet): add a request to verify a signature

* feat(wallet): add support to verify from account address

* feat(wallet): add support to verify from account address

* fix(wallet): verify tauri request signature

* wallet-recovery-cli: upgrade clap to 3.2

* Fix compile error

* Expose signing wallet for signing client

* Add stub tauri operation to sign a message with the current account

* feat(wallet): add a request to verify a signature

* feat(wallet): add support to verify from account address

* feat(wallet): add support to verify from account address

* fix(wallet): verify tauri request signature

* Fix deserializtion of U128

* feat(wallet): avoid unwrap

* refactor(wallet):suggested feedbacks

Co-authored-by: Mark Sinclair <mmsinclair@gmail.com>
Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
Co-authored-by: durch <durch@users.noreply.github.com>
2022-09-12 12:32:10 +02:00
Jon Häggblad 20624243c0 ci: another ugly fix for windows low disk space
Crazy. I hope we can get runners with more disk space soon
2022-09-12 10:38:48 +02:00
Mark Sinclair fdff4bf1b7 Nym Wallet v1.0.9 (#1605)
* network-defaults: update mainnet default nymd_url

* update tests

* Bump nym-wallet version to 1.0.9 and update CHANGELOG

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
2022-09-09 14:47:17 +01:00
Jon Häggblad 47726d3561 Merge pull request #1591 from nymtech/jon/feat/socks5-client-graceful-shutdown
socks5-client: graceful shutdown
2022-09-09 15:45:19 +02:00
Jon Häggblad f3ed0bb11f gateway-client: disable shutdown signalling for wasm 2022-09-09 15:00:13 +02:00
Jon Häggblad 351adb7f7b socks5: add missing SHUTDOWN_HAS_BEEN_SIGNALLED.store 2022-09-09 13:02:53 +02:00
Jon Häggblad e0567dddf2 gateway-client: additional shutdown handling 2022-09-09 12:10:41 +02:00
Jon Häggblad d109c53370 socks5: tasks with closed channels should all exit 2022-09-09 12:10:41 +02:00
Jon Häggblad baed6c89fc socks5: assert that tasks are not exiting when not shutdown 2022-09-09 12:10:32 +02:00
Jon Häggblad 106491ef01 more clippy 2022-09-09 12:09:59 +02:00
Jon Häggblad 46135146ea clippy 2022-09-09 12:09:59 +02:00
Jon Häggblad 04e5cfabb8 changelog: add note 2022-09-09 12:09:59 +02:00
Jon Häggblad 10be112279 socks5-client: graceful shutdown 2022-09-09 12:09:59 +02:00
Raphaël Walther 634818a988 Added notification workflow 2022-09-09 11:41:44 +02:00
Raphaël Walther 5cb80f7648 Revert "Added audit workflow"
This reverts commit a7afd2a1c7.
2022-09-09 11:36:49 +02:00
Bogdan-Ștefan Neacşu 4d5565d8b6 Remove migration code (#1604)
* Remove migration code

* Leave blacklist functionality, just in case
2022-09-08 18:41:56 +03:00
Gala 81f36e8da7 some refactor 2022-09-08 13:36:44 +02:00
Gala f230229ce9 change save button label 2022-09-08 12:18:09 +02:00
Gala 912fb4ab38 Merge branch 'develop' into 348-bonding-settings 2022-09-08 12:05:34 +02:00
Gala 28cc772d7b various ui updates 2022-09-08 11:43:59 +02:00
Jon Häggblad f172a23ef8 clients: remove cluster of unwrap and expects for gateway handling (#1599)
* clients: remove cluster of unwraps and expects for gateway handling

* rustfmt
2022-09-07 15:35:26 +02:00
Gala 1ab6bce821 Merge branch 'develop' into 305-ui-fixes-inputs 2022-09-07 11:27:57 +02:00
Drazen Urch 2363f3ad0a Initial docs pass (#1582) 2022-09-07 01:41:51 +02:00
Jędrzej Stuczyński 6d3e5f22d4 Removed mix_denom from vesting MigrateMsg 2022-09-06 16:45:32 +01:00
Jędrzej Stuczyński c74ea43b94 Removed migration artifacts from mixnet and vesting contracts (#1598)
* Removed migration artifacts from mixnet and vesting contracts

* Workaround for CI build

* unused imports
2022-09-06 16:20:16 +01:00
Gala 70624e9062 modals and dialogs border in dark mode 2022-09-06 16:40:50 +02:00
Gala 2407285121 fixing paddings on modals 2022-09-06 14:33:41 +02:00
Drazen Urch 49d8424e30 Update network-requester dependencies (#1588) 2022-09-06 14:24:17 +02:00
Drazen Urch 5a7f296328 Update validator-api dependencies (#1589) 2022-09-06 14:15:22 +02:00
Gala db3171ea09 ModalListItem fix font size 2022-09-06 13:58:54 +02:00
Gala 2aaaa0deb7 globally no colon at the end of ModalListItem 2022-09-06 13:55:20 +02:00
Gala d410277d14 change all placeholders on textfields into labels 2022-09-06 13:41:35 +02:00
Gala 99ceabb0b0 using the wallet Tab component 2022-09-06 13:18:43 +02:00
Fouad 8a6f8185db Update/update modal background color (#1594)
* update receive bg color + all other modals
2022-09-06 09:56:12 +01:00
Bogdan-Ștefan Neacşu 30dfa09e18 Simplify the migration to trust the owner more (#1593) 2022-09-05 17:31:06 +03:00
Mark Sinclair 7e7072258d Add nym-cli tool (#1577)
Co-authored-by: tommy <tommyvez@protonmail.com>
2022-09-05 12:06:35 +01:00
Bogdan-Ștefan Neacşu 10221a1767 Migrate heights to timestamps (#1584)
* Migrate heights to timestamps

* Improve test with a possible scenario

* Use account id instead of address, as returned by the query
2022-09-05 12:25:57 +03:00
Gala 25df7bcd4d Merge branch 'develop' into 348-bonding-settings 2022-09-02 09:39:21 +02:00
Jędrzej Stuczyński a2c6abd3dd Made nodes_to_remove field in mixnet MigrateMsg public 2022-09-01 17:10:17 +01:00
Gala 1cdca7bec3 unbond modal verification step 2022-09-01 16:57:48 +02:00
Gala c809c7733d logic refactor 2022-09-01 15:06:23 +02:00
Gala 7b53003edb wip verification modal 2022-08-31 18:49:47 +02:00
Gala 831d9d2bf8 update alert text 2022-08-31 18:20:40 +02:00
Gala cb7c51ba12 remove node settings modal trigger 2022-08-31 17:37:00 +02:00
Gala 0310f0a8a9 some refactor 2022-08-31 17:23:53 +02:00
Gala bb79d08f6d dynamic values and remove hard coded code 2022-08-31 16:58:53 +02:00
Bogdan-Ștefan Neacşu d289c46e87 Feature/nr err report (#1576)
* common/socks5: Use thiserror and add copyright notice

* Send allowlist failure msg back to socks5 client

* Add some serde unit tests

* Fix clippy after rustup update

* Update changelog
2022-08-31 16:27:02 +03:00
Gala 414c86b500 fix button width 2022-08-31 12:13:40 +02:00
Gala 4304ffcf3c adding notification span 2022-08-31 11:44:23 +02:00
Gala 309b23e18a adding confirmation modals 2022-08-31 10:55:13 +02:00
Gala 52703583f0 adding validation to parameters settings 2022-08-31 10:10:37 +02:00
Gala 6473ef13c6 validate info fields 2022-08-30 18:51:39 +02:00
Gala 6de7d060e3 keep same margin on between pages 2022-08-30 17:00:48 +02:00
Gala 9a45f15ba4 wip 2022-08-30 16:49:07 +02:00
Gala 66b5eb13b0 fixing nymcard title size and margin in delegations page 2022-08-30 14:32:15 +02:00
Bogdan-Ștefan Neacşu a6aba3defd Feature/validator api shutdown (#1573)
* Rewarded set updater shutdown (partial) handling

* Shutdown handling in monitor

* Remove shutdown from packet receiver

* Configurable shutdown timeout

* Select on test_run too

* Remove unnecessary await/async

* Add bias to shutdown select and concurrency for big tasks

* Put cpu-bound packet prep on separate thread, to avoid blocking

* Use a better fit timeout value

* Fix clippy warnings

* Update changelog

* Fix wasm client
2022-08-30 14:14:50 +03:00
Jędrzej Stuczyński 6557be3738 Delegator compoudning to bypass pending events (#1571)
* Delegator compoudning to bypass pending events

* Updated changelog
2022-08-30 11:56:13 +01:00
Gala 4b37d4f050 Merge branch 'develop' into 317-forms-menus-titles-ui 2022-08-30 12:50:11 +02:00
Gala 746795b7ce mook bonded node 2022-08-30 12:49:50 +02:00
Gala 8b81247044 Merge branch 'develop' into 348-bonding-settings 2022-08-30 11:08:19 +02:00
Bogdan-Ștefan Neacşu 7134755073 Feature/credential mode (#1570)
* Activate enabled cred mode for coconut feature

* Fix disable cred mode propagation bug
2022-08-26 16:45:32 +03:00
Sachin Kamath dd1420a65a Wallet - set gateway default port to 9000 (#1568)
* fix(wallet): client port to gateway defaults

* fix(wallet): refactor variable name
2022-08-26 13:28:58 +02:00
Jędrzej Stuczyński df1bc60464 Feature/vesting delegations queries (#1569)
* Added contract queries for vesting delegations

* Added the queries on NymdClient

* Added account_id to DelegationTimesResponse

* Returning raw u64 as opposed to wrapped Timestamp

* Updated changelog
2022-08-26 11:24:16 +01:00
Bogdan-Ștefan Neacşu 865e809342 Remove hard-coded values from credential client (#1566) 2022-08-25 17:52:43 +03:00
Jon Häggblad 51f9c1ca29 Connect: remove some sources of panics when initializing socks5-client (#1563)
* connect: remove panic when unable to load previous gateway conf

* connect: dont panic when cant get config file
2022-08-25 16:25:31 +02:00
Jon Häggblad 303b014a59 types: fix missing entries in SelectionChance (#1564) 2022-08-25 14:06:54 +02:00
Jon Häggblad e1e20fb13e inclusion-prob: make rng generic and predictable in tests (#1561) 2022-08-25 08:47:04 +02:00
Mark Sinclair 0c3c13ae88 Change nym-connect window title to NymConnect 2022-08-24 15:48:26 +01:00
Jon Häggblad 8c8b7d71d0 validator-api: create node status cache with selection probabilies (#1547)
* validator-api: create node status cache with selection probabilies

Create a node status cache to complement the contract cache. Initially
we store the simulated active set selection probabilities.

* validator-api: add validator cache watch channel

* changelog: add note

* validator-api: clippy fixes

* validator-api: fix clippy

* validator-api: additional fields to inclusion probabilities response

* selection chance: revert back to 3 buckets

* selection chance: revert buckets again

* rustfmt

* validator-api: remove the old get_mixnode_inclusion_probability

* node-status-cache: return error when refreshing

* inclusion-simulator: cap on wall clock time

* node status cache: tidy
2022-08-24 14:29:21 +02:00
Jon Häggblad 3163c5f054 gateway-client: clippy::question-mark 2022-08-24 09:51:47 +02:00
Jon Häggblad 4a1794b2f1 nymcoconut: fix named-arguments-used-positionally 2022-08-24 09:51:47 +02:00
Jon Häggblad 1898b8ed96 validator-api: add bounds checks in compute_mixnode_reward_estimation (#1559) 2022-08-24 09:30:12 +02:00
Mark Sinclair a23471859d GitHub Actions: fix up artifacts on nym-cli-publish 2022-08-23 20:19:57 +01:00
Mark Sinclair 9d8c9edf22 Add GitHub Action to build nym-cli on all platforms 2022-08-23 19:27:03 +01:00
Pierre Dommerc 5ea7b24efc fix(nym-wallet): bonding, enhance error handling (#1543)
open a dialog for user feedback when error occurs
add some better error logging
2022-08-23 17:53:57 +02:00
Jędrzej Stuczyński a43a24faa8 Exposed direct queries to smart contract on NymdClient (#1558)
* Exposed direct queries to smart contract on NymdClient

* Updated changelog
2022-08-23 15:45:43 +01:00
Jędrzej Stuczyński 39ee215005 Storing delegations using block timestamp as opposed to block height (#1544)
* Storing delegations using block timestamp as opposed to block height

* Updated changelog
2022-08-23 09:42:34 +01:00
Mark Sinclair ef7961f58e Update nym-release-publish.yml 2022-08-19 18:32:28 +01:00
Mark Sinclair e628338b33 GitHub Actions: add manual dispatch and artifact upload 2022-08-19 18:23:16 +01:00
Gala c6cd787950 adding unbonding modal 2022-08-19 18:06:04 +02:00
Pierre Dommerc 1bb137f87f Nym-connect - service provider persistant storage (#1540)
* feat(nym-connect): local storage service provider

* feat(nym-connect): local storage service provider

* feat(nym-connect): local storage service provider

* Add some extra height to the window to stop the scrollbar apearing

* Show the service description when selecting a Service Provider

* Bump version

* Update changelog

* fix(nym-connect): hotfix

* fix(nym-connect): hotfix

* fix(nym-connect): wrong disabled state for connection button

Co-authored-by: Mark Sinclair <mmsinclair@gmail.com>
2022-08-18 18:53:03 +02:00
Gala f9ab20b10f more styling in node
settings page
2022-08-18 17:27:28 +02:00
Gala acffd496ed nav styles 2022-08-18 17:07:59 +02:00
Gala 466ac1a1e0 settings general page 2022-08-18 16:39:05 +02:00
Dave Hrycyszyn 773f9e5ead Moving helpful comment into docs comment 2022-08-18 10:45:42 +01:00
Pierre Dommerc 79f695f138 Wallet: new UI for pending delegation (#1499)
* refactor(wallet-delegation): new delegation pending ui

* refactor(wallet-delegation): remove pending delegation table

* refactor(wallet-delegation): new pending delegation ui

* refactor(wallet-delegation): remove logs

* refactor(wallet-delegation): better typing

* refactor(wallet-balance): feedback review
2022-08-18 11:20:32 +02:00
Gala d53adcd17e nodesettings page and logic to browse 2022-08-17 18:55:58 +02:00
Pierre Dommerc 3aabbcf876 fix(nym-wallet): make get_operator_rewards request success optional (#1542) 2022-08-17 17:21:36 +02:00
Jędrzej Stuczyński d96b7408db Allowing optional fee for top-level NymdClient (#1541)
* Allowing optional fee for top-level NymdClient

* Updated changelog

* Fixed usages of said methods in validator-api
2022-08-17 13:27:53 +01:00
Gala 36e82e831f Merge branch 'develop' into 348-bonding-settings 2022-08-17 13:55:06 +02:00
Gala cbe0115f01 wip 2022-08-17 11:10:10 +02:00
Jon Häggblad 728b0f4549 inclusion-probability: new crate for simulation active set inclusion (#1534) 2022-08-16 14:19:55 +02:00
Gala 1dae3c3fc2 remove vAxis label 2022-08-16 14:08:00 +02:00
Gala 574e5cf10a change legend 2022-08-16 13:42:48 +02:00
Gala b3fcbb6726 remove log 2022-08-16 12:28:09 +02:00
Gala f96a60b6a2 log in staging 2022-08-16 12:10:17 +02:00
tommy 0a37c81709 remove not needed prior state of denom 2022-08-16 12:05:38 +02:00
Jędrzej Stuczyński 957cbb45b0 Chore/linter updates (#1530)
* Removed needless return

* Added Eq derivation where applicable for types with PartialEq
2022-08-12 17:56:49 +01:00
Pierre Dommerc 8ec074cb1f fix(wallet): typo (#1527) 2022-08-12 16:02:27 +02:00
Jess ab5740087f Update CHANGELOG.md 2022-08-12 14:55:39 +01:00
Jess 6af59c303e Update CHANGELOG.md 2022-08-12 14:54:09 +01:00
Jess 27b384e034 Update CHANGELOG.md 2022-08-12 14:53:40 +01:00
Dave Hrycyszyn 7f5ce3ffeb Removing wallet entries from main changelog 2022-08-12 12:58:49 +01:00
Dave Hrycyszyn 89b6667c75 Splitting changelogs into their own files 2022-08-12 12:50:17 +01:00
Tommy Verrall a94a9aeaf5 Update README.md 2022-08-11 16:18:06 +01:00
tommy 6bc8b88a20 WIP - validator-api-tests
- Test base line
- Jest / Typescript / Node
2022-08-11 17:14:04 +02:00
Gala 37d501f16d fix delegate more focus state 2022-08-11 16:20:05 +02:00
Gala 1e76169178 fixing spacing in modals 2022-08-11 14:57:37 +02:00
Gala 7406eeff14 ui top bar 2022-08-11 14:11:57 +02:00
Gala bdabe31fc9 side navigation 2022-08-11 14:03:02 +02:00
Fouad 21f3991714 update sample env (#1523) 2022-08-11 12:21:19 +01:00
Tommy Verrall cd8eba988a Merge pull request #1522 from nymtech/release/wallet-v1.0.8
Release/wallet v1.0.8
2022-08-11 11:45:53 +01:00
Tommy Verrall d2b3841bbd Update Cargo.toml 2022-08-11 11:45:28 +01:00
Tommy Verrall de877fb337 Merge pull request #1521 from nymtech/release/nym-binaries-1.0.2
Release/nym binaries 1.0.2
2022-08-11 11:42:36 +01:00
Tommy Verrall d4c2b9060f Update changelog for v1.0.2 -reference 2022-08-11 10:02:34 +01:00
Bogdan-Ștefan Neacşu 41ac866729 Feature/validator api panics (#1520)
* Coconut unwraps

* Fail softly on epoch queries

* Update changelog

* Retry a few times before failing as before
2022-08-11 11:58:17 +03:00
Raphaël Walther a7afd2a1c7 Added audit workflow 2022-08-11 10:41:57 +02:00
Jon Häggblad df03daf2cc socks5: remove pub mod not needed anymore (#1517)
* socks5: remove pub mod not needed anymore

* all: dedup parse_validators and move to common

* rustfmt
2022-08-10 21:14:12 +02:00
Gala f7b979825b Merge branch 'develop' into 340-ne-content 2022-08-10 16:44:02 +02:00
Raphaël Walther b3f5a4f496 Added audit workflow 2022-08-10 16:35:49 +02:00
Raphaël Walther d080d661f7 Added audit workflow 2022-08-10 16:29:54 +02:00
Raphaël Walther 6deb481e5d Added audit workflow 2022-08-10 16:09:05 +02:00
Raphaël Walther 5b98e18a4e Added audit workflow 2022-08-10 16:03:11 +02:00
Raphaël Walther 506a0da89c Added audit workflow 2022-08-10 16:00:50 +02:00
Bogdan-Ștefan Neacșu c7fdcf0a79 Change for default mainnet and fix typo 2022-08-10 13:40:28 +03:00
Gala 6ac1259f7a changing content 2022-08-10 11:24:02 +02:00
Fouad f7d38a7ec6 modal style updates (#1508)
remove commented code

remove unused props

fix props
2022-08-10 10:14:48 +01:00
tommy 8edc762df9 Update
- update the cargo toml
- amend the work flow file
- and the envs to mainnet (disclaimer add qa after)
2022-08-10 11:10:38 +02:00
Pierre Dommerc 4459aca933 fix(wallet-delegation): add error feedback on wrong address (#1510)
* fix(wallet-delegation): add error feedback on wrong address

* fix(wallet-delegation): use generic component for modal error
2022-08-10 09:31:14 +01:00
Pierre Dommerc 5b84c58985 feat(wallet-balance): hide vesting ui when vesting balance is empty (#1505)
* feat(wallet-balance): hide vesting ui when vesting balance is empty

* refactor(wallet-balance): feedback review
2022-08-10 09:29:01 +01:00
Fouad 4301d91f6c Feature/wallet style updates (#1506)
* update buttons hover colours

* fix nymcard title size

* style updates for accounts!

* fix delegations page lock-up on network switch
2022-08-10 09:28:03 +01:00
Fouad 03d28c115e delegations page style updates (#1507) 2022-08-10 09:27:03 +01:00
tommy 7b15f350cd add service-provider vesioning to match other binaries 2022-08-10 10:14:07 +02:00
tommy 2b4917b8b1 fix messaging on init for nym-client 2022-08-10 10:11:00 +02:00
Jędrzej Stuczyński de78ca8d9b Removed unnecessary to-owned conversion 2022-08-09 15:25:45 +01:00
Gala 58d09e382a Merge pull request #1504 from nymtech/smooth-filter-slider
Smooth filter slider
2022-08-09 14:59:11 +02:00
Gala 0cef12d05b Merge pull request #1502 from nymtech/1501-contrast-text
fixing text color
2022-08-09 14:58:07 +02:00
Jon Häggblad 30e73ee795 Explorer: tweak selection probability categories (#1503)
* validator-api: tweak SelectionChance

* wallet: update SelectionChance colorMap

* changelog: add note
2022-08-09 12:57:47 +02:00
Tommy Verrall d918b69664 Update .env.qa
Fix wrong denoms for the qa.env
2022-08-09 11:53:11 +01:00
tommy 921e558660 Update versions on binaries 2022-08-09 11:56:54 +02:00
Gala b3b8d2ab46 adding the value to the cursor 2022-08-08 17:03:05 +02:00
tommy d62638b8e2 update wallet version 2022-08-08 16:53:00 +02:00
Gala 67130a1289 adding smooth prop 2022-08-08 16:30:10 +02:00
Fouad 0dabff72bd Feature/bonding refactor (#1481)
* feat(wallet-bonding): bonding page, new bond form wip

* feat(wallet-bonding): add node table component

feat(wallet-bonding): new dialog component

* feat(wallet-bonding): node settings flow

* feat(wallet-bonding): bond more flow (done)

* feat(wallet): use confirmation modal component

* feat(wallet-bonding): node menu ui

* refactor(wallet-bonding): bonding flow with new gasFee estimation

* feat(wallet-bonding): unbond with gasFee and request

* refactor(wallet-bonding): switch to simpledialog component to keep modals consistency

* feat(wallet-bonding): fetch mixnode status

* update coin types in new bonding page

* fix displayed denom

* rebuild BondedNodeCard using existing shared components

* create reuseable ActionMenu component

* new mixnode form

* add gateway bond form

* check balance and fetch fee on bond mixnode request

* node settings

* get node description

* fix up rust request

* lint fixes + used NodeTypeSelector component

* temporarily remove estimated operator reward

* update return on rust function

* dont display node name UI if name doesnt exist

* rebase develop

* fix uppercase address bug

Co-authored-by: Mark Sinclair <mmsinclair@gmail.com>
Co-authored-by: pierre <dommerc.pierre@gmail.com>
2022-08-08 14:09:57 +01:00
Gala e8e2f195e6 fixing text color 2022-08-08 14:09:33 +02:00
Jędrzej Stuczyński fa354016e0 Removed useless into() conversion 2022-08-08 09:49:52 +01:00
Tommy Verrall 935ee765e9 Merge pull request #1498 from nymtech/feature/fix-envs
fix .env files for explorer.
2022-08-05 16:36:08 +01:00
tommy 4c8e59e6fc fix .env files for explorer. 2022-08-05 17:11:35 +02:00
Bogdan-Ștefan Neacşu 067f3e6f1a validator-api: handle SIGTERM (#1496)
* validator-api: handle SIGTERM

* Update CHANGELOG
2022-08-05 15:59:34 +03:00
Gala 6f09d46dce Merge pull request #1492 from nymtech/feature/delegating_ui_update
feat(wallet-delegation): new confirmation modal ui
2022-08-05 12:08:51 +02:00
Gala bdef48331b Merge pull request #1489 from nymtech/332-fix-vesting-ui
Wallet: Fixing dark mode colours in vesting shedule
2022-08-05 12:05:19 +02:00
Gala 51a6936e51 Merge pull request #1491 from nymtech/330-mix-wallet-ui
Wallet: Fix light mode bg and nav bar UI
2022-08-05 12:02:50 +02:00
Gala fd456d2952 Merge pull request #1490 from nymtech/334-ne-changes
NE: Filter by use routing score instead of stake parameter and adding filters info
2022-08-04 18:24:04 +02:00
Gala eee1abe593 removing extra styles 2022-08-04 18:15:12 +02:00
Gala fffad43937 Avoiding CAPS in button 2022-08-04 17:51:24 +02:00
Gala 3a79f43a8d styling 2022-08-04 17:23:32 +02:00
pierre 2e495f87ab refactor(wallet-delegation): ModalListItem component, pass colon in label value 2022-08-04 16:35:14 +02:00
Gala 57a9f18f5a fixing padding marging and wording 2022-08-04 16:30:33 +02:00
Gala 0c6a0a9cae Merge branch 'develop' into 334-ne-changes 2022-08-04 15:18:54 +02:00
Gala c80d8d354a adding nodes number info 2022-08-04 15:17:44 +02:00
Gala 3f544dbc69 adding Advanced filtering text and hover fix 2022-08-04 14:59:17 +02:00
pierre d1e1f15db0 Merge branch 'develop' into feature/delegating_ui_update 2022-08-04 13:26:41 +02:00
pierre 651c314182 feat(wallet-delegation): new confirmation modal ui 2022-08-04 13:20:00 +02:00
Dave Hrycyszyn b957b939cf Typo fix 2022-08-04 11:01:36 +01:00
Gala a57545521d some refactor 2022-08-04 11:28:04 +02:00
Gala da60606921 hover bg color in dark and light mode 2022-08-03 17:20:46 +02:00
Gala 14f9bf7234 left nav spacing 2022-08-03 16:50:02 +02:00
Gala c1fa92869a fix light bg color 2022-08-03 16:49:47 +02:00
Gala c8533e3ec8 cleaning 2022-08-03 14:15:03 +02:00
Gala 06c4dd601d filter by use routing score instead of stake parameter 2022-08-03 14:06:33 +02:00
Gala 4ff80bbab2 fixing dark mode progress bar 2022-08-03 14:02:50 +02:00
Gala d7220b1fec adding info text in filters and renaming 2022-08-03 13:42:48 +02:00
Gala d92df9ada3 fixing dark mode colours 2022-08-03 12:24:21 +02:00
Bogdan-Ștefan Neacşu 9c19ae322d Bump regex version to fix dependabot (#1488) 2022-08-03 12:45:21 +03:00
Bogdan-Ștefan Neacşu 07893828d8 Fix NC filter for domains suffix-only domains (#1487)
* Fix NC filter for domains suffix-only domains

* Update CHANGELOG

* Fix unit test for filter

Some domains might be composed of the suffix only.

There are no nonsense domains, as they can be defined even on the local
machine. The underlying library doesn't resolve them, but rather uses a
fixed list of public suffixes to assess the domains.

* Fix clippy
2022-08-03 11:58:20 +03:00
Pierre Dommerc 1167f50543 [Wallet] move Receive page in modal (#1484)
* feat(wallet): move receive page in modal

* feat(wallet-receive): some ui work

* feat(wallet): simple modal component

show or not the Ok button based on onOk props

* feat(wallet): fix sx props type imports
2022-08-02 12:04:47 +02:00
Drazen Urch ba1818a903 Chitchat example (#1464)
* Chitchat example

* Cleanup
2022-08-01 14:19:04 +02:00
Bogdan-Ștefan Neacşu e631219a73 explorer-api: handle SIGTERM (#1482)
* explorer-api: handle SIGTERM

* Update CHANGELOG
2022-08-01 13:30:31 +03:00
rachyandco 207c6cf2c7 Correcting a typo (#1475)
Co-authored-by: Rachyandco <alexis@nymtech.net>
2022-07-29 09:13:07 +01:00
Drazen Urch c5ece97872 Stake inflation mitigations (#1480)
* Return Err from compound transactions

* Remove malicious nodes migration

* Reduce total delegation, before adding to it

* Blacklist malicious nodes, prevent future bonding

* Blacklisted gets no reward, enable compound

* Add GetBlacklistedNodes message

* Rebase on develop

* Remove TODO
2022-07-28 15:19:31 +02:00
Bogdan-Ștefan Neacșu 8a2c95d044 Mixnode option doc fix 2022-07-26 15:00:27 +03:00
Bogdan-Ștefan Neacşu ba5e3d4efa Remove service entries instead of zeroing them (#1479) 2022-07-26 11:53:10 +03:00
Bogdan-Ștefan Neacşu c81623a61a Add gateway id in the gateway stats (#1478)
* Add gateway id in the gateway stats

* Update CHANGELOG
2022-07-25 16:59:45 +03:00
Bogdan-Ștefan Neacşu 8bb42c2b1b Add migration code for mixnet and vesting contracts (#1477) 2022-07-25 14:05:22 +03:00
Mark Sinclair 33e161bd59 GitHub Actions: make explorer deployment only a manual step 2022-07-22 12:19:58 +01:00
Mark Sinclair 0233499036 GitHub Actions: add prod deploy step for Network Explorer UI 2022-07-22 10:34:20 +01:00
Mark Sinclair a059a29173 nym-connect: update CHANGELOG and bump version to 1.0.1 2022-07-22 10:15:18 +01:00
Mark Sinclair 83c3398570 nym-connect: copy changes 2022-07-22 10:09:13 +01:00
Fouad 93f931459a fix type update issues with actions (bonding, delegating etc.) (#1469) 2022-07-22 09:40:06 +01:00
Bogdan-Ștefan Neacşu 5a7b19aeb6 Nym connect use config from env (mainnet defaulted (#1471) 2022-07-21 17:03:14 +03:00
Bogdan-Ștefan Neacşu b901655591 Fix message deserialization in socks5 client (#1470) 2022-07-21 15:36:38 +03:00
Drazen Urch a9fdbccb82 Universal compound rewards message that anyone can call (#1387) 2022-07-21 10:51:33 +02:00
Bogdan-Ștefan Neacşu 9ca3f69aa8 Feature/config from env (#1463)
* Clients use env

* Explorer api uses env

* Mainnet and qa env files

* Set CONFIGURED on the mainnet defaulting

* Gateway uses env

* Mixnode uses env

* Wallet error simplification

* Network requester takes only mainnet client address

* Validator api uses env

* Mixnet contract uses denom from instantiate

* Vesting contract uses denom from instantiate

* More contract test refactoring

* Coconut bandwidth contract uses denom from instantiate

* Bandwidth claim contract uses denom from instantiate and remove from Cargos

* More remove from Cargos and one missed DEFAULT_NETWORK

* Refactor some other missed places

* Minor fixes

* Test and clippy fixes

* Update CHANGELOG
2022-07-20 13:16:37 +03:00
Fouad c485934b06 Network Explorer: Mixnode filters (#1460)
* add filters UI

* use filter schema

* filter mixnode based on selected filters

* only show filters on the mixnode page

* use base api to get all mixnodes to avoid setting mixnodes in state

* prevent additional request when status changes

* create isMobile hook
2022-07-18 15:18:39 +01:00
Bogdan-Ștefan Neacşu d62e13c932 Feature/coconut double spend prev (#1457)
* Add spend credential endpoint to coconut bandwidth contract

* Store spent credentials support

* Add query endpoint for spent credentials

* Proposals allowed only from special (contract) address

* Include check for admin in tests

* Create proposal from CBC

* Refactor into coconut integration tests

* Create proposal with spend credential integration test

* Resolve mixnet warnings

* Refactor to re-enable build

* Call CBC from gateway and remove validator-api workaround

* Include migration for the first deployment of multisig

* Fix bug in proposal id parsing

* Remove more validator-api create proposal code

* Check for InProgress status of credential

* Check the proposed voucher value

* Unwrapping cosmos msg from gateway

* Improve error message

* More nit fixing

* Test getting validator api cosmos address endpoint

* Refactor to prepare for distributed comm channel

* Refactor coconut e2e test for reuse

* Verification of cred endpoint test

* Update CHANGELOG
2022-07-18 12:37:07 +03:00
Fouad 47f7a5f795 Feature/changing wallet currency types frontend work (#1455)
* Introduced concept of denom details

No longer exposing plain 'DENOM'

Denom registration + conversion

Generating typescript type for DecCoin

'New' API on 'send'

Further WIP work on transforming usages of MajorCurrencyAmount into DecCoin

Further replacements of MajorCurrencyAmount into DecCoin

Attempt at dec-coinifying get_all_mix_delegations

Finished purge of MajorCurrencyAmount

Display for Fee

More unification for conversion methods

Fixed up tests and made clippy happier

Minor post-merge fixes

Removed explicit Arc and RwLock from all tauri commands

Fixed conversion to display coin

More type-restrictive exported denom type

Regenerated rust => ts types

* post-rebase fixes

* update frontend

* fix lint errors

* Adjusted Display implementation of DecCoin to include space between amount and denom

* Adding separate base and display denoms for account

* Fixed account constructor

* Using CurrencyDenom for display_mix_denom

* uppercase denom on frontend

* Changed AutoFeeGrant constructor

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2022-07-15 15:30:40 +01:00
Raphaël Walther f29200431f Amended nightly build trigger 2022-07-15 13:37:43 +02:00
Bogdan-Ștefan Neacşu 0912627e1f Update cosmrs in lock file, so it points to a valid git hash (#1459) 2022-07-15 14:17:58 +03:00
Raphaël Walther 70fdcc9be0 Added nightly build trigger 2022-07-15 13:12:29 +02:00
Mark Sinclair 90da6f152b typescript validator client: add denom argument to constructor (#1458)
* typescript validator client: add `denom` argument to constructor and a simple test for querying a balance.
Add to yarn workspaces.

* Update CHANGELOG
2022-07-14 15:25:01 +01:00
Bogdan-Ștefan Neacşu ad547e516a Feature/fee grant (#1419)
* Temporarily point cosmrs to PR branch

* Expose grant allowance in client

* Move functions in coconut verifier

* Do execute from gateway

* Explicit fee payment by granter

* Include revoke grant after finishing with the op

* Gateway checks the proposal content before proceeding

* Clippy fixes

* CHANGELOG update
2022-07-14 12:24:46 +03:00
Gala 61c0092f27 Merge pull request #1442 from nymtech/300-fix-ne-validarors-link
using a tag instead of link component for external link
2022-07-12 16:08:22 +02:00
Gala 851b80aaab 261 ne tooltip refactor (#1390)
* creating tooltip component

* using the tooltip component in the node list

* test another storie

* fixing text color in the story
2022-07-12 14:46:48 +01:00
Fouad 1397662fc9 upgrade tauri to latest stable version (#1446)
* upgrade tauri to latest stable version
2022-07-12 14:40:05 +01:00
Raphaël Walther 1847c8fe73 Added env file for qa 2022-07-12 13:59:00 +02:00
Mark Sinclair 8ffe3adf0d Update CHANGELOG.md 2022-07-11 14:48:58 +01:00
Mark Sinclair 3e517b461c nym-wallet: release v1.0.7 with dark mode and new gas fee simulations 2022-07-11 14:45:52 +01:00
fmtabbara e42e4ddb9b remove hidden backdrops 2022-07-08 23:20:30 +01:00
fmtabbara a31f51b7ca only set stored mode in wallet if not undefined 2022-07-08 23:01:17 +01:00
Jon Häggblad c41a600bcb all: add clap test asserts (#1452) 2022-07-08 21:04:09 +02:00
Fouad 7aa34391fb use tauri forage (#1451)
* use tauri forage

* commit lock file

* update to set in storage directly in set state
2022-07-08 18:41:22 +01:00
fmtabbara f72b56d07e remove old fees ui 2022-07-08 17:06:08 +01:00
Jon Häggblad 44ddbf9ac3 nym-connect: update package versions to resolve conflict (#1450)
* nym-connect: update package versions to resolve conflict

* nym-connect: add pre-target to build shared packages when building storybook

Co-authored-by: Mark Sinclair <mmsinclair@gmail.com>
2022-07-08 16:34:25 +01:00
fmtabbara 27c377860a remove old property useBootstrapper. See https://newreleases.io/project/github/tauri-apps/tauri/release/tauri-utils-v1.0.0-rc.5 2022-07-08 15:33:06 +01:00
Mark Sinclair 9a3f60f224 nym-connect: at pre-build target that builds the shared packages 2022-07-08 14:16:10 +01:00
Gala 5776600db3 Wallet: Dark mode for Balance page, Side nav. bar & theming in Storybook. (#1396)
* dark mode for balance page

* nav bar dark mode styles

* test wallet stories modes view

* Action Modals and Simple Modal stories

* Redeem Modals stories

* Delegation Modals

* mode handling

* remove not used code

* updating modal historial after update with develop

* wallet: more modals refactor for storybook

* more refactor

* non use redundant boolean value

* dark mode for balance page

* nav bar dark mode styles

* test wallet stories modes view

* adding missing import

* fixing modals in stories

* Action Modals and Simple Modal stories

* Redeem Modals stories

* Delegation Modals

* wrapper dialog content with a paper
2022-07-08 14:08:54 +01:00
Mark Sinclair e851ad8b27 Nym Connect: move into the workspace (#1449)
* nym-connect: use monorepo workspace and dependent packages

* nym-wallet: fix up dependencies

* nym-connect: ip and port copy values to clipboard with UI hint in tooltip

* nym-connect: update icons and word mark

* nym-connect: add automatic updater

* nym-connect: update CHANGELOG
2022-07-08 12:31:30 +01:00
Jon Häggblad 2e0e319511 validator-api: fix typo in apy estimate endpoint (#1447)
* validator-api: fix bug in apy calculations

* validator-api: missing variable
2022-07-07 13:41:51 +02:00
Jon Häggblad 6dd3e36acb mixnode & gateway: move detailed build info back to --version (#1445)
* mixnode and gatway: move build info back to version instead of help

* changelog: add note
2022-07-07 13:16:46 +02:00
Jon Häggblad 40cbfccb73 client: upgrade clap to latest and use declarative form (#1444)
* socks5: upgrade clap to latest and use declarateive derive form

* socks5: rustfmt and clippy

* socks5: missing doc strings

* socks5: default values for eth arguments

* socks5: tidy

* client: upgrade native client to latest clap and declerative form

* changelog: add note
2022-07-07 11:44:08 +02:00
Fouad b49681ef1d Feature/wallet bonding with fees rebase (#1428)
* use confirmation modal for successful/failed unbond

* show loading modal when getting fees

* use new back button

* use new confirmation modal component
2022-07-06 22:34:46 +01:00
Fouad 7e9409bbef Feature/send with simulated fee (#1402)
* add simulate send function

* extract loading modal into its own component

* move appbar component into folder

* add additional prop for making modal list item text bold

* create new send UI and stories

* remove old send page

* use simulated fee in send request

* use new confirmation modal component
2022-07-06 21:08:40 +01:00
Fouad a11e674967 Wallet: Transfer token component with fee included (#1385)
* set up transfer token component with fee included

* open transfer modal after balance refresh

* create fee warning component

* use confirmation modal
2022-07-06 16:19:15 +01:00
Jon Häggblad 2f4e505aac connect: add export_keys tauri function (#1443)
* connect: tidy

* connect: add export_keys tauri function

* changelog: add note

* connect: remove unused
2022-07-06 14:02:40 +02:00
Gala 90d8e5305f some refactor 2022-07-06 13:35:54 +02:00
Gala 81a678f9e2 using a tag instead of link component for external link 2022-07-06 10:52:12 +02:00
Jon Häggblad 0a4bbf2573 Merge pull request #1440 from nymtech/jon/chore/nym-connect/upgrade-tauri
nym-connect: upgrade tauri to 1.0.2
2022-07-05 21:33:12 +02:00
Jon Häggblad 2ae5ebb8cb nym-connect: upgrade rust tauri to 1.0.2 2022-07-05 21:03:03 +02:00
Jon Häggblad 11be1f8e3e nym-connect: upgrade frontend tauri to 1.0.2
yarn upgrade @tauri-apps/cli @tauri-apps/api --latest
2022-07-05 21:03:03 +02:00
Jon Häggblad 513baba3fd nym-connect: sort out error handling 2022-07-05 21:02:39 +02:00
Jon Häggblad 21b87f6af5 nym-connect: fix catching panic in init 2022-07-05 20:36:55 +02:00
Fouad fe59697aa9 Merge pull request #1435 from nymtech/feature/wallet-modal-back-button
Feature/wallet modal back button
2022-07-05 14:58:32 +01:00
Pierre Dommerc 566ceae325 feat(wallet): add confirmation modal component (#1434)
* feat(wallet): add confirmation modal component
2022-07-05 15:48:47 +02:00
fmtabbara 6bc4d32573 remove unused import 2022-07-05 14:25:53 +01:00
fmtabbara 1fc3c9f31c rename prop 2022-07-05 14:10:54 +01:00
fmtabbara 3cb08a410e fix conflicts 2022-07-05 13:59:46 +01:00
fmtabbara 1648aef1d3 add component story 2022-07-05 11:16:58 +01:00
fmtabbara d98b6b107c add back button option to simple modal component 2022-07-05 11:03:11 +01:00
Mark Sinclair d3db0fc2cd Update CODEOWNERS 2022-07-05 10:00:29 +01:00
Jon Häggblad 06b823f4c1 connect: catch panics during init 2022-07-04 17:19:41 +02:00
Jon Häggblad 1c0ce9a420 Merge pull request #1429 from nymtech/jon/feat/nym-connect-disconnect-signalling
nym-connect: disconnect signalling
2022-07-04 16:46:37 +02:00
Jon Häggblad dede8899cf cargo: exclude nym-connect from top-level workspace 2022-07-04 15:51:09 +02:00
Jon Häggblad 70f6059ceb connect: handle disconnect signalling 2022-07-04 15:51:09 +02:00
Jon Häggblad fefd2dd267 Merge pull request #1427 from nymtech/feature/nym-connect-directory
nym-connect: add ability to select service provider and gateway
2022-07-04 15:50:17 +02:00
Jon Häggblad 0fbe77d934 connect: clippy 2022-07-04 15:23:14 +02:00
Tommy Verrall 8a267cfe3d Merge pull request #1426 from nymtech/tommy/add-placeholder-qa
Add placeholders to service
2022-07-04 14:10:06 +01:00
Jon Häggblad 5ebb2a3efe changelog: add note 2022-07-04 15:06:23 +02:00
Jon Häggblad de605dc3b9 connect: append gateway to id 2022-07-04 15:00:31 +02:00
Mark Sinclair 6a01edf5fe Nym Connect: fetch list of services from wellknown location and let the user choose 2022-07-04 15:00:31 +02:00
tommy 806b37bd83 Add placeholders to service
Update the all.rs to allow all envs
Placing placeholder addresses only
2022-07-04 13:40:22 +02:00
Jędrzej Stuczyński ffff596d45 Removed redundant lock file on explorer api (#1424) 2022-07-04 09:47:38 +01:00
dependabot[bot] ad826da782 build(deps): bump got from 11.8.2 to 11.8.5 in /nym-wallet/webdriver (#1394)
Bumps [got](https://github.com/sindresorhus/got) from 11.8.2 to 11.8.5.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.8.2...v11.8.5)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-04 09:45:31 +01:00
dependabot[bot] 3414eeea7a build(deps): bump protobufjs from 6.10.2 to 6.10.3 in /clients/validator (#1407)
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 6.10.2 to 6.10.3.
- [Release notes](https://github.com/protobufjs/protobuf.js/releases)
- [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/protobufjs/protobuf.js/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-04 09:45:10 +01:00
dependabot[bot] 3a32d34fb4 build(deps): bump protobufjs (#1408)
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 6.10.2 to 6.10.3.
- [Release notes](https://github.com/protobufjs/protobuf.js/releases)
- [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/protobufjs/protobuf.js/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-04 09:45:04 +01:00
dependabot[bot] 248052aec7 build(deps): bump protobufjs from 6.10.2 to 6.10.3 in /testnet-faucet (#1409)
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 6.10.2 to 6.10.3.
- [Release notes](https://github.com/protobufjs/protobuf.js/releases)
- [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/protobufjs/protobuf.js/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-04 09:44:58 +01:00
dependabot[bot] 90c00fc343 build(deps): bump protobufjs from 6.10.2 to 6.10.3 (#1410)
Bumps [protobufjs](https://github.com/protobufjs/protobuf.js) from 6.10.2 to 6.10.3.
- [Release notes](https://github.com/protobufjs/protobuf.js/releases)
- [Changelog](https://github.com/protobufjs/protobuf.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/protobufjs/protobuf.js/commits)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-07-04 09:44:51 +01:00
Tommy Verrall 7bdfbfdcc5 Merge pull request #1384 from Tonycrypto44/Tonycrypto44-patch-1
Update README.md
2022-07-04 09:15:06 +01:00
Jon Häggblad 44e22b74a5 all: fix more clippy::derive-partial-eq-without-eq (#1423) 2022-07-03 23:37:25 +02:00
Jon Häggblad 7920c27648 nym-connect: Cargo.lock (#1422) 2022-07-03 19:34:13 +02:00
Jon Häggblad be733fab5a contracts: comment out failing tests (#1418)
Comment out 3 failing tests. These have been failing for some time
(forever?), and were beind `ignore` flags. However recently we've
started using `ignore` for slow tests per the suggestion in the Rust
book, so we can't have failing ignored tests anymore.
2022-06-29 20:50:11 +02:00
Jon Häggblad 1fc3c2b792 all: fix clippy on beta toolchain (#1420)
* all: fix clippy::derive-partial-eq-without-eq

* all: fix clippy::let-and-return

* all: fix clippy::unnecessary-to-owned

* all: fix clippy::needless-return
2022-06-29 20:49:29 +02:00
Jon Häggblad f09b984b20 mixnode: handle SIGTERM (#1417)
* all: cargo upgrade dirs --workspace

* mixnode: remove unused serial dependency

* mixnode: handle SIGTERM and SIGQUIT on unix

* mixnode: some clippy warnings

* changelog: add note
2022-06-29 16:47:03 +02:00
Jon Häggblad f2afb42daf github: clippy review annotations for the workspace too (#1416)
* github: clippy review annotations for the workspace too

* client-libs: remove unused imports

* client-libs: tweak use dep

* client-libs: try to regroup cfg conditional use items
2022-06-29 08:47:12 +02:00
Bogdan-Ștefan Neacşu 03a78c04ef Get auto fee values for payer different then signer (#1414) 2022-06-29 09:34:19 +03:00
Jon Häggblad ea22a6f80f connect: allow user select gateway on backend (#1415)
* connect: allow user selected gateway

* rustfmt
2022-06-28 17:39:33 +02:00
Fouad bb0c3d251e Merge pull request #1357 from nymtech/feature/wallet-delegation-fees
Wallet: simulated delegation fees
2022-06-28 16:13:50 +01:00
Jon Häggblad 3e2c54c283 connect: expose tauri get_config_file_location (#1413)
* connect: expose get_config_file_location

* rustfmt
2022-06-28 17:11:03 +02:00
Mark Sinclair 6c9c961152 GitHub Actions: Nym Connect - fix filename 2022-06-28 16:07:56 +01:00
Jon Häggblad 64c3009aa9 connect: reuse the same id (#1412)
* connect: reuse the same id

* changelog: add note

* rustfmt

* clippy
2022-06-28 16:32:15 +02:00
Jędrzej Stuczyński a2409c0a84 Chore/network config (#1335)
* Definition of NymNetworkDetails

* Initial attempt at changing network usage for nymd client

* Removed deprecated denom call and added constructor for custom network

* Cargo fmt
2022-06-28 15:10:20 +01:00
Mark Sinclair a646f84221 GitHub Actions: fix up and adjust retention time 2022-06-28 14:53:59 +01:00
Mark Sinclair 33a6cb1f3e GitHub Actions: fix up Nym Connect output package paths 2022-06-28 13:55:56 +01:00
Jon Häggblad f8ceb0881f connect: update the hardcoded provider 2022-06-28 12:26:45 +02:00
Jon Häggblad a05830304f wallet-recovery-cli: add raw mode (#1411) 2022-06-28 07:46:11 +02:00
Mark Sinclair 8c25bc47c4 GitHub Actions: Nym Connect troubleshooting 2022-06-27 22:18:35 +01:00
Mark Sinclair c39046c4aa GitHub Actions: fix check 2022-06-27 21:05:14 +01:00
Mark Sinclair c2e4309212 GitHub Actions: add manual build steps and artifact uploads 2022-06-27 20:58:03 +01:00
Mark Sinclair 11d1397906 Nym Connect: add GitHub Actions to build signed binary 2022-06-27 20:54:07 +01:00
Jon Häggblad 479cc20083 connect: add tauri methods to get and set provider (#1406) 2022-06-27 20:54:58 +02:00
Jon Häggblad 97f77c4549 client: consolidate and de-duplicate initialization between clients and nym-connect (#1405)
* clients: consolidate and dedup init logic between clients and nym-connect

* changelog: add note

* connect: tweak print
2022-06-27 18:03:56 +02:00
Jon Häggblad 1de8b2abe9 explorer-api: add apy values to mix_nodes endpoint (#1401)
* explorer-api: add apy fields to PrettyDetailedMixNodeBond

* explorer-api: clippy warnings

* explorer-api: use uptime from mixnodes endpoint

* changelog: add note

* rustfmt
2022-06-27 16:18:56 +02:00
Mark Sinclair 70b01783bf ts-packages/react: Fix currency amount display key bug 2022-06-27 12:21:45 +01:00
Raphaël Walther c2375850f9 Changed cron time of nightly builds 2022-06-27 09:17:01 +02:00
Bogdan-Ștefan Neacşu 0df801ab4e Feature/expose validator cosmos address (#1404)
* Move coconut validator api req out of coconut interface

and expose a new cosmos-address endpoint

* Finish cosmos address endpoint

* Guard under coconut feature gateway & validator-api code

* Update CHANGELOG
2022-06-24 18:36:13 +03:00
Bogdan-Ștefan Neacşu fe9cb8a4e6 Feature/fix validator api (#1403)
* Include CoconutSigner in build for template completion

* Use dummy mnemonic for validator-api
2022-06-24 16:28:45 +03:00
fmtabbara 6f5878b6a7 add fees to operations 2022-06-24 12:49:07 +01:00
fmtabbara f4b15a8976 update type 2022-06-24 09:49:36 +01:00
fmtabbara bae495249c Merge branch 'develop' into feature/wallet-delegation-fees 2022-06-23 20:18:05 +01:00
Jędrzej Stuczyński aa3310fb9c Feature/wallet sim gas adjustment (#1388)
* Incorporating GasAdjustment into wallet fee simulation

* Adjusting the gas only a single time

* Hacky implementation of ts_rs on FeeDetails

* changelog
2022-06-23 17:31:02 +01:00
Jon Häggblad bfcc49ab78 validator-api: parametrized node reward endpoint (#1400)
* validator-api: initial work on compute reward endpoint

* validator-api: dedup and clean up

* cargo.lock
2022-06-23 13:54:45 +02:00
Jon Häggblad 3bd21300e0 validator-api: add apy data to mixnodes endpoint (#1393)
* validator-api: compute and return APY for all mixnode bonds

* validator-api: tidy

* validator-api: handle the absence of storage

* validator-api: some comments

* validator-api: refinements to apy calc

* validator-api: extract out some calculations

* changelog: add note
2022-06-23 13:42:29 +02:00
Mark Sinclair 63692eb30d GitHub Actions: fix paths 2022-06-23 11:58:16 +01:00
Mark Sinclair 6172f03ada GitHub Actions: fix typo 2022-06-23 11:57:20 +01:00
Mark Sinclair 5bb631fe8f GitHub Actions: new action to build release version of the smart contracts 2022-06-23 11:55:45 +01:00
Jędrzej Stuczyński 03aec96592 Defined DenomDetails that explicitly sets base and display names (#1389)
* Defined DenomDetails that explicitly sets base and display names

* missed substitutions

* Unused imports
2022-06-23 11:31:59 +01:00
Jon Häggblad 8c3d6fa54b wallet: fix error in unit test on windows (#1399) 2022-06-23 11:57:32 +02:00
Bogdan-Ștefan Neacşu ae88e25300 Feature/include nymd client in gateway (#1398)
* Reinclude custom validators in coconut

* Check mnemonic validity early

* Include nymd client in coconut verifier

and simplify the erc20 bridge part
2022-06-23 12:28:40 +03:00
Jon Häggblad 6b07f31a87 wallet: remove broken platform constants (#1395)
Due to a bug (typo) these constants were actually never used, and at
this point we can't fix it without breaking backwards compatibility.
2022-06-23 11:08:31 +02:00
Jon Häggblad 736fcafa9b rustfmt 2022-06-22 22:14:55 +02:00
Jędrzej Stuczyński 64687e9656 Removed mixnet contract migration 2022-06-22 17:55:14 +01:00
Jędrzej Stuczyński 49718e724e Removed mixnet contract migration 2022-06-22 17:51:38 +01:00
Jędrzej Stuczyński 8bce52f9a9 bump contract versions and update changelog 2022-06-22 17:02:07 +01:00
Mark Sinclair babc18d491 GitHub Actions: revert trigger changes 2022-06-21 19:02:51 +01:00
Mark Sinclair a5da6ccdab Update CHANGELOG for wallet release v1.0.6 2022-06-21 19:01:09 +01:00
Mark Sinclair 8dd10a5e10 GitHub Actions: wallet trigger 2022-06-21 18:52:49 +01:00
Mark Sinclair f9d3a60c32 GitHub Actions: triggers and Windows .env file 2022-06-21 18:50:08 +01:00
Drazen Urch 1178902634 Fix rewards bounds (#1391)
* Fix rewards bounds

* Fix operator reward calculation
2022-06-21 18:27:26 +02:00
Mark Sinclair c39527c841 GitHub Actions: generate wallet .env from base64 string 2022-06-21 17:04:46 +01:00
Mark Sinclair 2fecde8f19 Wallet: update copy on mixnode saturation delegation warning modal 2022-06-21 17:04:01 +01:00
Bogdan-Ștefan Neacşu 03b484dbdf Fix eth feature enabled build (#1379) 2022-06-21 15:16:17 +03:00
Drazen Urch f3a926375a Change epoch length to 10 minutes (#1345)
* Change epoch length to 10 minutes

* Derive operator cost, and reward params from epoch length

* Fix tests

* Migrate back to hourly

* Remove length migration

* Push everything
2022-06-21 14:04:27 +02:00
Drazen Urch 66b5f50ad0 Add locked token pledge limit (#1331)
* Add locked token pledge limit

* Add messages for interacting with the locked pledge cap

* Add locked pledge controls to the nymd client
2022-06-21 10:25:00 +02:00
Mark Sinclair f9cc21dce9 GitHub Actions: fix filenames in readme 2022-06-20 20:47:18 +01:00
Mark Sinclair a693195b57 Update nym-wallet-release.yml 2022-06-20 20:44:45 +01:00
Mark Sinclair c89c66b174 GitHub Actions - an action to create a wallet release 2022-06-20 20:42:43 +01:00
Jędrzej Stuczyński 42ef2eb98c Bugfix/correct reward stake supply (#1373)
* Constructing `EpochRewardParams` with proper staking_supply

* Query for current staking supply

* More crate visibility on epoch reward params

* unused import

* Remove duplicate save of epoch_reward_params

* test fixes

* Changelog

* Moved PR references to correct section

* cargo fmt

* Removed old migration code
2022-06-20 18:25:22 +01:00
Pierre Dommerc b2df4ca4fd feat(wallet): style changes to match new design (#1333)
* feat(wallet): style changes to match new design

* fix(wallet): style

* feat(wallet): style changes to match new design

* fix(wallet): style

* feat(wallet): style adjustment create mnemonic

* feat(wallet): style adjustment create mnemonic
2022-06-20 16:22:23 +01:00
Gala 608ef779d2 changing avg uptime name and tooltip (#1386) 2022-06-20 16:20:59 +01:00
Jędrzej Stuczyński c0e178fdf7 Feature/bond queries (#1369)
* Added queries to get bond details by identity key

* Added relevant calls in the nymd client

* Changelog

* Removed unused import
2022-06-20 11:25:00 +01:00
Fouad 60a58b30a1 bring back the modal (#1381) 2022-06-20 10:19:05 +01:00
Dave Hrycyszyn 135c818fee Feature/report node hardware info (#1308)
* Adding simple hardware info reporting to the mixnode HTTP API

* Adding sgx availability as another example field

* Added sysinfo crate for addtitional simple hardware reporting

* Added reporting on number of cpu cores and available ram

* Cleanup of unused struct

* Fixing merge conflict

* Checking for supported system before using sysinfo

* Breaking commit containing additional types

...and a painfully wrong implementation of the SMT processor cores type.

* Handling unavailable brand string

* Fixed getting SMT logical processor count

* Rebase with develop + cleaned up changelog

* unused import

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2022-06-20 09:49:32 +01:00
Raphaël Walther b4f3a48550 Fixed disk space issue with Ubuntu runner 2022-06-20 09:41:25 +02:00
Tonycrypto44 f02f914ae2 Update README.md 2022-06-19 19:10:27 -04:00
fmtabbara 3e5aeefbb8 Merge branch 'develop' into feature/wallet-delegation-fees 2022-06-17 10:43:53 +01:00
fmtabbara 8cc244cf9c include vesting fees for delegate and undelegate 2022-06-17 10:43:22 +01:00
Jon Häggblad 56b1dba66a cargo upgrade rocket --workspace (#1330) 2022-06-16 17:59:46 +02:00
Fouad 6bd0ff796a archive password when new paasword is created (#1380) 2022-06-16 16:02:36 +01:00
Jon Häggblad 287c45d6b5 ci: add nym-connect rust to build (#1378)
* ci: add nym-connect rust to build

* rustfmt

* connect: add gitkeep in dist dir

* wallet: dont trigger connect on pull_request

* github: libayatana-indicator3-dev

* github: libayatana-appindicator3-dev
2022-06-16 16:45:33 +02:00
Bogdan-Ștefan Neacșu 3aff419a76 Fix imports for macos 2022-06-16 16:26:51 +02:00
Bogdan-Ștefan Neacşu 4f46e36aa8 Feature/gateway direct stats (#1376)
* Make gateway mnemonic optional

* Remove unnecessary timer struct

* Prepare for code reuse

* Use trait for stats collector

* Put trait definition in common crate

* Gateway stats runner

* Custom statistics url arg

* Build & send stats req to url

* Storage support for new stats type

* Make gateway stats opt in

* Test&clippy fixes

* CHANGELOG update
2022-06-16 15:24:31 +02:00
Mark Sinclair c59e8086a6 GitHub Actions: fix up .env file generation 2022-06-16 14:14:20 +01:00
Mark Sinclair f8c8b1a85e GitHub Actions: adjust generating .env file and add conditional to release upload 2022-06-16 14:09:42 +01:00
Mark Sinclair c926e0e652 GitHub Actions: fix syntax error 2022-06-16 13:43:54 +01:00
Mark Sinclair 2689de2334 GitHub Actions: fix up condition 2022-06-16 13:42:46 +01:00
Mark Sinclair 92f154fde5 GitHub Actions: generate wallet .env file and add manual trigger for MacOS build 2022-06-16 13:35:07 +01:00
Mark Sinclair eaf207b667 GitHub Actions: delete test file 2022-06-16 13:22:25 +01:00
Mark Sinclair 13d74200e2 GitHub Actions: add test workflow 2022-06-16 13:19:51 +01:00
fmtabbara 3816c94ee5 merge develop 2022-06-16 13:05:47 +01:00
Pierre Dommerc b42472486f feat(wallet): add a custom link component to match new design (#1355)
* feat(wallet): add custom link component

* feat(wallet): uniformize links

* feat(wallet): move link component to ts-packages

* feat(wallet): post merge fix

* ts-packages: build theme first, then react components

* Update README.md

Co-authored-by: Mark Sinclair <mmsinclair@gmail.com>
2022-06-16 12:36:30 +01:00
Mark Sinclair 661a1420c1 Wallet: add error checking when switching networks and determining admin mode 2022-06-16 12:12:44 +01:00
Jon Häggblad 784f6d0939 wallet: dont try archive if file doesnt exist (#1377) 2022-06-16 11:52:23 +01:00
Jon Häggblad 5b715acc4e client: allow rerun init for gateway config (#1353)
* socks5: reuse existing gateway configuration instead of failing on init

* socks5: rework setting and registering gateway logic

* rustfmt

* client/native: port same changes here

* changelog: add note about re-running init for clients

* client-core/config: add with_gateway_endpoint_from_config

* clients: pass GatewayEndpoint

* clients: add warning note onf force-register-gateway

* connect: fix with_gateway_endpoint call
2022-06-16 12:24:19 +02:00
Gala 8eae2e3136 Wallet: Sending again the NodeId to fetch the saturation (#1375)
* Sending again the identity key when fetching the saturation

* Remove non-null assertion
2022-06-16 10:39:23 +01:00
Mark Sinclair e1a1b70832 Wallet: remove pre from version to try to fix Windows build failing on candle.exe 2022-06-16 10:38:20 +01:00
Mark Sinclair dc0cb3f68b GitHub Actions - make node version install regular and install NodeJS v16 2022-06-16 09:36:18 +01:00
Raphaël Walther 216b5535b3 Fixed nightly build windows storage issue 2022-06-16 08:58:04 +02:00
Mark Sinclair 8819e81393 Wallet: add env var ENABLE_QA_MODE to show QA network in built wallet versions 2022-06-15 19:03:49 +01:00
Mark Sinclair ce26c3cf76 Wallet: create main context mock to fix up delegation page stories 2022-06-15 18:19:22 +01:00
Mark Sinclair b826b5d957 Wallet: Fix up stories and linting 2022-06-15 18:18:58 +01:00
Mark Sinclair a4ec7e4912 Wallet: handle redeem and compound 2022-06-15 17:40:33 +01:00
Mark Sinclair a67a80d28d Derive debug for wallet types 2022-06-15 17:34:54 +01:00
Gala 1ad458b2be Wallet: Avoid oversaturated node delegation or compound (#1356)
* wip checking ts-package

* adding the validation to the identity form field

* changing the error message

* changing node oversaturated error mss

* adding oversaturated modal blocker

* adding error colour to palette, and styles to basic modal

* wip

* wip

* some refactor

* dont validate field till we have api response

* fix typo

* adding line break

* catch error when node is not valid

* handle error out of the field component

* removing logs

* Adding disableCompoundRewards prop in DelegationsActionsMenu

* Adding disableCompoundRewards to DelegationsActionsMenu

* refactor validation

* Revert some not needed changes

* adding line break

* adding stories

Co-authored-by: fmtabbara <fmtabbara@hotmail.co.uk>
2022-06-15 16:51:57 +01:00
Mark Sinclair 937ae22e6b Wallet - fix redeeming, compounding and undelegating with vesting contract (#1372)
* Add TODO reminders to implement vesting contract checks for operator reward compounding and redemption

* Add tauri operation to compound and redeem for locked and unlocked tokens

* Remove rewards from delegations context

* Claim and compound rewards for rewards context

* Delegations modal handles multiple transactions and can show the vested token balance (when present)

* Integrate changes to reward and delegation contexts

* Remove unused files

* Fix eslint errors

* Regenerate types

* Add tauri operation to undelegate using the mixnet and vesting contracts for a mixnode, producing two txs

* Fix up undelegation for mixed mixnet and vesting contract delegations

* Changelog grooming

* Update changelog
2022-06-15 16:51:37 +01:00
Fouad e6ffbc468b Wallet: create forgot password page (#1367)
* create forgot password page

* navigate back

* add rust work

* pr update
2022-06-15 16:50:35 +01:00
Jon Häggblad 8a3f7a869b wallet: add archive_wallet_file (#1370)
* wallet: add archive_wallet_file

* wallet: fix append filename test

* wallet: simplify exit logic

* rustfmt

* changelog: add entry

* wallet: fix append filename test
2022-06-15 16:57:11 +02:00
Jon Häggblad 4240a88be3 connect: remove webdriver directory (#1371) 2022-06-15 16:40:15 +02:00
dependabot[bot] cc293dc166 build(deps): bump simple-get from 3.1.0 to 3.1.1 in /nym-connect
Bumps [simple-get](https://github.com/feross/simple-get) from 3.1.0 to 3.1.1.
- [Release notes](https://github.com/feross/simple-get/releases)
- [Commits](https://github.com/feross/simple-get/compare/v3.1.0...v3.1.1)

---
updated-dependencies:
- dependency-name: simple-get
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-15 10:46:55 +01:00
dependabot[bot] 01f9871d1f build(deps): bump follow-redirects from 1.14.5 to 1.15.1 in /nym-connect (#1361)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.5 to 1.15.1.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.5...v1.15.1)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-15 10:23:25 +01:00
dependabot[bot] 244410f69d build(deps): bump async from 3.2.1 to 3.2.4 in /nym-connect/webdriver (#1359)
Bumps [async](https://github.com/caolan/async) from 3.2.1 to 3.2.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/master/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v3.2.1...v3.2.4)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-15 10:23:17 +01:00
Raphaël Walther b0517705ba Merge pull request #1364 from nymtech/chore/lock-dkg-tests-in-CI
Ignored most of expensive dkg tests and made them run only on PRs to develop/master
2022-06-15 09:29:53 +02:00
Mark Sinclair e6a00ad8d4 Merge pull request #1363 from nymtech/feature/reorder-delegation-table-columns
reorder delegation table columns
2022-06-14 18:40:14 +01:00
fmtabbara 815416bb41 allow sign in with enter key + create key listener hook 2022-06-14 17:21:07 +01:00
Jędrzej Stuczyński c7b480f488 Added expensive tests to nightly CI 2022-06-14 17:07:04 +01:00
Jędrzej Stuczyński 088b7ab16d Ignored most of expensive dkg tests and made them run only on PRs to develop/master 2022-06-14 17:03:35 +01:00
fmtabbara f6f0e68fac reorder delegation table columns 2022-06-14 16:52:45 +01:00
Mark Sinclair 70b23063c8 Update changelog and increment wallet version number for next release 2022-06-14 16:47:21 +01:00
Jędrzej Stuczyński 25a9fc85d2 Chore/lock file cleanup (#1360)
* Removed redundant lock files + updated cw3 and cw4 cw-storage-plus

addresses #1313

* Removed redundant lock files for clients

addresses #1314, #1315, #1316
2022-06-14 16:34:17 +01:00
Mark Sinclair 3079a9ee7e Merge pull request #1362 from nymtech/bugfix/delegations-reward-success-message
fix redeem rewards success message
2022-06-14 16:30:40 +01:00
fmtabbara 06603ec585 fix redeem rewards success message 2022-06-14 16:21:08 +01:00
dependabot[bot] fd940c4c7c build(deps): bump minimist from 1.2.5 to 1.2.6 in /nym-connect/webdriver (#1346)
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-14 15:39:10 +01:00
dependabot[bot] a90a8926fe build(deps): bump async from 2.6.3 to 2.6.4 in /nym-connect (#1349)
Bumps [async](https://github.com/caolan/async) from 2.6.3 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.6.3...v2.6.4)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-14 15:38:36 +01:00
dependabot[bot] e40cb960ce build(deps): bump ejs from 3.1.6 to 3.1.8 in /nym-connect/webdriver (#1348)
Bumps [ejs](https://github.com/mde/ejs) from 3.1.6 to 3.1.8.
- [Release notes](https://github.com/mde/ejs/releases)
- [Changelog](https://github.com/mde/ejs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mde/ejs/compare/v3.1.6...v3.1.8)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-14 15:38:30 +01:00
dependabot[bot] 0f2d01c91a build(deps): bump async from 3.2.1 to 3.2.4 in /nym-wallet/webdriver (#1347)
Bumps [async](https://github.com/caolan/async) from 3.2.1 to 3.2.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/master/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v3.2.1...v3.2.4)

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

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-14 15:38:22 +01:00
fmtabbara 660c813c0a remove duplicate function 2022-06-14 11:57:04 +01:00
Jędrzej Stuczyński ba8a8cbfa4 Added simulation endpoints for vesting delegation 2022-06-14 11:25:24 +01:00
fmtabbara 0702968f3a merge develop 2022-06-14 10:08:38 +01:00
fmtabbara ce7d02220f refactor 2022-06-13 17:17:26 +01:00
Gala 81bbb61dac enabling discord icon (#1319) 2022-06-13 15:56:07 +01:00
Gala e768d99e3d Explorer: Moving where is displayed the delegators number (#1341)
* moving the delegators number

* changing column header and styles order

* another color test
2022-06-13 15:37:48 +01:00
Mark Sinclair 987cb5d424 Bump wallet version number 2022-06-13 13:52:24 +01:00
Fouad 7f1d5e0691 Merge pull request #1352 from nymtech/feature/tx-hash-for-rewards
Show transaction hash in modals when redeeming or compounding rewards
2022-06-13 12:41:44 +01:00
Mark Sinclair 6ed28b5a1d Show transaction details in context methods and confirmation modals for redeeming/compounding rewards 2022-06-13 12:27:39 +01:00
Mark Sinclair b48184ba13 Add return type for redeeming or compounding rewards 2022-06-13 12:26:37 +01:00
Tommy Verrall d1499f3361 Merge pull request #1350 from nymtech/feature/bring-back-node-settings
bing back node settings
2022-06-13 12:04:47 +01:00
fmtabbara 98e0e1fc4e fix initial request for node stats 2022-06-13 11:49:18 +01:00
fmtabbara 70011d0592 add fees for claim and compound 2022-06-13 11:35:34 +01:00
Mark Sinclair bdc8fb7ae7 nym-wallet: add font files for all weights for wallet as not working in some Linux distros (#1351) 2022-06-13 10:50:53 +01:00
fmtabbara 0b0cbe3181 bing back node settings 2022-06-13 10:22:07 +01:00
Mark Sinclair 076a651199 Fix clippy warnings in tests 2022-06-13 10:14:13 +01:00
Pierre Dommerc b4e9ebd9cc [wallet] style changes to match new design and layout (#1336)
* feat(wallet): style changes to match new design

* fix(wallet): style

* feat(wallet): remove useless color

* feat(wallet): some style changes

in balance page, show entire address
set a small size to avatar account
set vertical alignment to start for page cards

* feat(wallet): fix padding
2022-06-13 11:03:16 +02:00
fmtabbara 0a632599cd make subheader optional 2022-06-11 00:22:50 +01:00
fmtabbara a9ff98418c update modals 2022-06-11 00:19:00 +01:00
fmtabbara 7d4f6c0bbd give SimpleModal component a secondary action 2022-06-10 21:49:26 +01:00
fmtabbara b731aa0bcf update modals 2022-06-10 21:48:43 +01:00
fmtabbara 89d4910e6f update simulation functions 2022-06-10 21:47:17 +01:00
fmtabbara 4ea9bb7dc6 fix spelling error 2022-06-10 21:41:09 +01:00
fmtabbara cfc7e6df77 widen delegation modals 2022-06-10 21:40:49 +01:00
fmtabbara a7a39526b4 move modal list item to shared dir 2022-06-10 21:40:28 +01:00
fmtabbara 70a9bd0f6d fix heading bug 2022-06-10 21:39:44 +01:00
fmtabbara 4cbbead359 create new tx confirmation modal 2022-06-10 21:38:53 +01:00
Jon Häggblad 77d16d34af changelog: added entry for nym-connect 2022-06-10 19:41:34 +02:00
Jon Häggblad 9e8868f357 Merge pull request #1338 from nymtech/feature/hrycyszynvpn 2022-06-10 16:44:16 +02:00
Jon Häggblad 64fdf5a270 Merge remote-tracking branch 'origin/develop' into feature/hrycyszynvpn 2022-06-10 16:13:21 +02:00
Jon Häggblad c17d65380c connect: disable keybase notfication 2022-06-10 16:12:40 +02:00
Mark Sinclair 00e234a754 Network Explorer upgrades and fixes (#1343)
* Upgrade storybook and add mock for Tauri `api/app`

* Upgrade Network Explorer to React Router 6

* Update changelog for react router 6 upgrade
2022-06-10 14:42:53 +01:00
Mark Sinclair 6ef50b93bc Fix type in StateParams.ts and apply es-lint formatting 2022-06-10 14:23:07 +01:00
Jon Häggblad 437b3b6885 socks5: allow some unused methods temporarily 2022-06-10 14:39:17 +02:00
Jon Häggblad 6976be3e3a connect: fix unused warnings 2022-06-10 14:18:58 +02:00
Jon Häggblad dca7a9da94 connect: update readme 2022-06-10 13:55:30 +02:00
Jon Häggblad 56b1005226 connect: remove some unused stuff and tidy 2022-06-10 13:55:14 +02:00
Jon Häggblad caa32299a9 workflow: rename support files for nym-connect 2022-06-10 12:49:34 +02:00
Drazen Urch eff732aa2c Introduce staking supply, contract and wallet (#1324)
* Introduce staking supply, contract and wallet

* Migration staking supply (#1327)

* Staking supply to params migration

* Include into migration entrypoint

* StateParams merge

* Add changelog

* Make everyone happy
2022-06-10 12:36:35 +02:00
Tommy Verrall 68889bd362 Merge pull request #1342 from nymtech/bugfix/prevent-multiple-send-requests
Bugfix: Prevent multiple send requests
2022-06-10 11:21:11 +01:00
Jon Häggblad 1b4853b5ba workflow: update nym-connect names 2022-06-10 12:16:11 +02:00
fmtabbara 45cc531056 move setloading state 2022-06-10 11:05:06 +01:00
Jon Häggblad 8df24b8ce2 verloc: signalling for graceful shutdown (#1323)
* common/verloc: signalling for graceful shutdown

* verloc: make shutdown handler not optional

* verloc: logging without explicit target

* rustmt

* mixnode: note about rocket

* verloc: remove accidental duplicate block

* verloc: pass shutdown handler as argument to connection handler
2022-06-10 11:36:48 +02:00
Elliot e1b5407613 Fix validator docker build on other platforms (#1329)
* Fix validator docker build on other platforms

* Require build arguments in validator docker build

* docker-compose.yml: Remove unused WASMD_COMMIT_HASH argument

* docker-compose.yml: Update WASMD_VERSION to v0.27.0

* Update changelog for 1329
2022-06-10 10:30:48 +03:00
Jon Häggblad 34d3d520d9 Merge remote-tracking branch 'origin/develop' into feature/hrycyszynvpn 2022-06-10 00:03:06 +02:00
Jon Häggblad 9a103d5e20 wallet: fix clippy (#1339) 2022-06-10 00:02:31 +02:00
Jon Häggblad 352111d443 wallet: add to Makefile 2022-06-09 23:30:04 +02:00
Jon Häggblad e9b72d1c37 rustfmt 2022-06-09 23:26:04 +02:00
Jon Häggblad 6e355dc75e connect: update tokio 2022-06-09 21:32:15 +02:00
Jon Häggblad d07279bde0 Merge remote-tracking branch 'origin/develop' into feature/hrycyszynvpn 2022-06-09 21:26:06 +02:00
Jon Häggblad 26f0001d9b rustfmt 2022-06-09 21:25:49 +02:00
Jon Häggblad f3ab6a6a4c Remove rustfmt.toml 2022-06-09 21:25:35 +02:00
Jon Häggblad 818d2585da Search replace all instances to nym-connect 2022-06-09 21:22:27 +02:00
Jon Häggblad 5f2b9378fe Rename directory to nym-connect 2022-06-09 21:10:01 +02:00
Jon Häggblad 5a374fe8ff Spawn socks5 runtime in thread 2022-06-09 21:07:44 +02:00
Fouad 62baada93d Feature/wallet delegation UI squashed (#1326)
* Delegation UI:

Update QA vars

fmt

re-map coin type for qa

add correct bech32 address as the network-explorer-api was complaining

clean up

fmt

Delegation components

Show delegation story on paper

Remove actions header from delegations list

Add copy to clipboard for delegation list node ids

Move tooltip

Modals

Extract modal styles

Fix exports

Rewards summary and redeem modal

Factor out simple modal

Delegations actions modals: delegate, delegate more, undelegate

Coin mark and move logo stories

Rust types

React components handle currency

Form field to enter and display an Identity Key

Fix up build order

Update README

Flat buttons

End adornment

Currency form field

Add more props

Export components

Add currency and mixnode fields

Group stories into folders and add flow

Change exports from shared packages to stop webpack bundling issues

Fix logo import

Add mock for tauri api in storybook that shows a console error for operations that are not mocked

Delegations views and routes for wallet

Delegations list show pending delegations and undelegations

wip - delegations page status

Add typescript type checking to storybook webpack config and more mocks for tauri

Add more interstitial states and confirmation modals

Copy change

Move config to inside source tree

Fix up `Console` typings

Add wrapper around Tauri `invoke` that logs operations in development mode

wip

wip

wip

ts-rs: remove old files

ts-rs: update paths to `ts-packages/types`

ts-rs: remove old files

ts-rs: export new types to `ts-packages/types`

Add `MajorCurrencyAmount` to convert to and from TS types for various backend currency types

New crate `nym-types` to provide types for frontend apps (wallet, explorer, etc)

wip

update type imports and fix some lint errors

update packages

update type imports

update type imports

update type imports

update type imports

start pulling out use of  minorMajor and majorMinor

update type imports

update import

Add missing types generated by ts-rs

fix types

Adding denom to account

type updates

Handle micro currency denoms

Fix type conversion mistake

Add clean target

eslint: formatting

Update React currency components to use `MajorCurrencyAmount`

Add separators and extra props to currency components

replace currency mapper with denom returning from service

Adjust type while generation is broken

start integrating new CurrencyFormField component

update balance and vesting on client change (not only client address)

Fix up conversion from cosmwasm coin to major currency for minor denoms

Fix up typings and validations to remove more `Coin` usage

fix conflict

fix delegations form

start fixing validation

type update

remove console log

tidy up

remove more unused types

remove more unused types

Fix `Coin` denom to be `minor`

Fix up to minor_cosmos_coin

Fix up send

Remove `Coin` type

Fix up exported types

start delegation UI

more UI work

close actions modal on action select

update label

fix old delegateion form

minor updates

undo change to currency in stringD

Fix up types

Add feature flag for generating typescript
Generate types behind feature flag

Use custom cli tool to export `ts-rs` types

`ts-rs-cli` moves files into place and fix up `Makefile`

Update generations target

Add missing types for generation

Generate typescript types

reorder imports

use make generate-typescript for new types + type import updates

update types

Add delegate with everything

Add get block to nymd client

More conversions

Get a big list of delegations with lots of stuff

Add `avg_uptime_percent`

component api updates

ui updates and fixes

Add delegation history and pending events

Fix up addition

Fix up pending delegation event types

Filter pending delegation events

add history and pending events

set total delegations

rebase

fix breaking type change on delegate page

Fix mixnode mapping

Add back refresh and set periodic refresh

upgrade to react router 6

Add logging
Export new types for gas and transactions

increase container size!

add sendtx type

update onOK to return MAjorCurrencyAmount

align table items

display dash if amount not availble

work on delegate and undelegate

Make serializable

More types

Fix up errors

align item icon

type updates

Add operation to get all pending delegation/undelegation events

Fix up logging

Add more logging

Fix undelegate error

get pending delegation events

remove unused import

* Fix rebase errors

* Integrate fees changes:
- make operations available as requests (typed with any for now, needs changing)
- move `FeeDetails` to `common/types`
- mock `getGasFee()`

* get wallet balance after transactions

* fix duplicate key

* use token pool selector

* update wording

* Created nymd internal coin

* spell delegations correctly!

* Additional From implementations plus a constructor

* try_add

* Changed client API to use the new coin type

* CoinConverter trait

* Made wallet compilable with the recent changes

* Simplified the API by removing the generics in favour of explicit Coin type

* Fixed validator api

* integrate modal divider with modal component

* handle undelegation of locked tokens

* only return events table if there are events

* Fixed up tests and clippy

* Refactored  missed coin-generic API methods

* changelog

* refresh on network or client details change

* Bunch of  temporary workaround to have wallet working-ish

* Add claim and compound wallet endpoints, proc_macro to generate execute and simulate

* CHANGELOG

* Sort CHANGELOG lines

* PR comments

* allow sorting of pending events

* fix lint errors

* handle page overflow

* handle reedem and vesting redeem requests

* set up compound rewards

* refresh locked tokens on page load

* remove old delegations pages + remove settings modal + update network explorer url

* update validation for hostname (prevent leading spaces)

* add compound success case

* display est fee until new simulations are used

* fix up coin validation

* tommy fixes

* Show app version at bottom of nav

* Show admin page when account matches account id from `.env` file `ADMIN_ADDRESS` map. Value is fetch from GH Actions secrets at build time.

* Update change log

Co-authored-by: tommy <tommyvez@protonmail.com>
Co-authored-by: Mark Sinclair <mmsinclair@gmail.com>
Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
Co-authored-by: durch <durch@users.noreply.github.com>
2022-06-09 17:05:17 +01:00
Jon Häggblad db09870352 Remove unused deps 2022-05-23 15:52:46 +02:00
Jon Häggblad d703e160e3 Start socks5 client in task 2022-05-23 15:49:21 +02:00
Jon Häggblad 1d6dabd0b5 Remove some tracing in socks5 client 2022-05-20 16:11:47 +02:00
Jon Häggblad 4ce68fd6f2 Merge branch 'develop' into feature/hrycyszynvpn 2022-05-20 16:07:11 +02:00
Jon Häggblad 83f6fbec5d Remove things not needed 2022-05-20 15:42:16 +02:00
Jon Häggblad d87479f28c Uncomment code and try build 2022-05-18 16:06:48 +02:00
Jon Häggblad 59db03a55d Fix build on linux 2022-05-11 11:20:20 +02:00
Jędrzej Stuczyński 5db7f7e0bc Fixing some dependencies 2022-04-29 14:39:42 +01:00
Mark Sinclair 2422f090cc wip: add client 2022-04-27 14:30:17 +01:00
Mark Sinclair 1362d8a3eb Bump rust version and make dependencies match wallet 2022-04-26 17:14:10 +01:00
Mark Sinclair 40274689e3 Add pinned versions from develop 2022-04-26 14:50:48 +01:00
Mark Sinclair 3f9d6b2f1c wip 2022-04-26 14:50:47 +01:00
1641 changed files with 121133 additions and 57215 deletions
+18
View File
@@ -3,3 +3,21 @@
RUST_LOG=info
RUST_BACKTRACE=1
#########################################
# geoipupdate (needed for explorer-api) #
#########################################
# MaxMind account ID (change it to a valid account ID)
GEOIPUPDATE_ACCOUNT_ID=xxx
# MaxMind license key (change it to a valid license key)
GEOIPUPDATE_LICENSE_KEY=xxx
# List of space-separated database edition IDs. Edition IDs may
# consist of letters, digits, and dashes. For example, GeoIP2-City
# would download the GeoIP2 City database (GeoIP2-City).
GEOIPUPDATE_EDITION_IDS=GeoLite2-Country
# The number of hours between geoipupdate runs. If this is not set
# or is set to 0, geoipupdate will run once and exit.
GEOIPUPDATE_FREQUENCY=72
# The path to the directory where geoipupdate will download the
# database.
GEOIP_DB_DIRECTORY=./explorer-api/geo_ip
+4 -4
View File
@@ -19,10 +19,10 @@
Cargo.* @durch @futurechimp @jstuczyn @neacsu @octol
# JS rules:
*.js @mmsinclair @fmtabbara @Aid19801
*.ts @mmsinclair @fmtabbara @Aid19801
*.tsx @mmsinclair @fmtabbara @Aid19801
*.jsx @mmsinclair @fmtabbara @Aid19801
*.js @mmsinclair @fmtabbara
*.ts @mmsinclair @fmtabbara
*.tsx @mmsinclair @fmtabbara
*.jsx @mmsinclair @fmtabbara
# Something looking like possible documentation rules:
*.md @mfahampshire
+52
View File
@@ -0,0 +1,52 @@
name: Daily security audit
on:
schedule:
- cron: '5 9 * * *'
jobs:
cargo-deny:
runs-on: ubuntu-20.04
steps:
- name: Checkout repository code
uses: actions/checkout@v2
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install cargo deny
run: cargo install --locked cargo-deny
- name: Run cargo deny
run: |
find . -name Cargo.toml -exec cargo deny --manifest-path {} check \
advisories -A advisory-not-detected --hide-inclusion-graph \; &> \
>(uniq &> .github/workflows/support-files/notifications/deny.message )
- uses: actions/upload-artifact@v3
with:
name: report
path: .github/workflows/support-files/notifications/deny.message
notification:
needs: cargo-deny
runs-on: ubuntu-20.04
steps:
- name: Check out repository code
uses: actions/checkout@v2
- name: Download report from previous job
uses: actions/download-artifact@v3
with:
name: report
path: .github/workflows/support-files/notifications
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: security
NYM_PROJECT_NAME: "Daily security report"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "security"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+2 -2
View File
@@ -13,9 +13,9 @@ jobs:
- name: Install rsync
run: sudo apt-get install rsync
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: '16'
node-version: 16
- name: Setup yarn
run: npm install -g yarn
- name: Build
+15 -6
View File
@@ -16,7 +16,7 @@ jobs:
RUSTC_WRAPPER: /home/ubuntu/.cargo/bin/sccache
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
- name: Check out repository code
uses: actions/checkout@v2
@@ -29,6 +29,12 @@ jobs:
override: true
components: rustfmt, clippy
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
@@ -41,17 +47,18 @@ jobs:
command: test
args: --workspace --all-features
- name: Check formatting
- name: Run expensive tests
if: github.ref == 'refs/heads/develop' || github.event.pull_request.base.ref == 'develop' || github.event.pull_request.base.ref == 'master'
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
command: test
args: --workspace --all-features -- --ignored
- uses: actions-rs/clippy-check@v1
name: Clippy checks
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
args: --workspace --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
@@ -59,6 +66,8 @@ jobs:
command: clippy
args: --workspace -- -D warnings
# COCONUT stuff
- name: Build all binaries with coconut enabled
uses: actions-rs/cargo@v1
with:
@@ -75,4 +84,4 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: clippy
args: --features=coconut -- -D warnings
args: --all-targets --features=coconut -- -D warnings
+1 -1
View File
@@ -1,6 +1,6 @@
[
{
"os":"ubuntu-latest",
"os":"ubuntu-20.04",
"rust":"stable",
"runOnEvent":"always"
},
@@ -1,16 +1,18 @@
name: Continuous integration on dispatch
name: Nym Connect (rust)
on: workflow_dispatch
on:
push:
paths-ignore:
- 'explorer/**'
jobs:
build:
runs-on: [ self-hosted, custom-linux ]
# Enable sccache via environment variable
env:
RUSTC_WRAPPER: /home/ubuntu/.cargo/bin/sccache
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools libayatana-appindicator3-dev
- name: Check out repository code
uses: actions/checkout@v2
@@ -27,46 +29,28 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace
args: --manifest-path nym-connect/Cargo.toml --workspace
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --all-features
args: --manifest-path nym-connect/Cargo.toml --workspace
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
args: --manifest-path nym-connect/Cargo.toml --all -- --check
- uses: actions-rs/clippy-check@v1
name: Clippy checks
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
args: --manifest-path nym-connect/Cargo.toml --workspace --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --workspace -- -D warnings
- name: Build all binaries with coconut enabled
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --features=coconut
- name: Run all tests with coconut enabled
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --features=coconut
- name: Run clippy with coconut enabled
uses: actions-rs/cargo@v1
with:
command: clippy
args: --features=coconut -- -D warnings
args: --manifest-path nym-connect/Cargo.toml --workspace --all-features -- -D warnings
+51
View File
@@ -0,0 +1,51 @@
name: Build release of Nym smart contracts
on:
workflow_dispatch:
release:
types: [created]
jobs:
build:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Check the release tag starts with `nym-contracts-`
if: startsWith(github.ref, 'refs/tags/nym-contracts-') == false && github.event_name != 'workflow_dispatch'
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-contracts-...')
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: wasm32-unknown-unknown
override: true
components: rustfmt, clippy
- name: Build release contracts
run: make wasm
- name: Upload Mixnet Contract Artifact
uses: actions/upload-artifact@v3
with:
name: mixnet_contract.wasm
path: contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm
retention-days: 5
- name: Upload Vesting Contract Artifact
uses: actions/upload-artifact@v3
with:
name: vesting_contract.wasm
path: contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm
retention-days: 5
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
if: github.event_name == 'release'
with:
files: |
contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm
contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm
+2 -2
View File
@@ -10,7 +10,7 @@ on:
jobs:
matrix_prep:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
@@ -24,7 +24,7 @@ jobs:
contracts:
# since it's going to be compiled into wasm, there's absolutely
# no point in running CI on different OS-es
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
continue-on-error: ${{ matrix.rust == 'nightly' }}
needs: matrix_prep
strategy:
@@ -0,0 +1,56 @@
name: CI for Network Explorer API
on:
workflow_dispatch:
release:
types: [created]
env:
NETWORK: mainnet
jobs:
publish-nym:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-20.04]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
- name: Check the release tag starts with `nym-explorer-api-`
if: startsWith(github.ref, 'refs/tags/nym-explorer-api-') == false && github.event_name != 'workflow_dispatch'
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-explorer-api-...')
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Build all explorer-api
uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path explorer-api/Cargo.toml --workspace --release
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: my-artifact
path: |
target/release/explorer-api
retention-days: 30
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
if: github.event_name == 'release'
with:
files: |
target/release/explorer-api
+2 -2
View File
@@ -14,9 +14,9 @@ jobs:
runs-on: custom-runner-linux
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: '16'
node-version: 16
- name: Setup yarn
run: npm install -g yarn
- name: Run ESLint
+14 -2
View File
@@ -1,6 +1,7 @@
name: CI for Network Explorer
on:
workflow_dispatch:
push:
paths:
- 'explorer/**'
@@ -17,9 +18,9 @@ jobs:
- name: Install rsync
run: sudo apt-get install rsync
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: '16'
node-version: 16
- name: Setup yarn
run: npm install -g yarn
continue-on-error: true
@@ -75,3 +76,14 @@ jobs:
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
- name: Deploy
if: github.event_name == 'workflow_dispatch'
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CD_PROD_NE_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "explorer/dist/"
REMOTE_HOST: ${{ secrets.CD_PROD_NE_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CD_PROD_NE_REMOTE_USER }}
TARGET: ${{ secrets.CD_PROD_NE_REMOTE_TARGET }}
EXCLUDE: "/dist/, /node_modules/"
+32 -7
View File
@@ -2,10 +2,10 @@ name: Nightly builds
on:
schedule:
- cron: '14 4 * * *'
- cron: '14 1 * * *'
jobs:
matrix_prep:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
@@ -24,8 +24,8 @@ jobs:
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.rust == 'stable' }}
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
if: matrix.os == 'ubuntu-20.04'
- name: Check out repository code
uses: actions/checkout@v2
@@ -44,12 +44,31 @@ jobs:
command: build
args: --workspace
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run expensive tests
if: github.ref == 'refs/heads/develop' || github.event.pull_request.base.ref == 'develop' || github.event.pull_request.base.ref == 'master'
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --all-features -- --ignored
- name: Check formatting
uses: actions-rs/cargo@v1
with:
@@ -75,9 +94,9 @@ jobs:
command: clippy
args: --workspace --all-targets -- -D warnings
- name: Reclaim some disk space (because Windows is being annoying)
- name: Reclaim some disk space
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
with:
command: clean
@@ -88,6 +107,12 @@ jobs:
command: build
args: --workspace --features=coconut
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run all tests with coconut enabled
uses: actions-rs/cargo@v1
with:
@@ -135,7 +160,7 @@ jobs:
notification:
needs: build
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- name: Collect jobs status
uses: technote-space/workflow-conclusion-action@v2
@@ -1,6 +1,6 @@
[
{
"os":"ubuntu-latest",
"os":"ubuntu-20.04",
"rust":"stable",
"runOnEvent":"schedule"
},
@@ -17,7 +17,7 @@
},
{
"os":"ubuntu-latest",
"os":"ubuntu-20.04",
"rust":"beta",
"runOnEvent":"schedule"
},
@@ -33,7 +33,7 @@
},
{
"os":"ubuntu-latest",
"os":"ubuntu-20.04",
"rust":"nightly",
"runOnEvent":"schedule"
},
+203
View File
@@ -0,0 +1,203 @@
name: Nightly builds on latest release
on:
schedule:
- cron: '14 2 * * *'
jobs:
matrix_prep:
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
# creates the matrix strategy from nightly_build_matrix_includes.json
- uses: actions/checkout@v3
- id: set-matrix
uses: JoshuaTheMiller/conditional-build-matrix@main
with:
inputFile: '.github/workflows/nightly_build_matrix_includes.json'
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
get_release:
runs-on: ubuntu-20.04
needs: matrix_prep
outputs:
output1: ${{ steps.step2.outputs.latest_release }}
steps:
- name: Check out repository code
uses: actions/checkout@v3
- name: Fetch all branches
run: git fetch --all
- name: Set output variable to latest release branch
id: step2
run: echo "latest_release=$(git branch -r | grep -E 'release/v[0-9]+\.[0-9]+\.[0-9]+' | tail -n 1 | sed 's/ origin\///')" >> $GITHUB_OUTPUT
build:
needs: [get_release,matrix_prep]
strategy:
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.rust == 'stable' }}
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
if: matrix.os == 'ubuntu-20.04'
- name: Check out latest release branch
uses: actions/checkout@v3
with:
ref: ${{needs.get_release.outputs.output1}}
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
components: rustfmt, clippy
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run expensive tests
if: github.ref == 'refs/heads/develop' || github.event.pull_request.base.ref == 'develop' || github.event.pull_request.base.ref == 'master'
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --all-features -- --ignored
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- uses: actions-rs/clippy-check@v1
name: Clippy checks
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --workspace --all-targets -- -D warnings
- name: Reclaim some disk space
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
with:
command: clean
# COCONUT stuff
- name: Build all binaries with coconut enabled
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --features=coconut
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run all tests with coconut enabled
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --features=coconut
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run clippy with coconut enabled
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --workspace --all-targets --features=coconut -- -D warnings
# nym-wallet (the rust part)
- name: Build nym-wallet rust code
uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path nym-wallet/Cargo.toml --workspace
- name: Run nym-wallet tests
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path nym-wallet/Cargo.toml --workspace
- name: Check nym-wallet formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --manifest-path nym-wallet/Cargo.toml --all -- --check
- name: Run clippy for nym-wallet
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-targets -- -D warnings
notification:
needs: [build,get_release]
runs-on: ubuntu-20.04
steps:
- name: Collect jobs status
uses: technote-space/workflow-conclusion-action@v2
- name: Check out repository code
uses: actions/checkout@v3
- name: Keybase - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
if: env.WORKFLOW_CONCLUSION == 'failure'
env:
NYM_NOTIFICATION_KIND: nightly
NYM_PROJECT_NAME: "Nym nightly build on latest release"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH_NAME: "${{needs.get_release.outputs.output1}}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-nightly-release"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
@@ -0,0 +1,203 @@
name: Nightly builds on second latest release
on:
schedule:
- cron: '24 2 * * *'
jobs:
matrix_prep:
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
# creates the matrix strategy from nightly_build_matrix_includes.json
- uses: actions/checkout@v3
- id: set-matrix
uses: JoshuaTheMiller/conditional-build-matrix@main
with:
inputFile: '.github/workflows/nightly_build_matrix_includes.json'
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
get_release:
runs-on: ubuntu-20.04
needs: matrix_prep
outputs:
output1: ${{ steps.step2.outputs.latest_release }}
steps:
- name: Check out repository code
uses: actions/checkout@v3
- name: Fetch all branches
run: git fetch --all
- name: Set output variable to latest release branch
id: step2
run: echo "latest_release=$(git branch -r | grep -E 'release/v[0-9]+\.[0-9]+\.[0-9]+' | tail -n 2 | head -n 1 | sed 's/ origin\///')" >> $GITHUB_OUTPUT
build:
needs: [get_release,matrix_prep]
strategy:
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
runs-on: ${{ matrix.os }}
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.rust == 'stable' }}
steps:
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
if: matrix.os == 'ubuntu-20.04'
- name: Check out latest release branch
uses: actions/checkout@v3
with:
ref: ${{needs.get_release.outputs.output1}}
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ matrix.rust }}
override: true
components: rustfmt, clippy
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run expensive tests
if: github.ref == 'refs/heads/develop' || github.event.pull_request.base.ref == 'develop' || github.event.pull_request.base.ref == 'master'
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --all-features -- --ignored
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- uses: actions-rs/clippy-check@v1
name: Clippy checks
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --workspace --all-targets -- -D warnings
- name: Reclaim some disk space
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
with:
command: clean
# COCONUT stuff
- name: Build all binaries with coconut enabled
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --features=coconut
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run all tests with coconut enabled
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --features=coconut
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
with:
command: clean
- name: Run clippy with coconut enabled
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --workspace --all-targets --features=coconut -- -D warnings
# nym-wallet (the rust part)
- name: Build nym-wallet rust code
uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path nym-wallet/Cargo.toml --workspace
- name: Run nym-wallet tests
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path nym-wallet/Cargo.toml --workspace
- name: Check nym-wallet formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --manifest-path nym-wallet/Cargo.toml --all -- --check
- name: Run clippy for nym-wallet
uses: actions-rs/cargo@v1
if: ${{ matrix.rust != 'nightly' }}
with:
command: clippy
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-targets -- -D warnings
notification:
needs: [build,get_release]
runs-on: ubuntu-20.04
steps:
- name: Collect jobs status
uses: technote-space/workflow-conclusion-action@v2
- name: Check out repository code
uses: actions/checkout@v3
- name: Keybase - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
if: env.WORKFLOW_CONCLUSION == 'failure'
env:
NYM_NOTIFICATION_KIND: nightly
NYM_PROJECT_NAME: "Nym nightly build on latest release"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH_NAME: "${{needs.get_release.outputs.output1}}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-nightly-release"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+50
View File
@@ -0,0 +1,50 @@
name: Publish Nym CLI binaries
on:
workflow_dispatch:
release:
types: [created]
env:
NETWORK: mainnet
jobs:
publish-nym-cli:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-20.04, windows-latest, macos-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Check the release tag starts with `nym-cli-`
if: startsWith(github.ref, 'refs/tags/nym-cli-') == false && github.event_name != 'workflow_dispatch'
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-cli-...')
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Build binary
run: make build-nym-cli
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: nym-cli-${{ matrix.platform }}
path: |
target/release/nym-cli*
retention-days: 30
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
if: github.event_name == 'release'
with:
files: |
target/release/nym-cli
@@ -0,0 +1,96 @@
name: Publish Nym Connect (MacOS)
on:
workflow_dispatch:
release:
types: [created]
defaults:
run:
working-directory: nym-connect
jobs:
publish-tauri:
strategy:
fail-fast: false
matrix:
platform: [macos-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- name: Check the release tag starts with `nym-connect-`
if: startsWith(github.ref, 'refs/tags/nym-connect-') == false && github.event_name != 'workflow_dispatch'
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-connect-...')
- name: Node v16
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install the Apple developer certificate for code signing
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$APPLE_CERTIFICATE" | base64 --decode --output $CERTIFICATE_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
- name: Create env file
uses: timheuer/base64-to-file@v1.1
with:
fileName: '.env'
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Install app dependencies and build it
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_IDENTITY_ID }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
run: yarn && yarn build
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: nym-connect_1.0.0_x64.dmg
path: nym-connect/target/release/bundle/dmg/nym-connect_1.0.0_x64.dmg
retention-days: 30
- name: Clean up keychain
if: ${{ always() }}
run: |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
if: github.event_name == 'release'
with:
files: |
nym-connect/target/release/bundle/dmg/*.dmg
nym-connect/target/release/bundle/macos/*.app.tar.gz*
@@ -0,0 +1,68 @@
name: Publish Nym Connect (Ubuntu)
on:
workflow_dispatch:
release:
types: [created]
defaults:
run:
working-directory: nym-connect
jobs:
publish-tauri:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-20.04]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- name: Tauri dependencies
run: >
sudo apt-get update &&
sudo apt-get install -y webkit2gtk-4.0 libayatana-appindicator3-dev
- name: Check the release tag starts with `nym-connect-`
if: startsWith(github.ref, 'refs/tags/nym-connect-') == false && github.event_name != 'workflow_dispatch'
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-connect-...')
- name: Node v16
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install app dependencies
run: yarn
- name: Create env file
uses: timheuer/base64-to-file@v1.1
with:
fileName: '.env'
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Build app
run: yarn build
env:
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: nym-connect.AppImage.tar.gz
path: nym-connect/target/release/bundle/appimage/nym-connect_1.0.0_amd64.AppImage
retention-days: 30
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
if: github.event_name == 'release'
with:
files: |
nym-connect/target/release/bundle/appimage/*.AppImage
nym-connect/target/release/bundle/appimage/*.AppImage.tar.gz*
@@ -0,0 +1,90 @@
name: Publish Nym Connect (Windows 10)
on:
workflow_dispatch:
release:
types: [created]
defaults:
run:
working-directory: nym-connect
jobs:
publish-tauri:
strategy:
fail-fast: false
matrix:
platform: [windows10]
runs-on: ${{ matrix.platform }}
steps:
- name: Clean up first
continue-on-error: true
working-directory: .
run: |
cd ..
del /s /q /A:H nym
rmdir /s /q nym
- uses: actions/checkout@v3
- name: Check the release tag starts with `nym-connect-`
if: startsWith(github.ref, 'refs/tags/nym-connect-') == false && github.event_name != 'workflow_dispatch'
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-connect-...')
- name: Import signing certificate
env:
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
run: |
New-Item -ItemType directory -Path certificate
Set-Content -Path certificate/tempCert.txt -Value $env:WINDOWS_CERTIFICATE
certutil -decode certificate/tempCert.txt certificate/certificate.pfx
Remove-Item -path certificate -include tempCert.txt
Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText)
- name: Node v16
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Create env file
uses: timheuer/base64-to-file@v1.1
with:
fileName: '.env'
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Install app dependencies
run: yarn
- name: Build and sign it
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ENABLE_CODE_SIGNING: ${{ secrets.WINDOWS_CERTIFICATE }}
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
run: yarn build
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: nym-connect_1.0.0_x64_en-US.msi
path: nym-connect/target/release/bundle/msi/nym-connect_1.0.0_x64_en-US.msi
retention-days: 30
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
if: github.event_name == 'release'
with:
files: |
nym-connect/target/release/bundle/msi/*.msi
nym-connect/target/release/bundle/msi/*.msi.zip*
+59
View File
@@ -0,0 +1,59 @@
name: CI for nym-connect
on:
push:
paths:
- 'nym-connect/**'
defaults:
run:
working-directory: nym-connect
jobs:
build:
runs-on: custom-runner-linux
steps:
- uses: actions/checkout@v2
- name: Install rsync
run: sudo apt-get install rsync
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Install Yarn
run: npm install -g yarn
- run: yarn
continue-on-error: true
- name: Set environment from the example
run: cp .env.sample .env
- run: yarn storybook:build
- name: Deploy branch to CI www
continue-on-error: true
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "nym-connect/storybook-static/"
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/nym-connect-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/"
- name: Keybase - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
env:
NYM_NOTIFICATION_KIND: nym-connect
NYM_PROJECT_NAME: "nym-connect"
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
NYM_CI_WWW_LOCATION: "nym-connect-${{ env.GITHUB_REF_SLUG }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
KEYBASE_NYM_CHANNEL: "ci-nym-connect"
IS_SUCCESS: "${{ job.status == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+36 -2
View File
@@ -1,5 +1,13 @@
name: Publish Nym binaries
on:
workflow_dispatch:
inputs:
add_tokio_unstable:
description: 'True to add RUSTFLAGS="--cfg tokio_unstable"'
required: true
default: false
type: boolean
release:
types: [created]
@@ -11,18 +19,26 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]
platform: [ubuntu-20.04]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
- name: Check the release tag starts with `nym-binaries-`
if: startsWith(github.ref, 'refs/tags/nym-binaries-') == false
if: startsWith(github.ref, 'refs/tags/nym-binaries-') == false && github.event_name != 'workflow_dispatch'
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-binaries-...')
- name: Sets env vars for tokio if set in manual dispatch inputs
run: |
echo 'RUSTFLAGS="--cfg tokio_unstable"' >> $GITHUB_ENV
if: github.event_name == 'workflow_dispatch' && inputs.add_tokio_unstable == true
- name: Install Rust stable
uses: actions-rs/toolchain@v1
@@ -35,8 +51,24 @@ jobs:
command: build
args: --workspace --release
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: my-artifact
path: |
target/release/nym-client
target/release/nym-gateway
target/release/nym-mixnode
target/release/nym-socks5-client
target/release/nym-validator-api
target/release/nym-network-requester
target/release/nym-network-statistics
target/release/nym-cli
retention-days: 30
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
if: github.event_name == 'release'
with:
files: |
target/release/nym-client
@@ -45,3 +77,5 @@ jobs:
target/release/nym-socks5-client
target/release/nym-validator-api
target/release/nym-network-requester
target/release/nym-network-statistics
target/release/nym-cli
+23 -8
View File
@@ -1,5 +1,6 @@
name: Publish Nym Wallet (MacOS)
on:
workflow_dispatch:
release:
types: [created]
@@ -19,16 +20,16 @@ jobs:
- uses: actions/checkout@v2
- name: Check the release tag starts with `nym-wallet-`
if: startsWith(github.ref, 'refs/tags/nym-wallet-') == false
if: startsWith(github.ref, 'refs/tags/nym-wallet-') == false && github.event_name != 'workflow_dispatch'
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-wallet-...')
- name: Node v16
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 16.x
node-version: 16
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
@@ -55,6 +56,12 @@ jobs:
security import $CERTIFICATE_PATH -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
- name: Create env file
uses: timheuer/base64-to-file@v1.1
with:
fileName: '.env'
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Install app dependencies and build it
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -68,14 +75,22 @@ jobs:
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
run: yarn && yarn build
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
files: |
nym-wallet/target/release/bundle/dmg/*.dmg
nym-wallet/target/release/bundle/macos/*.app.tar.gz*
name: nym-wallet.app.tar.gz
path: nym-wallet/target/release/bundle/macos/nym-wallet.app.tar.gz
retention-days: 5
- name: Clean up keychain
if: ${{ always() }}
run: |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
- name: Upload to release based on tag name
uses: softprops/action-gh-release@v1
if: github.event_name == 'release'
with:
files: |
nym-wallet/target/release/bundle/dmg/*.dmg
nym-wallet/target/release/bundle/macos/*.app.tar.gz*
@@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]
platform: [ubuntu-20.04]
runs-on: ${{ matrix.platform }}
steps:
@@ -30,15 +30,21 @@ jobs:
core.setFailed('Release tag did not start with nym-wallet-...')
- name: Node v16
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 16.x
node-version: 16
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install app dependencies
run: yarn
- name: Create env file
uses: timheuer/base64-to-file@v1.1
with:
fileName: '.env'
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Build app
run: yarn build
env:
@@ -45,15 +45,21 @@ jobs:
Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText)
- name: Node v16
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 16.x
node-version: 16
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Create env file
uses: timheuer/base64-to-file@v1.1
with:
fileName: '.env'
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Install app dependencies
run: yarn
+32
View File
@@ -0,0 +1,32 @@
name: Release Nym Wallet
on:
workflow_dispatch:
inputs:
nym_wallet_version:
description: 'The version of the Nym Wallet to release'
default: '1.0.x'
required: true
type: string
jobs:
create-release:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-20.04]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- name: Create release
uses: softprops/action-gh-release@v1
with:
body: >-
This is a pre-release
Download the wallet for your platform:
- [Linux](https://github.com/nymtech/nym/releases/download/nym-wallet-v${{ inputs.nym_wallet_version}}/nym-wallet_v${{ inputs.nym_wallet_version}}_amd64_ubuntu20.04.AppImage)
- [MacOS](https://github.com/nymtech/nym/releases/download/nym-wallet-v${{ inputs.nym_wallet_version}}/nym-wallet_v${{ inputs.nym_wallet_version}}_x64_macos_11.dmg)
- [Windows](https://github.com/nymtech/nym/releases/download/nym-wallet-v${{ inputs.nym_wallet_version}}/nym-wallet_v${{ inputs.nym_wallet_version}}_x64_windows.msi)
prerelease: true
name: Nym Wallet v${{ inputs.nym_wallet_version}}
tag_name: nym-wallet-v${{ inputs.nym_wallet_version}}
+2 -2
View File
@@ -13,9 +13,9 @@ jobs:
- name: Install rsync
run: sudo apt-get install rsync
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v2
- uses: actions/setup-node@v3
with:
node-version: '16'
node-version: 16
- name: Setup yarn
run: npm install -g yarn
- name: Build dependencies
+3 -3
View File
@@ -12,7 +12,7 @@ defaults:
jobs:
test:
name: wallet tests
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
@@ -34,9 +34,9 @@ jobs:
toolchain: stable
- name: Node v16
uses: actions/setup-node@v1
uses: actions/setup-node@v3
with:
node-version: 16.x
node-version: 16
- name: Install yarn for building application
run: yarn install
@@ -85,7 +85,7 @@ async function getMessageBody(context) {
...
],
check_run_url: 'https://api.github.com/repos/nymtech/nym/check-runs/5182940024',
labels: [ 'ubuntu-latest' ],
labels: [ 'ubuntu-20.04' ],
runner_id: 1,
runner_name: 'Hosted Agent',
runner_group_id: 2,
@@ -3,7 +3,7 @@ require('dotenv').config();
const Bot = require('keybase-bot');
let context = {
kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly'],
kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly', 'nym-connect','security'],
};
/**
@@ -89,7 +89,7 @@ async function sendKeybaseMessage(messageBody) {
});
const channel = {
name: 'nymtech_bot',
name: context.env.KEYBASE_NYMBOT_TEAM || 'nymtech_bot',
membersType: 'team',
topicName: context.keybase.channel,
topic_type: 'CHAT',
@@ -0,0 +1,29 @@
const Handlebars = require('handlebars');
const fs = require('fs');
const path = require('path');
async function addToContextAndValidate(context) {
if (!context.env.NYM_CI_WWW_LOCATION) {
throw new Error('Please ensure the env var NYM_CI_WWW_LOCATION is set');
}
if (!context.env.NYM_CI_WWW_BASE) {
throw new Error('Please ensure the env var NYM_CI_WWW_BASE is set');
}
}
async function getMessageBody(context) {
const source = fs
.readFileSync(
context.env.IS_SUCCESS === 'true'
? path.resolve(__dirname, 'templates', 'success')
: path.resolve(__dirname, 'templates', 'failure'),
)
.toString();
const template = Handlebars.compile(source);
return template(context);
}
module.exports = {
addToContextAndValidate,
getMessageBody,
};
@@ -0,0 +1,11 @@
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
> :rocket: {{ env.NYM_PROJECT_NAME }}
> 🔴 **FAILURE** :cry:
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
Commit message:
```
{{ env.GIT_COMMIT_MESSAGE }}
```
@@ -0,0 +1,11 @@
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
> :rocket: {{ env.NYM_PROJECT_NAME }} ➡️➡️➡️➡️➡️ **View storybook:** https://{{ env.NYM_CI_WWW_LOCATION }}.{{ env.NYM_CI_WWW_BASE }}/
> ✅ **SUCCESS**
> `branch` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/tree/{{ env.GIT_BRANCH_NAME }}
> `commit` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/commit/{{ env.GITHUB_SHA }}
> `build ` {{ env.GITHUB_SERVER_URL }}/{{ env.GITHUB_REPOSITORY }}/actions/runs/{{ env.GITHUB_RUN_ID }}
Commit message by `{{ env.GITHUB_ACTOR }}` at {{ timestamp }}:
```
{{ env.GIT_COMMIT_MESSAGE }}
```
@@ -0,0 +1,24 @@
const Handlebars = require('handlebars');
const fs = require('fs');
const path = require('path');
const { Octokit, App } = require('octokit');
async function addToContextAndValidate(context) {
return
}
async function getMessageBody(context) {
try {
const source = fs
.readFileSync("deny.message").toString();
return source;
} catch (error) {
console.error(error);
}
}
module.exports = {
addToContextAndValidate,
getMessageBody,
};
+1 -1
View File
@@ -7,7 +7,7 @@ on:
jobs:
wasm:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
+2 -1
View File
@@ -37,4 +37,5 @@ validator-config
*.patch
validator-api-config.toml
dist
storybook-static
storybook-static
envs/qwerty.env
+236 -225
View File
@@ -6,64 +6,247 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
### Added
- all: added network compilation target to `--help` (or `--version`) commands ([#1256]).
- explorer-api: learned how to sum the delegations by owner in a new endpoint.
- gateway: Added gateway coconut verifications and validator-api communication for double spending protection ([#1261])
- mixnet-contract: Added ClaimOperatorReward and ClaimDelegatorReward messages ([#1292])
- mixnet-contract: Replace all naked `-` with `saturating_sub`.
- validator-api: add `estimated_node_profit` and `estimated_operator_cost` to `reward-estimate` endpoint ([#1284])
- validator-api: add detailed mixnode bond endpoints, and explorer-api makes use of that data to append stake saturation.
- validator-api: add Swagger to document the REST API ([#1249]).
- validator-api: Added new endpoints for coconut spending flow and communications with coconut & multisig contracts ([#1261])
- vesting-contract: Added ClaimOperatorReward and ClaimDelegatorReward messages ([#1292])
- wallet: add simple CLI tool for decrypting and recovering the wallet file.
- wallet: added support for multiple accounts ([#1265])
- wallet: compound and claim reward endpoints for operators and delegators ([#1302])
- wallet: require password to switch accounts
- wallet: the wallet backend learned how to keep track of validator name, either hardcoded or by querying the status endpoint.
- network-statistics: a new mixnet service that aggregates and exposes anonymized data about mixnet services ([#1328])
- socks5: send status message for service ready, and network-requester error response
### Changed
- 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)
### Changed
- validator-api: can recover from shutdown during DKG process ([#1872])
- clients: deduplicate gateway inititialization, part of work towards a rust-sdk
- clients: keep all transmission lanes going at all times by making priority probabilistic
- clients: ability to use multi-reply SURBs to send arbitrarily long messages fully anonymously whilst requesting additional reply blocks whenever they're about to run out ([#1796], [#1801], [#1804], [#1835], [#1858], [#1883]))
### Fixed
- 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])
- socks5: fixed bug where connections sometimes where closed too early
- clients: improve message logging when received message fails to get reconstructed ([#1803])
[#1796]: https://github.com/nymtech/nym/pull/1796
[#1801]: https://github.com/nymtech/nym/pull/1801
[#1803]: https://github.com/nymtech/nym/pull/1803
[#1804]: https://github.com/nymtech/nym/pull/1804
[#1835]: https://github.com/nymtech/nym/pull/1835
[#1858]: https://github.com/nymtech/nym/pull/1858
[#1872]: https://github.com/nymtech/nym/pull/1872
[#1883]: https://github.com/nymtech/nym/pull/1883
[#1884]: https://github.com/nymtech/nym/pull/1884
## [v1.1.2]
### Changed
- 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
## [v1.1.1](https://github.com/nymtech/nym/tree/v1.1.1) (2022-11-29)
### Added
- binaries: add `-c` shortform for `--config-env-file`
- websocket-requests: add server response signalling current packet queue length in the client
- contracts: DKG contract that handles coconut key generation ([#1678][#1708][#1747])
- validator-api: generate coconut keys interactively, using DKG and multisig contracts ([#1678][#1708][#1747])
### Changed
- clients: add concept of transmission lanes to better handle multiple data streams ([#1720])
- clients,validator-api: take coconut signers from the chain instead of specifying them via CLI ([#1747])
- multisig contract: add DKG contract to the list of addresses that can create proposals ([#1747])
- socks5-client: wait closing inbound connection until data is sent, and throttle incoming data in general ([#1783])
- nym-cli: improve error reporting/handling and changed `vesting-schedule` queries to use query client instead of signing client
### Fixed
- gateway-client: fix decrypting stored messages on reconnect ([#1786])
### Fixed
- gateway-client: fix decrypting stored messages on reconnect ([#1786])
- socks5-client: fix shutting down all tasks if anyone of them panics or errors out ([#1805])
[#1678]: https://github.com/nymtech/nym/pull/1678
[#1708]: https://github.com/nymtech/nym/pull/1708
[#1720]: https://github.com/nymtech/nym/pull/1720
[#1747]: https://github.com/nymtech/nym/pull/1747
[#1783]: https://github.com/nymtech/nym/pull/1783
[#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
- clients: add testing-only support for two more extended packet sizes (8kb and 16kb).
- common/ledger: new library for communicating with a Ledger device ([#1640])
- native-client/socks5-client/wasm-client: `disable_loop_cover_traffic_stream` Debug config option to disable the separate loop cover traffic stream ([#1666])
- native-client/socks5-client/wasm-client: `disable_main_poisson_packet_distribution` Debug config option to make the client ignore poisson distribution in the main packet stream and ONLY send real message (and as fast as they come) ([#1664])
- native-client/socks5-client/wasm-client: `use_extended_packet_size` Debug config option to make the client use 'ExtendedPacketSize' for its traffic (32kB as opposed to 2kB in 1.0.2) ([#1671])
- network-requester: added additional Blockstream Green wallet endpoint to `example.allowed.list` ([#1611])
- validator-api: add `interval_operating_cost` and `profit_margin_percent` to compute reward estimation endpoint
- validator-client: added `query_contract_smart` and `query_contract_raw` on `NymdClient` ([#1558])
- wasm-client: uses updated wasm-compatible `client-core` so that it's now capable of packet retransmission, cover traffic and poisson delay (among other things!) ([#1673])
### Fixed
- socks5-client: fix bug where in some cases packet reordering could trigger a connection being closed too early ([#1702],[#1724])
- validator-api: mixnode, gateway should now prefer values in config.toml over mainnet defaults ([#1645])
- validator-api: should now correctly update historical uptimes for all mixnodes and gateways every 24h ([#1721])
### Changed
- clients: bound the sphinx packet channel and reduce sending rate if gateway can't keep up ([#1703],[#1725])
- 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-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])
- validator-api: changes to internal data structures due to the mixnet contract revamp ([#1472])
- validator-api: split epoch-operations into multiple separate transactions ([#1472])
[#1472]: https://github.com/nymtech/nym/pull/1472
[#1541]: https://github.com/nymtech/nym/pull/1541
[#1558]: https://github.com/nymtech/nym/pull/1558
[#1577]: https://github.com/nymtech/nym/pull/1577
[#1585]: https://github.com/nymtech/nym/pull/1585
[#1591]: https://github.com/nymtech/nym/pull/1591
[#1640]: https://github.com/nymtech/nym/pull/1640
[#1645]: https://github.com/nymtech/nym/pull/1645
[#1611]: https://github.com/nymtech/nym/pull/1611
[#1664]: https://github.com/nymtech/nym/pull/1664
[#1666]: https://github.com/nymtech/nym/pull/1645
[#1669]: https://github.com/nymtech/nym/pull/1669
[#1671]: https://github.com/nymtech/nym/pull/1671
[#1673]: https://github.com/nymtech/nym/pull/1673
[#1681]: https://github.com/nymtech/nym/pull/1681
[#1702]: https://github.com/nymtech/nym/pull/1702
[#1703]: https://github.com/nymtech/nym/pull/1703
[#1721]: https://github.com/nymtech/nym/pull/1721
[#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
- socks5 client/websocket client: add `--force-register-gateway` flag, useful when rerunning init ([#1353])
- all: added network compilation target to `--help` (or `--version`) commands ([#1256]).
- explorer-api: learned how to sum the delegations by owner in a new endpoint.
- explorer-api: add apy values to `mix_nodes` endpoint
- gateway: Added gateway coconut verifications and validator-api communication for double spending protection ([#1261])
- network-explorer-ui: Upgrade to React Router 6
- rewarding: replace circulating supply with staking supply in reward calculations ([#1324])
- validator-api: add `estimated_node_profit` and `estimated_operator_cost` to `reward-estimate` endpoint ([#1284])
- validator-api: add detailed mixnode bond endpoints, and explorer-api makes use of that data to append stake saturation
- validator-api: add Swagger to document the REST API ([#1249]).
- validator-api: Added new endpoints for coconut spending flow and communications with coconut & multisig contracts ([#1261])
- validator-api: add `uptime`, `estimated_operator_apy`, `estimated_delegators_apy` to `/mixnodes/detailed` endpoint ([#1393])
- validator-api: add node info cache storing simulated active set inclusion probabilities
- network-statistics: a new mixnet service that aggregates and exposes anonymized data about mixnet services ([#1328])
- mixnode: Added basic mixnode hardware reporting to the HTTP API ([#1308]).
- validator-api: endpoint, in coconut mode, for returning the validator-api cosmos address ([#1404]).
- validator-client: add `denom` argument and add simple test for querying an account balance
- gateway, validator-api: Checks for coconut credential double spending attempts, taking the coconut bandwidth contract as source of truth ([#1457])
- coconut-bandwidth-contract: Record the state of a coconut credential; create specific proposal for releasing funds ([#1457])
- inclusion-probability: add simulator for active set inclusion probability
### Fixed
- mixnet-contract: `estimated_delegator_reward` calculation ([#1284])
- mixnet-contract: delegator and operator rewards use lambda and sigma instead of lambda_ticked and sigma_ticked ([#1284])
- mixnet-contract: removed `expect` in `query_delegator_reward` and queries containing invalid proxy address should now return a more human-readable error ([#1257])
- mixnet-contract: replaced integer division with fixed for performance calculations ([#1284])
- mixnet-contract: Under certain circumstances nodes could not be unbonded ([#1255](https://github.com/nymtech/nym/issues/1255)) ([#1258])
- mixnode, gateway: attempting to determine reconnection backoff to persistently failing mixnode could result in a crash ([#1260])
- mixnode: the mixnode learned how to shutdown gracefully.
- vesting-contract: replaced `checked_sub` with `saturating_sub` to fix the underflow in `get_vesting_tokens` ([#1275])
- mixnode: the mixnode learned how to shutdown gracefully
- mixnode: listen out for SIGTERM and SIGQUIT too, making it play nicely as a system service.
- native & socks5 clients: fail early when clients try to re-init with a different gateway, which is not supported yet ([#1322])
- native & socks5 clients: rerun init will now reuse previous gateway configuration instead of failing ([#1353])
- native & socks5 clients: deduplicate big chunks of init logic
- validator: fixed local docker-compose setup to work on Apple M1 ([#1329])
- explorer-api: listen out for SIGTERM and SIGQUIT too, making it play nicely as a system service ([#1482]).
- network-requester: fix filter for suffix-only domains ([#1487])
- validator-api: listen out for SIGTERM and SIGQUIT too, making it play nicely as a system service; cleaner shutdown, without panics ([#1496], [#1573]).
### Changed
- validator-client: created internal `Coin` type that replaces coins from `cosmrs` and `cosmwasm` for API entrypoints [[#1295]]
- all: updated all `cosmwasm`-related dependencies to `1.0.0` and `cw-storage-plus` to `0.13.4` [[#1318]]
- all: updated `rocket` to `0.5.0-rc.2`.
- network-requester: allow to voluntarily store and send statistical data about the number of bytes the proxied server serves ([#1328])
- gateway: allow to voluntarily send statistical data about the number of active inboxes served by a gateway ([#1376])
- gateway & mixnode: move detailed build info back to `--version` from `--help`.
- socks5 client/websocket client: upgrade to latest clap and switched to declarative commandline parsing.
- validator-api: fee payment for multisig operations comes from the gateway account instead of the validator APIs' accounts ([#1419])
- multisig-contract: Limit the proposal creating functionality to one address (coconut-bandwidth-contract address) ([#1457])
- All binaries and cosmwasm blobs are configured at runtime now; binaries are configured using environment variables or .env files and contracts keep the configuration parameters in storage ([#1463])
- 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])
[#1249]: https://github.com/nymtech/nym/pull/1249
[#1256]: https://github.com/nymtech/nym/pull/1256
[#1257]: https://github.com/nymtech/nym/pull/1257
[#1258]: https://github.com/nymtech/nym/pull/1258
[#1260]: https://github.com/nymtech/nym/pull/1260
[#1261]: https://github.com/nymtech/nym/pull/1261
[#1265]: https://github.com/nymtech/nym/pull/1265
[#1267]: https://github.com/nymtech/nym/pull/1267
[#1275]: https://github.com/nymtech/nym/pull/1275
[#1278]: https://github.com/nymtech/nym/pull/1278
[#1284]: https://github.com/nymtech/nym/pull/1284
[#1292]: https://github.com/nymtech/nym/pull/1292
[#1295]: https://github.com/nymtech/nym/pull/1295
[#1302]: https://github.com/nymtech/nym/pull/1302
[#1308]: https://github.com/nymtech/nym/pull/1308
[#1318]: https://github.com/nymtech/nym/pull/1318
[#1322]: https://github.com/nymtech/nym/pull/1322
[#1324]: https://github.com/nymtech/nym/pull/1324
[#1328]: https://github.com/nymtech/nym/pull/1328
## [nym-wallet-v1.0.4](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.4) (2022-05-04)
### Changed
- all: the default behaviour of validator client is changed to use `broadcast_sync` and poll for transaction inclusion instead of using `broadcast_commit` to deal with timeouts ([#1246])
[#1329]: https://github.com/nymtech/nym/pull/1329
[#1353]: https://github.com/nymtech/nym/pull/1353
[#1376]: https://github.com/nymtech/nym/pull/1376
[#1393]: https://github.com/nymtech/nym/pull/1393
[#1404]: https://github.com/nymtech/nym/pull/1404
[#1419]: https://github.com/nymtech/nym/pull/1419
[#1457]: https://github.com/nymtech/nym/pull/1457
[#1463]: https://github.com/nymtech/nym/pull/1463
[#1478]: https://github.com/nymtech/nym/pull/1478
[#1482]: https://github.com/nymtech/nym/pull/1482
[#1487]: https://github.com/nymtech/nym/pull/1487
[#1496]: https://github.com/nymtech/nym/pull/1496
[#1503]: https://github.com/nymtech/nym/pull/1503
[#1520]: https://github.com/nymtech/nym/pull/1520
[#1573]: https://github.com/nymtech/nym/pull/1573
[#1576]: https://github.com/nymtech/nym/pull/1576
## [v1.0.1](https://github.com/nymtech/nym/tree/v1.0.1) (2022-05-04)
@@ -96,77 +279,10 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
[Full Changelog](https://github.com/nymtech/nym/compare/nym-wallet-v1.0.3...nym-binaries-1.0.0)
## [nym-wallet-v1.0.3](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.3) (2022-04-25)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-binaries-1.0.0-rc.2...nym-wallet-v1.0.3)
**Fixed bugs:**
- \[Issue\] Wallet 1.0.2 cannot send NYM tokens from a DelayedVestingAccount [\#1215](https://github.com/nymtech/nym/issues/1215)
- Main README not showing properly with GitHub dark mode [\#1211](https://github.com/nymtech/nym/issues/1211)
**Merged pull requests:**
- Bugfix - wallet undelegation for vesting accounts [\#1220](https://github.com/nymtech/nym/pull/1220) ([mmsinclair](https://github.com/mmsinclair))
- Bugfix/delegation reconcile [\#1219](https://github.com/nymtech/nym/pull/1219) ([jstuczyn](https://github.com/jstuczyn))
- Bugfix/query proxied pending delegations [\#1218](https://github.com/nymtech/nym/pull/1218) ([jstuczyn](https://github.com/jstuczyn))
- Using custom gas multiplier in the wallet [\#1217](https://github.com/nymtech/nym/pull/1217) ([jstuczyn](https://github.com/jstuczyn))
- Feature/vesting accounts support [\#1216](https://github.com/nymtech/nym/pull/1216) ([jstuczyn](https://github.com/jstuczyn))
- Release/1.0.0 rc.2 [\#1214](https://github.com/nymtech/nym/pull/1214) ([jstuczyn](https://github.com/jstuczyn))
- chore: fix dark mode rendering [\#1212](https://github.com/nymtech/nym/pull/1212) ([pwnfoo](https://github.com/pwnfoo))
- Feature/spend coconut [\#1210](https://github.com/nymtech/nym/pull/1210) ([neacsu](https://github.com/neacsu))
- Bugfix/unique sphinx key [\#1207](https://github.com/nymtech/nym/pull/1207) ([jstuczyn](https://github.com/jstuczyn))
- Add cache read and write timeouts [\#1206](https://github.com/nymtech/nym/pull/1206) ([durch](https://github.com/durch))
- Additional, more informative routes [\#1204](https://github.com/nymtech/nym/pull/1204) ([durch](https://github.com/durch))
- Feature/aggregated econ dynamics explorer endpoint [\#1203](https://github.com/nymtech/nym/pull/1203) ([jstuczyn](https://github.com/jstuczyn))
- Debugging validator [\#1198](https://github.com/nymtech/nym/pull/1198) ([durch](https://github.com/durch))
- wallet: expose additional validator configuration functionality to the frontend [\#1195](https://github.com/nymtech/nym/pull/1195) ([octol](https://github.com/octol))
- Update rewarding validator address [\#1193](https://github.com/nymtech/nym/pull/1193) ([durch](https://github.com/durch))
- Crypto part of the Groth's NIDKG [\#1182](https://github.com/nymtech/nym/pull/1182) ([jstuczyn](https://github.com/jstuczyn))
- fix unbond page [\#1180](https://github.com/nymtech/nym/pull/1180) ([tommyv1987](https://github.com/tommyv1987))
- Type safe bounds [\#1179](https://github.com/nymtech/nym/pull/1179) ([durch](https://github.com/durch))
- Fix delegation paging [\#1174](https://github.com/nymtech/nym/pull/1174) ([durch](https://github.com/durch))
- Update binaries to rc version [\#1172](https://github.com/nymtech/nym/pull/1172) ([tommyv1987](https://github.com/tommyv1987))
- Bump ansi-regex from 4.1.0 to 4.1.1 in /docker/typescript\_client/upload\_contract [\#1171](https://github.com/nymtech/nym/pull/1171) ([dependabot[bot]](https://github.com/apps/dependabot))
## [nym-binaries-1.0.0-rc.2](https://github.com/nymtech/nym/tree/nym-binaries-1.0.0-rc.2) (2022-04-15)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-wallet-v1.0.2...nym-binaries-1.0.0-rc.2)
## [nym-wallet-v1.0.2](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.2) (2022-04-05)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-wallet-v1.0.1...nym-wallet-v1.0.2)
**Merged pull requests:**
- Wallet 1.0.2 visual tweaks [\#1197](https://github.com/nymtech/nym/pull/1197) ([mmsinclair](https://github.com/mmsinclair))
- Password for wallet with routes [\#1196](https://github.com/nymtech/nym/pull/1196) ([fmtabbara](https://github.com/fmtabbara))
- Add auto-updater to Nym Wallet [\#1194](https://github.com/nymtech/nym/pull/1194) ([mmsinclair](https://github.com/mmsinclair))
- Fix clippy warnings for beta toolchain [\#1191](https://github.com/nymtech/nym/pull/1191) ([octol](https://github.com/octol))
- wallet: expose validator urls to the frontend [\#1190](https://github.com/nymtech/nym/pull/1190) ([octol](https://github.com/octol))
- wallet: add test for decrypting stored wallet file [\#1189](https://github.com/nymtech/nym/pull/1189) ([octol](https://github.com/octol))
- Fix clippy warnings [\#1188](https://github.com/nymtech/nym/pull/1188) ([octol](https://github.com/octol))
- Password for wallet with routes [\#1187](https://github.com/nymtech/nym/pull/1187) ([mmsinclair](https://github.com/mmsinclair))
- wallet: add validate\_mnemonic [\#1186](https://github.com/nymtech/nym/pull/1186) ([octol](https://github.com/octol))
- wallet: support removing accounts from the wallet file [\#1185](https://github.com/nymtech/nym/pull/1185) ([octol](https://github.com/octol))
- Feature/adding discord [\#1184](https://github.com/nymtech/nym/pull/1184) ([gala1234](https://github.com/gala1234))
- wallet: config backend for validator selection [\#1183](https://github.com/nymtech/nym/pull/1183) ([octol](https://github.com/octol))
- Add storybook to wallet [\#1178](https://github.com/nymtech/nym/pull/1178) ([mmsinclair](https://github.com/mmsinclair))
- wallet: connection test nymd and api urls independently [\#1170](https://github.com/nymtech/nym/pull/1170) ([octol](https://github.com/octol))
- wallet: wire up account storage [\#1153](https://github.com/nymtech/nym/pull/1153) ([octol](https://github.com/octol))
- Feature/signature on deposit [\#1151](https://github.com/nymtech/nym/pull/1151) ([neacsu](https://github.com/neacsu))
## [nym-wallet-v1.0.1](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.1) (2022-04-05)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-binaries-1.0.0-rc.1...nym-wallet-v1.0.1)
**Closed issues:**
- Check enabling bbbc simultaneously with open access. Estimate what it would take to make this the default compilation target. [\#1175](https://github.com/nymtech/nym/issues/1175)
- Get coconut credential for deposited tokens [\#1138](https://github.com/nymtech/nym/issues/1138)
- Make payments lazy [\#1135](https://github.com/nymtech/nym/issues/1135)
- Uptime on node selection for sets [\#1049](https://github.com/nymtech/nym/issues/1049)
## [nym-binaries-1.0.0-rc.1](https://github.com/nymtech/nym/tree/nym-binaries-1.0.0-rc.1) (2022-03-28)
[Full Changelog](https://github.com/nymtech/nym/compare/nym-wallet-v1.0.0...nym-binaries-1.0.0-rc.1)
@@ -194,9 +310,9 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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))
@@ -205,7 +321,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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))
@@ -245,116 +361,13 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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))
## [nym-wallet-v1.0.0](https://github.com/nymtech/nym/tree/nym-wallet-v1.0.0) (2022-02-03)
[Full Changelog](https://github.com/nymtech/nym/compare/v0.12.1...nym-wallet-v1.0.0)
**Implemented enhancements:**
- \[Feature Request\] Please enable registration without need for Telegram account [\#1016](https://github.com/nymtech/nym/issues/1016)
- Fast mixnode launch with a pre-built ISO + VM software [\#1001](https://github.com/nymtech/nym/issues/1001)
**Fixed bugs:**
- \[Issue\] [\#1000](https://github.com/nymtech/nym/issues/1000)
- \[Issue\] `nym-client` requires multiple attempts to run a server [\#869](https://github.com/nymtech/nym/issues/869)
- De-'float'-ing `Interval` \(`Display` impl + `serde`\) [\#1065](https://github.com/nymtech/nym/pull/1065) ([jstuczyn](https://github.com/jstuczyn))
- display client address on wallet creation [\#1058](https://github.com/nymtech/nym/pull/1058) ([fmtabbara](https://github.com/fmtabbara))
**Closed issues:**
- Rewarded set inclusion probability API endpoint [\#1037](https://github.com/nymtech/nym/issues/1037)
- Update cw-storage-plus to 0.11 [\#1032](https://github.com/nymtech/nym/issues/1032)
- Change `u128` fields in `RewardEstimationResponse` to `u64` [\#1029](https://github.com/nymtech/nym/issues/1029)
- Test out the mainnet Gravity Bridge [\#1006](https://github.com/nymtech/nym/issues/1006)
- Add vesting contract interface to nym-wallet [\#959](https://github.com/nymtech/nym/issues/959)
- Mixnode crash [\#486](https://github.com/nymtech/nym/issues/486)
**Merged pull requests:**
- create custom urls for mainnet [\#1095](https://github.com/nymtech/nym/pull/1095) ([fmtabbara](https://github.com/fmtabbara))
- Wallet signing on MacOS [\#1093](https://github.com/nymtech/nym/pull/1093) ([mmsinclair](https://github.com/mmsinclair))
- Fix rust 2018 idioms warnings [\#1092](https://github.com/nymtech/nym/pull/1092) ([octol](https://github.com/octol))
- Prevent contract overwriting [\#1090](https://github.com/nymtech/nym/pull/1090) ([durch](https://github.com/durch))
- Logout operation [\#1087](https://github.com/nymtech/nym/pull/1087) ([jstuczyn](https://github.com/jstuczyn))
- Update to rust edition 2021 everywhere [\#1086](https://github.com/nymtech/nym/pull/1086) ([octol](https://github.com/octol))
- Tag contract errors, and print out lines for easier QA [\#1084](https://github.com/nymtech/nym/pull/1084) ([durch](https://github.com/durch))
- Feature/flexible vesting + utility queries [\#1083](https://github.com/nymtech/nym/pull/1083) ([durch](https://github.com/durch))
- Bump @openzeppelin/contracts from 4.3.1 to 4.4.2 in /contracts/basic-bandwidth-generation [\#1082](https://github.com/nymtech/nym/pull/1082) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump nth-check from 2.0.0 to 2.0.1 in /clients/native/examples/js-examples/websocket [\#1081](https://github.com/nymtech/nym/pull/1081) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump url-parse from 1.5.1 to 1.5.4 in /clients/native/examples/js-examples/websocket [\#1080](https://github.com/nymtech/nym/pull/1080) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump follow-redirects from 1.14.1 to 1.14.7 in /clients/native/examples/js-examples/websocket [\#1079](https://github.com/nymtech/nym/pull/1079) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump nanoid from 3.1.23 to 3.2.0 in /clients/native/examples/js-examples/websocket [\#1078](https://github.com/nymtech/nym/pull/1078) ([dependabot[bot]](https://github.com/apps/dependabot))
- Setup basic test for mixnode stats reporting [\#1077](https://github.com/nymtech/nym/pull/1077) ([octol](https://github.com/octol))
- Make wallet\_address mandatory for mixnode init [\#1076](https://github.com/nymtech/nym/pull/1076) ([octol](https://github.com/octol))
- Tidy nym-mixnode module visibility [\#1075](https://github.com/nymtech/nym/pull/1075) ([octol](https://github.com/octol))
- Feature/wallet login with password [\#1074](https://github.com/nymtech/nym/pull/1074) ([fmtabbara](https://github.com/fmtabbara))
- Add trait to mock client dependency in DelayForwarder [\#1073](https://github.com/nymtech/nym/pull/1073) ([octol](https://github.com/octol))
- Bump rust-version to latest stable for nym-mixnode [\#1072](https://github.com/nymtech/nym/pull/1072) ([octol](https://github.com/octol))
- Fixes CI for our wasm build [\#1069](https://github.com/nymtech/nym/pull/1069) ([jstuczyn](https://github.com/jstuczyn))
- Add @octol as codeowner [\#1068](https://github.com/nymtech/nym/pull/1068) ([octol](https://github.com/octol))
- set-up inclusion probability [\#1067](https://github.com/nymtech/nym/pull/1067) ([fmtabbara](https://github.com/fmtabbara))
- Feature/wasm client [\#1066](https://github.com/nymtech/nym/pull/1066) ([neacsu](https://github.com/neacsu))
- Changed bech32\_prefix from punk to nymt [\#1064](https://github.com/nymtech/nym/pull/1064) ([jstuczyn](https://github.com/jstuczyn))
- Bump nanoid from 3.1.30 to 3.2.0 in /testnet-faucet [\#1063](https://github.com/nymtech/nym/pull/1063) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump nanoid from 3.1.30 to 3.2.0 in /nym-wallet [\#1062](https://github.com/nymtech/nym/pull/1062) ([dependabot[bot]](https://github.com/apps/dependabot))
- Rework vesting contract storage [\#1061](https://github.com/nymtech/nym/pull/1061) ([durch](https://github.com/durch))
- Mixnet Contract constants extraction [\#1060](https://github.com/nymtech/nym/pull/1060) ([jstuczyn](https://github.com/jstuczyn))
- fix: make explorer footer year dynamic [\#1059](https://github.com/nymtech/nym/pull/1059) ([martinyung](https://github.com/martinyung))
- Add mnemonic just on creation, to display it [\#1057](https://github.com/nymtech/nym/pull/1057) ([neacsu](https://github.com/neacsu))
- Network Explorer: updates to API and UI to show the active set [\#1056](https://github.com/nymtech/nym/pull/1056) ([mmsinclair](https://github.com/mmsinclair))
- Made contract addresses for query NymdClient construction optional [\#1055](https://github.com/nymtech/nym/pull/1055) ([jstuczyn](https://github.com/jstuczyn))
- Introduced RPC query for total token supply [\#1053](https://github.com/nymtech/nym/pull/1053) ([jstuczyn](https://github.com/jstuczyn))
- Feature/tokio console [\#1052](https://github.com/nymtech/nym/pull/1052) ([durch](https://github.com/durch))
- Implemented beta clippy lint recommendations [\#1051](https://github.com/nymtech/nym/pull/1051) ([jstuczyn](https://github.com/jstuczyn))
- add new function to update profit percentage [\#1050](https://github.com/nymtech/nym/pull/1050) ([fmtabbara](https://github.com/fmtabbara))
- Upgrade Clap and use declarative argument parsing for nym-mixnode [\#1047](https://github.com/nymtech/nym/pull/1047) ([octol](https://github.com/octol))
- Feature/additional bond validation [\#1046](https://github.com/nymtech/nym/pull/1046) ([fmtabbara](https://github.com/fmtabbara))
- Fix clippy on relevant lints [\#1044](https://github.com/nymtech/nym/pull/1044) ([neacsu](https://github.com/neacsu))
- Bump shelljs from 0.8.4 to 0.8.5 in /contracts/basic-bandwidth-generation [\#1043](https://github.com/nymtech/nym/pull/1043) ([dependabot[bot]](https://github.com/apps/dependabot))
- Endpoint for rewarded set inclusion probabilities [\#1042](https://github.com/nymtech/nym/pull/1042) ([durch](https://github.com/durch))
- Bump follow-redirects from 1.14.4 to 1.14.7 in /contracts/basic-bandwidth-generation [\#1041](https://github.com/nymtech/nym/pull/1041) ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump follow-redirects from 1.14.5 to 1.14.7 in /testnet-faucet [\#1040](https://github.com/nymtech/nym/pull/1040) ([dependabot[bot]](https://github.com/apps/dependabot))
- Feature/node settings update [\#1036](https://github.com/nymtech/nym/pull/1036) ([fmtabbara](https://github.com/fmtabbara))
- Migrate to cw-storage-plus 0.11.1 [\#1035](https://github.com/nymtech/nym/pull/1035) ([durch](https://github.com/durch))
- Bump @openzeppelin/contracts from 4.4.1 to 4.4.2 in /contracts/basic-bandwidth-generation [\#1034](https://github.com/nymtech/nym/pull/1034) ([dependabot[bot]](https://github.com/apps/dependabot))
- Feature/configurable wallet [\#1033](https://github.com/nymtech/nym/pull/1033) ([neacsu](https://github.com/neacsu))
- Feature/downcast reward estimation [\#1031](https://github.com/nymtech/nym/pull/1031) ([durch](https://github.com/durch))
- Wallet UI updates [\#1028](https://github.com/nymtech/nym/pull/1028) ([fmtabbara](https://github.com/fmtabbara))
- Remove migration code [\#1027](https://github.com/nymtech/nym/pull/1027) ([neacsu](https://github.com/neacsu))
- Chore/stricter dependency requirements [\#1025](https://github.com/nymtech/nym/pull/1025) ([jstuczyn](https://github.com/jstuczyn))
- Feature/validator api client endpoints [\#1024](https://github.com/nymtech/nym/pull/1024) ([jstuczyn](https://github.com/jstuczyn))
- Updated cosmrs to 0.4.1 [\#1023](https://github.com/nymtech/nym/pull/1023) ([jstuczyn](https://github.com/jstuczyn))
- Feature/testnet deploy scripts [\#1022](https://github.com/nymtech/nym/pull/1022) ([mfahampshire](https://github.com/mfahampshire))
- Changed wallet's client to a full validator client [\#1021](https://github.com/nymtech/nym/pull/1021) ([jstuczyn](https://github.com/jstuczyn))
- Fix 404 link [\#1020](https://github.com/nymtech/nym/pull/1020) ([RiccardoMasutti](https://github.com/RiccardoMasutti))
- Feature/additional mixnode endpoints [\#1019](https://github.com/nymtech/nym/pull/1019) ([jstuczyn](https://github.com/jstuczyn))
- Introduced denom check when trying to withdraw vested coins [\#1018](https://github.com/nymtech/nym/pull/1018) ([jstuczyn](https://github.com/jstuczyn))
- Add network defaults for qa [\#1017](https://github.com/nymtech/nym/pull/1017) ([neacsu](https://github.com/neacsu))
- Feature/expanded events [\#1015](https://github.com/nymtech/nym/pull/1015) ([jstuczyn](https://github.com/jstuczyn))
- update frontend to use new profit update api [\#1014](https://github.com/nymtech/nym/pull/1014) ([fmtabbara](https://github.com/fmtabbara))
- Feature/node state endpoint [\#1013](https://github.com/nymtech/nym/pull/1013) ([jstuczyn](https://github.com/jstuczyn))
- Feature/hourly set updates [\#1012](https://github.com/nymtech/nym/pull/1012) ([durch](https://github.com/durch))
- Feature/remove unused profit margin [\#1011](https://github.com/nymtech/nym/pull/1011) ([neacsu](https://github.com/neacsu))
- Feature/explorer node status [\#1010](https://github.com/nymtech/nym/pull/1010) ([jstuczyn](https://github.com/jstuczyn))
- Use serial integer instead of random [\#1009](https://github.com/nymtech/nym/pull/1009) ([durch](https://github.com/durch))
- Feature/configure profit [\#1008](https://github.com/nymtech/nym/pull/1008) ([neacsu](https://github.com/neacsu))
- Feature/fix gateway sign [\#1004](https://github.com/nymtech/nym/pull/1004) ([neacsu](https://github.com/neacsu))
- Fix clippy [\#1003](https://github.com/nymtech/nym/pull/1003) ([neacsu](https://github.com/neacsu))
- Update wallet version [\#998](https://github.com/nymtech/nym/pull/998) ([tommyv1987](https://github.com/tommyv1987))
- Fix wallet build instructions [\#997](https://github.com/nymtech/nym/pull/997) ([tommyv1987](https://github.com/tommyv1987))
- Make the separation between testnet-mode and erc20 bandwidth mode clearer [\#994](https://github.com/nymtech/nym/pull/994) ([neacsu](https://github.com/neacsu))
- Bump @openzeppelin/contracts from 3.4.0 to 4.4.1 in /contracts/basic-bandwidth-generation [\#983](https://github.com/nymtech/nym/pull/983) ([dependabot[bot]](https://github.com/apps/dependabot))
- Feature/implicit runtime [\#973](https://github.com/nymtech/nym/pull/973) ([jstuczyn](https://github.com/jstuczyn))
- Differentiate staking and ownership [\#961](https://github.com/nymtech/nym/pull/961) ([durch](https://github.com/durch))
## [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:**
@@ -384,7 +397,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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:**
@@ -399,7 +412,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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)
@@ -409,7 +422,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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)
@@ -465,10 +478,10 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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))
@@ -481,7 +494,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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))
@@ -499,7 +512,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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))
@@ -515,7 +528,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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))
@@ -539,8 +552,8 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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))
@@ -549,14 +562,14 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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))
@@ -568,7 +581,7 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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))
@@ -605,6 +618,4 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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
+1510 -1062
View File
File diff suppressed because it is too large Load Diff
+25 -11
View File
@@ -22,22 +22,29 @@ members = [
"clients/native",
"clients/native/websocket-requests",
"clients/socks5",
"common/bandwidth-claim-contract",
"common/client-libs/gateway-client",
"common/client-libs/mixnet-client",
"common/client-libs/validator-client",
"common/credential-storage",
"common/client-connections",
"common/coconut-interface",
"common/commands",
"common/config",
"common/credentials",
"common/crypto",
"common/crypto/dkg",
"common/execute",
"common/bandwidth-claim-contract",
"common/build-information",
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
"common/cosmwasm-smart-contracts/coconut-dkg",
"common/cosmwasm-smart-contracts/contracts-common",
"common/cosmwasm-smart-contracts/mixnet-contract",
"common/cosmwasm-smart-contracts/multisig-contract",
"common/cosmwasm-smart-contracts/vesting-contract",
"common/credential-storage",
"common/credentials",
"common/crypto",
"common/crypto/dkg",
"common/execute",
"common/inclusion-probability",
"common/ledger",
"common/logging",
"common/mixnode-common",
"common/network-defaults",
"common/nonexhaustive-delayqueue",
@@ -53,20 +60,26 @@ members = [
"common/nymsphinx/params",
"common/nymsphinx/types",
"common/pemstore",
"common/statistics",
"common/socks5/proxy-helpers",
"common/socks5/requests",
"common/statistics",
"common/task",
"common/topology",
"common/types",
"common/wasm-utils",
"common/completions",
"explorer-api",
"gateway",
"gateway/gateway-requests",
"integrations/bity",
"mixnode",
"service-providers/network-requester",
"service-providers/network-statistics",
"validator-api",
"validator-api/validator-api-requests",
"nym-api",
"nym-api/nym-api-requests",
"nym-outfox",
"tools/nym-cli",
"tools/ts-rs-cli"
]
default-members = [
@@ -74,9 +87,10 @@ default-members = [
"clients/socks5",
"gateway",
"service-providers/network-requester",
"service-providers/network-statistics",
"mixnode",
"validator-api",
"nym-api",
"explorer-api",
]
exclude = ["explorer", "contracts", "tokenomics-py", "clients/webassembly"]
exclude = ["explorer", "contracts", "clients/webassembly", "nym-wallet", "nym-connect"]
+77 -9
View File
@@ -1,11 +1,13 @@
test: build clippy-all cargo-test wasm fmt
test: clippy-all cargo-test wasm fmt
test-all: test cargo-test-expensive
no-clippy: build cargo-test wasm fmt
happy: fmt clippy-happy test
clippy-all: clippy-all-main clippy-all-contracts clippy-all-wallet
clippy-happy: clippy-happy-main clippy-happy-contracts clippy-happy-wallet
cargo-test: test-main test-contracts test-wallet
build: build-contracts build-wallet build-main
fmt: fmt-main fmt-contracts fmt-wallet
clippy-all: clippy-main clippy-coconut clippy-all-contracts clippy-all-wallet clippy-all-connect clippy-all-wasm-client
clippy-happy: clippy-happy-main clippy-happy-contracts clippy-happy-wallet clippy-happy-connect
cargo-test: test-main test-contracts test-wallet test-connect test-coconut test-wasm-client
cargo-test-expensive: test-main-expensive test-contracts-expensive test-wallet-expensive test-connect-expensive test-coconut-expensive
build: build-contracts build-wallet build-main build-connect build-wasm-client
fmt: fmt-main fmt-contracts fmt-wallet fmt-connect fmt-wasm-client
clippy-happy-main:
cargo clippy
@@ -16,8 +18,18 @@ clippy-happy-contracts:
clippy-happy-wallet:
cargo clippy --manifest-path nym-wallet/Cargo.toml
clippy-all-main:
cargo clippy --workspace --all-features -- -D warnings
clippy-happy-connect:
cargo clippy --manifest-path nym-connect/Cargo.toml
clippy-main:
cargo clippy --workspace -- -D warnings
clippy-coconut:
cargo clippy --workspace --features coconut -- -D warnings
clippy-wasm:
cargo clippy --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown --workspace -- -D warnings
clippy-all-contracts:
cargo clippy --workspace --manifest-path contracts/Cargo.toml --all-features --target wasm32-unknown-unknown -- -D warnings
@@ -25,15 +37,46 @@ clippy-all-contracts:
clippy-all-wallet:
cargo clippy --workspace --manifest-path nym-wallet/Cargo.toml --all-features -- -D warnings
clippy-all-connect:
cargo clippy --workspace --manifest-path nym-connect/Cargo.toml --all-features -- -D warnings
clippy-all-wasm-client:
cargo clippy --workspace --manifest-path clients/webassembly/Cargo.toml --all-features --target wasm32-unknown-unknown -- -D warnings
test-main:
cargo test --all-features --workspace
cargo test --workspace
test-coconut:
cargo test --workspace --features coconut
test-main-expensive:
cargo test --workspace -- --ignored
test-coconut-expensive:
cargo test --workspace --features coconut -- --ignored
test-contracts:
cargo test --manifest-path contracts/Cargo.toml --all-features
test-contracts-expensive:
cargo test --manifest-path contracts/Cargo.toml --all-features -- --ignored
test-wallet:
cargo test --manifest-path nym-wallet/Cargo.toml --all-features
test-wallet-expensive:
cargo test --manifest-path nym-wallet/Cargo.toml --all-features -- --ignored
test-wasm-client:
cargo test --workspace --manifest-path clients/webassembly/Cargo.toml --all-features
test-connect:
cargo test --manifest-path nym-connect/Cargo.toml --all-features
test-connect-expensive:
cargo test --manifest-path nym-connect/Cargo.toml --all-features -- --ignored
build-main:
cargo build --workspace
@@ -43,6 +86,18 @@ build-contracts:
build-wallet:
cargo build --manifest-path nym-wallet/Cargo.toml --workspace
build-connect:
cargo build --manifest-path nym-connect/Cargo.toml --workspace
build-explorer-api:
cargo build --manifest-path explorer-api/Cargo.toml --workspace
build-wasm-client:
cargo build --manifest-path clients/webassembly/Cargo.toml --workspace --target wasm32-unknown-unknown
build-nym-cli:
cargo build --release --manifest-path tools/nym-cli/Cargo.toml
fmt-main:
cargo fmt --all
@@ -52,5 +107,18 @@ fmt-contracts:
fmt-wallet:
cargo fmt --manifest-path nym-wallet/Cargo.toml --all
fmt-connect:
cargo fmt --manifest-path nym-connect/Cargo.toml --all
fmt-wasm-client:
cargo fmt --manifest-path clients/webassembly/Cargo.toml --all
wasm:
RUSTFLAGS='-C link-arg=-s' cargo build --manifest-path contracts/Cargo.toml --release --target wasm32-unknown-unknown
mixnet-opt: wasm
cd contracts/mixnet && make opt
generate-typescript:
cd tools/ts-rs-cli && cargo run && cd ../..
yarn types:lint:fix
+2 -2
View File
@@ -9,8 +9,8 @@ The platform is composed of multiple Rust crates. Top-level executable binary cr
* nym-mixnode - shuffles [Sphinx](https://github.com/nymtech/sphinx) packets together to provide privacy against network-level attackers.
* nym-client - an executable which you can build into your own applications. Use it for interacting with Nym nodes.
* nym-socks5-client - a Socks5 proxy you can run on your machine, and use with existing applications
* nym-gateway - acts sort of like a mailbox for mixnet messages, removing the need for directly delivery to potentially offline or firewalled devices.
* nym-socks5-client - a Socks5 proxy you can run on your machine and use with existing applications.
* nym-gateway - acts sort of like a mailbox for mixnet messages, which removes the need for direct delivery to potentially offline or firewalled devices.
* nym-network-monitor - sends packets through the full system to check that they are working as expected, and stores node uptime histories as the basis of a rewards system ("mixmining" or "proof-of-mixing").
* nym-explorer - a (projected) block explorer and (existing) mixnet viewer.
* nym-wallet - a desktop wallet implemented using the [Tauri](https://tauri.studio/en/docs/about/intro) framework.
+8
View File
@@ -0,0 +1,8 @@
Update fonts by doing the following:
1. Go to https://fonts.google.com/specimen/Open+Sans
2. Add all the styles you want and select `@import`
3. Copy the url (e.g. curl https://fonts.googleapis.com/css2\?family\=Open+Sans:ital,wght@0,300\;0,400\;0,500\;0,600\;0,700\;0,800\;1,300\;1,400\;1,500\;1,600\;1,700\;1,800\&display\=swap)
4. Run `curl curl https://fonts.googleapis.com/css2\?family\=Open+Sans:ital,wght@0,300\;0,400\;0,500\;0,600\;0,700\;0,800\;1,300\;1,400\;1,500\;1,600\;1,700\;1,800\&display\=swap`
5. Use the response as the CSS import directives and download the font files for each font weight
6. Remember to delete any old font files
+96
View File
@@ -0,0 +1,96 @@
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 300;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk5hkaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 400;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk8ZkaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 500;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk_RkaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 600;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkxhjaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 700;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0RkyFjaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: italic;
font-weight: 800;
font-stretch: normal;
font-display: swap;
src: url(./memQYaGs126MiZpBA-UFUIcVXSCEkx2cmqvXlWq8tWZ0Pw86hd0Rk0ZjaVc.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 300;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsiH0C4n.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 400;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjZ0C4n.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 500;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsjr0C4n.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 600;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsgH1y4n.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 700;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsg-1y4n.ttf) format('truetype');
}
@font-face {
font-family: 'Open Sans';
font-style: normal;
font-weight: 800;
font-stretch: normal;
font-display: swap;
src: url(./memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgshZ1y4n.ttf) format('truetype');
}
+7
View File
@@ -0,0 +1,7 @@
<svg viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M171.7,30.3001 C132.7,-8.7999 69.3001,-8.7999 30.3001,30.3001 C-8.7999,69.4001 -8.7999,132.7 30.3001,171.7 C69.4001,210.8 132.7,210.8 171.7,171.7 C210.8,132.7 210.8,69.3001 171.7,30.3001 Z M163.1,163.1 C128.8,197.4 73.1001,197.4 38.8001,163.1 C4.5001,128.8 4.5001,73.1001 38.8001,38.8001 C73.1001,4.5001 128.8,4.5001 163.1,38.8001 C197.5,73.2001 197.5,128.8 163.1,163.1 Z" id="Shape" fill="#fff"></path>
<path d="M163.1,38.9 C128.8,4.60005 73.1002,4.60005 38.8002,38.9 C4.50019,73.2 4.50019,128.9 38.8002,163.2 C73.1002,197.5 128.8,197.5 163.1,163.2 C197.5,128.8 197.5,73.2 163.1,38.9 Z" id="Shape" fill="#000"></path>
<g id="T" transform="translate(25, 25) scale(5,5)">
<path d="M18.4804688,24 C19.203125,24 19.7182617,23.8608398 20.0258789,23.5825195 C20.3334961,23.3041992 20.4873047,22.9453125 20.4873047,22.5058594 C20.4873047,22.0566406 20.3334961,21.6928711 20.0258789,21.4145508 C19.7182617,21.1362305 19.203125,20.9970703 18.4804688,20.9970703 L18.4804688,20.9970703 L16.4589844,20.9970703 L16.4589844,9.24902344 L19.7548828,9.24902344 L19.7548828,12.0908203 C19.7548828,12.8134766 19.894043,13.3286133 20.1723633,13.6362305 C20.4506836,13.9438477 20.8095703,14.0976562 21.2490234,14.0976562 C21.6982422,14.0976562 22.0620117,13.9438477 22.340332,13.6362305 C22.6186523,13.3286133 22.7578125,12.8134766 22.7578125,12.0908203 L22.7578125,12.0908203 L22.7578125,6.24609375 L7.20117188,6.23144531 L7.20117188,12.0908203 C7.20117188,12.8134766 7.34033203,13.3286133 7.61865234,13.6362305 C7.89697266,13.9438477 8.25585938,14.0976562 8.6953125,14.0976562 C9.14453125,14.0976562 9.50830078,13.9438477 9.78662109,13.6362305 C10.0649414,13.3286133 10.2041016,12.8134766 10.2041016,12.0908203 L10.2041016,12.0908203 L10.2041016,9.24902344 L13.4560547,9.24902344 L13.4560547,20.9970703 L11.4492188,20.9970703 C10.7265625,20.9970703 10.2114258,21.1362305 9.90380859,21.4145508 C9.59619141,21.6928711 9.44238281,22.0517578 9.44238281,22.4912109 C9.44238281,22.9404297 9.59619141,23.3041992 9.90380859,23.5825195 C10.2114258,23.8608398 10.7265625,24 11.4492188,24 L11.4492188,24 L18.4804688,24 Z" id="T" fill="#fff"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

+1 -1
View File
@@ -1,4 +1,4 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M170.7 29.3001C131.7 -9.7999 68.3001 -9.7999 29.3001 29.3001C-9.7999 68.4001 -9.7999 131.7 29.3001 170.7C68.4001 209.8 131.7 209.8 170.7 170.7C209.8 131.7 209.8 68.3001 170.7 29.3001ZM162.1 162.1C127.8 196.4 72.1001 196.4 37.8001 162.1C3.5001 127.8 3.5001 72.1001 37.8001 37.8001C72.1001 3.5001 127.8 3.5001 162.1 37.8001C196.5 72.2001 196.5 127.8 162.1 162.1Z" fill="white"/>
<path d="M162.1 37.9C127.8 3.60005 72.1002 3.60005 37.8002 37.9C3.50019 72.2 3.50019 127.9 37.8002 162.2C72.1002 196.5 127.8 196.5 162.1 162.2C196.5 127.8 196.5 72.2 162.1 37.9ZM63.0002 170.7C56.8002 167.4 51.1002 163.2 46.1002 158.4V41.7C51.3002 36.7 57.2002 32.5 63.6002 29.1L137 140.9V29.3C143.2 32.6 148.9 36.8 153.9 41.6V158.3C148.7 163.3 142.8 167.5 136.4 170.9L63.0002 59.1V170.7Z" fill="#070B15"/>
<path d="M154 158.3V41.7C148.9 36.9 143.2 32.7 137.1 29.4V140.9L63.5 29C57.1 32.4 51.2 36.6 46 41.6V158.3C51.1 163.1 56.8 167.3 62.9 170.6V59.1L136.5 171C142.9 167.6 148.8 163.3 154 158.3Z" fill="white"/>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

+7
View File
@@ -0,0 +1,7 @@
<svg viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M171.7,30.3001 C132.7,-8.7999 69.3001,-8.7999 30.3001,30.3001 C-8.7999,69.4001 -8.7999,132.7 30.3001,171.7 C69.4001,210.8 132.7,210.8 171.7,171.7 C210.8,132.7 210.8,69.3001 171.7,30.3001 Z M163.1,163.1 C128.8,197.4 73.1001,197.4 38.8001,163.1 C4.5001,128.8 4.5001,73.1001 38.8001,38.8001 C73.1001,4.5001 128.8,4.5001 163.1,38.8001 C197.5,73.2001 197.5,128.8 163.1,163.1 Z" id="Shape" fill="#141521"></path>
<path d="M163.1,38.9 C128.8,4.60005 73.1002,4.60005 38.8002,38.9 C4.50019,73.2 4.50019,128.9 38.8002,163.2 C73.1002,197.5 128.8,197.5 163.1,163.2 C197.5,128.8 197.5,73.2 163.1,38.9 Z" id="Shape" fill="#FFFFFF"></path>
<g id="T" transform="translate(25, 25) scale(5,5)">
<path d="M18.4804688,24 C19.203125,24 19.7182617,23.8608398 20.0258789,23.5825195 C20.3334961,23.3041992 20.4873047,22.9453125 20.4873047,22.5058594 C20.4873047,22.0566406 20.3334961,21.6928711 20.0258789,21.4145508 C19.7182617,21.1362305 19.203125,20.9970703 18.4804688,20.9970703 L18.4804688,20.9970703 L16.4589844,20.9970703 L16.4589844,9.24902344 L19.7548828,9.24902344 L19.7548828,12.0908203 C19.7548828,12.8134766 19.894043,13.3286133 20.1723633,13.6362305 C20.4506836,13.9438477 20.8095703,14.0976562 21.2490234,14.0976562 C21.6982422,14.0976562 22.0620117,13.9438477 22.340332,13.6362305 C22.6186523,13.3286133 22.7578125,12.8134766 22.7578125,12.0908203 L22.7578125,12.0908203 L22.7578125,6.24609375 L7.20117188,6.23144531 L7.20117188,12.0908203 C7.20117188,12.8134766 7.34033203,13.3286133 7.61865234,13.6362305 C7.89697266,13.9438477 8.25585938,14.0976562 8.6953125,14.0976562 C9.14453125,14.0976562 9.50830078,13.9438477 9.78662109,13.6362305 C10.0649414,13.3286133 10.2041016,12.8134766 10.2041016,12.0908203 L10.2041016,12.0908203 L10.2041016,9.24902344 L13.4560547,9.24902344 L13.4560547,20.9970703 L11.4492188,20.9970703 C10.7265625,20.9970703 10.2114258,21.1362305 9.90380859,21.4145508 C9.59619141,21.6928711 9.44238281,22.0517578 9.44238281,22.4912109 C9.44238281,22.9404297 9.59619141,23.3041992 9.90380859,23.5825195 C10.2114258,23.8608398 10.7265625,24 11.4492188,24 L11.4492188,24 L18.4804688,24 Z" id="T" fill="#000" fill-rule="nonzero"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

+1 -1
View File
@@ -1,4 +1,4 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M170.7 29.3001C131.7 -9.7999 68.3001 -9.7999 29.3001 29.3001C-9.7999 68.4001 -9.7999 131.7 29.3001 170.7C68.4001 209.8 131.7 209.8 170.7 170.7C209.8 131.7 209.8 68.3001 170.7 29.3001ZM162.1 162.1C127.8 196.4 72.1001 196.4 37.8001 162.1C3.5001 127.8 3.5001 72.1001 37.8001 37.8001C72.1001 3.5001 127.8 3.5001 162.1 37.8001C196.5 72.2001 196.5 127.8 162.1 162.1Z" fill="#141521"/>
<path d="M162.1 37.9C127.8 3.60005 72.1002 3.60005 37.8002 37.9C3.50019 72.2 3.50019 127.9 37.8002 162.2C72.1002 196.5 127.8 196.5 162.1 162.2C196.5 127.8 196.5 72.2 162.1 37.9ZM63.0002 170.7C56.8002 167.4 51.1002 163.2 46.1002 158.4V41.7C51.3002 36.7 57.2002 32.5 63.6002 29.1L137 140.9V29.3C143.2 32.6 148.9 36.8 153.9 41.6V158.3C148.7 163.3 142.8 167.5 136.4 170.9L63.0002 59.1V170.7Z" fill="white"/>
<path d="M154 158.3V41.7C148.9 36.9 143.2 32.7 137.1 29.4V140.9L63.5 29C57.1 32.4 51.2 36.6 46 41.6V158.3C51.1 163.1 56.8 167.3 62.9 170.6V59.1L136.5 171C142.9 167.6 148.8 163.3 154 158.3Z" fill="#141521"/>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

+57 -6
View File
@@ -1,35 +1,86 @@
[package]
name = "client-core"
version = "1.0.1"
version = "1.1.4"
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
[dependencies]
dirs = "3.0"
async-trait = { version = "0.1.58" }
dirs = "4.0"
dashmap = "5.4.0"
futures = "0.3"
humantime-serde = "1.0"
log = "0.4"
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
serde = { version = "1.0", features = ["derive"] }
sled = "0.34"
tokio = { version = "1.19.1", features = ["macros"] }
serde_json = "1.0.89"
tap = "1.0.1"
thiserror = "1.0.34"
url = { version ="2.2", features = ["serde"] }
tokio = { version = "1.21.2", features = ["macros"]}
time = "0.3.17"
# internal
config = { path = "../../common/config" }
client-connections = { path = "../../common/client-connections" }
crypto = { path = "../../common/crypto" }
gateway-client = { path = "../../common/client-libs/gateway-client" }
#gateway-client = { path = "../../common/client-libs/gateway-client", default-features = false, features = ["wasm", "coconut"] }
gateway-requests = { path = "../../gateway/gateway-requests" }
nonexhaustive-delayqueue = { path = "../../common/nonexhaustive-delayqueue" }
nymsphinx = { path = "../../common/nymsphinx" }
pemstore = { path = "../../common/pemstore" }
topology = { path = "../../common/topology" }
validator-client = { path = "../../common/client-libs/validator-client" }
validator-client = { path = "../../common/client-libs/validator-client", default-features = false }
task = { path = "../../common/task" }
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream]
version = "0.1.9"
features = ["time"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
version = "1.21.2"
features = ["time"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx]
version = "0.6.2"
features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"]
optional = true
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen-futures]
version = "0.4"
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen]
version = "0.2.83"
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-timer]
git = "https://github.com/mmsinclair/wasm-timer"
rev = "b9d1a54ad514c2f230a026afe0dde341e98cd7b6"
[target."cfg(target_arch = \"wasm32\")".dependencies.gloo-timers]
version = "0.2.4"
features = ["futures"]
[target."cfg(target_arch = \"wasm32\")".dependencies.wasm-utils]
path = "../../common/wasm-utils"
[target."cfg(target_arch = \"wasm32\")".dependencies.time]
version = "0.3.17"
features = ["wasm-bindgen"]
[dev-dependencies]
tempfile = "3.1.0"
[build-dependencies]
tokio = { version = "1.21.2", features = ["rt-multi-thread", "macros"] }
sqlx = { version = "0.6.2", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
[features]
coconut = ["gateway-client/coconut", "gateway-requests/coconut"]
default = []
fs-surb-storage = ["sqlx"]
wasm = ["gateway-client/wasm"]
coconut = ["gateway-client/coconut", "gateway-requests/coconut"]
+31
View File
@@ -0,0 +1,31 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
#[tokio::main]
async fn main() {
#[cfg(feature = "fs-surb-storage")]
{
use sqlx::{Connection, SqliteConnection};
use std::env;
let out_dir = env::var("OUT_DIR").unwrap();
let database_path = format!("{}/fs-surbs-example.sqlite", out_dir);
let mut conn = SqliteConnection::connect(&format!("sqlite://{}?mode=rwc", database_path))
.await
.expect("Failed to create SQLx database connection");
sqlx::migrate!("./fs_surbs_migrations")
.run(&mut conn)
.await
.expect("Failed to perform SQLx migrations");
#[cfg(target_family = "unix")]
println!("cargo:rustc-env=DATABASE_URL=sqlite://{}", &database_path);
#[cfg(target_family = "windows")]
// 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);
}
}
@@ -0,0 +1,40 @@
CREATE TABLE status
(
flush_in_progress INTEGER NOT NULL,
previous_flush_timestamp INTEGER NOT NULL,
client_in_use INTEGER NOT NULL
);
CREATE TABLE reply_surb_storage_metadata
(
min_reply_surb_threshold INTEGER NOT NULL,
max_reply_surb_threshold INTEGER NOT NULL
);
CREATE TABLE sender_tag
(
recipient BLOB NOT NULL UNIQUE,
tag BLOB NOT NULL UNIQUE
);
CREATE TABLE reply_key
(
key_digest BLOB NOT NULL UNIQUE,
reply_key BLOB NOT NULL UNIQUE,
sent_at_timestamp INTEGER NOT NULL
);
CREATE TABLE reply_surb_sender
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
last_sent_timestamp INTEGER NOT NULL,
tag BLOB NOT NULL UNIQUE
);
CREATE TABLE reply_surb
(
reply_surb_sender_id INTEGER NOT NULL,
reply_surb BLOB NOT NULL,
FOREIGN KEY (reply_surb_sender_id) REFERENCES reply_surb_sender (id)
);
@@ -0,0 +1,496 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::cover_traffic_stream::LoopCoverTrafficStream;
use crate::client::inbound_messages::{InputMessage, InputMessageReceiver, InputMessageSender};
use crate::client::key_manager::KeyManager;
use crate::client::mix_traffic::{BatchMixMessageSender, MixTrafficController};
use crate::client::real_messages_control;
use crate::client::real_messages_control::RealMessagesController;
use crate::client::received_buffer::{
ReceivedBufferRequestReceiver, ReceivedBufferRequestSender, ReceivedMessagesBufferController,
};
use crate::client::replies::reply_controller;
use crate::client::replies::reply_controller::{ReplyControllerReceiver, ReplyControllerSender};
use crate::client::replies::reply_storage::{
CombinedReplyStorage, PersistentReplyStorage, ReplyStorageBackend, SentReplyKeys,
};
use crate::client::topology_control::{
TopologyAccessor, TopologyRefresher, TopologyRefresherConfig,
};
use crate::config::{Config, DebugConfig, GatewayEndpointConfig};
use crate::error::ClientCoreError;
use crate::spawn_future;
use client_connections::{ConnectionCommandReceiver, ConnectionCommandSender, LaneQueueLengths};
use crypto::asymmetric::{encryption, identity};
use futures::channel::mpsc;
use gateway_client::bandwidth::BandwidthController;
use gateway_client::{
AcknowledgementReceiver, AcknowledgementSender, GatewayClient, MixnetMessageReceiver,
MixnetMessageSender,
};
use log::{debug, info};
use nymsphinx::acknowledgements::AckKey;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::addressing::nodes::NodeIdentity;
use std::sync::Arc;
use std::time::Duration;
use tap::TapFallible;
use task::{TaskClient, TaskManager};
use url::Url;
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
pub mod non_wasm_helpers;
pub struct ClientInput {
pub connection_command_sender: ConnectionCommandSender,
pub input_sender: InputMessageSender,
}
pub struct ClientOutput {
pub shared_lane_queue_lengths: LaneQueueLengths,
pub received_buffer_request_sender: ReceivedBufferRequestSender,
}
pub enum ClientInputStatus {
AwaitingProducer { client_input: ClientInput },
Connected,
}
impl ClientInputStatus {
pub fn register_producer(&mut self) -> ClientInput {
match std::mem::replace(self, ClientInputStatus::Connected) {
ClientInputStatus::AwaitingProducer { client_input } => client_input,
ClientInputStatus::Connected => panic!("producer was already registered before"),
}
}
}
pub enum ClientOutputStatus {
AwaitingConsumer { client_output: ClientOutput },
Connected,
}
impl ClientOutputStatus {
pub fn register_consumer(&mut self) -> ClientOutput {
match std::mem::replace(self, ClientOutputStatus::Connected) {
ClientOutputStatus::AwaitingConsumer { client_output } => client_output,
ClientOutputStatus::Connected => panic!("consumer was already registered before"),
}
}
}
pub struct BaseClientBuilder<'a, B> {
// due to wasm limitations I had to split it like this : (
gateway_config: &'a GatewayEndpointConfig,
debug_config: &'a DebugConfig,
disabled_credentials: bool,
nym_api_endpoints: Vec<Url>,
reply_storage_backend: B,
bandwidth_controller: Option<BandwidthController>,
key_manager: KeyManager,
}
impl<'a, B> BaseClientBuilder<'a, B>
where
B: ReplyStorageBackend + Send + Sync + 'static,
{
pub fn new_from_base_config<T>(
base_config: &'a Config<T>,
key_manager: KeyManager,
bandwidth_controller: Option<BandwidthController>,
reply_storage_backend: B,
) -> BaseClientBuilder<'a, B> {
BaseClientBuilder {
gateway_config: base_config.get_gateway_endpoint_config(),
debug_config: base_config.get_debug_config(),
disabled_credentials: base_config.get_disabled_credentials_mode(),
nym_api_endpoints: base_config.get_nym_api_endpoints(),
bandwidth_controller,
reply_storage_backend,
key_manager,
}
}
pub fn new(
gateway_config: &'a GatewayEndpointConfig,
debug_config: &'a DebugConfig,
key_manager: KeyManager,
bandwidth_controller: Option<BandwidthController>,
reply_storage_backend: B,
disabled_credentials: bool,
nym_api_endpoints: Vec<Url>,
) -> BaseClientBuilder<'a, B> {
BaseClientBuilder {
gateway_config,
debug_config,
disabled_credentials,
nym_api_endpoints,
reply_storage_backend,
bandwidth_controller,
key_manager,
}
}
pub fn as_mix_recipient(&self) -> Recipient {
Recipient::new(
*self.key_manager.identity_keypair().public_key(),
*self.key_manager.encryption_keypair().public_key(),
// TODO: below only works under assumption that gateway address == gateway id
// (which currently is true)
NodeIdentity::from_base58_string(&self.gateway_config.gateway_id).unwrap(),
)
}
// future constantly pumping loop cover traffic at some specified average rate
// the pumped traffic goes to the MixTrafficController
fn start_cover_traffic_stream(
debug_config: &DebugConfig,
ack_key: Arc<AckKey>,
self_address: Recipient,
topology_accessor: TopologyAccessor,
mix_tx: BatchMixMessageSender,
shutdown: TaskClient,
) {
info!("Starting loop cover traffic stream...");
let mut stream = LoopCoverTrafficStream::new(
ack_key,
debug_config.average_ack_delay,
debug_config.average_packet_delay,
debug_config.loop_cover_traffic_average_delay,
mix_tx,
self_address,
topology_accessor,
);
if let Some(size) = debug_config.use_extended_packet_size {
log::debug!("Setting extended packet size: {:?}", size);
stream.set_custom_packet_size(size.into());
}
stream.start_with_shutdown(shutdown);
}
#[allow(clippy::too_many_arguments)]
fn start_real_traffic_controller(
controller_config: real_messages_control::Config,
topology_accessor: TopologyAccessor,
ack_receiver: AcknowledgementReceiver,
input_receiver: InputMessageReceiver,
mix_sender: BatchMixMessageSender,
reply_storage: CombinedReplyStorage,
reply_controller_sender: ReplyControllerSender,
reply_controller_receiver: ReplyControllerReceiver,
lane_queue_lengths: LaneQueueLengths,
client_connection_rx: ConnectionCommandReceiver,
shutdown: TaskClient,
) {
info!("Starting real traffic stream...");
RealMessagesController::new(
controller_config,
ack_receiver,
input_receiver,
mix_sender,
topology_accessor,
reply_storage,
reply_controller_sender,
reply_controller_receiver,
lane_queue_lengths,
client_connection_rx,
)
.start_with_shutdown(shutdown);
}
// buffer controlling all messages fetched from provider
// required so that other components would be able to use them (say the websocket)
fn start_received_messages_buffer_controller(
local_encryption_keypair: Arc<encryption::KeyPair>,
query_receiver: ReceivedBufferRequestReceiver,
mixnet_receiver: MixnetMessageReceiver,
reply_key_storage: SentReplyKeys,
reply_controller_sender: ReplyControllerSender,
shutdown: TaskClient,
) {
info!("Starting received messages buffer controller...");
ReceivedMessagesBufferController::new(
local_encryption_keypair,
query_receiver,
mixnet_receiver,
reply_key_storage,
reply_controller_sender,
)
.start_with_shutdown(shutdown)
}
async fn start_gateway_client(
&mut self,
mixnet_message_sender: MixnetMessageSender,
ack_sender: AcknowledgementSender,
shutdown: TaskClient,
) -> Result<GatewayClient, ClientCoreError> {
let gateway_id = self.gateway_config.gateway_id.clone();
if gateway_id.is_empty() {
return Err(ClientCoreError::GatewayIdUnknown);
}
let gateway_owner = self.gateway_config.gateway_owner.clone();
if gateway_owner.is_empty() {
return Err(ClientCoreError::GatewayOwnerUnknown);
}
let gateway_address = self.gateway_config.gateway_listener.clone();
if gateway_address.is_empty() {
return Err(ClientCoreError::GatwayAddressUnknown);
}
let gateway_identity = identity::PublicKey::from_base58_string(gateway_id)
.map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?;
// disgusting wasm workaround since there's no key persistence there (nor `client init`)
let shared_key = if self.key_manager.gateway_key_set() {
Some(self.key_manager.gateway_shared_key())
} else {
None
};
let mut gateway_client = GatewayClient::new(
gateway_address,
self.key_manager.identity_keypair(),
gateway_identity,
gateway_owner,
shared_key,
mixnet_message_sender,
ack_sender,
self.debug_config.gateway_response_timeout,
self.bandwidth_controller.take(),
shutdown,
);
gateway_client.set_disabled_credentials_mode(self.disabled_credentials);
gateway_client
.authenticate_and_start()
.await
.tap_err(|err| {
log::error!("Could not authenticate and start up the gateway connection - {err}")
})?;
Ok(gateway_client)
}
// future responsible for periodically polling directory server and updating
// the current global view of topology
async fn start_topology_refresher(
nym_api_urls: Vec<Url>,
refresh_rate: Duration,
topology_accessor: TopologyAccessor,
shutdown: TaskClient,
) -> Result<(), ClientCoreError> {
let topology_refresher_config = TopologyRefresherConfig::new(
nym_api_urls,
refresh_rate,
env!("CARGO_PKG_VERSION").to_string(),
);
let mut topology_refresher =
TopologyRefresher::new(topology_refresher_config, topology_accessor);
// before returning, block entire runtime to refresh the current network view so that any
// components depending on topology would see a non-empty view
info!("Obtaining initial network topology");
topology_refresher.refresh().await;
if let Err(err) = topology_refresher.ensure_topology_is_routable().await {
log::error!(
"The current network topology seem to be insufficient to route any packets through \
- check if enough nodes and a gateway are online - source: {err}"
);
return Err(ClientCoreError::InsufficientNetworkTopology(err));
}
info!("Starting topology refresher...");
topology_refresher.start_with_shutdown(shutdown);
Ok(())
}
// controller for sending sphinx packets to mixnet (either real traffic or cover traffic)
// TODO: if we want to send control messages to gateway_client, this CAN'T take the ownership
// over it. Perhaps GatewayClient needs to be thread-shareable or have some channel for
// requests?
fn start_mix_traffic_controller(
gateway_client: GatewayClient,
shutdown: TaskClient,
) -> BatchMixMessageSender {
info!("Starting mix traffic controller...");
let (mix_traffic_controller, mix_tx) = MixTrafficController::new(gateway_client);
mix_traffic_controller.start_with_shutdown(shutdown);
mix_tx
}
async fn setup_persistent_reply_storage(
backend: B,
shutdown: TaskClient,
) -> Result<CombinedReplyStorage, ClientCoreError>
where
<B as ReplyStorageBackend>::StorageError: Sync + Send,
{
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),
})?;
let store_clone = mem_store.clone();
spawn_future(async move {
persistent_storage
.flush_on_shutdown(store_clone, shutdown)
.await
});
Ok(mem_store)
}
pub async fn start_base(mut self) -> Result<BaseClient, ClientCoreError>
where
<B as ReplyStorageBackend>::StorageError: Sync + Send,
{
info!("Starting nym client");
// channels for inter-component communication
// TODO: make the channels be internally created by the relevant components
// rather than creating them here, so say for example the buffer controller would create the request channels
// and would allow anyone to clone the sender channel
// unwrapped_sphinx_sender is the transmitter of mixnet messages received from the gateway
// unwrapped_sphinx_receiver is the receiver for said messages - used by ReceivedMessagesBuffer
let (mixnet_messages_sender, mixnet_messages_receiver) = mpsc::unbounded();
// used for announcing connection or disconnection of a channel for pushing re-assembled messages to
let (received_buffer_request_sender, received_buffer_request_receiver) = mpsc::unbounded();
// channels responsible for controlling real messages
let (input_sender, input_receiver) = tokio::sync::mpsc::channel::<InputMessage>(1);
// channels responsible for controlling ack messages
let (ack_sender, ack_receiver) = mpsc::unbounded();
let shared_topology_accessor = TopologyAccessor::new();
// Shutdown notifier for signalling tasks to stop
let task_manager = TaskManager::default();
// channels responsible for dealing with reply-related fun
let (reply_controller_sender, reply_controller_receiver) =
reply_controller::requests::new_control_channels();
let self_address = self.as_mix_recipient();
// the components are started in very specific order. Unless you know what you are doing,
// do not change that.
let gateway_client = self
.start_gateway_client(mixnet_messages_sender, ack_sender, task_manager.subscribe())
.await?;
let reply_storage = Self::setup_persistent_reply_storage(
self.reply_storage_backend,
task_manager.subscribe(),
)
.await?;
Self::start_topology_refresher(
self.nym_api_endpoints.clone(),
self.debug_config.topology_refresh_rate,
shared_topology_accessor.clone(),
task_manager.subscribe(),
)
.await?;
Self::start_received_messages_buffer_controller(
self.key_manager.encryption_keypair(),
received_buffer_request_receiver,
mixnet_messages_receiver,
reply_storage.key_storage(),
reply_controller_sender.clone(),
task_manager.subscribe(),
);
// The sphinx_message_sender is the transmitter for any component generating sphinx packets
// that are to be sent to the mixnet. They are used by cover traffic stream and real
// traffic stream.
// The MixTrafficController then sends the actual traffic
let sphinx_message_sender =
Self::start_mix_traffic_controller(gateway_client, task_manager.subscribe());
// Channels that the websocket listener can use to signal downstream to the real traffic
// controller that connections are closed.
let (client_connection_tx, client_connection_rx) = mpsc::unbounded();
// Shared queue length data. Published by the `OutQueueController` in the client, and used
// primarily to throttle incoming connections (e.g socks5 for attached network-requesters)
let shared_lane_queue_lengths = LaneQueueLengths::new();
let mut controller_config = real_messages_control::Config::new(
self.debug_config,
self.key_manager.ack_key(),
self_address,
);
if let Some(size) = self.debug_config.use_extended_packet_size {
log::debug!("Setting extended packet size: {:?}", size);
controller_config.set_custom_packet_size(size.into());
}
Self::start_real_traffic_controller(
controller_config,
shared_topology_accessor.clone(),
ack_receiver,
input_receiver,
sphinx_message_sender.clone(),
reply_storage,
reply_controller_sender.clone(),
reply_controller_receiver,
shared_lane_queue_lengths.clone(),
client_connection_rx,
task_manager.subscribe(),
);
if !self.debug_config.disable_loop_cover_traffic_stream {
Self::start_cover_traffic_stream(
self.debug_config,
self.key_manager.ack_key(),
self_address,
shared_topology_accessor,
sphinx_message_sender,
task_manager.subscribe(),
);
}
debug!("Core client startup finished!");
debug!("The address of this client is: {self_address}");
Ok(BaseClient {
client_input: ClientInputStatus::AwaitingProducer {
client_input: ClientInput {
connection_command_sender: client_connection_tx,
input_sender,
},
},
client_output: ClientOutputStatus::AwaitingConsumer {
client_output: ClientOutput {
shared_lane_queue_lengths,
received_buffer_request_sender,
},
},
reply_controller_sender,
task_manager,
})
}
}
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,
}
@@ -0,0 +1,87 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_storage::{
fs_backend, CombinedReplyStorage, ReplyStorageBackend,
};
use crate::config::DebugConfig;
use crate::error::ClientCoreError;
use log::{error, info};
use std::path::Path;
use std::{fs, io};
use time::OffsetDateTime;
async fn setup_fresh_backend<P: AsRef<Path>>(
db_path: P,
debug_config: &DebugConfig,
) -> Result<fs_backend::Backend, ClientCoreError> {
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),
});
}
};
// while I kinda hate that we're going to be creating `CombinedReplyStorage` twice,
// it will only be happening on the very first run and in practice won't incur huge
// costs since the storage is going to be empty
let mem_store = CombinedReplyStorage::new(
debug_config.minimum_reply_surb_storage_threshold,
debug_config.maximum_reply_surb_storage_threshold,
);
storage_backend
.init_fresh(&mem_store)
.await
.map_err(|err| ClientCoreError::SurbStorageError {
source: Box::new(err),
})?;
Ok(storage_backend)
}
fn archive_corrupted_database<P: AsRef<Path>>(db_path: P) -> io::Result<()> {
let db_path = db_path.as_ref();
debug_assert!(db_path.exists());
let now = OffsetDateTime::now_utc().unix_timestamp();
let suffix = format!("_{now}.corrupted");
let new_extension =
if let Some(existing_extension) = db_path.extension().and_then(|ext| ext.to_str()) {
format!("{existing_extension}.{}", suffix)
} else {
suffix
};
let mut renamed = db_path.to_owned();
renamed.set_extension(new_extension);
fs::rename(db_path, renamed)
}
pub async fn setup_fs_reply_surb_backend<P: AsRef<Path>>(
db_path: P,
debug_config: &DebugConfig,
) -> Result<fs_backend::Backend, ClientCoreError> {
// 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() {
info!("loading existing surb database");
match fs_backend::Backend::try_load(db_path).await {
Ok(backend) => Ok(backend),
Err(err) => {
error!("failed to setup persistent storage backend for our reply needs: {err}. We're going to create a fresh database instead. This behaviour might change in the future");
archive_corrupted_database(db_path)?;
setup_fresh_backend(db_path, debug_config).await
}
}
} else {
setup_fresh_backend(db_path, debug_config).await
}
}
@@ -3,19 +3,27 @@
use crate::client::mix_traffic::BatchMixMessageSender;
use crate::client::topology_control::TopologyAccessor;
use crate::spawn_future;
use futures::task::{Context, Poll};
use futures::{Future, Stream, StreamExt};
use log::*;
use nymsphinx::acknowledgements::AckKey;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::cover::generate_loop_cover_packet;
use nymsphinx::params::PacketSize;
use nymsphinx::utils::sample_poisson_duration;
use rand::{rngs::OsRng, CryptoRng, Rng};
use std::pin::Pin;
use std::sync::Arc;
use tokio::task::JoinHandle;
use std::time::Duration;
use tokio::sync::mpsc::error::TrySendError;
#[cfg(not(target_arch = "wasm32"))]
use tokio::time;
#[cfg(target_arch = "wasm32")]
use wasm_timer;
pub struct LoopCoverTrafficStream<R>
where
R: CryptoRng + Rng,
@@ -24,18 +32,22 @@ where
ack_key: Arc<AckKey>,
/// Average delay an acknowledgement packet is going to get delay at a single mixnode.
average_ack_delay: time::Duration,
average_ack_delay: Duration,
/// Average delay a data packet is going to get delay at a single mixnode.
average_packet_delay: time::Duration,
average_packet_delay: Duration,
/// Average delay between sending subsequent cover packets.
average_cover_message_sending_delay: time::Duration,
average_cover_message_sending_delay: Duration,
/// Internal state, determined by `average_message_sending_delay`,
/// used to keep track of when a next packet should be sent out.
#[cfg(not(target_arch = "wasm32"))]
next_delay: Pin<Box<time::Sleep>>,
#[cfg(target_arch = "wasm32")]
next_delay: Pin<Box<wasm_timer::Delay>>,
/// Channel used for sending prepared sphinx packets to `MixTrafficController` that sends them
/// out to the network without any further delays.
mix_tx: BatchMixMessageSender,
@@ -48,6 +60,9 @@ where
/// Accessor to the common instance of network topology.
topology_access: TopologyAccessor,
/// Predefined packet size used for the loop cover messages.
packet_size: PacketSize,
}
impl<R> Stream for LoopCoverTrafficStream<R>
@@ -69,13 +84,21 @@ where
// we know it's time to send a message, so let's prepare delay for the next one
// Get the `now` by looking at the current `delay` deadline
let avg_delay = self.average_cover_message_sending_delay;
let now = self.next_delay.deadline();
let next_poisson_delay = sample_poisson_duration(&mut self.rng, avg_delay);
// The next interval value is `next_poisson_delay` after the one that just
// yielded.
let next = now + next_poisson_delay;
self.next_delay.as_mut().reset(next);
#[cfg(not(target_arch = "wasm32"))]
{
let now = self.next_delay.deadline();
let next = now + next_poisson_delay;
self.next_delay.as_mut().reset(next);
}
#[cfg(target_arch = "wasm32")]
{
self.next_delay.as_mut().reset(next_poisson_delay);
}
Poll::Ready(Some(()))
}
@@ -84,30 +107,52 @@ where
// obviously when we finally make shared rng that is on 'higher' level, this should become
// generic `R`
impl LoopCoverTrafficStream<OsRng> {
#[allow(clippy::too_many_arguments)]
pub fn new(
ack_key: Arc<AckKey>,
average_ack_delay: time::Duration,
average_packet_delay: time::Duration,
average_cover_message_sending_delay: time::Duration,
average_ack_delay: Duration,
average_packet_delay: Duration,
average_cover_message_sending_delay: Duration,
mix_tx: BatchMixMessageSender,
our_full_destination: Recipient,
topology_access: TopologyAccessor,
) -> Self {
let rng = OsRng;
#[cfg(not(target_arch = "wasm32"))]
let next_delay = Box::pin(time::sleep(Default::default()));
#[cfg(target_arch = "wasm32")]
let next_delay = Box::pin(wasm_timer::Delay::new(Default::default()));
LoopCoverTrafficStream {
ack_key,
average_ack_delay,
average_packet_delay,
average_cover_message_sending_delay,
next_delay: Box::pin(time::sleep(Default::default())),
next_delay,
mix_tx,
our_full_destination,
rng,
topology_access,
packet_size: Default::default(),
}
}
pub fn set_custom_packet_size(&mut self, packet_size: PacketSize) {
self.packet_size = packet_size;
}
fn set_next_delay(&mut self, amount: Duration) {
#[cfg(not(target_arch = "wasm32"))]
let next_delay = Box::pin(time::sleep(amount));
#[cfg(target_arch = "wasm32")]
let next_delay = Box::pin(wasm_timer::Delay::new(amount));
self.next_delay = next_delay;
}
async fn on_new_message(&mut self) {
trace!("next cover message!");
@@ -116,31 +161,44 @@ impl LoopCoverTrafficStream<OsRng> {
// poisson delay, but is it really a problem?
let topology_permit = self.topology_access.get_read_permit().await;
// the ack is sent back to ourselves (and then ignored)
let topology_ref_option = topology_permit.try_get_valid_topology_ref(
let topology_ref = match topology_permit.try_get_valid_topology_ref(
&self.our_full_destination,
Some(&self.our_full_destination),
);
if topology_ref_option.is_none() {
warn!("No valid topology detected - won't send any loop cover message this time");
return;
}
let topology_ref = topology_ref_option.unwrap();
) {
Ok(topology) => topology,
Err(err) => {
warn!("We're not going to send any loop cover message this time, as the current topology seem to be invalid - {err}");
return;
}
};
let cover_message = generate_loop_cover_packet(
&mut self.rng,
topology_ref,
&*self.ack_key,
&self.ack_key,
&self.our_full_destination,
self.average_ack_delay,
self.average_packet_delay,
self.packet_size,
)
.expect("Somehow failed to generate a loop cover message with a valid topology");
// if this one fails, there's no retrying because it means that either:
// - we run out of memory
// - the receiver channel is closed
// in either case there's no recovery and we can only panic
self.mix_tx.unbounded_send(vec![cover_message]).unwrap();
if let Err(err) = self.mix_tx.try_send(vec![cover_message]) {
match err {
TrySendError::Full(_) => {
// This isn't a problem, if the channel is full means we're already sending the
// max amount of messages downstream can handle.
log::debug!("Failed to send cover message - channel full");
// However it's still useful to alert the user that the gateway or the link to
// the gateway can't keep up. Either due to insufficient bandwidth on the
// client side, or that the gateway is overloaded.
log::warn!("Failed to send sphinx packet - gateway or connection to gatway can't keep up");
}
TrySendError::Closed(_) => {
log::warn!("Failed to send cover message - channel closed");
}
}
}
// TODO: I'm not entirely sure whether this is really required, because I'm not 100%
// sure how `yield_now()` works - whether it just notifies the scheduler or whether it
@@ -149,24 +207,39 @@ impl LoopCoverTrafficStream<OsRng> {
// JS: due to identical logical structure to OutQueueControl::on_message(), this is also
// presumably required to prevent bugs in the future. Exact reason is still unknown to me.
// TODO: temporary and BAD workaround for wasm (we should find a way to yield here in wasm)
#[cfg(not(target_arch = "wasm32"))]
tokio::task::yield_now().await;
}
async fn run(&mut self) {
pub fn start_with_shutdown(mut self, mut shutdown: task::TaskClient) {
// we should set initial delay only when we actually start the stream
self.next_delay = Box::pin(time::sleep(sample_poisson_duration(
&mut self.rng,
self.average_cover_message_sending_delay,
)));
let sampled =
sample_poisson_duration(&mut self.rng, self.average_cover_message_sending_delay);
self.set_next_delay(sampled);
while self.next().await.is_some() {
self.on_new_message().await;
}
}
spawn_future(async move {
debug!("Started LoopCoverTrafficStream with graceful shutdown support");
pub fn start(mut self) -> JoinHandle<()> {
tokio::spawn(async move {
self.run().await;
while !shutdown.is_shutdown() {
tokio::select! {
biased;
_ = shutdown.recv() => {
log::trace!("LoopCoverTrafficStream: Received shutdown");
}
next = self.next() => {
if next.is_some() {
self.on_new_message().await;
} else {
log::trace!("LoopCoverTrafficStream: Stopping since channel closed");
break;
}
}
}
}
shutdown.recv_timeout().await;
log::debug!("LoopCoverTrafficStream: Exiting");
})
}
}
@@ -0,0 +1,14 @@
// 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::*;
@@ -0,0 +1,13 @@
// 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))
}
@@ -0,0 +1,16 @@
// 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)
}
@@ -1,33 +1,80 @@
use futures::channel::mpsc;
use client_connections::TransmissionLane;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::anonymous_replies::ReplySurb;
use nymsphinx::anonymous_replies::requests::AnonymousSenderTag;
pub type InputMessageSender = mpsc::UnboundedSender<InputMessage>;
pub type InputMessageReceiver = mpsc::UnboundedReceiver<InputMessage>;
pub type InputMessageSender = tokio::sync::mpsc::Sender<InputMessage>;
pub type InputMessageReceiver = tokio::sync::mpsc::Receiver<InputMessage>;
#[derive(Debug)]
pub enum InputMessage {
Fresh {
/// The simplest message variant where no additional information is attached.
/// You're simply sending your `data` to specified `recipient` without any tagging.
///
/// Ends up with `NymMessage::Plain` variant
Regular {
recipient: Recipient,
data: Vec<u8>,
with_reply_surb: bool,
lane: TransmissionLane,
},
Reply {
reply_surb: ReplySurb,
/// Creates a message used for a duplex anonymous communication where the recipient
/// will never learn of our true identity. This is achieved by carefully sending `reply_surbs`.
///
/// Note that if reply_surbs is set to zero then
/// this variant requires the client having sent some reply_surbs in the past
/// (and thus the recipient also knowing our sender tag).
///
/// Ends up with `NymMessage::Repliable` variant
Anonymous {
recipient: Recipient,
data: Vec<u8>,
reply_surbs: u32,
lane: TransmissionLane,
},
/// Attempt to use our internally received and stored `ReplySurb` to send the message back
/// to specified recipient whilst not knowing its full identity (or even gateway).
///
/// Ends up with `NymMessage::Reply` variant
Reply {
recipient_tag: AnonymousSenderTag,
data: Vec<u8>,
lane: TransmissionLane,
},
}
impl InputMessage {
pub fn new_fresh(recipient: Recipient, data: Vec<u8>, with_reply_surb: bool) -> Self {
InputMessage::Fresh {
pub fn new_regular(recipient: Recipient, data: Vec<u8>, lane: TransmissionLane) -> Self {
InputMessage::Regular {
recipient,
data,
with_reply_surb,
lane,
}
}
pub fn new_reply(reply_surb: ReplySurb, data: Vec<u8>) -> Self {
InputMessage::Reply { reply_surb, data }
pub fn new_anonymous(
recipient: Recipient,
data: Vec<u8>,
reply_surbs: u32,
lane: TransmissionLane,
) -> Self {
InputMessage::Anonymous {
recipient,
data,
reply_surbs,
lane,
}
}
pub fn new_reply(
recipient_tag: AnonymousSenderTag,
data: Vec<u8>,
lane: TransmissionLane,
) -> Self {
InputMessage::Reply {
recipient_tag,
data,
lane,
}
}
}
@@ -149,6 +149,10 @@ impl KeyManager {
)
}
pub fn gateway_key_set(&self) -> bool {
self.gateway_shared_key.is_some()
}
/// Gets an atomically reference counted pointer to [`AckKey`].
pub fn ack_key(&self) -> Arc<AckKey> {
Arc::clone(&self.ack_key)
+40 -24
View File
@@ -1,16 +1,16 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use futures::channel::mpsc;
use futures::StreamExt;
use crate::spawn_future;
use gateway_client::GatewayClient;
use log::*;
use nymsphinx::forwarding::packet::MixPacket;
use tokio::task::JoinHandle;
pub type BatchMixMessageSender = mpsc::UnboundedSender<Vec<MixPacket>>;
pub type BatchMixMessageReceiver = mpsc::UnboundedReceiver<Vec<MixPacket>>;
pub type BatchMixMessageSender = tokio::sync::mpsc::Sender<Vec<MixPacket>>;
pub type BatchMixMessageReceiver = tokio::sync::mpsc::Receiver<Vec<MixPacket>>;
// We remind ourselves that 32 x 32kb = 1024kb, a reasonable size for a network buffer.
pub const MIX_MESSAGE_RECEIVER_BUFFER_SIZE: usize = 32;
const MAX_FAILURE_COUNT: usize = 100;
pub struct MixTrafficController {
@@ -25,15 +25,17 @@ pub struct MixTrafficController {
}
impl MixTrafficController {
pub fn new(
mix_rx: BatchMixMessageReceiver,
gateway_client: GatewayClient,
) -> MixTrafficController {
MixTrafficController {
gateway_client,
mix_rx,
consecutive_gateway_failure_count: 0,
}
pub fn new(gateway_client: GatewayClient) -> (MixTrafficController, BatchMixMessageSender) {
let (sphinx_message_sender, sphinx_message_receiver) =
tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE);
(
MixTrafficController {
gateway_client,
mix_rx: sphinx_message_receiver,
consecutive_gateway_failure_count: 0,
},
sphinx_message_sender,
)
}
async fn on_messages(&mut self, mut mix_packets: Vec<MixPacket>) {
@@ -49,8 +51,8 @@ impl MixTrafficController {
};
match result {
Err(e) => {
error!("Failed to send sphinx packet(s) to the gateway! - {:?}", e);
Err(err) => {
error!("Failed to send sphinx packet(s) to the gateway! - {err}");
self.consecutive_gateway_failure_count += 1;
if self.consecutive_gateway_failure_count == MAX_FAILURE_COUNT {
// todo: in the future this should initiate a 'graceful' shutdown or try
@@ -65,15 +67,29 @@ impl MixTrafficController {
}
}
pub async fn run(&mut self) {
while let Some(mix_packets) = self.mix_rx.next().await {
self.on_messages(mix_packets).await;
}
}
pub fn start_with_shutdown(mut self, mut shutdown: task::TaskClient) {
spawn_future(async move {
debug!("Started MixTrafficController with graceful shutdown support");
pub fn start(mut self) -> JoinHandle<()> {
tokio::spawn(async move {
self.run().await;
loop {
tokio::select! {
mix_packets = self.mix_rx.recv() => match mix_packets {
Some(mix_packets) => {
self.on_messages(mix_packets).await;
},
None => {
log::trace!("MixTrafficController: Stopping since channel closed");
break;
}
},
_ = shutdown.recv_with_delay() => {
log::trace!("MixTrafficController: Received shutdown");
break;
}
}
}
shutdown.recv_timeout().await;
log::debug!("MixTrafficController: Exiting");
})
}
}
+7 -1
View File
@@ -1,8 +1,14 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
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;
pub mod real_messages_control;
pub mod received_buffer;
pub mod reply_key_storage;
pub mod replies;
pub mod topology_control;
pub(crate) mod transmission_buffer;
@@ -1,7 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::action_controller::{Action, ActionSender};
use super::action_controller::{AckActionSender, Action};
use futures::StreamExt;
use gateway_client::AcknowledgementReceiver;
use log::*;
@@ -16,14 +16,14 @@ use std::sync::Arc;
pub(super) struct AcknowledgementListener {
ack_key: Arc<AckKey>,
ack_receiver: AcknowledgementReceiver,
action_sender: ActionSender,
action_sender: AckActionSender,
}
impl AcknowledgementListener {
pub(super) fn new(
ack_key: Arc<AckKey>,
ack_receiver: AcknowledgementReceiver,
action_sender: ActionSender,
action_sender: AckActionSender,
) -> Self {
AcknowledgementListener {
ack_key,
@@ -33,7 +33,7 @@ impl AcknowledgementListener {
}
async fn on_ack(&mut self, ack_content: Vec<u8>) {
debug!("Received an ack");
trace!("Received an ack");
let frag_id = match recover_identifier(&self.ack_key, &ack_content)
.map(FragmentIdentifier::try_from_bytes)
{
@@ -49,11 +49,6 @@ impl AcknowledgementListener {
if frag_id == COVER_FRAG_ID {
trace!("Received an ack for a cover message - no need to do anything");
return;
} else if frag_id.is_reply() {
info!("Received an ack for a reply message - no need to do anything! (don't know what to do!)");
// TODO: probably there will need to be some extra procedure here, something to notify
// user that his reply reached the recipient (since we got an ack)
return;
}
trace!("Received {} from the mix network", frag_id);
@@ -63,14 +58,31 @@ impl AcknowledgementListener {
.unwrap();
}
pub(super) async fn run(&mut self) {
debug!("Started AcknowledgementListener");
while let Some(acks) = self.ack_receiver.next().await {
// realistically we would only be getting one ack at the time
for ack in acks {
self.on_ack(ack).await;
async fn handle_ack_receiver_item(&mut self, item: Vec<Vec<u8>>) {
// realistically we would only be getting one ack at the time
for ack in item {
self.on_ack(ack).await;
}
}
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::TaskClient) {
debug!("Started AcknowledgementListener with graceful shutdown support");
while !shutdown.is_shutdown() {
tokio::select! {
acks = self.ack_receiver.next() => match acks {
Some(acks) => self.handle_ack_receiver_item(acks).await,
None => {
log::trace!("AcknowledgementListener: Stopping since channel closed");
break;
}
},
_ = shutdown.recv_with_delay() => {
log::trace!("AcknowledgementListener: Received shutdown");
}
}
}
error!("TODO: error msg. Or maybe panic?")
shutdown.recv_timeout().await;
log::debug!("AcknowledgementListener: Exiting");
}
}
@@ -3,7 +3,7 @@
use super::PendingAcknowledgement;
use crate::client::real_messages_control::acknowledgement_control::RetransmissionRequestSender;
use futures::channel::mpsc::{self, UnboundedReceiver, UnboundedSender};
use futures::channel::mpsc;
use futures::StreamExt;
use log::*;
use nonexhaustive_delayqueue::{Expired, NonExhaustiveDelayQueue, QueueKey};
@@ -13,7 +13,8 @@ use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
pub(crate) type ActionSender = UnboundedSender<Action>;
pub(crate) type AckActionSender = mpsc::UnboundedSender<Action>;
pub(crate) type AckActionReceiver = mpsc::UnboundedReceiver<Action>;
// The actual data being sent off as well as potential key to the delay queue
type PendingAckEntry = (Arc<PendingAcknowledgement>, Option<QueueKey>);
@@ -95,7 +96,7 @@ pub(super) struct ActionController {
pending_acks_timers: NonExhaustiveDelayQueue<FragmentIdentifier>,
/// Channel for receiving `Action`s from other modules.
incoming_actions: UnboundedReceiver<Action>,
incoming_actions: AckActionReceiver,
/// Channel for notifying `RetransmissionRequestListener` about expired acknowledgements.
retransmission_sender: RetransmissionRequestSender,
@@ -105,18 +106,15 @@ impl ActionController {
pub(super) fn new(
config: Config,
retransmission_sender: RetransmissionRequestSender,
) -> (Self, ActionSender) {
let (sender, receiver) = mpsc::unbounded();
(
ActionController {
config,
pending_acks_data: HashMap::new(),
pending_acks_timers: NonExhaustiveDelayQueue::new(),
incoming_actions: receiver,
retransmission_sender,
},
sender,
)
incoming_actions: AckActionReceiver,
) -> Self {
ActionController {
config,
pending_acks_data: HashMap::new(),
pending_acks_timers: NonExhaustiveDelayQueue::new(),
incoming_actions,
retransmission_sender,
}
}
fn handle_insert(&mut self, pending_acks: Vec<PendingAcknowledgement>) {
@@ -138,13 +136,18 @@ impl ActionController {
trace!("{} is starting its timer", frag_id);
if let Some((pending_ack_data, queue_key)) = self.pending_acks_data.get_mut(&frag_id) {
if queue_key.is_some() {
// this branch should be IMPOSSIBLE under ANY condition. It would imply starting
// timer TWICE for the SAME PendingAcknowledgement
panic!("Tried to start an already started ack timer!")
}
let timeout = (pending_ack_data.delay.clone() * self.config.ack_wait_multiplier)
.to_duration()
// the fact that this branch is now POSSIBLE is a sign of a need to refactor this whole
// retransmission procedure
//
// (it can happen as timer is started when ack expires to make sure it's not stuck in memory
// and the second instance can be fired when we finally get reply surbs for data we failed to retransmit)
// if queue_key.is_some() {
// // this branch should be IMPOSSIBLE under ANY condition. It would imply starting
// // timer TWICE for the SAME PendingAcknowledgement
// panic!("Tried to start an already started ack timer!")
// }
let timeout = (pending_ack_data.delay * self.config.ack_wait_multiplier).to_duration()
+ self.config.ack_wait_addition;
let new_queue_key = self.pending_acks_timers.insert(frag_id, timeout);
@@ -192,7 +195,8 @@ impl ActionController {
trace!("{} is updating its delay", frag_id);
// TODO: is it possible to solve this without either locking or temporarily removing the value?
if let Some((pending_ack_data, queue_key)) = self.pending_acks_data.remove(&frag_id) {
// this Action is triggered by `RetransmissionRequestListener` which held the other potential
// this Action is triggered by `RetransmissionRequestListener` (for 'normal' packets)
// or `ReplyController` (for 'reply' packets) which held the other potential
// reference to this Arc. HOWEVER, before the Action was pushed onto the queue, the reference
// was dropped hence this unwrap is safe.
let mut inner_data = Arc::try_unwrap(pending_ack_data).unwrap();
@@ -245,15 +249,36 @@ impl ActionController {
}
}
pub(super) async fn run(&mut self) {
loop {
// at some point there will be a global shutdown signal here as the third option
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::TaskClient) {
debug!("Started ActionController with graceful shutdown support");
while !shutdown.is_shutdown() {
tokio::select! {
// we NEVER expect for ANY sender to get dropped so unwrap here is fine
action = self.incoming_actions.next() => self.process_action(action.unwrap()),
// pending ack queue Stream CANNOT return a `None` so unwrap here is fine
expired_ack = self.pending_acks_timers.next() => self.handle_expired_ack_timer(expired_ack.unwrap())
action = self.incoming_actions.next() => match action {
Some(action) => self.process_action(action),
None => {
log::trace!(
"ActionController: Stopping since incoming actions channel closed"
);
break;
}
},
expired_ack = self.pending_acks_timers.next() => match expired_ack {
Some(expired_ack) => self.handle_expired_ack_timer(expired_ack),
None => {
log::trace!("ActionController: Stopping since ack channel closed");
break;
}
},
_ = shutdown.recv_with_delay() => {
log::trace!("ActionController: Received shutdown");
}
}
}
#[cfg(not(target_arch = "wasm32"))]
tokio::time::timeout(Duration::from_secs(5), shutdown.recv())
.await
.expect("Task stopped without shutdown called");
log::debug!("ActionController: Exiting");
}
}
@@ -1,21 +1,14 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::action_controller::{Action, ActionSender};
use super::PendingAcknowledgement;
use crate::client::reply_key_storage::ReplyKeyStorage;
use crate::client::{
inbound_messages::{InputMessage, InputMessageReceiver},
real_messages_control::real_traffic_stream::{BatchRealMessageSender, RealMessage},
topology_control::TopologyAccessor,
};
use futures::StreamExt;
use crate::client::inbound_messages::{InputMessage, InputMessageReceiver};
use crate::client::real_messages_control::message_handler::MessageHandler;
use crate::client::replies::reply_controller::ReplyControllerSender;
use client_connections::TransmissionLane;
use log::*;
use nymsphinx::anonymous_replies::ReplySurb;
use nymsphinx::preparer::MessagePreparer;
use nymsphinx::{acknowledgements::AckKey, addressing::clients::Recipient};
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::anonymous_replies::requests::AnonymousSenderTag;
use rand::{CryptoRng, Rng};
use std::sync::Arc;
/// Module responsible for dealing with the received messages: splitting them, creating acknowledgements,
/// putting everything into sphinx packets, etc.
@@ -24,14 +17,9 @@ pub(super) struct InputMessageListener<R>
where
R: CryptoRng + Rng,
{
ack_key: Arc<AckKey>,
ack_recipient: Recipient,
input_receiver: InputMessageReceiver,
message_preparer: MessagePreparer<R>,
action_sender: ActionSender,
real_message_sender: BatchRealMessageSender,
topology_access: TopologyAccessor,
reply_key_storage: ReplyKeyStorage,
message_handler: MessageHandler<R>,
reply_controller_sender: ReplyControllerSender,
}
impl<R> InputMessageListener<R>
@@ -42,150 +30,105 @@ where
// some considerable refactoring
#[allow(clippy::too_many_arguments)]
pub(super) fn new(
ack_key: Arc<AckKey>,
ack_recipient: Recipient,
input_receiver: InputMessageReceiver,
message_preparer: MessagePreparer<R>,
action_sender: ActionSender,
real_message_sender: BatchRealMessageSender,
topology_access: TopologyAccessor,
reply_key_storage: ReplyKeyStorage,
message_handler: MessageHandler<R>,
reply_controller_sender: ReplyControllerSender,
) -> Self {
InputMessageListener {
ack_key,
ack_recipient,
input_receiver,
message_preparer,
action_sender,
real_message_sender,
topology_access,
reply_key_storage,
message_handler,
reply_controller_sender,
}
}
// we require topology for replies to generate surb_acks
async fn handle_reply(&mut self, reply_surb: ReplySurb, data: Vec<u8>) -> Option<RealMessage> {
let topology_permit = self.topology_access.get_read_permit().await;
let topology = match topology_permit.try_get_valid_topology_ref(&self.ack_recipient, None) {
Some(topology_ref) => topology_ref,
None => {
warn!("Could not process the message - the network topology is invalid");
return None;
}
};
match self
.message_preparer
.prepare_reply_for_use(data, reply_surb, topology, &self.ack_key)
.await
{
Ok((mix_packet, reply_id)) => {
// TODO: later probably write pending ack here
// and deal with them....
// ... somehow
Some(RealMessage::new(mix_packet, reply_id))
}
Err(err) => {
// TODO: should we have some mechanism to indicate to the user that the `reply_surb`
// could be reused since technically it wasn't used up here?
warn!("failed to deal with received reply surb - {:?}", err);
None
}
}
async fn handle_reply(
&mut self,
recipient_tag: AnonymousSenderTag,
data: Vec<u8>,
lane: TransmissionLane,
) {
// offload reply handling to the dedicated task
self.reply_controller_sender
.send_reply(recipient_tag, data, lane)
}
async fn handle_fresh_message(
async fn handle_plain_message(
&mut self,
recipient: Recipient,
content: Vec<u8>,
with_reply_surb: bool,
) -> Option<Vec<RealMessage>> {
let topology_permit = self.topology_access.get_read_permit().await;
let topology = match topology_permit
.try_get_valid_topology_ref(&self.ack_recipient, Some(&recipient))
lane: TransmissionLane,
) {
if let Err(err) = self
.message_handler
.try_send_plain_message(recipient, content, lane)
.await
{
Some(topology_ref) => topology_ref,
None => {
warn!("Could not process the message - the network topology is invalid");
return None;
}
};
// split the message, attach optional reply surb
let (split_message, reply_key) = self
.message_preparer
.prepare_and_split_message(content, with_reply_surb, topology)
.expect("somehow the topology was invalid after all!");
if let Some(reply_key) = reply_key {
self.reply_key_storage
.insert_encryption_key(reply_key)
.expect("Failed to insert surb reply key to the store!")
warn!("failed to send a plain message - {err}")
}
}
// encrypt chunks, put them inside sphinx packets and generate acks
let mut pending_acks = Vec::with_capacity(split_message.len());
let mut real_messages = Vec::with_capacity(split_message.len());
for message_chunk in split_message {
// we need to clone it because we need to keep it in memory in case we had to retransmit
// it. And then we'd need to recreate entire ACK again.
let chunk_clone = message_chunk.clone();
let prepared_fragment = self
.message_preparer
.prepare_chunk_for_sending(chunk_clone, topology, &self.ack_key, &recipient)
.await
.unwrap();
real_messages.push(RealMessage::new(
prepared_fragment.mix_packet,
message_chunk.fragment_identifier(),
));
pending_acks.push(PendingAcknowledgement::new(
message_chunk,
prepared_fragment.total_delay,
recipient,
));
async fn handle_repliable_message(
&mut self,
recipient: Recipient,
content: Vec<u8>,
reply_surbs: u32,
lane: TransmissionLane,
) {
if let Err(err) = self
.message_handler
.try_send_message_with_reply_surbs(recipient, content, reply_surbs, lane)
.await
{
warn!("failed to send a repliable message - {err}")
}
// tells the controller to put this into the hashmap
self.action_sender
.unbounded_send(Action::new_insert(pending_acks))
.unwrap();
Some(real_messages)
}
async fn on_input_message(&mut self, msg: InputMessage) {
let real_messages = match msg {
InputMessage::Fresh {
match msg {
InputMessage::Regular {
recipient,
data,
with_reply_surb,
lane,
} => self.handle_plain_message(recipient, data, lane).await,
InputMessage::Anonymous {
recipient,
data,
reply_surbs,
lane,
} => {
self.handle_fresh_message(recipient, data, with_reply_surb)
self.handle_repliable_message(recipient, data, reply_surbs, lane)
.await
}
InputMessage::Reply { reply_surb, data } => self
.handle_reply(reply_surb, data)
.await
.map(|message| vec![message]),
InputMessage::Reply {
recipient_tag,
data,
lane,
} => {
self.handle_reply(recipient_tag, data, lane).await;
}
};
// there's no point in trying to send nothing
if let Some(real_messages) = real_messages {
// tells real message sender (with the poisson timer) to send this to the mix network
self.real_message_sender
.unbounded_send(real_messages)
.unwrap();
}
}
pub(super) async fn run(&mut self) {
debug!("Started InputMessageListener");
while let Some(input_msg) = self.input_receiver.next().await {
self.on_input_message(input_msg).await;
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::TaskClient) {
debug!("Started InputMessageListener with graceful shutdown support");
while !shutdown.is_shutdown() {
tokio::select! {
input_msg = self.input_receiver.recv() => match input_msg {
Some(input_msg) => {
self.on_input_message(input_msg).await;
},
None => {
log::trace!("InputMessageListener: Stopping since channel closed");
break;
}
},
_ = shutdown.recv_with_delay() => {
log::trace!("InputMessageListener: Received shutdown");
}
}
}
error!("TODO: error msg. Or maybe panic?")
shutdown.recv_timeout().await;
log::debug!("InputMessageListener: Exiting");
}
}
@@ -7,17 +7,20 @@ use self::{
retransmission_request_listener::RetransmissionRequestListener,
sent_notification_listener::SentNotificationListener,
};
use super::real_traffic_stream::BatchRealMessageSender;
use crate::client::reply_key_storage::ReplyKeyStorage;
use crate::client::{inbound_messages::InputMessageReceiver, topology_control::TopologyAccessor};
use crate::client::inbound_messages::InputMessageReceiver;
use crate::client::real_messages_control::message_handler::MessageHandler;
use crate::client::replies::reply_controller::ReplyControllerSender;
use crate::spawn_future;
use action_controller::AckActionReceiver;
use futures::channel::mpsc;
use gateway_client::AcknowledgementReceiver;
use log::*;
use nymsphinx::anonymous_replies::requests::AnonymousSenderTag;
use nymsphinx::params::PacketSize;
use nymsphinx::{
acknowledgements::AckKey,
addressing::clients::Recipient,
chunking::fragment::{Fragment, FragmentIdentifier},
preparer::MessagePreparer,
Delay as SphinxDelay,
};
use rand::{CryptoRng, Rng};
@@ -25,7 +28,8 @@ use std::{
sync::{Arc, Weak},
time::Duration,
};
use tokio::task::JoinHandle;
pub(crate) use action_controller::{AckActionSender, Action};
mod acknowledgement_listener;
mod action_controller;
@@ -47,24 +51,64 @@ pub(super) type SentPacketNotificationSender = mpsc::UnboundedSender<FragmentIde
/// that it is about to be sent to the mix network and its timeout timer should be started.
type SentPacketNotificationReceiver = mpsc::UnboundedReceiver<FragmentIdentifier>;
#[derive(Debug)]
pub(crate) enum PacketDestination {
Anonymous {
recipient_tag: AnonymousSenderTag,
// special flag to indicate whether this was an ack for requesting additional surbs,
// in that case we have to do everything we can to get it through, even if it means going
// below our stored reply surb threshold
extra_surb_request: bool,
},
KnownRecipient(Box<Recipient>),
}
/// Structure representing a data `Fragment` that is on-route to the specified `Recipient`
#[derive(Debug)]
pub(crate) struct PendingAcknowledgement {
message_chunk: Fragment,
delay: SphinxDelay,
recipient: Recipient,
destination: PacketDestination,
}
impl PendingAcknowledgement {
/// Creates new instance of `PendingAcknowledgement` using the provided data.
fn new(message_chunk: Fragment, delay: SphinxDelay, recipient: Recipient) -> Self {
pub(crate) fn new_known(
message_chunk: Fragment,
delay: SphinxDelay,
recipient: Recipient,
) -> Self {
PendingAcknowledgement {
message_chunk,
delay,
recipient,
destination: PacketDestination::KnownRecipient(recipient.into()),
}
}
pub(crate) fn new_anonymous(
message_chunk: Fragment,
delay: SphinxDelay,
recipient_tag: AnonymousSenderTag,
extra_surb_request: bool,
) -> Self {
PendingAcknowledgement {
message_chunk,
delay,
destination: PacketDestination::Anonymous {
recipient_tag,
extra_surb_request,
},
}
}
pub(crate) fn inner_fragment_identifier(&self) -> FragmentIdentifier {
self.message_chunk.fragment_identifier()
}
pub(crate) fn fragment_data(&self) -> Fragment {
self.message_chunk.clone()
}
fn update_delay(&mut self, new_delay: SphinxDelay) {
self.delay = new_delay;
}
@@ -73,10 +117,6 @@ impl PendingAcknowledgement {
/// AcknowledgementControllerConnectors represents set of channels for communication with
/// other parts of the system in order to support acknowledgements and retransmission.
pub(super) struct AcknowledgementControllerConnectors {
/// Channel used for forwarding prepared sphinx messages into the poisson sender
/// to be sent to the mix network.
real_message_sender: BatchRealMessageSender,
/// Channel used for receiving raw messages from a client. The messages need to be put
/// into sphinx packets first.
input_receiver: InputMessageReceiver,
@@ -88,20 +128,28 @@ pub(super) struct AcknowledgementControllerConnectors {
/// Channel used for receiving acknowledgements from the mix network.
ack_receiver: AcknowledgementReceiver,
/// Channel used for sending request to `ActionController` to deal with anything ack-related,
ack_action_sender: AckActionSender,
/// Channel used for receiving request by `ActionController` to deal with anything ack-related,
ack_action_receiver: AckActionReceiver,
}
impl AcknowledgementControllerConnectors {
pub(super) fn new(
real_message_sender: BatchRealMessageSender,
input_receiver: InputMessageReceiver,
sent_notifier: SentPacketNotificationReceiver,
ack_receiver: AcknowledgementReceiver,
ack_action_sender: AckActionSender,
ack_action_receiver: AckActionReceiver,
) -> Self {
AcknowledgementControllerConnectors {
real_message_sender,
input_receiver,
sent_notifier,
ack_receiver,
ack_action_sender,
ack_action_receiver,
}
}
}
@@ -114,163 +162,135 @@ pub(super) struct Config {
/// Given ack timeout in the form a * BASE_DELAY + b, it specifies the multiplier `a`
ack_wait_multiplier: f64,
/// Average delay an acknowledgement packet is going to get delayed at a single mixnode.
average_ack_delay: Duration,
/// Average delay a data packet is going to get delayed at a single mixnode.
average_packet_delay: Duration,
/// Predefined packet size used for the encapsulated messages.
packet_size: PacketSize,
}
impl Config {
pub(super) fn new(
ack_wait_addition: Duration,
ack_wait_multiplier: f64,
average_ack_delay: Duration,
average_packet_delay: Duration,
) -> Self {
pub(super) fn new(ack_wait_addition: Duration, ack_wait_multiplier: f64) -> Self {
Config {
ack_wait_addition,
ack_wait_multiplier,
average_ack_delay,
average_packet_delay,
packet_size: Default::default(),
}
}
pub fn with_custom_packet_size(mut self, packet_size: PacketSize) -> Self {
self.packet_size = packet_size;
self
}
}
pub(super) struct AcknowledgementController<R>
where
R: CryptoRng + Rng,
{
acknowledgement_listener: Option<AcknowledgementListener>,
input_message_listener: Option<InputMessageListener<R>>,
retransmission_request_listener: Option<RetransmissionRequestListener<R>>,
sent_notification_listener: Option<SentNotificationListener>,
action_controller: Option<ActionController>,
acknowledgement_listener: AcknowledgementListener,
input_message_listener: InputMessageListener<R>,
retransmission_request_listener: RetransmissionRequestListener<R>,
sent_notification_listener: SentNotificationListener,
action_controller: ActionController,
}
impl<R> AcknowledgementController<R>
where
R: 'static + CryptoRng + Rng + Clone + Send,
R: 'static + CryptoRng + Rng + Clone + Send + Sync,
{
pub(super) fn new(
config: Config,
rng: R,
topology_access: TopologyAccessor,
ack_key: Arc<AckKey>,
ack_recipient: Recipient,
reply_key_storage: ReplyKeyStorage,
connectors: AcknowledgementControllerConnectors,
message_handler: MessageHandler<R>,
reply_controller_sender: ReplyControllerSender,
) -> Self {
let (retransmission_tx, retransmission_rx) = mpsc::unbounded();
let action_config =
action_controller::Config::new(config.ack_wait_addition, config.ack_wait_multiplier);
let (action_controller, action_sender) =
ActionController::new(action_config, retransmission_tx);
let message_preparer = MessagePreparer::new(
rng,
ack_recipient,
config.average_packet_delay,
config.average_ack_delay,
let action_controller = ActionController::new(
action_config,
retransmission_tx,
connectors.ack_action_receiver,
);
// will listen for any acks coming from the network
let acknowledgement_listener = AcknowledgementListener::new(
Arc::clone(&ack_key),
connectors.ack_receiver,
action_sender.clone(),
connectors.ack_action_sender.clone(),
);
// will listen for any new messages from the client
let input_message_listener = InputMessageListener::new(
Arc::clone(&ack_key),
ack_recipient,
connectors.input_receiver,
message_preparer.clone(),
action_sender.clone(),
connectors.real_message_sender.clone(),
topology_access.clone(),
reply_key_storage,
message_handler.clone(),
reply_controller_sender.clone(),
);
// will listen for any ack timeouts and trigger retransmission
let retransmission_request_listener = RetransmissionRequestListener::new(
Arc::clone(&ack_key),
ack_recipient,
message_preparer,
action_sender.clone(),
connectors.real_message_sender,
connectors.ack_action_sender.clone(),
message_handler,
retransmission_rx,
topology_access,
reply_controller_sender,
);
// will listen for events indicating the packet was sent through the network so that
// the retransmission timer should be started.
let sent_notification_listener =
SentNotificationListener::new(connectors.sent_notifier, action_sender);
SentNotificationListener::new(connectors.sent_notifier, connectors.ack_action_sender);
AcknowledgementController {
acknowledgement_listener: Some(acknowledgement_listener),
input_message_listener: Some(input_message_listener),
retransmission_request_listener: Some(retransmission_request_listener),
sent_notification_listener: Some(sent_notification_listener),
action_controller: Some(action_controller),
acknowledgement_listener,
input_message_listener,
retransmission_request_listener,
sent_notification_listener,
action_controller,
}
}
pub(super) async fn run(&mut self) {
let mut acknowledgement_listener = self.acknowledgement_listener.take().unwrap();
let mut input_message_listener = self.input_message_listener.take().unwrap();
let mut retransmission_request_listener =
self.retransmission_request_listener.take().unwrap();
let mut sent_notification_listener = self.sent_notification_listener.take().unwrap();
let mut action_controller = self.action_controller.take().unwrap();
pub(super) fn start_with_shutdown(self, shutdown: task::TaskClient) {
let mut acknowledgement_listener = self.acknowledgement_listener;
let mut input_message_listener = self.input_message_listener;
let mut retransmission_request_listener = self.retransmission_request_listener;
let mut sent_notification_listener = self.sent_notification_listener;
let mut action_controller = self.action_controller;
// the below are log messages are errors as at the current stage we do not expect any of
// the task to ever finish. This will of course change once we introduce
// graceful shutdowns.
let ack_listener_fut = tokio::spawn(async move {
acknowledgement_listener.run().await;
error!("The acknowledgement listener has finished execution!");
let shutdown_handle = shutdown.clone();
spawn_future(async move {
acknowledgement_listener
.run_with_shutdown(shutdown_handle)
.await;
debug!("The acknowledgement listener has finished execution!");
});
let input_listener_fut = tokio::spawn(async move {
input_message_listener.run().await;
error!("The input listener has finished execution!");
let shutdown_handle = shutdown.clone();
spawn_future(async move {
input_message_listener
.run_with_shutdown(shutdown_handle)
.await;
debug!("The input listener has finished execution!");
});
let retransmission_req_fut = tokio::spawn(async move {
retransmission_request_listener.run().await;
error!("The retransmission request listener has finished execution!");
let shutdown_handle = shutdown.clone();
spawn_future(async move {
retransmission_request_listener
.run_with_shutdown(shutdown_handle)
.await;
debug!("The retransmission request listener has finished execution!");
});
let sent_notification_fut = tokio::spawn(async move {
sent_notification_listener.run().await;
error!("The sent notification listener has finished execution!");
let shutdown_handle = shutdown.clone();
spawn_future(async move {
sent_notification_listener
});
let action_controller_fut = tokio::spawn(async move {
action_controller.run().await;
error!("The controller has finished execution!");
action_controller
.run_with_shutdown(shutdown_handle)
.await;
debug!("The sent notification listener has finished execution!");
});
// technically we don't have to bring `AcknowledgementController` back to a valid state
// but we can do it, so why not? Perhaps it might be useful if we wanted to allow
// for restarts of certain modules without killing the entire process.
self.acknowledgement_listener = Some(ack_listener_fut.await.unwrap());
self.input_message_listener = Some(input_listener_fut.await.unwrap());
self.retransmission_request_listener = Some(retransmission_req_fut.await.unwrap());
self.sent_notification_listener = Some(sent_notification_fut.await.unwrap());
self.action_controller = Some(action_controller_fut.await.unwrap());
}
#[allow(dead_code)]
pub(super) fn start(mut self) -> JoinHandle<Self> {
tokio::spawn(async move {
self.run().await;
self
})
spawn_future(async move {
action_controller.run_with_shutdown(shutdown).await;
debug!("The controller has finished execution!");
});
}
}
@@ -1,32 +1,29 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::action_controller::{Action, ActionSender};
use super::PendingAcknowledgement;
use super::RetransmissionRequestReceiver;
use crate::client::{
real_messages_control::real_traffic_stream::{BatchRealMessageSender, RealMessage},
topology_control::TopologyAccessor,
use super::{
action_controller::{AckActionSender, Action},
PendingAcknowledgement, RetransmissionRequestReceiver,
};
use crate::client::real_messages_control::acknowledgement_control::PacketDestination;
use crate::client::real_messages_control::message_handler::{MessageHandler, PreparationError};
use crate::client::real_messages_control::real_traffic_stream::RealMessage;
use crate::client::replies::reply_controller::ReplyControllerSender;
use client_connections::TransmissionLane;
use futures::StreamExt;
use log::*;
use nymsphinx::preparer::MessagePreparer;
use nymsphinx::{acknowledgements::AckKey, addressing::clients::Recipient};
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::chunking::fragment::Fragment;
use nymsphinx::preparer::PreparedFragment;
use rand::{CryptoRng, Rng};
use std::sync::{Arc, Weak};
// responsible for packet retransmission upon fired timer
pub(super) struct RetransmissionRequestListener<R>
where
R: CryptoRng + Rng,
{
ack_key: Arc<AckKey>,
ack_recipient: Recipient,
message_preparer: MessagePreparer<R>,
action_sender: ActionSender,
real_message_sender: BatchRealMessageSender,
pub(super) struct RetransmissionRequestListener<R> {
action_sender: AckActionSender,
message_handler: MessageHandler<R>,
request_receiver: RetransmissionRequestReceiver,
topology_access: TopologyAccessor,
reply_controller_sender: ReplyControllerSender,
}
impl<R> RetransmissionRequestListener<R>
@@ -34,44 +31,71 @@ where
R: CryptoRng + Rng,
{
pub(super) fn new(
ack_key: Arc<AckKey>,
ack_recipient: Recipient,
message_preparer: MessagePreparer<R>,
action_sender: ActionSender,
real_message_sender: BatchRealMessageSender,
action_sender: AckActionSender,
message_handler: MessageHandler<R>,
request_receiver: RetransmissionRequestReceiver,
topology_access: TopologyAccessor,
reply_controller_sender: ReplyControllerSender,
) -> Self {
RetransmissionRequestListener {
ack_key,
ack_recipient,
message_preparer,
action_sender,
real_message_sender,
message_handler,
request_receiver,
topology_access,
reply_controller_sender,
}
}
async fn on_retransmission_request(&mut self, timed_out_ack: Weak<PendingAcknowledgement>) {
let timed_out_ack = match timed_out_ack.upgrade() {
async fn prepare_normal_retransmission_chunk(
&mut self,
packet_recipient: Recipient,
chunk_data: Fragment,
) -> Result<PreparedFragment, PreparationError> {
debug!("retransmitting normal packet...");
self.message_handler
.try_prepare_single_chunk_for_sending(packet_recipient, chunk_data)
.await
}
async fn on_retransmission_request(
&mut self,
weak_timed_out_ack: Weak<PendingAcknowledgement>,
) {
let timed_out_ack = match weak_timed_out_ack.upgrade() {
Some(timed_out_ack) => timed_out_ack,
None => {
debug!("We received an ack JUST as we were about to retransmit [1]");
return;
}
};
let packet_recipient = &timed_out_ack.recipient;
let chunk_clone = timed_out_ack.message_chunk.clone();
let frag_id = chunk_clone.fragment_identifier();
let topology_permit = self.topology_access.get_read_permit().await;
let topology_ref = match topology_permit
.try_get_valid_topology_ref(&self.ack_recipient, Some(packet_recipient))
{
Some(topology_ref) => topology_ref,
None => {
warn!("Could not retransmit the packet - the network topology is invalid");
let maybe_prepared_fragment = match &timed_out_ack.destination {
PacketDestination::Anonymous {
recipient_tag,
extra_surb_request,
} => {
// if this is retransmission for reply, offload it to the dedicated task
// that deals with all the surbs
return self.reply_controller_sender.send_retransmission_data(
*recipient_tag,
weak_timed_out_ack,
*extra_surb_request,
);
}
PacketDestination::KnownRecipient(recipient) => {
self.prepare_normal_retransmission_chunk(
**recipient,
timed_out_ack.message_chunk.clone(),
)
.await
}
};
let frag_id = timed_out_ack.message_chunk.fragment_identifier();
let prepared_fragment = match maybe_prepared_fragment {
Ok(prepared_fragment) => prepared_fragment,
Err(err) => {
warn!("Could not retransmit the packet - {err}");
// we NEED to start timer here otherwise we will have this guy permanently stuck in memory
self.action_sender
.unbounded_send(Action::new_start_timer(frag_id))
@@ -80,12 +104,6 @@ where
}
};
let prepared_fragment = self
.message_preparer
.prepare_chunk_for_sending(chunk_clone, topology_ref, &self.ack_key, packet_recipient)
.await
.unwrap();
// if we have the ONLY strong reference to the ack data, it means it was removed from the
// pending acks
if Arc::strong_count(&timed_out_ack) == 1 {
@@ -97,7 +115,6 @@ where
// we no longer need the reference - let's drop it so that if somehow `UpdateTimer` action
// reached the controller before this function terminated, the controller would not panic.
drop(timed_out_ack);
let new_delay = prepared_fragment.total_delay;
// We know this update will be reflected by the `StartTimer` Action performed when this
@@ -112,19 +129,32 @@ where
.unwrap();
// send to `OutQueueControl` to eventually send to the mix network
self.real_message_sender
.unbounded_send(vec![RealMessage::new(
prepared_fragment.mix_packet,
frag_id,
)])
.unwrap();
self.message_handler
.forward_messages(
vec![RealMessage::new(prepared_fragment.mix_packet, frag_id)],
TransmissionLane::Retransmission,
)
.await
}
pub(super) async fn run(&mut self) {
debug!("Started RetransmissionRequestListener");
while let Some(timed_out_ack) = self.request_receiver.next().await {
self.on_retransmission_request(timed_out_ack).await;
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::TaskClient) {
debug!("Started RetransmissionRequestListener with graceful shutdown support");
while !shutdown.is_shutdown() {
tokio::select! {
timed_out_ack = self.request_receiver.next() => match timed_out_ack {
Some(timed_out_ack) => self.on_retransmission_request(timed_out_ack).await,
None => {
log::trace!("RetransmissionRequestListener: Stopping since channel closed");
break;
}
},
_ = shutdown.recv() => {
log::trace!("RetransmissionRequestListener: Received shutdown");
}
}
}
error!("TODO: error msg. Or maybe panic?")
shutdown.recv_timeout().await;
log::debug!("RetransmissionRequestListener: Exiting");
}
}
@@ -1,7 +1,7 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use super::action_controller::{Action, ActionSender};
use super::action_controller::{AckActionSender, Action};
use super::SentPacketNotificationReceiver;
use futures::StreamExt;
use log::*;
@@ -13,13 +13,13 @@ use nymsphinx::chunking::fragment::{FragmentIdentifier, COVER_FRAG_ID};
/// accidentally fire retransmission way quicker than we should have.
pub(super) struct SentNotificationListener {
sent_notifier: SentPacketNotificationReceiver,
action_sender: ActionSender,
action_sender: AckActionSender,
}
impl SentNotificationListener {
pub(super) fn new(
sent_notifier: SentPacketNotificationReceiver,
action_sender: ActionSender,
action_sender: AckActionSender,
) -> Self {
SentNotificationListener {
sent_notifier,
@@ -31,22 +31,32 @@ impl SentNotificationListener {
if frag_id == COVER_FRAG_ID {
trace!("sent off a cover message - no need to start retransmission timer!");
return;
} else if frag_id.is_reply() {
debug!("sent off a reply message - no need to start retransmission timer!");
// TODO: probably there will need to be some extra procedure here, like it would
// be nice to know that our reply actually reached the recipient (i.e. we got the ack)
return;
}
self.action_sender
.unbounded_send(Action::new_start_timer(frag_id))
.unwrap();
}
pub(super) async fn run(&mut self) {
debug!("Started SentNotificationListener");
while let Some(frag_id) = self.sent_notifier.next().await {
self.on_sent_message(frag_id).await;
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::TaskClient) {
debug!("Started SentNotificationListener with graceful shutdown support");
while !shutdown.is_shutdown() {
tokio::select! {
frag_id = self.sent_notifier.next() => match frag_id {
Some(frag_id) => {
self.on_sent_message(frag_id).await;
}
None => {
log::trace!("SentNotificationListener: Stopping since channel closed");
break;
}
},
_ = shutdown.recv_with_delay() => {
log::trace!("SentNotificationListener: Received shutdown");
}
}
}
error!("TODO: error msg. Or maybe panic?")
assert!(shutdown.is_shutdown_poll());
log::debug!("SentNotificationListener: Exiting");
}
}
@@ -0,0 +1,566 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::real_messages_control::acknowledgement_control::PendingAcknowledgement;
use crate::client::real_messages_control::real_traffic_stream::{
BatchRealMessageSender, RealMessage,
};
use crate::client::real_messages_control::{AckActionSender, Action};
use crate::client::replies::reply_storage::{ReceivedReplySurbsMap, SentReplyKeys, UsedSenderTags};
use crate::client::topology_control::{TopologyAccessor, TopologyReadPermit};
use client_connections::TransmissionLane;
use log::{debug, error, info, trace, warn};
use nymsphinx::acknowledgements::AckKey;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::anonymous_replies::requests::{AnonymousSenderTag, RepliableMessage, ReplyMessage};
use nymsphinx::anonymous_replies::{ReplySurb, SurbEncryptionKey};
use nymsphinx::chunking::fragment::{Fragment, FragmentIdentifier};
use nymsphinx::message::NymMessage;
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;
use topology::{NymTopology, NymTopologyError};
// TODO: move that error elsewhere since it seems to be contaminating different files
#[derive(Debug, Clone, Error)]
pub enum PreparationError {
#[error(transparent)]
NymTopologyError(#[from] NymTopologyError),
#[error("The received message cannot be sent using a single reply surb. It ended up getting split into {fragments} fragments.")]
MessageTooLongForSingleSurb { fragments: usize },
#[error("Not enough reply SURBs to send the message. We have {available} available and require at least {required}.")]
NotEnoughSurbs { available: usize, required: usize },
}
impl PreparationError {
fn return_surbs(self, returned_surbs: Vec<ReplySurb>) -> SurbWrappedPreparationError {
SurbWrappedPreparationError {
source: self,
returned_surbs: Some(returned_surbs),
}
}
}
#[derive(Debug, Error)]
#[error("Failed to prepare packets - {source}. {} reply surbs will be returned", .returned_surbs.as_ref().map(|s| s.len()).unwrap_or_default())]
pub struct SurbWrappedPreparationError {
#[source]
source: PreparationError,
returned_surbs: Option<Vec<ReplySurb>>,
}
impl<T> From<T> for SurbWrappedPreparationError
where
T: Into<PreparationError>,
{
fn from(err: T) -> Self {
SurbWrappedPreparationError {
source: err.into(),
returned_surbs: None,
}
}
}
impl SurbWrappedPreparationError {
pub(crate) fn return_unused_surbs(
self,
surb_storage: &ReceivedReplySurbsMap,
target: &AnonymousSenderTag,
) -> PreparationError {
if let Some(reply_surbs) = self.returned_surbs {
surb_storage.insert_surbs(target, reply_surbs)
}
self.source
}
}
#[derive(Clone)]
pub(crate) struct Config {
/// Key used to decrypt contents of received SURBAcks
ack_key: Arc<AckKey>,
/// Address of this client which also represent an address to which all acknowledgements
/// and surb-based are going to be sent.
sender_address: Recipient,
/// Average delay a data packet is going to get delay at a single mixnode.
average_packet_delay: Duration,
/// Average delay an acknowledgement packet is going to get delay at a single mixnode.
average_ack_delay: Duration,
/// Number of mix hops each packet ('real' message, ack, reply) is expected to take.
/// Note that it does not include gateway hops.
num_mix_hops: u8,
/// Predefined packet size used for the encapsulated messages.
packet_size: PacketSize,
}
impl Config {
pub fn new(
ack_key: Arc<AckKey>,
sender_address: Recipient,
average_packet_delay: Duration,
average_ack_delay: Duration,
) -> Self {
Config {
ack_key,
sender_address,
average_packet_delay,
average_ack_delay,
num_mix_hops: DEFAULT_NUM_MIX_HOPS,
packet_size: PacketSize::default(),
}
}
/// Allows setting non-default number of expected mix hops in the network.
#[allow(dead_code)]
pub fn with_mix_hops(mut self, hops: u8) -> Self {
self.num_mix_hops = hops;
self
}
/// Allows setting non-default size of the sphinx packets sent out.
pub fn with_custom_packet_size(mut self, packet_size: PacketSize) -> Self {
self.packet_size = packet_size;
self
}
}
#[derive(Clone)]
pub(crate) struct MessageHandler<R> {
config: Config,
rng: R,
message_preparer: MessagePreparer<R>,
action_sender: AckActionSender,
real_message_sender: BatchRealMessageSender,
topology_access: TopologyAccessor,
reply_key_storage: SentReplyKeys,
tag_storage: UsedSenderTags,
}
impl<R> MessageHandler<R>
where
R: CryptoRng + Rng,
{
pub(crate) fn new(
config: Config,
rng: R,
action_sender: AckActionSender,
real_message_sender: BatchRealMessageSender,
topology_access: TopologyAccessor,
reply_key_storage: SentReplyKeys,
tag_storage: UsedSenderTags,
) -> Self
where
R: Copy,
{
let message_preparer = MessagePreparer::new(
rng,
config.sender_address,
config.average_packet_delay,
config.average_ack_delay,
)
.with_custom_real_message_packet_size(config.packet_size)
.with_mix_hops(config.num_mix_hops);
MessageHandler {
config,
rng,
message_preparer,
action_sender,
real_message_sender,
topology_access,
reply_key_storage,
tag_storage,
}
}
fn get_or_create_sender_tag(&mut self, recipient: &Recipient) -> AnonymousSenderTag {
if let Some(existing) = self.tag_storage.try_get_existing(recipient) {
trace!("we already had sender tag for {recipient}");
existing
} else {
info!("creating new sender tag for {recipient}");
let new_tag = AnonymousSenderTag::new_random(&mut self.rng);
self.tag_storage.insert_new(recipient, new_tag);
info!("we'll be using {new_tag} for all anonymous messages sent to {recipient}");
new_tag
}
}
fn get_topology<'a>(
&self,
permit: &'a TopologyReadPermit<'a>,
) -> Result<&'a NymTopology, PreparationError> {
match permit.try_get_valid_topology_ref(&self.config.sender_address, None) {
Ok(topology_ref) => Ok(topology_ref),
Err(err) => {
warn!("Could not process the packet - the network topology is invalid - {err}");
Err(err.into())
}
}
}
async fn generate_reply_surbs_with_keys(
&mut self,
amount: usize,
) -> Result<(Vec<ReplySurb>, Vec<SurbEncryptionKey>), PreparationError> {
let topology_permit = self.topology_access.get_read_permit().await;
let topology = self.get_topology(&topology_permit)?;
let reply_surbs = self
.message_preparer
.generate_reply_surbs(amount, topology)?;
let reply_keys = reply_surbs
.iter()
.map(|s| *s.encryption_key())
.collect::<Vec<_>>();
Ok((reply_surbs, reply_keys))
}
pub(crate) async fn try_send_single_surb_message(
&mut self,
target: AnonymousSenderTag,
message: ReplyMessage,
reply_surb: ReplySurb,
is_extra_surb_request: bool,
) -> Result<(), SurbWrappedPreparationError> {
let mut fragment = self
.message_preparer
.pad_and_split_message(NymMessage::new_reply(message));
if fragment.len() > 1 {
// well, it's not a single surb message
return Err(SurbWrappedPreparationError {
source: PreparationError::MessageTooLongForSingleSurb {
fragments: fragment.len(),
},
returned_surbs: Some(vec![reply_surb]),
});
}
let chunk = fragment.pop().unwrap();
let chunk_clone = chunk.clone();
let prepared_fragment = self
.try_prepare_single_reply_chunk_for_sending(reply_surb, chunk_clone)
.await?;
let real_messages =
RealMessage::new(prepared_fragment.mix_packet, chunk.fragment_identifier());
let delay = prepared_fragment.total_delay;
let pending_ack =
PendingAcknowledgement::new_anonymous(chunk, delay, target, is_extra_surb_request);
let lane = if is_extra_surb_request {
TransmissionLane::ReplySurbRequest
} else {
TransmissionLane::General
};
self.forward_messages(vec![real_messages], lane).await;
self.insert_pending_acks(vec![pending_ack]);
Ok(())
}
pub(crate) async fn try_request_additional_reply_surbs(
&mut self,
from: AnonymousSenderTag,
reply_surb: ReplySurb,
amount: u32,
) -> Result<(), SurbWrappedPreparationError> {
debug!("requesting {amount} reply SURBs from {from}");
let surbs_request =
ReplyMessage::new_surb_request_message(self.config.sender_address, amount);
self.try_send_single_surb_message(from, surbs_request, reply_surb, true)
.await
}
// // TODO: this will require additional argument to make it use different variant of `ReplyMessage`
pub(crate) fn split_reply_message(&mut self, message: Vec<u8>) -> Vec<Fragment> {
self.message_preparer
.pad_and_split_message(NymMessage::new_reply(ReplyMessage::new_data_message(
message,
)))
}
pub(crate) async fn send_retransmission_reply_chunks(
&mut self,
prepared_fragments: Vec<PreparedFragment>,
lane: TransmissionLane,
) {
let mut real_messages = Vec::with_capacity(prepared_fragments.len());
for prepared in prepared_fragments {
self.update_ack_delay(prepared.fragment_identifier, prepared.total_delay);
real_messages.push(prepared.into())
}
self.forward_messages(real_messages, lane).await;
}
pub(crate) async fn try_send_reply_chunks_on_lane(
&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,
)
.await?;
let mut pending_acks = Vec::with_capacity(fragments.len());
let mut to_forward: HashMap<_, Vec<_>> = HashMap::new();
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 entry = to_forward.entry(lane).or_default();
entry.push(real_message);
pending_acks.push(pending_ack);
}
for (lane, real_messages) in to_forward {
self.forward_messages(real_messages, lane).await;
}
self.insert_pending_acks(pending_acks);
Ok(())
}
pub(crate) async fn try_send_plain_message(
&mut self,
recipient: Recipient,
message: Vec<u8>,
lane: TransmissionLane,
) -> Result<(), PreparationError> {
let message = NymMessage::new_plain(message);
self.try_split_and_send_non_reply_message(message, recipient, lane)
.await
}
pub(crate) async fn try_split_and_send_non_reply_message(
&mut self,
message: NymMessage,
recipient: Recipient,
lane: TransmissionLane,
) -> Result<(), PreparationError> {
// TODO: I really dislike existence of this assertion, it implies code has to be re-organised
debug_assert!(!matches!(message, NymMessage::Reply(_)));
// TODO2: it's really annoying we have to get topology permit again here due to borrow-checker
let topology_permit = self.topology_access.get_read_permit().await;
let topology = self.get_topology(&topology_permit)?;
let fragments = self.message_preparer.pad_and_split_message(message);
let mut pending_acks = Vec::with_capacity(fragments.len());
let mut real_messages = Vec::with_capacity(fragments.len());
for fragment in fragments {
// we need to clone it because we need to keep it in memory in case we had to retransmit
// it. And then we'd need to recreate entire ACK again.
let chunk_clone = fragment.clone();
let prepared_fragment = self.message_preparer.prepare_chunk_for_sending(
chunk_clone,
topology,
&self.config.ack_key,
&recipient,
)?;
let real_message =
RealMessage::new(prepared_fragment.mix_packet, fragment.fragment_identifier());
let delay = prepared_fragment.total_delay;
let pending_ack = PendingAcknowledgement::new_known(fragment, delay, recipient);
real_messages.push(real_message);
pending_acks.push(pending_ack);
}
self.insert_pending_acks(pending_acks);
self.forward_messages(real_messages, lane).await;
Ok(())
}
pub(crate) async fn try_send_additional_reply_surbs(
&mut self,
recipient: Recipient,
amount: u32,
) -> Result<(), PreparationError> {
let sender_tag = self.get_or_create_sender_tag(&recipient);
let (reply_surbs, reply_keys) =
self.generate_reply_surbs_with_keys(amount as usize).await?;
let message = NymMessage::new_repliable(RepliableMessage::new_additional_surbs(
sender_tag,
reply_surbs,
));
self.try_split_and_send_non_reply_message(
message,
recipient,
TransmissionLane::AdditionalReplySurbs,
)
.await?;
log::trace!("storing {} reply keys", reply_keys.len());
self.reply_key_storage.insert_multiple(reply_keys);
Ok(())
}
pub(crate) async fn try_send_message_with_reply_surbs(
&mut self,
recipient: Recipient,
message: Vec<u8>,
num_reply_surbs: u32,
lane: TransmissionLane,
) -> Result<(), SurbWrappedPreparationError> {
let sender_tag = self.get_or_create_sender_tag(&recipient);
let (reply_surbs, reply_keys) = self
.generate_reply_surbs_with_keys(num_reply_surbs as usize)
.await?;
let message =
NymMessage::new_repliable(RepliableMessage::new_data(message, sender_tag, reply_surbs));
self.try_split_and_send_non_reply_message(message, recipient, lane)
.await?;
log::trace!("storing {} reply keys", reply_keys.len());
self.reply_key_storage.insert_multiple(reply_keys);
Ok(())
}
pub(crate) async fn try_prepare_single_chunk_for_sending(
&mut self,
recipient: Recipient,
chunk: Fragment,
) -> Result<PreparedFragment, PreparationError> {
let topology_permit = self.topology_access.get_read_permit().await;
let topology = self.get_topology(&topology_permit)?;
let prepared_fragment = self
.message_preparer
.prepare_chunk_for_sending(chunk, topology, &self.config.ack_key, &recipient)
.unwrap();
Ok(prepared_fragment)
}
pub(crate) async fn prepare_reply_chunks_for_sending(
&mut self,
fragments: Vec<Fragment>,
reply_surbs: Vec<ReplySurb>,
) -> Result<Vec<PreparedFragment>, SurbWrappedPreparationError> {
debug_assert_ne!(
fragments.len(),
reply_surbs.len(),
"attempted to send {} fragments with {} reply surbs",
fragments.len(),
reply_surbs.len()
);
let topology_permit = self.topology_access.get_read_permit().await;
let topology = match self.get_topology(&topology_permit) {
Ok(topology) => topology,
Err(err) => return Err(err.return_surbs(reply_surbs)),
};
Ok(fragments
.into_iter()
.zip(reply_surbs.into_iter())
.map(|(fragment, reply_surb)| {
// unwrap here is fine as we know we have a valid topology
self.message_preparer
.prepare_reply_chunk_for_sending(
fragment,
topology,
&self.config.ack_key,
reply_surb,
)
.unwrap()
})
.collect())
}
pub(crate) async fn try_prepare_single_reply_chunk_for_sending(
&mut self,
reply_surb: ReplySurb,
chunk: Fragment,
) -> Result<PreparedFragment, SurbWrappedPreparationError> {
let topology_permit = self.topology_access.get_read_permit().await;
let topology = match self.get_topology(&topology_permit) {
Ok(topology) => topology,
Err(err) => return Err(err.return_surbs(vec![reply_surb])),
};
let prepared_fragment = self
.message_preparer
.prepare_reply_chunk_for_sending(chunk, topology, &self.config.ack_key, reply_surb)
.unwrap();
Ok(prepared_fragment)
}
pub(crate) fn update_ack_delay(&self, id: FragmentIdentifier, new_delay: Delay) {
self.action_sender
.unbounded_send(Action::UpdateDelay(id, new_delay))
.expect("action control task has died")
}
pub(crate) fn insert_pending_acks(&self, pending_acks: Vec<PendingAcknowledgement>) {
self.action_sender
.unbounded_send(Action::new_insert(pending_acks))
.expect("action control task has died")
}
// tells real message sender (with the poisson timer) to send this to the mix network
pub(crate) async fn forward_messages(
&self,
messages: Vec<RealMessage>,
transmission_lane: TransmissionLane,
) {
self.real_message_sender
.send((messages, transmission_lane))
.await
.expect("real message receiver task (OutQueueControl) has died");
}
}
@@ -8,24 +8,37 @@
use self::{
acknowledgement_control::AcknowledgementController, real_traffic_stream::OutQueueControl,
};
use crate::client::real_messages_control::acknowledgement_control::AcknowledgementControllerConnectors;
use crate::client::reply_key_storage::ReplyKeyStorage;
use crate::client::{
inbound_messages::InputMessageReceiver, mix_traffic::BatchMixMessageSender,
topology_control::TopologyAccessor,
use crate::client::real_messages_control::message_handler::MessageHandler;
use crate::client::replies::reply_controller::{
ReplyController, ReplyControllerReceiver, ReplyControllerSender,
};
use crate::client::replies::reply_storage::CombinedReplyStorage;
use crate::{
client::{
inbound_messages::InputMessageReceiver, mix_traffic::BatchMixMessageSender,
real_messages_control::acknowledgement_control::AcknowledgementControllerConnectors,
topology_control::TopologyAccessor,
},
spawn_future,
};
use client_connections::{ConnectionCommandReceiver, LaneQueueLengths};
use futures::channel::mpsc;
use gateway_client::AcknowledgementReceiver;
use log::*;
use nymsphinx::acknowledgements::AckKey;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::params::PacketSize;
use rand::{rngs::OsRng, CryptoRng, Rng};
use std::sync::Arc;
use std::time::Duration;
use tokio::task::JoinHandle;
mod acknowledgement_control;
mod real_traffic_stream;
use crate::client::replies::reply_controller;
use crate::config;
pub(crate) use acknowledgement_control::{AckActionSender, Action};
pub(crate) mod acknowledgement_control;
pub(crate) mod message_handler;
pub(crate) mod real_traffic_stream;
// TODO: ack_key and self_recipient shouldn't really be part of this config
pub struct Config {
@@ -49,130 +62,223 @@ pub struct Config {
/// Average delay an acknowledgement packet is going to get delayed at a single mixnode.
average_ack_delay_duration: Duration,
/// Controls whether the main packet stream constantly produces packets according to the predefined
/// poisson distribution.
disable_main_poisson_packet_distribution: bool,
/// Predefined packet size used for the encapsulated messages.
packet_size: PacketSize,
/// Defines the minimum number of reply surbs the client would request.
minimum_reply_surb_request_size: u32,
/// Defines the maximum number of reply surbs the client would request.
maximum_reply_surb_request_size: u32,
/// Defines the maximum number of reply surbs a remote party is allowed to request from this client at once.
maximum_allowed_reply_surb_request_size: u32,
/// Defines maximum amount of time the client is going to wait for reply surbs before explicitly asking
/// for more even though in theory they wouldn't need to.
maximum_reply_surb_waiting_period: Duration,
/// Defines maximum amount of time given reply surb is going to be valid for.
/// This is going to be superseded by key rotation once implemented.
maximum_reply_surb_age: Duration,
/// Defines maximum amount of time given reply key is going to be valid for.
/// This is going to be superseded by key rotation once implemented.
maximum_reply_key_age: Duration,
}
impl<'a> From<&'a Config> for acknowledgement_control::Config {
fn from(cfg: &'a Config) -> Self {
acknowledgement_control::Config::new(cfg.ack_wait_addition, cfg.ack_wait_multiplier)
.with_custom_packet_size(cfg.packet_size)
}
}
impl<'a> From<&'a Config> for real_traffic_stream::Config {
fn from(cfg: &'a Config) -> Self {
real_traffic_stream::Config::new(
Arc::clone(&cfg.ack_key),
cfg.self_recipient,
cfg.average_ack_delay_duration,
cfg.average_packet_delay_duration,
cfg.average_message_sending_delay,
cfg.disable_main_poisson_packet_distribution,
)
.with_custom_cover_packet_size(cfg.packet_size)
}
}
impl<'a> From<&'a Config> for reply_controller::Config {
fn from(cfg: &'a Config) -> Self {
reply_controller::Config::new(
cfg.minimum_reply_surb_request_size,
cfg.maximum_reply_surb_request_size,
cfg.maximum_allowed_reply_surb_request_size,
cfg.maximum_reply_surb_waiting_period,
cfg.maximum_reply_surb_age,
cfg.maximum_reply_key_age,
)
}
}
impl<'a> From<&'a Config> for message_handler::Config {
fn from(cfg: &'a Config) -> Self {
message_handler::Config::new(
Arc::clone(&cfg.ack_key),
cfg.self_recipient,
cfg.average_packet_delay_duration,
cfg.average_ack_delay_duration,
)
.with_custom_packet_size(cfg.packet_size)
}
}
impl Config {
pub fn new(
base_client_debug_config: &config::DebugConfig,
ack_key: Arc<AckKey>,
ack_wait_multiplier: f64,
ack_wait_addition: Duration,
average_ack_delay_duration: Duration,
average_message_sending_delay: Duration,
average_packet_delay_duration: Duration,
self_recipient: Recipient,
) -> Self {
Config {
ack_key,
ack_wait_addition,
ack_wait_multiplier,
self_recipient,
average_message_sending_delay,
average_packet_delay_duration,
average_ack_delay_duration,
packet_size: Default::default(),
ack_wait_addition: base_client_debug_config.ack_wait_addition,
ack_wait_multiplier: base_client_debug_config.ack_wait_multiplier,
average_message_sending_delay: base_client_debug_config.message_sending_average_delay,
average_packet_delay_duration: base_client_debug_config.average_packet_delay,
average_ack_delay_duration: base_client_debug_config.average_ack_delay,
disable_main_poisson_packet_distribution: base_client_debug_config
.disable_main_poisson_packet_distribution,
minimum_reply_surb_request_size: base_client_debug_config
.minimum_reply_surb_request_size,
maximum_reply_surb_request_size: base_client_debug_config
.maximum_reply_surb_request_size,
maximum_allowed_reply_surb_request_size: base_client_debug_config
.maximum_allowed_reply_surb_request_size,
maximum_reply_surb_waiting_period: base_client_debug_config
.maximum_reply_surb_waiting_period,
maximum_reply_surb_age: base_client_debug_config.maximum_reply_surb_age,
maximum_reply_key_age: base_client_debug_config.maximum_reply_key_age,
}
}
pub fn set_custom_packet_size(&mut self, packet_size: PacketSize) {
self.packet_size = packet_size;
}
}
pub struct RealMessagesController<R>
pub(crate) struct RealMessagesController<R>
where
R: CryptoRng + Rng,
{
out_queue_control: Option<OutQueueControl<R>>,
ack_control: Option<AcknowledgementController<R>>,
out_queue_control: OutQueueControl<R>,
ack_control: AcknowledgementController<R>,
reply_control: ReplyController<R>,
}
// obviously when we finally make shared rng that is on 'higher' level, this should become
// generic `R`
impl RealMessagesController<OsRng> {
pub fn new(
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
config: Config,
ack_receiver: AcknowledgementReceiver,
input_receiver: InputMessageReceiver,
mix_sender: BatchMixMessageSender,
topology_access: TopologyAccessor,
reply_key_storage: ReplyKeyStorage,
reply_storage: CombinedReplyStorage,
// so much refactoring needed, but this is temporary just to test things out
reply_controller_sender: ReplyControllerSender,
reply_controller_receiver: ReplyControllerReceiver,
lane_queue_lengths: LaneQueueLengths,
client_connection_rx: ConnectionCommandReceiver,
) -> Self {
let rng = OsRng;
let (real_message_sender, real_message_receiver) = mpsc::unbounded();
// create channels for inter-task communication
let (real_message_sender, real_message_receiver) = tokio::sync::mpsc::channel(1);
let (sent_notifier_tx, sent_notifier_rx) = mpsc::unbounded();
let (ack_action_tx, ack_action_rx) = mpsc::unbounded();
let ack_controller_connectors = AcknowledgementControllerConnectors::new(
real_message_sender,
input_receiver,
sent_notifier_rx,
ack_receiver,
ack_action_tx.clone(),
ack_action_rx,
);
let ack_control_config = acknowledgement_control::Config::new(
config.ack_wait_addition,
config.ack_wait_multiplier,
config.average_ack_delay_duration,
config.average_packet_delay_duration,
// create all configs for the components
let ack_control_config = (&config).into();
let out_queue_config = (&config).into();
let reply_controller_config = (&config).into();
let message_handler_config = (&config).into();
// create the actual components
let message_handler = MessageHandler::new(
message_handler_config,
rng,
ack_action_tx,
real_message_sender,
topology_access.clone(),
reply_storage.key_storage(),
reply_storage.tags_storage(),
);
let ack_control = AcknowledgementController::new(
ack_control_config,
rng,
topology_access.clone(),
Arc::clone(&config.ack_key),
config.self_recipient,
reply_key_storage,
ack_controller_connectors,
message_handler.clone(),
reply_controller_sender,
);
let out_queue_config = real_traffic_stream::Config::new(
config.average_ack_delay_duration,
config.average_packet_delay_duration,
config.average_message_sending_delay,
let reply_control = ReplyController::new(
reply_controller_config,
message_handler,
reply_storage,
reply_controller_receiver,
);
let out_queue_control = OutQueueControl::new(
out_queue_config,
Arc::clone(&config.ack_key),
rng,
sent_notifier_tx,
mix_sender,
real_message_receiver,
rng,
config.self_recipient,
topology_access,
lane_queue_lengths,
client_connection_rx,
);
RealMessagesController {
out_queue_control: Some(out_queue_control),
ack_control: Some(ack_control),
out_queue_control,
ack_control,
reply_control,
}
}
pub(super) async fn run(&mut self) {
let mut out_queue_control = self.out_queue_control.take().unwrap();
let mut ack_control = self.ack_control.take().unwrap();
pub fn start_with_shutdown(self, shutdown: task::TaskClient) {
let mut out_queue_control = self.out_queue_control;
let ack_control = self.ack_control;
let mut reply_control = self.reply_control;
// the below are log messages are errors as at the current stage we do not expect any of
// the task to ever finish. This will of course change once we introduce
// graceful shutdowns.
let out_queue_control_fut = tokio::spawn(async move {
out_queue_control.run_out_queue_control().await;
error!("The out queue controller has finished execution!");
out_queue_control
let shutdown_handle = shutdown.clone();
spawn_future(async move {
out_queue_control.run_with_shutdown(shutdown_handle).await;
debug!("The out queue controller has finished execution!");
});
let ack_control_fut = tokio::spawn(async move {
ack_control.run().await;
error!("The acknowledgement controller has finished execution!");
ack_control
let shutdown_handle = shutdown.clone();
spawn_future(async move {
reply_control.run_with_shutdown(shutdown_handle).await;
debug!("The reply controller has finished execution!");
});
// technically we don't have to bring `RealMessagesController` back to a valid state
// but we can do it, so why not? Perhaps it might be useful if we wanted to allow
// for restarts of certain modules without killing the entire process.
self.out_queue_control = Some(out_queue_control_fut.await.unwrap());
self.ack_control = Some(ack_control_fut.await.unwrap());
}
pub fn start(mut self) -> JoinHandle<Self> {
tokio::spawn(async move {
self.run().await;
self
})
ack_control.start_with_shutdown(shutdown);
}
}
@@ -1,10 +1,14 @@
// 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 futures::channel::mpsc;
use crate::client::transmission_buffer::TransmissionBuffer;
use client_connections::{
ConnectionCommand, ConnectionCommandReceiver, ConnectionId, LaneQueueLengths, TransmissionLane,
};
use futures::task::{Context, Poll};
use futures::{Future, Stream, StreamExt};
use log::*;
@@ -13,16 +17,30 @@ use nymsphinx::addressing::clients::Recipient;
use nymsphinx::chunking::fragment::FragmentIdentifier;
use nymsphinx::cover::generate_loop_cover_packet;
use nymsphinx::forwarding::packet::MixPacket;
use nymsphinx::params::PacketSize;
use nymsphinx::preparer::PreparedFragment;
use nymsphinx::utils::sample_poisson_duration;
use rand::{CryptoRng, Rng};
use std::collections::VecDeque;
use std::pin::Pin;
use std::sync::Arc;
use std::time::Duration;
#[cfg(not(target_arch = "wasm32"))]
use tokio::time;
#[cfg(target_arch = "wasm32")]
use wasm_timer;
mod sending_delay_controller;
/// Configurable parameters of the `OutQueueControl`
pub(crate) struct Config {
/// Key used to encrypt and decrypt content of an ACK packet.
ack_key: Arc<AckKey>,
/// Represents full address of this client.
our_full_destination: Recipient,
/// Average delay an acknowledgement packet is going to get delay at a single mixnode.
average_ack_delay: Duration,
@@ -31,20 +49,39 @@ pub(crate) struct Config {
/// Average delay between sending subsequent packets.
average_message_sending_delay: Duration,
/// Controls whether the stream constantly produces packets according to the predefined
/// poisson distribution.
disable_poisson_packet_distribution: bool,
/// Predefined packet size used for the loop cover messages.
cover_packet_size: PacketSize,
}
impl Config {
pub(crate) fn new(
ack_key: Arc<AckKey>,
our_full_destination: Recipient,
average_ack_delay: Duration,
average_packet_delay: Duration,
average_message_sending_delay: Duration,
disable_poisson_packet_distribution: bool,
) -> Self {
Config {
ack_key,
our_full_destination,
average_ack_delay,
average_packet_delay,
average_message_sending_delay,
disable_poisson_packet_distribution,
cover_packet_size: Default::default(),
}
}
pub fn with_custom_cover_packet_size(mut self, packet_size: PacketSize) -> Self {
self.cover_packet_size = packet_size;
self
}
}
pub(crate) struct OutQueueControl<R>
@@ -54,15 +91,20 @@ where
/// Configurable parameters of the `ActionController`
config: Config,
/// Key used to encrypt and decrypt content of an ACK packet.
ack_key: Arc<AckKey>,
/// Channel used for notifying of a real packet being sent out. Used to start up retransmission timer.
sent_notifier: SentPacketNotificationSender,
/// Internal state, determined by `average_message_sending_delay`,
/// used to keep track of when a next packet should be sent out.
next_delay: Pin<Box<time::Sleep>>,
#[cfg(not(target_arch = "wasm32"))]
next_delay: Option<Pin<Box<time::Sleep>>>,
#[cfg(target_arch = "wasm32")]
next_delay: Option<Pin<Box<wasm_timer::Delay>>>,
// To make sure we don't overload the mix_tx channel, we limit the rate we are pushing
// messages.
sending_delay_controller: SendingDelayController,
/// Channel used for sending prepared sphinx packets to `MixTrafficController` that sends them
/// out to the network without any further delays.
@@ -72,25 +114,45 @@ where
/// before being sent out into the network.
real_receiver: BatchRealMessageReceiver,
/// Represents full address of this client.
our_full_destination: Recipient,
/// Instance of a cryptographically secure random number generator.
rng: R,
/// Accessor to the common instance of network topology.
topology_access: TopologyAccessor,
/// Buffer containing all real messages received. It is first exhausted before more are pulled.
received_buffer: VecDeque<RealMessage>,
/// Buffer containing all incoming real messages keyed by transmission lane, that we will send
/// out to the mixnet.
transmission_buffer: TransmissionBuffer<RealMessage>,
/// Incoming channel for being notified of closed connections, so that we can close lanes
/// corresponding to connections. To avoid sending traffic unnecessary
client_connection_rx: ConnectionCommandReceiver,
/// Report queue lengths so that upstream can backoff sending data, and keep connections open.
lane_queue_lengths: LaneQueueLengths,
}
#[derive(Debug)]
pub(crate) struct RealMessage {
mix_packet: MixPacket,
fragment_id: FragmentIdentifier,
// TODO: add info about it being constructed with reply-surb
}
impl From<PreparedFragment> for RealMessage {
fn from(fragment: PreparedFragment) -> Self {
RealMessage {
mix_packet: fragment.mix_packet,
fragment_id: fragment.fragment_identifier,
}
}
}
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,
@@ -101,63 +163,15 @@ impl RealMessage {
// messages are already prepared, etc. the real point of it is to forward it to mix_traffic
// after sufficient delay
pub(crate) type BatchRealMessageSender = mpsc::UnboundedSender<Vec<RealMessage>>;
type BatchRealMessageReceiver = mpsc::UnboundedReceiver<Vec<RealMessage>>;
pub(crate) type BatchRealMessageSender =
tokio::sync::mpsc::Sender<(Vec<RealMessage>, TransmissionLane)>;
type BatchRealMessageReceiver = tokio::sync::mpsc::Receiver<(Vec<RealMessage>, TransmissionLane)>;
pub(crate) enum StreamMessage {
Cover,
Real(Box<RealMessage>),
}
impl<R> Stream for OutQueueControl<R>
where
R: CryptoRng + Rng + Unpin,
{
type Item = StreamMessage;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
// it is not yet time to return a message
if self.next_delay.as_mut().poll(cx).is_pending() {
return Poll::Pending;
};
// we know it's time to send a message, so let's prepare delay for the next one
// Get the `now` by looking at the current `delay` deadline
let avg_delay = self.config.average_message_sending_delay;
let now = self.next_delay.deadline();
let next_poisson_delay = sample_poisson_duration(&mut self.rng, avg_delay);
// The next interval value is `next_poisson_delay` after the one that just
// yielded.
let next = now + next_poisson_delay;
self.next_delay.as_mut().reset(next);
// check if we have anything immediately available
if let Some(real_available) = self.received_buffer.pop_front() {
return Poll::Ready(Some(StreamMessage::Real(Box::new(real_available))));
}
// decide what kind of message to send
match Pin::new(&mut self.real_receiver).poll_next(cx) {
// in the case our real message channel stream was closed, we should also indicate we are closed
// (and whoever is using the stream should panic)
Poll::Ready(None) => Poll::Ready(None),
// if there are more messages available, return first one and store the rest
Poll::Ready(Some(real_messages)) => {
self.received_buffer = real_messages.into();
// we MUST HAVE received at least ONE message
Poll::Ready(Some(StreamMessage::Real(Box::new(
self.received_buffer.pop_front().unwrap(),
))))
}
// otherwise construct a dummy one
Poll::Pending => Poll::Ready(Some(StreamMessage::Cover)),
}
}
}
impl<R> OutQueueControl<R>
where
R: CryptoRng + Rng + Unpin,
@@ -167,25 +181,26 @@ where
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
config: Config,
ack_key: Arc<AckKey>,
rng: R,
sent_notifier: SentPacketNotificationSender,
mix_tx: BatchMixMessageSender,
real_receiver: BatchRealMessageReceiver,
rng: R,
our_full_destination: Recipient,
topology_access: TopologyAccessor,
lane_queue_lengths: LaneQueueLengths,
client_connection_rx: ConnectionCommandReceiver,
) -> Self {
OutQueueControl {
config,
ack_key,
sent_notifier,
next_delay: Box::pin(time::sleep(Default::default())),
next_delay: None,
sending_delay_controller: Default::default(),
mix_tx,
real_receiver,
our_full_destination,
rng,
topology_access,
received_buffer: VecDeque::with_capacity(0), // we won't be putting any data into this guy directly
transmission_buffer: TransmissionBuffer::new(),
client_connection_rx,
lane_queue_lengths,
}
}
@@ -200,70 +215,359 @@ where
async fn on_message(&mut self, next_message: StreamMessage) {
trace!("created new message");
let next_message = match next_message {
let (next_message, fragment_id) = match next_message {
StreamMessage::Cover => {
// TODO for way down the line: in very rare cases (during topology update) we might have
// to wait a really tiny bit before actually obtaining the permit hence messing with our
// poisson delay, but is it really a problem?
let topology_permit = self.topology_access.get_read_permit().await;
// the ack is sent back to ourselves (and then ignored)
let topology_ref_option = topology_permit.try_get_valid_topology_ref(
&self.our_full_destination,
Some(&self.our_full_destination),
);
if topology_ref_option.is_none() {
warn!(
"No valid topology detected - won't send any loop cover message this time"
);
return;
}
let topology_ref = topology_ref_option.unwrap();
let topology_ref = match topology_permit.try_get_valid_topology_ref(
&self.config.our_full_destination,
Some(&self.config.our_full_destination),
) {
Ok(topology) => topology,
Err(err) => {
warn!("We're not going to send any loop cover message this time, as the current topology seem to be invalid - {err}");
return;
}
};
generate_loop_cover_packet(
&mut self.rng,
topology_ref,
&*self.ack_key,
&self.our_full_destination,
self.config.average_ack_delay,
self.config.average_packet_delay,
(
generate_loop_cover_packet(
&mut self.rng,
topology_ref,
&self.config.ack_key,
&self.config.our_full_destination,
self.config.average_ack_delay,
self.config.average_packet_delay,
self.config.cover_packet_size,
)
.expect(
"Somehow failed to generate a loop cover message with a valid topology",
),
None,
)
.expect("Somehow failed to generate a loop cover message with a valid topology")
}
StreamMessage::Real(real_message) => {
self.sent_notify(real_message.fragment_id);
real_message.mix_packet
(real_message.mix_packet, Some(real_message.fragment_id))
}
};
// if this one fails, there's no retrying because it means that either:
// - we run out of memory
// - the receiver channel is closed
// in either case there's no recovery and we can only panic
self.mix_tx.unbounded_send(vec![next_message]).unwrap();
if let Err(err) = self.mix_tx.send(vec![next_message]).await {
log::error!("Failed to send: {err}");
}
// notify ack controller about sending our message only after we actually managed to push it
// through the channel
if let Some(fragment_id) = fragment_id {
self.sent_notify(fragment_id);
}
// In addition to closing connections on receiving messages throught client_connection_rx,
// also close connections when sufficiently stale.
self.transmission_buffer.prune_stale_connections();
// JS: Not entirely sure why or how it fixes stuff, but without the yield call,
// the UnboundedReceiver [of mix_rx] will not get a chance to read anything
// JS2: Basically it was the case that with high enough rate, the stream had already a next value
// ready and hence was immediately re-scheduled causing other tasks to be starved;
// yield makes it go back the scheduling queue regardless of its value availability
// TODO: temporary and BAD workaround for wasm (we should find a way to yield here in wasm)
#[cfg(not(target_arch = "wasm32"))]
tokio::task::yield_now().await;
}
// Send messages at certain rate and if no real traffic is available, send cover message.
async fn run_normal_out_queue(&mut self) {
// we should set initial delay only when we actually start the stream
self.next_delay = Box::pin(time::sleep(sample_poisson_duration(
&mut self.rng,
self.config.average_message_sending_delay,
)));
fn on_close_connection(&mut self, connection_id: ConnectionId) {
log::debug!("Removing lane for connection: {connection_id}");
self.transmission_buffer
.remove(&TransmissionLane::ConnectionId(connection_id));
}
while let Some(next_message) = self.next().await {
self.on_message(next_message).await;
fn current_average_message_sending_delay(&self) -> Duration {
self.config.average_message_sending_delay
* self.sending_delay_controller.current_multiplier()
}
fn adjust_current_average_message_sending_delay(&mut self) {
let used_slots = self.mix_tx.max_capacity() - self.mix_tx.capacity();
log::trace!(
"used_slots: {used_slots}, current_multiplier: {}",
self.sending_delay_controller.current_multiplier()
);
// Even just a single used slot is enough to signal backpressure
if used_slots > 0 {
log::trace!("Backpressure detected");
self.sending_delay_controller.record_backpressure_detected();
}
// If the buffer is running out, slow down the sending rate
if self.mix_tx.capacity() == 0
&& self.sending_delay_controller.not_increased_delay_recently()
{
self.sending_delay_controller.increase_delay_multiplier();
}
// Very carefully step up the sending rate in case it seems like we can solidly handle the
// current rate.
if self.sending_delay_controller.is_sending_reliable() {
self.sending_delay_controller.decrease_delay_multiplier();
}
}
pub(crate) async fn run_out_queue_control(&mut self) {
debug!("Starting out queue controller...");
self.run_normal_out_queue().await
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)?;
// Update the published queue length
let lane_length = self.transmission_buffer.lane_length(&lane);
self.lane_queue_lengths.set(&lane, lane_length);
Some(real_next)
}
fn poll_poisson(&mut self, cx: &mut Context<'_>) -> Poll<Option<StreamMessage>> {
// The average delay could change depending on if backpressure in the downstream channel
// (mix_tx) was detected.
self.adjust_current_average_message_sending_delay();
let avg_delay = self.current_average_message_sending_delay();
// Start by checking if we have any incoming messages about closed connections
// NOTE: this feels a bit iffy, the `OutQueueControl` is getting ripe for a rewrite to
// something simpler.
if let Poll::Ready(Some(id)) = Pin::new(&mut self.client_connection_rx).poll_next(cx) {
match id {
ConnectionCommand::Close(id) => self.on_close_connection(id),
ConnectionCommand::ActiveConnections(_) => panic!(),
}
}
if let Some(ref mut next_delay) = &mut self.next_delay {
// it is not yet time to return a message
if next_delay.as_mut().poll(cx).is_pending() {
return Poll::Pending;
};
// we know it's time to send a message, so let's prepare delay for the next one
// Get the `now` by looking at the current `delay` deadline
let next_poisson_delay = sample_poisson_duration(&mut self.rng, avg_delay);
// The next interval value is `next_poisson_delay` after the one that just
// yielded.
#[cfg(not(target_arch = "wasm32"))]
{
let now = next_delay.deadline();
let next = now + next_poisson_delay;
next_delay.as_mut().reset(next);
}
#[cfg(target_arch = "wasm32")]
{
next_delay.as_mut().reset(next_poisson_delay);
}
// On every iteration we get new messages from upstream. Given that these come bunched
// in `Vec`, this ensures that on average we will fetch messages faster than we can
// send, which is a condition for being able to multiplex sphinx packets from multiple
// data streams.
match Pin::new(&mut self.real_receiver).poll_recv(cx) {
// in the case our real message channel stream was closed, we should also indicate we are closed
// (and whoever is using the stream should panic)
Poll::Ready(None) => Poll::Ready(None),
Poll::Ready(Some((real_messages, conn_id))) => {
log::trace!("handling real_messages: size: {}", real_messages.len());
self.transmission_buffer.store(&conn_id, real_messages);
let real_next = self.pop_next_message().expect("Just stored one");
Poll::Ready(Some(StreamMessage::Real(Box::new(real_next))))
}
Poll::Pending => {
if let Some(real_next) = self.pop_next_message() {
Poll::Ready(Some(StreamMessage::Real(Box::new(real_next))))
} else {
// otherwise construct a dummy one
Poll::Ready(Some(StreamMessage::Cover))
}
}
}
} else {
// we never set an initial delay - let's do it now
cx.waker().wake_by_ref();
let sampled =
sample_poisson_duration(&mut self.rng, self.config.average_message_sending_delay);
#[cfg(not(target_arch = "wasm32"))]
let next_delay = Box::pin(time::sleep(sampled));
#[cfg(target_arch = "wasm32")]
let next_delay = Box::pin(wasm_timer::Delay::new(sampled));
self.next_delay = Some(next_delay);
Poll::Pending
}
}
fn poll_immediate(&mut self, cx: &mut Context<'_>) -> Poll<Option<StreamMessage>> {
// Start by checking if we have any incoming messages about closed connections
if let Poll::Ready(Some(id)) = Pin::new(&mut self.client_connection_rx).poll_next(cx) {
match id {
ConnectionCommand::Close(id) => self.on_close_connection(id),
ConnectionCommand::ActiveConnections(_) => panic!(),
}
}
match Pin::new(&mut self.real_receiver).poll_recv(cx) {
// in the case our real message channel stream was closed, we should also indicate we are closed
// (and whoever is using the stream should panic)
Poll::Ready(None) => Poll::Ready(None),
Poll::Ready(Some((real_messages, conn_id))) => {
log::trace!("handling real_messages: size: {}", real_messages.len());
// First store what we got for the given connection id
self.transmission_buffer.store(&conn_id, real_messages);
let real_next = self.pop_next_message().expect("we just added one");
Poll::Ready(Some(StreamMessage::Real(Box::new(real_next))))
}
Poll::Pending => {
if let Some(real_next) = self.pop_next_message() {
Poll::Ready(Some(StreamMessage::Real(Box::new(real_next))))
} else {
Poll::Pending
}
}
}
}
fn poll_next_message(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<StreamMessage>> {
if self.config.disable_poisson_packet_distribution {
self.poll_immediate(cx)
} else {
self.poll_poisson(cx)
}
}
#[cfg(not(target_arch = "wasm32"))]
fn log_status(&self, shutdown: &mut task::TaskClient) {
use crate::error::ClientCoreStatusMessage;
let packets = self.transmission_buffer.total_size();
let backlog = self.transmission_buffer.total_size_in_bytes() as f64 / 1024.0;
let lanes = self.transmission_buffer.num_lanes();
let mult = self.sending_delay_controller.current_multiplier();
let delay = self.current_average_message_sending_delay().as_millis();
let status_str = if self.config.disable_poisson_packet_distribution {
format!(
"Status: {lanes} lanes, backlog: {:.2} kiB ({packets}), no delay",
backlog
)
} else {
format!(
"Status: {lanes} lanes, backlog: {:.2} kiB ({packets}), avg delay: {}ms ({mult})",
backlog, delay
)
};
if packets > 1000 {
log::warn!("{status_str}");
} else if packets > 0 {
log::info!("{status_str}");
} else {
log::debug!("{status_str}");
}
// Send status message to whoever is listening (possibly UI)
if mult == self.sending_delay_controller.max_multiplier() {
shutdown.send_status_msg(Box::new(ClientCoreStatusMessage::GatewayIsVerySlow));
} else if mult > self.sending_delay_controller.min_multiplier() {
shutdown.send_status_msg(Box::new(ClientCoreStatusMessage::GatewayIsSlow));
}
}
#[cfg(not(target_arch = "wasm32"))]
fn log_status_infrequent(&self) {
if self.sending_delay_controller.current_multiplier() > 1 {
log::warn!(
"Unable to send packets at the default rate - rate reduced by setting the delay multiplier set to: {}",
self.sending_delay_controller.current_multiplier()
);
}
}
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::TaskClient) {
debug!("Started OutQueueControl with graceful shutdown support");
#[cfg(not(target_arch = "wasm32"))]
{
let mut status_timer = tokio::time::interval(Duration::from_secs(5));
let mut infrequent_status_timer = tokio::time::interval(Duration::from_secs(60));
while !shutdown.is_shutdown() {
tokio::select! {
biased;
_ = shutdown.recv_with_delay() => {
log::trace!("OutQueueControl: Received shutdown");
}
_ = status_timer.tick() => {
self.log_status(&mut shutdown);
}
_ = infrequent_status_timer.tick() => {
self.log_status_infrequent();
}
next_message = self.next() => if let Some(next_message) = next_message {
self.on_message(next_message).await;
} else {
log::trace!("OutQueueControl: Stopping since channel closed");
break;
}
}
}
tokio::time::timeout(Duration::from_secs(5), shutdown.recv())
.await
.expect("Task stopped without shutdown called");
}
#[cfg(target_arch = "wasm32")]
{
while !shutdown.is_shutdown() {
tokio::select! {
biased;
_ = shutdown.recv() => {
log::trace!("OutQueueControl: Received shutdown");
}
next_message = self.next() => if let Some(next_message) = next_message {
self.on_message(next_message).await;
} else {
log::trace!("OutQueueControl: Stopping since channel closed");
break;
}
}
}
}
log::debug!("OutQueueControl: Exiting");
}
}
impl<R> Stream for OutQueueControl<R>
where
R: CryptoRng + Rng + Unpin,
{
type Item = StreamMessage;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
self.poll_next_message(cx)
}
}
@@ -0,0 +1,121 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::helpers::{get_time_now, Instant};
use std::time::Duration;
// 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.
const INCREASE_DELAY_MIN_CHANGE_INTERVAL_SECS: u64 = 1;
// The minimum time between decreasing the average delay between packets. We don't want to change
// to quickly to keep things somewhat stable. Also there are buffers downstreams meaning we need to
// wait a little to see the effect before we decrease further.
const DECREASE_DELAY_MIN_CHANGE_INTERVAL_SECS: u64 = 30;
// If we enough time passes without any sign of backpressure in the channel, we can consider
// lowering the average delay. The goal is to keep somewhat stable, rather than maxing out
// bandwidth at all times.
const ACCEPTABLE_TIME_WITHOUT_BACKPRESSURE_SECS: u64 = 30;
// The maximum multiplier we apply to the base average Poisson delay.
const MAX_DELAY_MULTIPLIER: u32 = 6;
// The minium multiplier we apply to the base average Poisson delay.
const MIN_DELAY_MULTIPLIER: u32 = 1;
pub(crate) struct SendingDelayController {
/// Multiply the average sending delay.
/// This is normally set to unity, but if we detect backpressure we increase this
/// multiplier. We use discrete steps.
current_multiplier: u32,
/// Maximum delay multiplier
upper_bound: u32,
/// Minimum delay multiplier
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,
/// If we have a long enough time without any backpressure detected we try reducing the sending
/// delay multiplier
time_when_backpressure_detected: Instant,
}
impl Default for SendingDelayController {
fn default() -> Self {
SendingDelayController::new(MIN_DELAY_MULTIPLIER, MAX_DELAY_MULTIPLIER)
}
}
impl SendingDelayController {
pub(crate) fn new(lower_bound: u32, upper_bound: u32) -> Self {
assert!(lower_bound <= upper_bound);
let now = get_time_now();
SendingDelayController {
current_multiplier: MIN_DELAY_MULTIPLIER,
upper_bound,
lower_bound,
time_when_changed: now,
time_when_backpressure_detected: now,
}
}
pub(crate) fn current_multiplier(&self) -> u32 {
self.current_multiplier
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn min_multiplier(&self) -> u32 {
self.lower_bound
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn max_multiplier(&self) -> u32 {
self.upper_bound
}
pub(crate) fn increase_delay_multiplier(&mut self) {
if self.current_multiplier < self.upper_bound {
self.current_multiplier =
(self.current_multiplier + 1).clamp(self.lower_bound, self.upper_bound);
self.time_when_changed = get_time_now();
log::warn!(
"Increasing sending delay multiplier to: {}",
self.current_multiplier
);
} else {
log::warn!("Trying to increase delay multipler higher than allowed");
}
}
pub(crate) fn decrease_delay_multiplier(&mut self) {
if self.current_multiplier > self.lower_bound {
self.current_multiplier =
(self.current_multiplier - 1).clamp(self.lower_bound, self.upper_bound);
self.time_when_changed = get_time_now();
log::debug!(
"Decreasing sending delay multiplier to: {}",
self.current_multiplier
);
}
}
pub(crate) fn record_backpressure_detected(&mut self) {
self.time_when_backpressure_detected = get_time_now();
}
pub(crate) fn not_increased_delay_recently(&self) -> bool {
get_time_now()
> self.time_when_changed + Duration::from_secs(INCREASE_DELAY_MIN_CHANGE_INTERVAL_SECS)
}
pub(crate) fn is_sending_reliable(&self) -> bool {
let now = get_time_now();
let delay_change_interval = Duration::from_secs(DECREASE_DELAY_MIN_CHANGE_INTERVAL_SECS);
let acceptable_time_without_backpressure =
Duration::from_secs(ACCEPTABLE_TIME_WITHOUT_BACKPRESSURE_SECS);
now > self.time_when_backpressure_detected + acceptable_time_without_backpressure
&& now > self.time_when_changed + delay_change_interval
}
}
+262 -119
View File
@@ -1,21 +1,25 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::reply_key_storage::ReplyKeyStorage;
use crate::client::replies::reply_controller::ReplyControllerSender;
use crate::client::replies::reply_storage::SentReplyKeys;
use crate::spawn_future;
use crypto::asymmetric::encryption;
use crypto::symmetric::stream_cipher;
use crypto::Digest;
use futures::channel::mpsc;
use futures::lock::Mutex;
use futures::StreamExt;
use gateway_client::MixnetMessageReceiver;
use log::*;
use nymsphinx::anonymous_replies::requests::{
RepliableMessage, RepliableMessageContent, ReplyMessage, ReplyMessageContent,
};
use nymsphinx::anonymous_replies::{encryption_key::EncryptionKeyDigest, SurbEncryptionKey};
use nymsphinx::params::{ReplySurbEncryptionAlgorithm, ReplySurbKeyDigestAlgorithm};
use nymsphinx::message::{NymMessage, PlainMessage};
use nymsphinx::params::ReplySurbKeyDigestAlgorithm;
use nymsphinx::receiver::{MessageReceiver, MessageRecoveryError, ReconstructedMessage};
use std::collections::HashSet;
use std::sync::Arc;
use tokio::task::JoinHandle;
// Buffer Requests to say "hey, send any reconstructed messages to this channel"
// or to say "hey, I'm going offline, don't send anything more to me. Just buffer them instead"
@@ -42,26 +46,15 @@ struct ReceivedMessagesBufferInner {
}
impl ReceivedMessagesBufferInner {
fn process_received_fragment(&mut self, raw_fragment: Vec<u8>) -> Option<ReconstructedMessage> {
let fragment_data = match self
.message_receiver
.recover_plaintext(self.local_encryption_keypair.private_key(), raw_fragment)
{
Err(e) => {
warn!("failed to recover fragment data: {:?}. The whole underlying message might be corrupted and unrecoverable!", e);
return None;
}
Ok(frag_data) => frag_data,
};
if nymsphinx::cover::is_cover(&fragment_data) {
fn recover_from_fragment(&mut self, fragment_data: &[u8]) -> Option<NymMessage> {
if nymsphinx::cover::is_cover(fragment_data) {
trace!("The message was a loop cover message! Skipping it");
return None;
}
let fragment = match self.message_receiver.recover_fragment(&fragment_data) {
Err(e) => {
warn!("failed to recover fragment from raw data: {:?}. The whole underlying message might be corrupted and unrecoverable!", e);
let fragment = match self.message_receiver.recover_fragment(fragment_data) {
Err(err) => {
warn!("failed to recover fragment from raw data: {err}. The whole underlying message might be corrupted and unrecoverable!");
return None;
}
Ok(frag) => frag,
@@ -75,9 +68,10 @@ impl ReceivedMessagesBufferInner {
// if we returned an error the underlying message is malformed in some way
match self.message_receiver.insert_new_fragment(fragment) {
Err(err) => match err {
MessageRecoveryError::MalformedReconstructedMessage(message_sets) => {
MessageRecoveryError::MalformedReconstructedMessage { source, used_sets } => {
error!("message reconstruction failed - {source}. Attempting to re-use the message sets...");
// TODO: should we really insert reconstructed sets? could this be abused for some attack?
for set_id in message_sets {
for set_id in used_sets {
if !self.recently_reconstructed.insert(set_id) {
// or perhaps we should even panic at this point?
error!("Reconstructed another message containing already used set id!")
@@ -103,6 +97,34 @@ impl ReceivedMessagesBufferInner {
},
}
}
fn process_received_reply(
&mut self,
reply_ciphertext: &mut [u8],
reply_key: SurbEncryptionKey,
) -> Option<NymMessage> {
// note: this performs decryption IN PLACE without extra allocation
self.message_receiver
.recover_plaintext_from_reply(reply_ciphertext, reply_key);
let fragment_data = reply_ciphertext;
self.recover_from_fragment(fragment_data)
}
fn process_received_regular_packet(&mut self, mut raw_fragment: Vec<u8>) -> Option<NymMessage> {
let fragment_data = match self.message_receiver.recover_plaintext_from_regular_packet(
self.local_encryption_keypair.private_key(),
&mut raw_fragment,
) {
Err(err) => {
warn!("failed to recover fragment data: {err}. The whole underlying message might be corrupted and unrecoverable!");
return None;
}
Ok(frag_data) => frag_data,
};
self.recover_from_fragment(fragment_data)
}
}
#[derive(Debug, Clone)]
@@ -110,16 +132,15 @@ impl ReceivedMessagesBufferInner {
// You should always use .clone() to create additional instances
struct ReceivedMessagesBuffer {
inner: Arc<Mutex<ReceivedMessagesBufferInner>>,
/// Storage containing keys to all [`ReplySURB`]s ever sent out that we did not receive back.
// There's no need to put it behind a Mutex since it's already properly concurrent
reply_key_storage: ReplyKeyStorage,
reply_key_storage: SentReplyKeys,
reply_controller_sender: ReplyControllerSender,
}
impl ReceivedMessagesBuffer {
fn new(
local_encryption_keypair: Arc<encryption::KeyPair>,
reply_key_storage: ReplyKeyStorage,
reply_key_storage: SentReplyKeys,
reply_controller_sender: ReplyControllerSender,
) -> Self {
ReceivedMessagesBuffer {
inner: Arc::new(Mutex::new(ReceivedMessagesBufferInner {
@@ -130,6 +151,7 @@ impl ReceivedMessagesBuffer {
recently_reconstructed: HashSet::new(),
})),
reply_key_storage,
reply_controller_sender,
}
}
@@ -171,37 +193,143 @@ impl ReceivedMessagesBuffer {
guard.message_sender = Some(sender);
}
async fn add_reconstructed_messages(&mut self, msgs: Vec<ReconstructedMessage>) {
debug!("Adding {:?} new messages to the buffer!", msgs.len());
trace!("Adding new messages to the buffer! {:?}", msgs);
self.inner.lock().await.messages.extend(msgs)
fn handle_reconstructed_plain_messages(
&mut self,
msgs: Vec<PlainMessage>,
) -> Vec<ReconstructedMessage> {
msgs.into_iter().map(Into::into).collect()
}
fn process_received_reply(
reply_ciphertext: &[u8],
reply_key: SurbEncryptionKey,
) -> Option<ReconstructedMessage> {
let zero_iv = stream_cipher::zero_iv::<ReplySurbEncryptionAlgorithm>();
fn handle_reconstructed_repliable_messages(
&mut self,
msgs: Vec<RepliableMessage>,
) -> Vec<ReconstructedMessage> {
let mut reconstructed = Vec::new();
for msg in msgs {
let (reply_surbs, from_surb_request) = match msg.content {
RepliableMessageContent::Data {
message,
reply_surbs,
} => {
trace!(
"received message that also contained additional {} reply surbs from {:?}!",
reply_surbs.len(),
msg.sender_tag
);
let mut reply_msg = stream_cipher::decrypt::<ReplySurbEncryptionAlgorithm>(
reply_key.inner(),
&zero_iv,
reply_ciphertext,
reconstructed.push(ReconstructedMessage::new(message, msg.sender_tag));
(reply_surbs, false)
}
RepliableMessageContent::AdditionalSurbs { reply_surbs } => {
trace!(
"received additional {} reply surbs from {:?}!",
reply_surbs.len(),
msg.sender_tag
);
(reply_surbs, true)
}
RepliableMessageContent::Heartbeat {
additional_reply_surbs,
} => {
error!("received a repliable heartbeat message - we don't know how to handle it yet (and we won't know until future PRs)");
(additional_reply_surbs, false)
}
};
self.reply_controller_sender.send_additional_surbs(
msg.sender_tag,
reply_surbs,
from_surb_request,
)
}
reconstructed
}
fn handle_reconstructed_reply_messages(
&mut self,
msgs: Vec<ReplyMessage>,
) -> Vec<ReconstructedMessage> {
let mut reconstructed = Vec::new();
for msg in msgs {
match msg.content {
ReplyMessageContent::Data { message } => reconstructed.push(message.into()),
ReplyMessageContent::SurbRequest { recipient, amount } => {
debug!("received request for {amount} additional reply SURBs from {recipient}");
self.reply_controller_sender
.send_additional_surbs_request(*recipient, amount);
}
}
}
reconstructed
}
async fn handle_reconstructed_messages(&mut self, msgs: Vec<NymMessage>) {
if msgs.is_empty() {
return;
}
let mut plain_messages = Vec::new();
let mut repliable_messages = Vec::new();
let mut reply_messages = Vec::new();
for msg in msgs {
match msg {
NymMessage::Plain(plain) => plain_messages.push(plain),
NymMessage::Repliable(repliable) => repliable_messages.push(repliable),
NymMessage::Reply(reply) => reply_messages.push(reply),
}
}
let mut reconstructed_messages = self.handle_reconstructed_plain_messages(plain_messages);
reconstructed_messages
.append(&mut self.handle_reconstructed_repliable_messages(repliable_messages));
reconstructed_messages
.append(&mut self.handle_reconstructed_reply_messages(reply_messages));
let mut inner_guard = self.inner.lock().await;
debug!(
"Adding {:?} new messages to the buffer!",
reconstructed_messages.len()
);
if let Err(err) = MessageReceiver::remove_padding(&mut reply_msg) {
warn!("Received reply had malformed padding! - {:?}", err);
None
if let Some(sender) = &inner_guard.message_sender {
trace!("Sending reconstructed messages to announced sender");
if let Err(err) = sender.unbounded_send(reconstructed_messages) {
warn!("The reconstructed message receiver went offline without explicit notification (relevant error: - {err})");
inner_guard.message_sender = None;
inner_guard.messages.extend(err.into_inner());
}
} else {
// TODO: perhaps having to say it doesn't have a surb an indication the type should be changed?
Some(ReconstructedMessage {
message: reply_msg,
reply_surb: None,
})
trace!("No sender available - buffering reconstructed messages");
inner_guard.messages.extend(reconstructed_messages)
}
}
// this function doesn't really belong here...
fn get_reply_key<'a>(
&self,
raw_message: &'a mut [u8],
) -> Option<(SurbEncryptionKey, &'a mut [u8])> {
let reply_surb_digest_size = ReplySurbKeyDigestAlgorithm::output_size();
if raw_message.len() < reply_surb_digest_size {
return None;
}
let possible_key_digest =
EncryptionKeyDigest::clone_from_slice(&raw_message[..reply_surb_digest_size]);
self.reply_key_storage
.try_pop(possible_key_digest)
.map(|reply_encryption_key| {
(
*reply_encryption_key,
&mut raw_message[reply_surb_digest_size..],
)
})
}
async fn handle_new_received(&mut self, msgs: Vec<Vec<u8>>) {
debug!(
trace!(
"Processing {:?} new message that might get added to the buffer!",
msgs.len()
);
@@ -209,58 +337,28 @@ impl ReceivedMessagesBuffer {
let mut completed_messages = Vec::new();
let mut inner_guard = self.inner.lock().await;
let reply_surb_digest_size = ReplySurbKeyDigestAlgorithm::output_size();
// first check if this is a reply or a chunked message
// TODO: verify with @AP if this way of doing it is safe or whether it could
// cause some attacks due to, I don't know, stupid edge case collisions?
// Update: this DOES introduce a possible leakage: https://github.com/nymtech/nym/issues/296
for msg in msgs {
let possible_key_digest =
EncryptionKeyDigest::clone_from_slice(&msg[..reply_surb_digest_size]);
// note: there's a possible information leakage associated with this check https://github.com/nymtech/nym/issues/296
for mut msg in msgs {
// check first `HasherOutputSize` bytes if they correspond to known encryption key
// if yes - this is a reply message
let completed_message =
if let Some((reply_key, reply_message)) = self.get_reply_key(&mut msg) {
inner_guard.process_received_reply(reply_message, reply_key)
} else {
inner_guard.process_received_regular_packet(msg)
};
// TODO: this might be a bottleneck - since the keys are stored on disk we, presumably,
// are doing a disk operation every single received fragment
if let Some(reply_encryption_key) = self
.reply_key_storage
.get_and_remove_encryption_key(possible_key_digest)
.expect("storage operation failed!")
{
if let Some(completed_message) = Self::process_received_reply(
&msg[reply_surb_digest_size..],
reply_encryption_key,
) {
completed_messages.push(completed_message)
}
} else {
// otherwise - it's a 'normal' message
if let Some(completed_message) = inner_guard.process_received_fragment(msg) {
completed_messages.push(completed_message)
}
if let Some(completed) = completed_message {
info!("received {completed}");
completed_messages.push(completed)
}
}
drop(inner_guard);
if !completed_messages.is_empty() {
if let Some(sender) = &inner_guard.message_sender {
trace!("Sending reconstructed messages to announced sender");
if let Err(err) = sender.unbounded_send(completed_messages) {
warn!("The reconstructed message receiver went offline without explicit notification (relevant error: - {:?})", err);
// make sure to drop the lock to not deadlock
// (it is required by `add_reconstructed_messages`)
inner_guard.message_sender = None;
drop(inner_guard);
self.add_reconstructed_messages(err.into_inner()).await;
}
} else {
// make sure to drop the lock to not deadlock
// (it is required by `add_reconstructed_messages`)
drop(inner_guard);
trace!("No sender available - buffering reconstructed messages");
self.add_reconstructed_messages(completed_messages).await;
}
self.handle_reconstructed_messages(completed_messages).await
}
}
}
@@ -290,19 +388,37 @@ impl RequestReceiver {
}
}
fn start(mut self) -> JoinHandle<()> {
tokio::spawn(async move {
while let Some(request) = self.query_receiver.next().await {
match request {
ReceivedBufferMessage::ReceiverAnnounce(sender) => {
self.received_buffer.connect_sender(sender).await;
}
ReceivedBufferMessage::ReceiverDisconnect => {
self.received_buffer.disconnect_sender().await
}
}
async fn handle_message(&mut self, message: ReceivedBufferMessage) {
match message {
ReceivedBufferMessage::ReceiverAnnounce(sender) => {
self.received_buffer.connect_sender(sender).await;
}
})
ReceivedBufferMessage::ReceiverDisconnect => {
self.received_buffer.disconnect_sender().await
}
}
}
async fn run_with_shutdown(&mut self, mut shutdown: task::TaskClient) {
debug!("Started RequestReceiver with graceful shutdown support");
while !shutdown.is_shutdown() {
tokio::select! {
biased;
_ = shutdown.recv_with_delay() => {
log::trace!("RequestReceiver: Received shutdown");
}
request = self.query_receiver.next() => {
if let Some(message) = request {
self.handle_message(message).await
} else {
log::trace!("RequestReceiver: Stopping since channel closed");
break;
}
},
}
}
shutdown.recv_timeout().await;
log::debug!("RequestReceiver: Exiting");
}
}
@@ -321,29 +437,47 @@ impl FragmentedMessageReceiver {
mixnet_packet_receiver,
}
}
fn start(mut self) -> JoinHandle<()> {
tokio::spawn(async move {
while let Some(new_messages) = self.mixnet_packet_receiver.next().await {
self.received_buffer.handle_new_received(new_messages).await;
async fn run_with_shutdown(&mut self, mut shutdown: task::TaskClient) {
debug!("Started FragmentedMessageReceiver with graceful shutdown support");
while !shutdown.is_shutdown() {
tokio::select! {
new_messages = self.mixnet_packet_receiver.next() => {
if let Some(new_messages) = new_messages {
self.received_buffer.handle_new_received(new_messages).await;
} else {
log::trace!("FragmentedMessageReceiver: Stopping since channel closed");
break;
}
},
_ = shutdown.recv_with_delay() => {
log::trace!("FragmentedMessageReceiver: Received shutdown");
}
}
})
}
shutdown.recv_timeout().await;
log::debug!("FragmentedMessageReceiver: Exiting");
}
}
pub struct ReceivedMessagesBufferController {
pub(crate) struct ReceivedMessagesBufferController {
fragmented_message_receiver: FragmentedMessageReceiver,
request_receiver: RequestReceiver,
}
impl ReceivedMessagesBufferController {
pub fn new(
pub(crate) fn new(
local_encryption_keypair: Arc<encryption::KeyPair>,
query_receiver: ReceivedBufferRequestReceiver,
mixnet_packet_receiver: MixnetMessageReceiver,
reply_key_storage: ReplyKeyStorage,
reply_key_storage: SentReplyKeys,
reply_controller_sender: ReplyControllerSender,
) -> Self {
let received_buffer =
ReceivedMessagesBuffer::new(local_encryption_keypair, reply_key_storage);
let received_buffer = ReceivedMessagesBuffer::new(
local_encryption_keypair,
reply_key_storage,
reply_controller_sender,
);
ReceivedMessagesBufferController {
fragmented_message_receiver: FragmentedMessageReceiver::new(
@@ -354,9 +488,18 @@ impl ReceivedMessagesBufferController {
}
}
pub fn start(self) {
// TODO: should we do anything with JoinHandle(s) returned by start methods?
self.fragmented_message_receiver.start();
self.request_receiver.start();
pub fn start_with_shutdown(self, shutdown: task::TaskClient) {
let mut fragmented_message_receiver = self.fragmented_message_receiver;
let mut request_receiver = self.request_receiver;
let shutdown_handle = shutdown.clone();
spawn_future(async move {
fragmented_message_receiver
.run_with_shutdown(shutdown_handle)
.await;
});
spawn_future(async move {
request_receiver.run_with_shutdown(shutdown).await;
});
}
}
@@ -0,0 +1,5 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub mod reply_controller;
pub mod reply_storage;
@@ -0,0 +1,865 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
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 futures::StreamExt;
use log::{debug, error, info, trace, warn};
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::anonymous_replies::requests::AnonymousSenderTag;
use nymsphinx::anonymous_replies::ReplySurb;
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::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};
pub mod requests;
pub struct Config {
min_surb_request_size: u32,
max_surb_request_size: u32,
maximum_allowed_reply_surb_request_size: u32,
max_surb_waiting_period: Duration,
max_reply_surb_age: Duration,
max_reply_key_age: Duration,
}
impl Config {
pub(crate) fn new(
min_surb_request_size: u32,
max_surb_request_size: u32,
maximum_allowed_reply_surb_request_size: u32,
max_surb_waiting_period: Duration,
max_reply_surb_age: Duration,
max_reply_key_age: Duration,
) -> Self {
Self {
min_surb_request_size,
max_surb_request_size,
maximum_allowed_reply_surb_request_size,
max_surb_waiting_period,
max_reply_surb_age,
max_reply_key_age,
}
}
}
// the purpose of this task:
// - buffers split messages from input message listener if there were insufficient surbs to send them
// - upon getting extra surbs, resends them
// - so I guess it will handle all 'RepliableMessage' and requests from 'ReplyMessage'
// - replies to "give additional surbs" requests
// - will reply to future heartbeats
// TODO: this should be split into ingress and egress controllers
// because currently its trying to perform two distinct jobs
pub struct ReplyController<R> {
config: Config,
// TODO: incorporate that field at some point
// and use binomial distribution to determine the expected required number
// of surbs required to send the message through
// expected_reliability: f32,
request_receiver: ReplyControllerReceiver,
pending_replies: HashMap<AnonymousSenderTag, TransmissionBuffer<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.
// TODO: when purging stale entries, we must take extra care to also purge all pending ACK data!!
pending_retransmissions:
HashMap<AnonymousSenderTag, BTreeMap<FragmentIdentifier, Weak<PendingAcknowledgement>>>,
message_handler: MessageHandler<R>,
full_reply_storage: CombinedReplyStorage,
}
impl<R> ReplyController<R>
where
R: CryptoRng + Rng,
{
pub(crate) fn new(
config: Config,
message_handler: MessageHandler<R>,
full_reply_storage: CombinedReplyStorage,
request_receiver: ReplyControllerReceiver,
) -> Self {
ReplyController {
config,
request_receiver,
pending_replies: HashMap::new(),
pending_retransmissions: HashMap::new(),
message_handler,
full_reply_storage,
}
}
fn insert_pending_replies<I: IntoIterator<Item = Fragment>>(
&mut self,
recipient: &AnonymousSenderTag,
fragments: I,
lane: TransmissionLane,
) {
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)
}
fn re_insert_pending_retransmission(
&mut self,
recipient: &AnonymousSenderTag,
data: Vec<Arc<PendingAcknowledgement>>,
) {
// the underlying entry MUST exist as we've just got data from there
let map_entry = self
.pending_retransmissions
.get_mut(recipient)
.expect("our pending retransmission entry is somehow gone!");
for pending in data {
// if it's 0, we don't need to do anything - we just got that ack!
if Arc::strong_count(&pending) > 1 {
let id = pending.inner_fragment_identifier();
let downgraded = Arc::downgrade(&pending);
map_entry.insert(id, downgraded);
}
}
}
fn should_request_more_surbs(&self, target: &AnonymousSenderTag) -> bool {
trace!("checking if we should request more surbs from {:?}", target);
let pending_queue_size = self
.pending_replies
.get(target)
.map(|pending_queue| pending_queue.total_size())
.unwrap_or_default();
let retransmission_queue = self
.pending_retransmissions
.get(target)
.map(|pending_queue| pending_queue.len())
.unwrap_or_default();
let total_queue = pending_queue_size + retransmission_queue;
// simple as that - there's absolutely nothing to retransmit
if total_queue == 0 {
return false;
}
let available_surbs = self
.full_reply_storage
.surbs_storage_ref()
.available_surbs(target);
let pending_surbs = self
.full_reply_storage
.surbs_storage_ref()
.pending_reception(target) as usize;
let min_surbs_threshold = self
.full_reply_storage
.surbs_storage_ref()
.min_surb_threshold();
let max_surbs_threshold = self
.full_reply_storage
.surbs_storage_ref()
.max_surb_threshold();
debug!("total queue size: {total_queue} = pending data {pending_queue_size} + pending retransmission {retransmission_queue}, available surbs: {available_surbs} pending surbs: {pending_surbs} threshold range: {min_surbs_threshold}..{max_surbs_threshold}");
(pending_surbs + available_surbs) < max_surbs_threshold
&& (pending_surbs + available_surbs) < (total_queue + min_surbs_threshold)
}
async fn handle_send_reply(
&mut self,
recipient_tag: AnonymousSenderTag,
data: Vec<u8>,
lane: TransmissionLane,
) {
if !self
.full_reply_storage
.surbs_storage_ref()
.contains_surbs_for(&recipient_tag)
{
warn!("received reply request for {:?} but we don't have any surbs stored for that recipient!", recipient_tag);
return;
}
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 available_surbs = 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();
let max_to_send = if available_surbs > min_surbs_threshold {
min(fragments.len(), available_surbs - min_surbs_threshold)
} else {
0
};
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);
}
}
}
// 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;
}
}
async fn request_additional_reply_surbs(
&mut self,
target: AnonymousSenderTag,
amount: u32,
) -> Result<(), PreparationError> {
let reply_surb = self
.full_reply_storage
.surbs_storage_ref()
.get_reply_surb_ignoring_threshold(&target)
.and_then(|(reply_surb, _)| reply_surb)
.ok_or(PreparationError::NotEnoughSurbs {
available: 0,
required: 1,
})?;
if let Err(err) = self
.message_handler
.try_request_additional_reply_surbs(target, reply_surb, amount)
.await
{
let err = err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target);
warn!(
"failed to request additional surbs from {:?} - {err}",
target
);
return Err(err);
} else {
self.full_reply_storage
.surbs_storage_ref()
.increment_pending_reception(&target, amount);
}
Ok(())
}
async fn try_clear_pending_retransmission(&mut self, target: AnonymousSenderTag) {
trace!("trying to clear pending retransmission queue");
let available_surbs = self
.full_reply_storage
.surbs_storage_ref()
.available_surbs(&target);
let min_surbs_threshold = self
.full_reply_storage
.surbs_storage_ref()
.min_surb_threshold();
let max_to_clear = if available_surbs > min_surbs_threshold {
available_surbs - min_surbs_threshold
} else {
trace!("we don't have enough surbs for retransmission queue clearing...");
return;
};
trace!("we can clear up to {max_to_clear} entries");
let Some(pending) = self.pending_retransmissions.get_mut(&target) else {
trace!("there are no pending retransmissions for {target}!");
return;
};
let mut to_take = 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)
}
} else {
// our map is empty!
break;
}
}
if to_take.is_empty() {
// no need to do anything
return;
}
let (surbs_for_reply, _) = self
.full_reply_storage
.surbs_storage_ref()
.get_reply_surbs(&target, to_take.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_retransmission(&target, to_take);
return;
};
let to_send_vec = to_take.iter().map(|ack| ack.fragment_data()).collect();
let prepared_fragments = match self
.message_handler
.prepare_reply_chunks_for_sending(to_send_vec, surbs_for_reply)
.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);
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;
}
fn pop_at_most_pending_replies(
&mut self,
from: &AnonymousSenderTag,
amount: usize,
) -> Option<Vec<(TransmissionLane, 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();
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)
}
async fn try_clear_pending_queue(&mut self, target: AnonymousSenderTag) {
trace!("trying to clear pending queue");
let available_surbs = self
.full_reply_storage
.surbs_storage_ref()
.available_surbs(&target);
let min_surbs_threshold = self
.full_reply_storage
.surbs_storage_ref()
.min_surb_threshold();
let max_to_clear = if available_surbs > min_surbs_threshold {
available_surbs - min_surbs_threshold
} else {
trace!("we don't have enough surbs for queue clearing...");
return;
};
trace!("we can clear up to {max_to_clear} entries");
// 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();
if to_send_clone.is_empty() {
panic!(
"please let the devs know if you ever see this message (reply_controller.rs)"
);
}
let (surbs_for_reply, _) = self
.full_reply_storage
.surbs_storage_ref()
.get_reply_surbs(&target, to_send_clone.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);
return;
};
if let Err(err) = self
.message_handler
.try_send_reply_chunks(target, to_send_clone, surbs_for_reply)
.await
{
let err =
err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target);
self.re_insert_pending_replies(&target, to_send);
warn!("failed to clear pending queue for {:?} - {err}", target);
}
} else {
trace!("the pending queue is empty");
}
}
async fn handle_received_surbs(
&mut self,
from: AnonymousSenderTag,
reply_surbs: Vec<ReplySurb>,
from_surb_request: bool,
) {
trace!("handling received surbs");
// clear the requesting flag since we should have been asking for surbs
self.full_reply_storage
.surbs_storage_ref()
.reset_surbs_last_received_at(&from);
if from_surb_request {
self.full_reply_storage
.surbs_storage_ref()
.decrement_pending_reception(&from, reply_surbs.len() as u32);
}
// store received surbs
self.full_reply_storage
.surbs_storage_ref()
.insert_surbs(&from, reply_surbs);
// use as many as we can for clearing pending retransmission queue
self.try_clear_pending_retransmission(from).await;
// use as many as we can for clearing pending 'normal' queue
self.try_clear_pending_queue(from).await;
// if we have to, request more
if self.should_request_more_surbs(&from) {
self.request_reply_surbs_for_queue_clearing(from).await;
}
}
async fn handle_surb_request(&mut self, recipient: Recipient, mut amount: u32) {
// 1. check whether we sent any surbs in the past to this recipient, otherwise
// they have no business in asking for more
if !self
.full_reply_storage
.tags_storage_ref()
.exists(&recipient)
{
warn!("{recipient} asked us for reply SURBs even though we never sent them any anonymous messages before!");
return;
}
// 2. check whether the requested amount is within sane range
if amount > self.config.maximum_allowed_reply_surb_request_size {
warn!("The requested reply surb amount is larger than our maximum allowed ({amount} > {}). Lowering it to a more sane value...", self.config.maximum_allowed_reply_surb_request_size);
amount = self.config.maximum_allowed_reply_surb_request_size;
}
// 3. construct and send the surbs away
// (send them in smaller batches to make the experience a bit smoother
let mut remaining = amount;
while remaining > 0 {
let to_send = min(remaining, 100);
if let Err(err) = self
.message_handler
.try_send_additional_reply_surbs(recipient, to_send)
.await
{
warn!("failed to send additional surbs to {recipient} - {err}");
} else {
trace!("sent {to_send} reply SURBs to {recipient}");
}
remaining -= to_send;
}
}
fn buffer_pending_ack(
&mut self,
recipient: AnonymousSenderTag,
ack_ref: Arc<PendingAcknowledgement>,
weak_ack_ref: Weak<PendingAcknowledgement>,
) {
let frag_id = ack_ref.inner_fragment_identifier();
if let Some(existing) = self.pending_retransmissions.get_mut(&recipient) {
if let Entry::Vacant(e) = existing.entry(frag_id) {
e.insert(weak_ack_ref);
} else {
warn!("we're already trying to retransmit {frag_id}. We must be really behind in surbs!");
}
} else {
let mut inner = BTreeMap::new();
inner.insert(frag_id, weak_ack_ref);
self.pending_retransmissions.insert(recipient, inner);
}
}
async fn handle_reply_retransmission(
&mut self,
recipient_tag: AnonymousSenderTag,
timed_out_ack: Weak<PendingAcknowledgement>,
extra_surbs_request: bool,
) {
// seems we got the ack in the end
let ack_ref = match timed_out_ack.upgrade() {
Some(ack) => ack,
None => {
debug!("we received the ack for one of the reply packets as we were putting it in the retransmission queue");
return;
}
};
// if this is retransmission for obtaining additional reply surbs,
// we can dip below the storage threshold
let (maybe_reply_surb, _) = if extra_surbs_request {
self.full_reply_storage
.surbs_storage_ref()
.get_reply_surb_ignoring_threshold(&recipient_tag)
} else {
self.full_reply_storage
.surbs_storage_ref()
.get_reply_surb(&recipient_tag)
}
.expect("attempted to retransmit a packet to an unknown recipient - we shouldn't have sent the original packet in the first place!");
if let Some(reply_surb) = maybe_reply_surb {
match self
.message_handler
.try_prepare_single_reply_chunk_for_sending(reply_surb, ack_ref.fragment_data())
.await
{
Ok(prepared) => {
// drop the ack ref so that controller would not panic on `UpdateTimer` if that task
// got to handle the action before this function terminated (which is very much
// possible if `forward_messages` takes a while)
drop(ack_ref);
self.message_handler
.update_ack_delay(prepared.fragment_identifier, prepared.total_delay);
self.message_handler
.forward_messages(vec![prepared.into()], TransmissionLane::Retransmission)
.await;
}
Err(err) => {
let err = err.return_unused_surbs(
self.full_reply_storage.surbs_storage_ref(),
&recipient_tag,
);
warn!("failed to prepare message for retransmission - {err}");
// we buffer that packet and to try another day
self.buffer_pending_ack(recipient_tag, ack_ref, timed_out_ack);
if self.should_request_more_surbs(&recipient_tag) {
self.request_reply_surbs_for_queue_clearing(recipient_tag)
.await;
}
}
};
} else {
self.buffer_pending_ack(recipient_tag, ack_ref, timed_out_ack);
if self.should_request_more_surbs(&recipient_tag) {
self.request_reply_surbs_for_queue_clearing(recipient_tag)
.await;
}
}
}
// 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 {
recipient,
timed_out_ack,
extra_surb_request,
} => {
self.handle_reply_retransmission(recipient, timed_out_ack, extra_surb_request)
.await
}
ReplyControllerMessage::SendReply {
recipient,
message,
lane,
} => self.handle_send_reply(recipient, message, lane).await,
ReplyControllerMessage::AdditionalSurbs {
sender_tag,
reply_surbs,
from_surb_request,
} => {
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())
.unwrap_or_default();
let retransmission_queue = self
.pending_retransmissions
.get(&target)
.map(|pending_queue| pending_queue.len())
.unwrap_or_default();
let total_queue = (pending_queue_size + retransmission_queue) as u32;
if total_queue == 0 {
trace!("the pending queues for {:?} are already empty", target);
return;
}
let request_size = min(
self.config.max_surb_request_size,
max(total_queue, self.config.min_surb_request_size),
);
if let Err(err) = self
.request_additional_reply_surbs(target, request_size)
.await
{
warn!("failed to request additional surbs... - {err}")
}
}
async fn inspect_stale_entries(&mut self) {
let mut to_request = Vec::new();
let mut to_remove = Vec::new();
let now = OffsetDateTime::now_utc();
for (pending_reply_target, vals) in &self.pending_replies {
if vals.is_empty() {
continue;
}
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());
to_remove.push(*pending_reply_target);
continue;
};
// this should never ever happen (famous last words, eh?), but in case it DOES happen eventually
// purge that malformed data
let Ok(last_received_time) = OffsetDateTime::from_unix_timestamp(last_received) else {
error!("somehow our stored timestamp ({last_received}) for surbs from {pending_reply_target} is corrupted!. Going to remove all the associated entries");
to_remove.push(*pending_reply_target);
continue;
};
let diff = now - last_received_time;
if diff > self.config.max_surb_waiting_period {
warn!("We haven't received any surbs in {:?} from {pending_reply_target}. Going to explicitly ask for more", diff);
to_request.push(*pending_reply_target);
}
}
for pending_reply_target in to_request {
self.request_reply_surbs_for_queue_clearing(pending_reply_target)
.await;
self.full_reply_storage
.surbs_storage_ref()
.reset_pending_reception(&pending_reply_target)
}
for to_remove in to_remove {
self.pending_replies.remove(&to_remove);
}
}
async fn invalidate_old_data(&self) {
let now = OffsetDateTime::now_utc();
let mut to_remove_surbs = Vec::new();
let mut to_remove_keys = Vec::new();
for map_ref in self.full_reply_storage.surbs_storage_ref().as_raw_iter() {
let (sender, received) = map_ref.pair();
// TODO: handle the following edge case:
// there's a malicious client sending us exactly one reply surb just before we should have invalidated
// the data thus making us keep everything in memory
// possible solution: keep timestamp PER reply surb (but that seems like an overkill)
// but I doubt this is ever going to be a problem...
// ...
// However, if you're reading this message, it probably became a legit problem,
// so I guess add timestamp per surb then? chop-chop.
let last_received = received.surbs_last_received_at();
// this should never ever happen (famous last words, eh?), but in case it DOES happen eventually
// purge that malformed data
let Ok(last_received_time) = OffsetDateTime::from_unix_timestamp(last_received) else {
error!("somehow our stored timestamp ({last_received}) for surbs from {sender} is corrupted!. Going to remove all the associated entries");
to_remove_surbs.push(*sender);
continue;
};
let diff = now - last_received_time;
if diff > self.config.max_reply_surb_age {
info!("it's been {diff:?} since we last received any reply surb from {sender}. Going to remove all stored entries...");
to_remove_surbs.push(*sender);
}
}
for map_ref in self.full_reply_storage.key_storage_ref().as_raw_iter() {
let (digest, reply_key) = map_ref.pair();
// this should never ever happen (famous last words, eh?), but in case it DOES happen eventually
// purge that malformed data
let Ok(sent_at) = OffsetDateTime::from_unix_timestamp(reply_key.sent_at_timestamp) else {
error!("somehow our stored timestamp ({}) for one of our reply key is corrupted!. Going to remove all the entry", reply_key.sent_at_timestamp);
to_remove_keys.push(*digest);
continue;
};
let diff = now - sent_at;
if diff > self.config.max_reply_key_age {
debug!("it's been {diff:?} since we created this reply key. it's probably never going to get used, so we're going to purge it...");
to_remove_keys.push(*digest);
}
}
for to_remove in to_remove_surbs {
self.full_reply_storage
.surbs_storage_ref()
.remove(&to_remove);
}
for to_remove in to_remove_keys {
self.full_reply_storage.key_storage().remove(to_remove)
}
}
// #[cfg(not(target_arch = "wasm32"))]
// async fn log_status(&self) {
// todo!()
// }
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);
// 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);
while !shutdown.is_shutdown() {
tokio::select! {
biased;
_ = shutdown.recv_with_delay() => {
log::trace!("ReplyController: Received shutdown");
},
req = self.request_receiver.next() => match req {
Some(req) => self.handle_request(req).await,
None => {
log::trace!("ReplyController: Stopping since channel closed");
break;
}
},
_ = stale_inspection.next() => {
self.inspect_stale_entries().await
},
_ = invalidation_inspection.next() => {
self.invalidate_old_data().await
}
}
}
assert!(shutdown.is_shutdown_poll());
log::debug!("ReplyController: Exiting");
}
}
@@ -0,0 +1,136 @@
// 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,
},
}
@@ -0,0 +1,43 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_storage::backend::Empty;
use crate::client::replies::reply_storage::{CombinedReplyStorage, ReplyStorageBackend};
use async_trait::async_trait;
// well, right now we don't have the browser storage : (
// so we keep everything in memory
pub struct Backend {
empty: Empty,
}
impl Backend {
pub fn new(min_surb_threshold: usize, max_surb_threshold: usize) -> Self {
Backend {
empty: Empty {
min_surb_threshold,
max_surb_threshold,
},
}
}
}
#[async_trait]
impl ReplyStorageBackend for Backend {
type StorageError = <Empty as ReplyStorageBackend>::StorageError;
async fn flush_surb_storage(
&mut self,
storage: &CombinedReplyStorage,
) -> Result<(), Self::StorageError> {
self.empty.flush_surb_storage(storage).await
}
async fn init_fresh(&mut self, fresh: &CombinedReplyStorage) -> Result<(), Self::StorageError> {
self.empty.init_fresh(fresh).await
}
async fn load_surb_storage(&self) -> Result<CombinedReplyStorage, Self::StorageError> {
self.empty.load_surb_storage().await
}
}
@@ -0,0 +1,53 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::io;
use std::path::PathBuf;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum StorageError {
#[error("the provided database path doesn't have a filename defined")]
DatabasePathWithoutFilename { provided_path: PathBuf },
#[error("failed to rename our databse file - {source}")]
DatabaseRenameError {
#[source]
source: io::Error,
},
#[error("failed to rename our old databse file - {source}")]
DatabaseOldFileRemoveError {
#[source]
source: io::Error,
},
#[error("failed to perform sqlx migration: {source}")]
MigrationError {
#[source]
#[from]
source: sqlx::migrate::MigrateError,
},
#[error("failed to connect to the underlying connection pool: {source}")]
DatabaseConnectionError {
#[source]
source: sqlx::error::Error,
},
#[error("failed to run the SQL query: {source}")]
QueryError {
#[source]
#[from]
source: sqlx::error::Error,
},
#[error("The loaded data is inconsistent - it seems that on the last shutdown the client hasn't finished the data flush. You may have to remove the entire storage manually")]
IncompleteDataFlush,
#[error("data retrieved from the underlying storage is corrupted: {details}")]
CorruptedData {
details: String,
// err: Option<Box<dyn std::error::Error>>
},
}
@@ -0,0 +1,257 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_storage::backend::fs_backend::error::StorageError;
use crate::client::replies::reply_storage::backend::fs_backend::models::{
ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender,
};
use log::{error, info};
use sqlx::ConnectOptions;
use std::path::Path;
#[derive(Debug, Clone)]
pub(crate) struct StorageManager {
pub(crate) connection_pool: sqlx::SqlitePool,
}
// all SQL goes here
impl StorageManager {
pub(crate) async fn init<P: AsRef<Path>>(
database_path: P,
fresh: bool,
) -> Result<Self, StorageError> {
let mut opts = sqlx::sqlite::SqliteConnectOptions::new()
.filename(database_path)
.create_if_missing(fresh);
opts.disable_statement_logging();
let connection_pool = match sqlx::SqlitePool::connect_with(opts).await {
Ok(pool) => pool,
Err(err) => {
error!("Failed to connect to SQLx database: {err}");
return Err(StorageError::DatabaseConnectionError { source: err });
}
};
if let Err(err) = sqlx::migrate!("./fs_surbs_migrations")
.run(&connection_pool)
.await
{
error!("Failed to initialize SQLx database: {err}");
return Err(err.into());
}
info!("Database migration finished!");
Ok(StorageManager { connection_pool })
}
#[allow(dead_code)]
pub(crate) async fn status_table_exists(&self) -> Result<bool, sqlx::Error> {
sqlx::query!("SELECT name FROM sqlite_master WHERE type='table' AND name='status'")
.fetch_optional(&self.connection_pool)
.await
.map(|r| r.is_some())
}
pub(crate) async fn create_status_table(&self) -> Result<(), sqlx::Error> {
sqlx::query!("INSERT INTO status(flush_in_progress, previous_flush_timestamp, client_in_use) VALUES (0, 0, 1)")
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn get_flush_status(&self) -> Result<bool, sqlx::Error> {
sqlx::query!("SELECT flush_in_progress FROM status;")
.fetch_one(&self.connection_pool)
.await
.map(|r| r.flush_in_progress > 0)
}
pub(crate) async fn set_previous_flush_timestamp(
&self,
timestamp: i64,
) -> Result<(), sqlx::Error> {
sqlx::query!("UPDATE status SET previous_flush_timestamp = ?", timestamp)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn get_previous_flush_timestamp(&self) -> Result<i64, sqlx::Error> {
sqlx::query!("SELECT previous_flush_timestamp FROM status;")
.fetch_one(&self.connection_pool)
.await
.map(|r| r.previous_flush_timestamp)
}
pub(crate) async fn set_flush_status(&self, in_progress: bool) -> Result<(), sqlx::Error> {
let in_progress_int = i64::from(in_progress);
sqlx::query!("UPDATE status SET flush_in_progress = ?", in_progress_int)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn get_client_in_use_status(&self) -> Result<bool, sqlx::Error> {
sqlx::query!("SELECT client_in_use FROM status;")
.fetch_one(&self.connection_pool)
.await
.map(|r| r.client_in_use > 0)
}
pub(crate) async fn set_client_in_use_status(&self, in_use: bool) -> Result<(), sqlx::Error> {
let in_use_int = i64::from(in_use);
sqlx::query!("UPDATE status SET client_in_use = ?", in_use_int)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn delete_all_tags(&self) -> Result<(), sqlx::Error> {
sqlx::query!("DELETE FROM sender_tag;")
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn get_tags(&self) -> Result<Vec<StoredSenderTag>, sqlx::Error> {
sqlx::query_as!(StoredSenderTag, "SELECT * FROM sender_tag;",)
.fetch_all(&self.connection_pool)
.await
}
pub(crate) async fn insert_tag(&self, stored_tag: StoredSenderTag) -> Result<(), sqlx::Error> {
sqlx::query!(
r#"
INSERT INTO sender_tag(recipient, tag) VALUES (?, ?);
"#,
stored_tag.recipient,
stored_tag.tag
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn delete_all_reply_keys(&self) -> Result<(), sqlx::Error> {
sqlx::query!("DELETE FROM reply_key;")
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn get_reply_keys(&self) -> Result<Vec<StoredReplyKey>, sqlx::Error> {
sqlx::query_as!(StoredReplyKey, "SELECT * FROM reply_key;",)
.fetch_all(&self.connection_pool)
.await
}
pub(crate) async fn insert_reply_key(
&self,
stored_reply_key: StoredReplyKey,
) -> Result<(), sqlx::Error> {
sqlx::query!(
r#"
INSERT INTO reply_key(key_digest, reply_key, sent_at_timestamp) VALUES (?, ?, ?);
"#,
stored_reply_key.key_digest,
stored_reply_key.reply_key,
stored_reply_key.sent_at_timestamp
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn get_surb_senders(&self) -> Result<Vec<StoredSurbSender>, sqlx::Error> {
sqlx::query_as!(StoredSurbSender, "SELECT * FROM reply_surb_sender;",)
.fetch_all(&self.connection_pool)
.await
}
pub(crate) async fn insert_surb_sender(
&self,
stored_surb_sender: StoredSurbSender,
) -> Result<i64, sqlx::Error> {
let id = sqlx::query!(
r#"
INSERT INTO reply_surb_sender(tag, last_sent_timestamp) VALUES (?, ?);
"#,
stored_surb_sender.tag,
stored_surb_sender.last_sent_timestamp
)
.execute(&self.connection_pool)
.await?
.last_insert_rowid();
Ok(id)
}
pub(crate) async fn get_reply_surbs(
&self,
sender_id: i64,
) -> Result<Vec<StoredReplySurb>, sqlx::Error> {
sqlx::query_as!(
StoredReplySurb,
"SELECT * FROM reply_surb WHERE reply_surb_sender_id = ?",
sender_id
)
.fetch_all(&self.connection_pool)
.await
}
pub(crate) async fn delete_all_reply_surb_data(&self) -> Result<(), sqlx::Error> {
sqlx::query!("DELETE FROM reply_surb;")
.execute(&self.connection_pool)
.await?;
sqlx::query!("DELETE FROM reply_surb_sender;")
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn insert_reply_surb(
&self,
stored_reply_surb: StoredReplySurb,
) -> Result<(), sqlx::Error> {
sqlx::query!(
r#"
INSERT INTO reply_surb(reply_surb_sender_id, reply_surb) VALUES (?, ?);
"#,
stored_reply_surb.reply_surb_sender_id,
stored_reply_surb.reply_surb
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
pub(crate) async fn get_reply_surb_storage_metadata(
&self,
) -> Result<ReplySurbStorageMetadata, sqlx::Error> {
sqlx::query_as!(
ReplySurbStorageMetadata,
r#"
SELECT min_reply_surb_threshold as "min_reply_surb_threshold: u32", max_reply_surb_threshold as "max_reply_surb_threshold: u32" FROM reply_surb_storage_metadata;
"#,
)
.fetch_one(&self.connection_pool)
.await
}
pub(crate) async fn insert_reply_surb_storage_metadata(
&self,
metadata: ReplySurbStorageMetadata,
) -> Result<(), sqlx::Error> {
sqlx::query!(r#"
INSERT INTO reply_surb_storage_metadata(min_reply_surb_threshold, max_reply_surb_threshold)
VALUES (?, ?);
"#,
metadata.min_reply_surb_threshold,
metadata.max_reply_surb_threshold,
).execute(&self.connection_pool).await?;
Ok(())
}
}
@@ -0,0 +1,348 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_storage::backend::fs_backend::manager::StorageManager;
use crate::client::replies::reply_storage::backend::fs_backend::models::{
ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender,
};
use crate::client::replies::reply_storage::surb_storage::ReceivedReplySurbs;
use crate::client::replies::reply_storage::{
CombinedReplyStorage, ReceivedReplySurbsMap, ReplyStorageBackend, SentReplyKeys, UsedSenderTags,
};
use async_trait::async_trait;
use log::{error, info, warn};
use nymsphinx::anonymous_replies::requests::AnonymousSenderTag;
use std::fs;
use std::path::{Path, PathBuf};
use time::OffsetDateTime;
pub use self::error::StorageError;
mod error;
mod manager;
mod models;
#[derive(Debug)]
pub struct Backend {
temporary_old_path: Option<PathBuf>,
database_path: PathBuf,
manager: StorageManager,
}
impl Backend {
const OLD_EXTENSION: &'static str = "old";
pub async fn init<P: AsRef<Path>>(database_path: P) -> Result<Self, StorageError> {
let owned_path: PathBuf = database_path.as_ref().into();
if owned_path.file_name().is_none() {
return Err(StorageError::DatabasePathWithoutFilename {
provided_path: owned_path,
});
}
let backend = Backend {
temporary_old_path: None,
database_path: owned_path,
manager: StorageManager::init(database_path, true).await?,
};
backend.manager.create_status_table().await?;
Ok(backend)
}
pub async fn try_load<P: AsRef<Path>>(database_path: P) -> Result<Self, StorageError> {
let owned_path: PathBuf = database_path.as_ref().into();
if owned_path.file_name().is_none() {
return Err(StorageError::DatabasePathWithoutFilename {
provided_path: owned_path,
});
}
let manager = StorageManager::init(database_path, false).await?;
// the database flush wasn't fully finished and thus the data is in inconsistent state
// (we don't really know what's properly saved or what's not)
if manager.get_flush_status().await? {
return Err(StorageError::IncompleteDataFlush);
}
let last_flush_timestamp = manager.get_previous_flush_timestamp().await?;
if last_flush_timestamp == 0 {
// either this client has been running since 1970 or the flush failed
return Err(StorageError::IncompleteDataFlush);
}
// the process has gone down without full graceful shutdown,
// meaning the database doesn't contain valid data anymore
// so we have to purge it
if manager.get_client_in_use_status().await? {
error!("the client hasn't undergone through graceful shutdown the last time it's gone down - we can't trust its reply surbs or stored encryption keys. They shall get purged");
manager.delete_all_reply_surb_data().await?;
manager.delete_all_reply_keys().await?;
}
if let Err(err) = manager.get_reply_surb_storage_metadata().await {
// we can't recover here, we HAVE TO initialise fresh (because we don't know correct starting metadata)
error!("it seems the client has been shutdown gracefully - we're missing valid surb data dump. the existing database cannot be used");
return Err(err.into());
}
let last_flush = match OffsetDateTime::from_unix_timestamp(last_flush_timestamp) {
Ok(last_flush) => last_flush,
Err(err) => {
return Err(StorageError::CorruptedData {
details: format!("failed to parse stored timestamp - {err}"),
});
}
};
// in theory clients can use our reply surbs whenever they want, even a year in the future
// (assuming no key rotation has happened)
// but the way it's currently coded, everyone will purge old data
let since_last_flush = OffsetDateTime::now_utc() - last_flush;
if since_last_flush.whole_days() > 0 {
info!("it's been over {} days and {} hours since we last used our data store. our reply surbs are already outdated - we're going to purge them now.", since_last_flush.whole_days(), since_last_flush.whole_hours());
manager.delete_all_reply_surb_data().await?;
}
if since_last_flush.whole_days() > 1 {
info!("it's been over {} days and {} hours since we last used our data store. our reply keys are already outdated - we're going to purge them now.", since_last_flush.whole_days(), since_last_flush.whole_hours());
manager.delete_all_reply_keys().await?;
}
if since_last_flush.whole_days() > 2 {
info!("it's been over {} days and {} hours since we last used our data store. our used sender tags are already outdated - we're going to purge them now.", since_last_flush.whole_days(), since_last_flush.whole_hours());
manager.delete_all_tags().await?;
}
Ok(Backend {
temporary_old_path: None,
database_path: owned_path,
manager,
})
}
async fn close_pool(&mut self) {
self.manager.connection_pool.close().await;
}
async fn rotate(&mut self) -> Result<(), StorageError> {
self.close_pool().await;
let new_extension = if let Some(existing_extension) =
self.database_path.extension().and_then(|ext| ext.to_str())
{
format!("{existing_extension}.{}", Self::OLD_EXTENSION)
} else {
Self::OLD_EXTENSION.to_string()
};
let mut temp_old = self.database_path.clone();
temp_old.set_extension(new_extension);
fs::rename(&self.database_path, &temp_old)
.map_err(|err| StorageError::DatabaseRenameError { source: err })?;
self.manager = StorageManager::init(&self.database_path, true).await?;
self.manager.create_status_table().await?;
self.temporary_old_path = Some(temp_old);
Ok(())
}
fn remove_old(&mut self) -> Result<(), StorageError> {
if let Some(old_path) = self.temporary_old_path.take() {
fs::remove_file(old_path)
.map_err(|err| StorageError::DatabaseOldFileRemoveError { source: err })
} else {
warn!("the old database file doesn't seem to exist!");
Ok(())
}
}
async fn start_storage_flush(&self) -> Result<(), StorageError> {
Ok(self.manager.set_flush_status(true).await?)
}
async fn end_storage_flush(&self) -> Result<(), StorageError> {
self.manager
.set_previous_flush_timestamp(OffsetDateTime::now_utc().unix_timestamp())
.await?;
Ok(self.manager.set_flush_status(false).await?)
}
async fn start_client_use(&self) -> Result<(), StorageError> {
Ok(self.manager.set_client_in_use_status(true).await?)
}
async fn stop_client_use(&self) -> Result<(), StorageError> {
Ok(self.manager.set_client_in_use_status(false).await?)
}
async fn get_stored_tags(&self) -> Result<UsedSenderTags, StorageError> {
let stored = self.manager.get_tags().await?;
// stop at the first instance of corruption. if even a single entry is malformed,
// something weird has happened and we can't trust the rest of the data
let raw = stored
.into_iter()
.map(TryInto::try_into)
.collect::<Result<_, _>>()?;
Ok(UsedSenderTags::from_raw(raw))
}
async fn dump_sender_tags(&self, tags: &UsedSenderTags) -> Result<(), StorageError> {
for map_ref in tags.as_raw_iter() {
let (recipient, tag) = map_ref.pair();
self.manager
.insert_tag(StoredSenderTag::new(*recipient, *tag))
.await?;
}
Ok(())
}
async fn get_stored_reply_keys(&self) -> Result<SentReplyKeys, StorageError> {
let stored = self.manager.get_reply_keys().await?;
// stop at the first instance of corruption. if even a single entry is malformed,
// something weird has happened and we can't trust the rest of the data
let raw = stored
.into_iter()
.map(TryInto::try_into)
.collect::<Result<_, _>>()?;
Ok(SentReplyKeys::from_raw(raw))
}
async fn dump_sender_reply_keys(&self, reply_keys: &SentReplyKeys) -> Result<(), StorageError> {
for map_ref in reply_keys.as_raw_iter() {
let (digest, key) = map_ref.pair();
self.manager
.insert_reply_key(StoredReplyKey::new(*digest, *key))
.await?;
}
Ok(())
}
async fn get_stored_reply_surbs(&self) -> Result<ReceivedReplySurbsMap, StorageError> {
let surb_senders = self.manager.get_surb_senders().await?;
let metadata = self.get_reply_surb_storage_metadata().await?;
let mut received_surbs = Vec::with_capacity(surb_senders.len());
for sender in surb_senders {
let sender_id = sender.id;
let (sender_tag, surbs_last_received_at_timestamp): (AnonymousSenderTag, i64) =
sender.try_into()?;
let stored_surbs = self
.manager
.get_reply_surbs(sender_id)
.await?
.into_iter()
.map(|raw| raw.try_into())
.collect::<Result<_, _>>()?;
received_surbs.push((
sender_tag,
ReceivedReplySurbs::new_retrieved(stored_surbs, surbs_last_received_at_timestamp),
))
}
Ok(ReceivedReplySurbsMap::from_raw(
metadata.min_reply_surb_threshold as usize,
metadata.max_reply_surb_threshold as usize,
received_surbs,
))
}
async fn dump_reply_surbs(
&self,
reply_surbs: &ReceivedReplySurbsMap,
) -> Result<(), StorageError> {
for map_ref in reply_surbs.as_raw_iter() {
let (tag, received_surbs) = map_ref.pair();
let sender_id = self
.manager
.insert_surb_sender(StoredSurbSender::new(
*tag,
received_surbs.surbs_last_received_at(),
))
.await?;
for reply_surb in received_surbs.surbs_ref() {
self.manager
.insert_reply_surb(StoredReplySurb::new(sender_id, reply_surb))
.await?
}
}
Ok(())
}
async fn get_reply_surb_storage_metadata(
&self,
) -> Result<ReplySurbStorageMetadata, StorageError> {
self.manager
.get_reply_surb_storage_metadata()
.await
.map_err(Into::into)
}
async fn dump_reply_surb_storage_metadata(
&self,
reply_surbs: &ReceivedReplySurbsMap,
) -> Result<(), StorageError> {
self.manager
.insert_reply_surb_storage_metadata(ReplySurbStorageMetadata::new(
reply_surbs.min_surb_threshold(),
reply_surbs.max_surb_threshold(),
))
.await
.map_err(Into::into)
}
}
#[async_trait]
impl ReplyStorageBackend for Backend {
type StorageError = error::StorageError;
async fn start_storage_session(&self) -> Result<(), Self::StorageError> {
self.start_client_use().await
}
async fn flush_surb_storage(
&mut self,
storage: &CombinedReplyStorage,
) -> Result<(), Self::StorageError> {
// close all connections (there should be none! and rename the file to contain .old extension)
self.rotate().await?;
self.start_storage_flush().await?;
self.dump_sender_tags(storage.tags_storage_ref()).await?;
self.dump_sender_reply_keys(storage.key_storage_ref())
.await?;
let surbs_ref = storage.surbs_storage_ref();
self.dump_reply_surb_storage_metadata(surbs_ref).await?;
self.dump_reply_surbs(surbs_ref).await?;
self.remove_old()?;
self.end_storage_flush().await
}
async fn init_fresh(&mut self, fresh: &CombinedReplyStorage) -> Result<(), Self::StorageError> {
// for now nothing more to do apart from dumping the metadata
self.dump_reply_surb_storage_metadata(fresh.surbs_storage_ref())
.await
}
async fn load_surb_storage(&self) -> Result<CombinedReplyStorage, Self::StorageError> {
let reply_keys = self.get_stored_reply_keys().await?;
let tags = self.get_stored_tags().await?;
let reply_surbs = self.get_stored_reply_surbs().await?;
Ok(CombinedReplyStorage::load(reply_keys, reply_surbs, tags))
}
async fn stop_storage_session(self) -> Result<(), Self::StorageError> {
self.stop_client_use().await
}
}
@@ -0,0 +1,185 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_storage::backend::fs_backend::error::StorageError;
use crate::client::replies::reply_storage::key_storage::UsedReplyKey;
use crypto::generic_array::typenum::Unsigned;
use crypto::Digest;
use nymsphinx::addressing::clients::{Recipient, RecipientBytes};
use nymsphinx::anonymous_replies::encryption_key::EncryptionKeyDigest;
use nymsphinx::anonymous_replies::requests::{AnonymousSenderTag, SENDER_TAG_SIZE};
use nymsphinx::anonymous_replies::{ReplySurb, SurbEncryptionKey, SurbEncryptionKeySize};
use nymsphinx::params::ReplySurbKeyDigestAlgorithm;
#[derive(Debug, Clone)]
pub(crate) struct StoredSenderTag {
pub(crate) recipient: Vec<u8>,
pub(crate) tag: Vec<u8>,
}
impl StoredSenderTag {
pub(crate) fn new(recipient: RecipientBytes, tag: AnonymousSenderTag) -> StoredSenderTag {
StoredSenderTag {
recipient: recipient.to_vec(),
tag: tag.to_bytes().to_vec(),
}
}
}
impl TryFrom<StoredSenderTag> for (RecipientBytes, AnonymousSenderTag) {
type Error = StorageError;
fn try_from(value: StoredSenderTag) -> Result<Self, Self::Error> {
let recipient_len = value.recipient.len();
let Ok(recipient_bytes) = value.recipient.try_into() else {
return Err(StorageError::CorruptedData {
details: format!(
"the retrieved recipient has length of {recipient_len} while {} was expected",
Recipient::LEN
),
});
};
let tag_len = value.tag.len();
let Ok(sender_tag_bytes) = value.tag.try_into() else {
return Err(StorageError::CorruptedData {
details: format!(
"the retrieved sender tag has length of {tag_len} while {} was expected",
SENDER_TAG_SIZE
),
});
};
Ok((
recipient_bytes,
AnonymousSenderTag::from_bytes(sender_tag_bytes),
))
}
}
#[derive(Debug, Clone)]
pub(crate) struct StoredReplyKey {
pub(crate) key_digest: Vec<u8>,
pub(crate) reply_key: Vec<u8>,
pub(crate) sent_at_timestamp: i64,
}
impl StoredReplyKey {
pub(crate) fn new(key_digest: EncryptionKeyDigest, reply_key: UsedReplyKey) -> StoredReplyKey {
StoredReplyKey {
key_digest: key_digest.to_vec(),
reply_key: (*reply_key).to_bytes(),
sent_at_timestamp: reply_key.sent_at_timestamp,
}
}
}
impl TryFrom<StoredReplyKey> for (EncryptionKeyDigest, UsedReplyKey) {
type Error = StorageError;
fn try_from(value: StoredReplyKey) -> Result<Self, Self::Error> {
let expected_reply_key_digest_size = ReplySurbKeyDigestAlgorithm::output_size();
let reply_key_digest_size = value.key_digest.len();
let Some(digest) = EncryptionKeyDigest::from_exact_iter(value.key_digest) else {
return Err(StorageError::CorruptedData {
details: format!(
"the reply surb digest has length of {reply_key_digest_size} while {expected_reply_key_digest_size} was expected",
),
});
};
let reply_key_len = value.reply_key.len();
let Ok(reply_key) = SurbEncryptionKey::try_from_bytes(&value.reply_key) else {
return Err(StorageError::CorruptedData {
details: format!(
"the reply key has length of {reply_key_len} while {} was expected",
SurbEncryptionKeySize::USIZE
),
});
};
Ok((
digest,
UsedReplyKey::new(reply_key, value.sent_at_timestamp),
))
}
}
pub(crate) struct StoredSurbSender {
pub(crate) id: i64,
pub(crate) tag: Vec<u8>,
pub(crate) last_sent_timestamp: i64,
}
impl StoredSurbSender {
pub(crate) fn new(tag: AnonymousSenderTag, last_sent_timestamp: i64) -> Self {
StoredSurbSender {
// for the purposes of STORING data,
// we ignore that field anyway
id: 0,
tag: tag.to_bytes().to_vec(),
last_sent_timestamp,
}
}
}
impl TryFrom<StoredSurbSender> for (AnonymousSenderTag, i64) {
type Error = StorageError;
fn try_from(value: StoredSurbSender) -> Result<Self, Self::Error> {
let tag_len = value.tag.len();
let Ok(sender_tag_bytes) = value.tag.try_into() else {
return Err(StorageError::CorruptedData {
details: format!(
"the retrieved sender tag has length of {tag_len} while {} was expected",
SENDER_TAG_SIZE
),
});
};
Ok((
AnonymousSenderTag::from_bytes(sender_tag_bytes),
value.last_sent_timestamp,
))
}
}
pub(crate) struct StoredReplySurb {
pub(crate) reply_surb_sender_id: i64,
pub(crate) reply_surb: Vec<u8>,
}
impl StoredReplySurb {
pub(crate) fn new(reply_surb_sender_id: i64, reply_surb: &ReplySurb) -> Self {
StoredReplySurb {
reply_surb_sender_id,
reply_surb: reply_surb.to_bytes(),
}
}
}
impl TryFrom<StoredReplySurb> for ReplySurb {
type Error = StorageError;
fn try_from(value: StoredReplySurb) -> Result<Self, Self::Error> {
ReplySurb::from_bytes(&value.reply_surb).map_err(|err| StorageError::CorruptedData {
details: format!("failed to recover the reply surb: {err}"),
})
}
}
#[derive(Copy, Clone)]
pub(crate) struct ReplySurbStorageMetadata {
pub(crate) min_reply_surb_threshold: u32,
pub(crate) max_reply_surb_threshold: u32,
}
impl ReplySurbStorageMetadata {
pub(crate) fn new(min_reply_surb_threshold: usize, max_reply_surb_threshold: usize) -> Self {
Self {
min_reply_surb_threshold: min_reply_surb_threshold as u32,
max_reply_surb_threshold: max_reply_surb_threshold as u32,
}
}
}
@@ -0,0 +1,78 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_storage::CombinedReplyStorage;
use async_trait::async_trait;
use std::error::Error;
use thiserror::Error;
#[cfg(target_arch = "wasm32")]
pub mod browser_backend;
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
pub mod fs_backend;
// #[cfg(all(test, feature = "std"))]
// third case: node with actual filesystem
#[derive(Debug, Error)]
#[error("no information provided")]
pub struct UndefinedError;
pub struct Empty {
// we need to keep 'basic' metadata here to "load" the CombinedReplyStorage
min_surb_threshold: usize,
max_surb_threshold: usize,
}
#[async_trait]
impl ReplyStorageBackend for Empty {
type StorageError = UndefinedError;
async fn flush_surb_storage(
&mut self,
_storage: &CombinedReplyStorage,
) -> Result<(), Self::StorageError> {
Ok(())
}
async fn init_fresh(
&mut self,
_fresh: &CombinedReplyStorage,
) -> Result<(), Self::StorageError> {
Ok(())
}
async fn load_surb_storage(&self) -> Result<CombinedReplyStorage, Self::StorageError> {
Ok(CombinedReplyStorage::new(
self.min_surb_threshold,
self.max_surb_threshold,
))
}
}
#[async_trait]
pub trait ReplyStorageBackend: Sized {
type StorageError: Error + 'static;
async fn start_storage_session(&self) -> Result<(), Self::StorageError> {
Ok(())
}
// reply keys and surbs would need additional field set when data is loaded
// so if there's some failure, we'd trash it all
async fn flush_surb_storage(
&mut self,
storage: &CombinedReplyStorage,
) -> Result<(), Self::StorageError>;
/// The purpose of this call is to save any metadata that might be present.
/// (such as surb thresholds)
async fn init_fresh(&mut self, fresh: &CombinedReplyStorage) -> Result<(), Self::StorageError>;
async fn load_surb_storage(&self) -> Result<CombinedReplyStorage, Self::StorageError>;
async fn stop_storage_session(self) -> Result<(), Self::StorageError> {
Ok(())
}
}
@@ -0,0 +1,60 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_storage::{ReceivedReplySurbsMap, SentReplyKeys, UsedSenderTags};
#[derive(Debug, Clone)]
pub struct CombinedReplyStorage {
sent_reply_keys: SentReplyKeys,
received_reply_surbs: ReceivedReplySurbsMap,
used_tags: UsedSenderTags,
}
impl CombinedReplyStorage {
pub fn new(min_surb_threshold: usize, max_surb_threshold: usize) -> CombinedReplyStorage {
CombinedReplyStorage {
sent_reply_keys: SentReplyKeys::new(),
received_reply_surbs: ReceivedReplySurbsMap::new(
min_surb_threshold,
max_surb_threshold,
),
used_tags: UsedSenderTags::new(),
}
}
pub fn load(
sent_reply_keys: SentReplyKeys,
received_reply_surbs: ReceivedReplySurbsMap,
used_tags: UsedSenderTags,
) -> Self {
CombinedReplyStorage {
sent_reply_keys,
received_reply_surbs,
used_tags,
}
}
pub fn key_storage(&self) -> SentReplyKeys {
self.sent_reply_keys.clone()
}
pub fn surbs_storage(&self) -> ReceivedReplySurbsMap {
self.received_reply_surbs.clone()
}
pub fn tags_storage(&self) -> UsedSenderTags {
self.used_tags.clone()
}
pub fn key_storage_ref(&self) -> &SentReplyKeys {
&self.sent_reply_keys
}
pub fn surbs_storage_ref(&self) -> &ReceivedReplySurbsMap {
&self.received_reply_surbs
}
pub fn tags_storage_ref(&self) -> &UsedSenderTags {
&self.used_tags
}
}
@@ -0,0 +1,86 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use dashmap::iter::Iter;
use dashmap::DashMap;
use nymsphinx::anonymous_replies::encryption_key::EncryptionKeyDigest;
use nymsphinx::anonymous_replies::SurbEncryptionKey;
use std::ops::Deref;
use std::sync::Arc;
use time::OffsetDateTime;
#[derive(Debug, Clone)]
pub struct SentReplyKeys {
inner: Arc<SentReplyKeysInner>,
}
#[derive(Debug)]
struct SentReplyKeysInner {
data: DashMap<EncryptionKeyDigest, UsedReplyKey>,
}
impl SentReplyKeys {
pub(crate) fn new() -> SentReplyKeys {
SentReplyKeys {
inner: Arc::new(SentReplyKeysInner {
data: DashMap::new(),
}),
}
}
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
pub(crate) fn from_raw(raw: Vec<(EncryptionKeyDigest, UsedReplyKey)>) -> SentReplyKeys {
SentReplyKeys {
inner: Arc::new(SentReplyKeysInner {
data: raw.into_iter().collect(),
}),
}
}
pub(crate) fn as_raw_iter(&self) -> Iter<'_, EncryptionKeyDigest, UsedReplyKey> {
self.inner.data.iter()
}
pub(crate) fn insert_multiple(&self, keys: Vec<SurbEncryptionKey>) {
let now = OffsetDateTime::now_utc().unix_timestamp();
for key in keys {
self.insert(UsedReplyKey::new(key, now))
}
}
pub(crate) fn insert(&self, key: UsedReplyKey) {
self.inner.data.insert(key.compute_digest(), key);
}
pub(crate) fn try_pop(&self, digest: EncryptionKeyDigest) -> Option<UsedReplyKey> {
self.inner.data.remove(&digest).map(|(_k, v)| v)
}
pub(crate) fn remove(&self, digest: EncryptionKeyDigest) {
self.inner.data.remove(&digest);
}
}
#[derive(Debug, Copy, Clone)]
pub(crate) struct UsedReplyKey {
key: SurbEncryptionKey,
// the purpose of this field is to perform invalidation at relatively very long intervals
pub(crate) sent_at_timestamp: i64,
}
impl UsedReplyKey {
pub(crate) fn new(key: SurbEncryptionKey, sent_at_timestamp: i64) -> Self {
UsedReplyKey {
key,
sent_at_timestamp,
}
}
}
impl Deref for UsedReplyKey {
type Target = SurbEncryptionKey;
fn deref(&self) -> &Self::Target {
&self.key
}
}
@@ -0,0 +1,64 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub use crate::client::replies::reply_storage::combined::CombinedReplyStorage;
pub use crate::client::replies::reply_storage::key_storage::SentReplyKeys;
pub use crate::client::replies::reply_storage::surb_storage::ReceivedReplySurbsMap;
pub use crate::client::replies::reply_storage::tag_storage::UsedSenderTags;
pub use backend::*;
mod backend;
mod combined;
mod key_storage;
mod surb_storage;
mod tag_storage;
// only really exists to get information about shutdown and save data to the backing storage
pub struct PersistentReplyStorage<T = backend::Empty>
where
T: ReplyStorageBackend,
{
backend: T,
}
impl<T> PersistentReplyStorage<T>
where
T: ReplyStorageBackend + Send + Sync,
{
pub fn new(backend: T) -> Self {
PersistentReplyStorage { backend }
}
pub async fn load_state_from_backend(&self) -> Result<CombinedReplyStorage, T::StorageError> {
self.backend.load_surb_storage().await
}
// this will have to get enabled after merging develop
pub async fn flush_on_shutdown(
mut self,
mem_state: CombinedReplyStorage,
mut shutdown: task::TaskClient,
) {
use log::{debug, error, info, warn};
debug!("Started PersistentReplyStorage");
if let Err(err) = self.backend.start_storage_session().await {
error!("failed to start the storage session - {err}");
return;
}
shutdown.recv().await;
info!("PersistentReplyStorage is flushing all reply-related data to underlying storage");
warn!("you MUST NOT forcefully shutdown now or you risk data corruption!");
if let Err(err) = self.backend.flush_surb_storage(&mem_state).await {
error!("failed to flush our reply-related data to the persistent storage: {err}")
} else {
info!("Data flush is complete")
}
if let Err(err) = self.backend.stop_storage_session().await {
error!("failed to properly stop the storage session - {err}. We might not be able to smoothly restore it")
}
}
}
@@ -0,0 +1,278 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use dashmap::iter::Iter;
use dashmap::DashMap;
use log::trace;
use nymsphinx::anonymous_replies::requests::AnonymousSenderTag;
use nymsphinx::anonymous_replies::ReplySurb;
use std::collections::VecDeque;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use time::OffsetDateTime;
#[derive(Debug, Clone)]
pub struct ReceivedReplySurbsMap {
inner: Arc<ReceivedReplySurbsMapInner>,
}
#[derive(Debug)]
struct ReceivedReplySurbsMapInner {
data: DashMap<AnonymousSenderTag, ReceivedReplySurbs>,
// the minimum amount of surbs that have to be kept in storage for requests for more surbs
min_surb_threshold: AtomicUsize,
// the maximum amount of surbs that we want to keep in storage so that we don't over-request them
max_surb_threshold: AtomicUsize,
}
impl ReceivedReplySurbsMap {
pub(crate) fn new(
min_surb_threshold: usize,
max_surb_threshold: usize,
) -> ReceivedReplySurbsMap {
ReceivedReplySurbsMap {
inner: Arc::new(ReceivedReplySurbsMapInner {
data: DashMap::new(),
min_surb_threshold: AtomicUsize::new(min_surb_threshold),
max_surb_threshold: AtomicUsize::new(max_surb_threshold),
}),
}
}
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
pub(crate) fn from_raw(
min_surb_threshold: usize,
max_surb_threshold: usize,
raw: Vec<(AnonymousSenderTag, ReceivedReplySurbs)>,
) -> ReceivedReplySurbsMap {
ReceivedReplySurbsMap {
inner: Arc::new(ReceivedReplySurbsMapInner {
data: raw.into_iter().collect(),
min_surb_threshold: AtomicUsize::new(min_surb_threshold),
max_surb_threshold: AtomicUsize::new(max_surb_threshold),
}),
}
}
pub(crate) fn as_raw_iter(&self) -> Iter<'_, AnonymousSenderTag, ReceivedReplySurbs> {
self.inner.data.iter()
}
pub(crate) fn remove(&self, target: &AnonymousSenderTag) {
self.inner.data.remove(target);
}
pub(crate) fn reset_surbs_last_received_at(&self, target: &AnonymousSenderTag) {
if let Some(mut entry) = self.inner.data.get_mut(target) {
entry.surbs_last_received_at_timestamp = OffsetDateTime::now_utc().unix_timestamp();
}
}
pub(crate) fn surbs_last_received_at(&self, target: &AnonymousSenderTag) -> Option<i64> {
self.inner
.data
.get(target)
.map(|e| e.surbs_last_received_at())
}
pub(crate) fn pending_reception(&self, target: &AnonymousSenderTag) -> u32 {
self.inner
.data
.get(target)
.map(|e| e.pending_reception())
.unwrap_or_default()
}
pub(crate) fn increment_pending_reception(
&self,
target: &AnonymousSenderTag,
amount: u32,
) -> Option<u32> {
self.inner
.data
.get_mut(target)
.map(|mut e| e.increment_pending_reception(amount))
}
pub(crate) fn decrement_pending_reception(
&self,
target: &AnonymousSenderTag,
amount: u32,
) -> Option<u32> {
self.inner
.data
.get_mut(target)
.map(|mut e| e.decrement_pending_reception(amount))
}
pub(crate) fn reset_pending_reception(&self, target: &AnonymousSenderTag) {
if let Some(mut e) = self.inner.data.get_mut(target) {
e.reset_pending_reception()
}
}
pub(crate) fn min_surb_threshold(&self) -> usize {
self.inner.min_surb_threshold.load(Ordering::Relaxed)
}
pub(crate) fn max_surb_threshold(&self) -> usize {
self.inner.max_surb_threshold.load(Ordering::Relaxed)
}
pub(crate) fn available_surbs(&self, target: &AnonymousSenderTag) -> usize {
self.inner
.data
.get(target)
.map(|entry| entry.items_left())
.unwrap_or_default()
}
pub(crate) fn contains_surbs_for(&self, target: &AnonymousSenderTag) -> bool {
self.inner.data.contains_key(target)
}
pub(crate) fn get_reply_surbs(
&self,
target: &AnonymousSenderTag,
amount: usize,
) -> (Option<Vec<ReplySurb>>, usize) {
if let Some(mut entry) = self.inner.data.get_mut(target) {
let surbs_left = entry.items_left();
if surbs_left < self.min_surb_threshold() + amount {
(None, surbs_left)
} else {
entry.get_reply_surbs(amount)
}
} else {
(None, 0)
}
}
pub(crate) fn get_reply_surb_ignoring_threshold(
&self,
target: &AnonymousSenderTag,
) -> Option<(Option<ReplySurb>, usize)> {
self.inner
.data
.get_mut(target)
.map(|mut s| s.get_reply_surb())
}
pub(crate) fn get_reply_surb(
&self,
target: &AnonymousSenderTag,
) -> Option<(Option<ReplySurb>, usize)> {
self.inner.data.get_mut(target).map(|mut entry| {
let surbs_left = entry.items_left();
if surbs_left < self.min_surb_threshold() {
(None, surbs_left)
} else {
entry.get_reply_surb()
}
})
}
pub(crate) fn insert_surbs<I: IntoIterator<Item = ReplySurb>>(
&self,
target: &AnonymousSenderTag,
surbs: I,
) {
if let Some(mut existing_data) = self.inner.data.get_mut(target) {
existing_data.insert_reply_surbs(surbs)
} else {
let new_entry = ReceivedReplySurbs::new(surbs.into_iter().collect());
self.inner.data.insert(*target, new_entry);
}
}
}
#[derive(Debug)]
pub(crate) struct ReceivedReplySurbs {
// in the future we'd probably want to put extra data here to indicate when the SURBs got received
// so we could invalidate entries from the previous key rotations
data: VecDeque<ReplySurb>,
pending_reception: u32,
surbs_last_received_at_timestamp: i64,
}
impl ReceivedReplySurbs {
fn new(initial_surbs: VecDeque<ReplySurb>) -> Self {
ReceivedReplySurbs {
data: initial_surbs,
pending_reception: 0,
surbs_last_received_at_timestamp: OffsetDateTime::now_utc().unix_timestamp(),
}
}
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
pub(crate) fn new_retrieved(
surbs: Vec<ReplySurb>,
surbs_last_received_at_timestamp: i64,
) -> ReceivedReplySurbs {
ReceivedReplySurbs {
data: surbs.into(),
pending_reception: 0,
surbs_last_received_at_timestamp,
}
}
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
pub(crate) fn surbs_ref(&self) -> &VecDeque<ReplySurb> {
&self.data
}
pub(crate) fn surbs_last_received_at(&self) -> i64 {
self.surbs_last_received_at_timestamp
}
pub(crate) fn pending_reception(&self) -> u32 {
self.pending_reception
}
pub(crate) fn increment_pending_reception(&mut self, amount: u32) -> u32 {
self.pending_reception += amount;
self.pending_reception
}
pub(crate) fn decrement_pending_reception(&mut self, amount: u32) -> u32 {
self.pending_reception = self.pending_reception.saturating_sub(amount);
self.pending_reception
}
pub(crate) fn reset_pending_reception(&mut self) {
self.pending_reception = 0;
}
pub(crate) fn get_reply_surbs(&mut self, amount: usize) -> (Option<Vec<ReplySurb>>, usize) {
if self.items_left() < amount {
(None, self.items_left())
} else {
let surbs = self.data.drain(..amount).collect();
(Some(surbs), self.items_left())
}
}
pub(crate) fn get_reply_surb(&mut self) -> (Option<ReplySurb>, usize) {
(self.pop_surb(), self.items_left())
}
fn pop_surb(&mut self) -> Option<ReplySurb> {
self.data.pop_front()
}
fn items_left(&self) -> usize {
self.data.len()
}
// realistically we're always going to be getting multiple surbs at once
pub(crate) fn insert_reply_surbs<I: IntoIterator<Item = ReplySurb>>(&mut self, surbs: I) {
let mut v = surbs.into_iter().collect::<VecDeque<_>>();
trace!("storing {} surbs in the storage", v.len());
self.data.append(&mut v);
self.surbs_last_received_at_timestamp = OffsetDateTime::now_utc().unix_timestamp();
trace!("we now have {} surbs!", self.data.len());
}
}
@@ -0,0 +1,59 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use dashmap::DashMap;
use nymsphinx::addressing::clients::{Recipient, RecipientBytes};
use nymsphinx::anonymous_replies::requests::AnonymousSenderTag;
use std::sync::Arc;
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
use dashmap::iter::Iter;
#[derive(Debug, Clone)]
pub struct UsedSenderTags {
inner: Arc<UsedSenderTagsInner>,
}
#[derive(Debug)]
struct UsedSenderTagsInner {
data: DashMap<RecipientBytes, AnonymousSenderTag>,
}
impl UsedSenderTags {
pub(crate) fn new() -> UsedSenderTags {
UsedSenderTags {
inner: Arc::new(UsedSenderTagsInner {
data: DashMap::new(),
}),
}
}
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
pub(crate) fn from_raw(raw: Vec<(RecipientBytes, AnonymousSenderTag)>) -> UsedSenderTags {
UsedSenderTags {
inner: Arc::new(UsedSenderTagsInner {
data: raw.into_iter().collect(),
}),
}
}
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
pub(crate) fn as_raw_iter(&self) -> Iter<'_, RecipientBytes, AnonymousSenderTag> {
self.inner.data.iter()
}
pub(crate) fn insert_new(&self, recipient: &Recipient, tag: AnonymousSenderTag) {
self.inner.data.insert(recipient.to_bytes(), tag);
}
pub(crate) fn try_get_existing(&self, recipient: &Recipient) -> Option<AnonymousSenderTag> {
self.inner
.data
.get(&recipient.to_bytes())
.map(|r| *r.value())
}
pub(crate) fn exists(&self, recipient: &Recipient) -> bool {
self.inner.data.contains_key(&recipient.to_bytes())
}
}
@@ -1,94 +0,0 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crypto::generic_array::typenum::Unsigned;
use log::*;
use nymsphinx::anonymous_replies::{
encryption_key::EncryptionKeyDigest, SurbEncryptionKey, SurbEncryptionKeySize,
};
use std::path::Path;
#[derive(Debug)]
pub enum ReplyKeyStorageError {
DbReadError(sled::Error),
DbWriteError(sled::Error),
DbOpenError(sled::Error),
}
/// Permanent storage for keys in all sent [`ReplySURB`]
///
/// Each sent out [`ReplySURB`] has a new key associated with it that is going to be used for
/// payload encryption. In order to -decrypt whatever reply we receive, we need to know which
/// key to use for that purpose. We do it based on received `H(t)` which has to be included
/// with each reply.
/// Moreover, there is no restriction when the [`ReplySURB`] might get used so we need to
/// have a permanent storage for all the keys that we might ever see in the future.
#[derive(Debug, Clone)]
pub struct ReplyKeyStorage {
db: sled::Db,
}
impl ReplyKeyStorage {
pub fn load<P: AsRef<Path>>(path: P) -> Result<Self, ReplyKeyStorageError> {
let db = match sled::open(path) {
Err(e) => return Err(ReplyKeyStorageError::DbOpenError(e)),
Ok(db) => db,
};
Ok(ReplyKeyStorage { db })
}
fn read_encryption_key(&self, raw_key: sled::IVec) -> SurbEncryptionKey {
let key_bytes_ref = raw_key.as_ref();
// if this fails it means we have some database corruption and we
// absolutely can't continue
if key_bytes_ref.len() != SurbEncryptionKeySize::USIZE {
error!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH");
panic!("REPLY KEY STORAGE DATA CORRUPTION - ENCRYPTION KEY HAS INVALID LENGTH");
}
// this can only fail if the bytes have invalid length but we already asserted it
SurbEncryptionKey::try_from_bytes(key_bytes_ref).unwrap()
}
// TOOD: perhaps we could also store some part of original message here too?
pub fn insert_encryption_key(
&mut self,
encryption_key: SurbEncryptionKey,
) -> Result<(), ReplyKeyStorageError> {
let digest = encryption_key.compute_digest();
let insertion_result = match self.db.insert(digest, encryption_key.to_bytes()) {
Err(e) => Err(ReplyKeyStorageError::DbWriteError(e)),
Ok(existing_key) => {
if existing_key.is_some() {
panic!("HASH COLLISION DETECTED")
};
Ok(())
}
};
// TODO: perhaps we could implement some batching mechanism to avoid frequent flushes?
self.db.flush().unwrap();
insertion_result
}
// Once we use key once, we do not expect to use it again
pub fn get_and_remove_encryption_key(
&self,
key_digest: EncryptionKeyDigest,
) -> Result<Option<SurbEncryptionKey>, ReplyKeyStorageError> {
let removal_result = match self.db.remove(key_digest) {
Err(e) => Err(ReplyKeyStorageError::DbReadError(e)),
Ok(existing_key) => {
Ok(existing_key.map(|existing_key| self.read_encryption_key(existing_key)))
}
};
// TODO: not sure how to feel about flushing it every single time here...
// same with insertion
self.db.flush().unwrap();
removal_result
}
}
@@ -1,6 +1,8 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::spawn_future;
use futures::StreamExt;
use log::*;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::params::DEFAULT_NUM_MIX_HOPS;
@@ -8,11 +10,9 @@ use rand::seq::SliceRandom;
use rand::thread_rng;
use std::ops::Deref;
use std::sync::Arc;
use std::time;
use std::time::Duration;
use tokio::sync::{RwLock, RwLockReadGuard};
use tokio::task::JoinHandle;
use topology::{nym_topology_from_bonds, NymTopology};
use topology::{nym_topology_from_detailed, NymTopology, NymTopologyError};
use url::Url;
// I'm extremely curious why compiler NEVER complained about lack of Debug here before
@@ -54,27 +54,36 @@ impl<'a> TopologyReadPermit<'a> {
&'a self,
ack_recipient: &Recipient,
packet_recipient: Option<&Recipient>,
) -> Option<&'a NymTopology> {
// Note: implicit deref with Deref for TopologyReadPermit is happening here
let topology_ref_option = self.permit.as_ref();
match topology_ref_option {
None => None,
Some(topology_ref) => {
// see if it's possible to route the packet to both gateways
if !topology_ref.can_construct_path_through(DEFAULT_NUM_MIX_HOPS)
|| !topology_ref.gateway_exists(ack_recipient.gateway())
|| if let Some(packet_recipient) = packet_recipient {
!topology_ref.gateway_exists(packet_recipient.gateway())
} else {
false
}
{
None
} else {
Some(topology_ref)
}
) -> Result<&'a NymTopology, NymTopologyError> {
// 1. Have we managed to get anything from the refresher, i.e. have the nym-api queries gone through?
let topology = self
.permit
.as_ref()
.as_ref()
.ok_or(NymTopologyError::EmptyNetworkTopology)?;
// 2. does it have any mixnode at all?
// 3. does it have any gateways at all?
// 4. does it have a mixnode on each layer?
topology.ensure_can_construct_path_through(DEFAULT_NUM_MIX_HOPS)?;
// 5. does it contain OUR gateway (so that we could create an ack packet)?
if !topology.gateway_exists(ack_recipient.gateway()) {
return Err(NymTopologyError::NonExistentGatewayError {
identity_key: ack_recipient.gateway().to_base58_string(),
});
}
// 6. for our target recipient, does it contain THEIR gateway (so that we could create
if let Some(recipient) = packet_recipient {
if !topology.gateway_exists(recipient.gateway()) {
return Err(NymTopologyError::NonExistentGatewayError {
identity_key: recipient.gateway().to_base58_string(),
});
}
}
Ok(topology)
}
}
@@ -112,10 +121,10 @@ impl TopologyAccessor {
// only used by the client at startup to get a slightly more reasonable error message
// (currently displays as unused because health checker is disabled due to required changes)
pub async fn is_routable(&self) -> bool {
pub async fn ensure_is_routable(&self) -> Result<(), NymTopologyError> {
match &self.inner.read().await.0 {
None => false,
Some(ref topology) => topology.can_construct_path_through(DEFAULT_NUM_MIX_HOPS),
None => Err(NymTopologyError::EmptyNetworkTopology),
Some(ref topology) => topology.ensure_can_construct_path_through(DEFAULT_NUM_MIX_HOPS),
}
}
}
@@ -127,19 +136,15 @@ impl Default for TopologyAccessor {
}
pub struct TopologyRefresherConfig {
validator_api_urls: Vec<Url>,
refresh_rate: time::Duration,
nym_api_urls: Vec<Url>,
refresh_rate: Duration,
client_version: String,
}
impl TopologyRefresherConfig {
pub fn new(
validator_api_urls: Vec<Url>,
refresh_rate: time::Duration,
client_version: String,
) -> Self {
pub fn new(nym_api_urls: Vec<Url>, refresh_rate: Duration, client_version: String) -> Self {
TopologyRefresherConfig {
validator_api_urls,
nym_api_urls,
refresh_rate,
client_version,
}
@@ -147,10 +152,10 @@ impl TopologyRefresherConfig {
}
pub struct TopologyRefresher {
validator_client: validator_client::ApiClient,
validator_client: validator_client::client::ApiClient,
client_version: String,
validator_api_urls: Vec<Url>,
nym_api_urls: Vec<Url>,
topology_accessor: TopologyAccessor,
refresh_rate: Duration,
@@ -160,12 +165,12 @@ pub struct TopologyRefresher {
impl TopologyRefresher {
pub fn new(mut cfg: TopologyRefresherConfig, topology_accessor: TopologyAccessor) -> Self {
cfg.validator_api_urls.shuffle(&mut thread_rng());
cfg.nym_api_urls.shuffle(&mut thread_rng());
TopologyRefresher {
validator_client: validator_client::ApiClient::new(cfg.validator_api_urls[0].clone()),
validator_client: validator_client::client::ApiClient::new(cfg.nym_api_urls[0].clone()),
client_version: cfg.client_version,
validator_api_urls: cfg.validator_api_urls,
nym_api_urls: cfg.nym_api_urls,
topology_accessor,
refresh_rate: cfg.refresh_rate,
currently_used_api: 0,
@@ -173,15 +178,15 @@ impl TopologyRefresher {
}
}
fn use_next_validator_api(&mut self) {
if self.validator_api_urls.len() == 1 {
warn!("There's only a single validator API available - it won't be possible to use a different one");
fn use_next_nym_api(&mut self) {
if self.nym_api_urls.len() == 1 {
warn!("There's only a single nym API available - it won't be possible to use a different one");
return;
}
self.currently_used_api = (self.currently_used_api + 1) % self.validator_api_urls.len();
self.currently_used_api = (self.currently_used_api + 1) % self.nym_api_urls.len();
self.validator_client
.change_validator_api(self.validator_api_urls[self.currently_used_api].clone())
.change_nym_api(self.nym_api_urls[self.currently_used_api].clone())
}
/// Verifies whether nodes a reasonably distributed among all mix layers.
@@ -193,13 +198,10 @@ impl TopologyRefresher {
/// # Arguments
///
/// * `topology`: active topology constructed from validator api data
/// * `mixnodes_count`: total number of active mixnodes
fn check_layer_distribution(
&self,
active_topology: &NymTopology,
mixnodes_count: usize,
) -> bool {
fn check_layer_distribution(&self, active_topology: &NymTopology) -> bool {
let mixes = active_topology.mixes();
let mixnodes_count = active_topology.num_mixnodes();
if active_topology.gateways().is_empty() {
return false;
}
@@ -250,7 +252,7 @@ impl TopologyRefresher {
let mixnodes = match self.validator_client.get_cached_active_mixnodes().await {
Err(err) => {
error!("failed to get network mixnodes - {}", err);
error!("failed to get network mixnodes - {err}");
return None;
}
Ok(mixes) => mixes,
@@ -258,17 +260,16 @@ impl TopologyRefresher {
let gateways = match self.validator_client.get_cached_gateways().await {
Err(err) => {
error!("failed to get network gateways - {}", err);
error!("failed to get network gateways - {err}");
return None;
}
Ok(gateways) => gateways,
};
let mixnodes_count = mixnodes.len();
let topology =
nym_topology_from_bonds(mixnodes, gateways).filter_system_version(&self.client_version);
let topology = nym_topology_from_detailed(mixnodes, gateways)
.filter_system_version(&self.client_version);
if !self.check_layer_distribution(&topology, mixnodes_count) {
if !self.check_layer_distribution(&topology) {
warn!("The current filtered active topology has extremely skewed layer distribution. It cannot be used.");
None
} else {
@@ -281,7 +282,7 @@ impl TopologyRefresher {
let new_topology = self.get_current_compatible_topology().await;
if new_topology.is_none() {
self.use_next_validator_api();
self.use_next_nym_api();
}
if new_topology.is_none() && self.was_latest_valid {
@@ -299,16 +300,35 @@ impl TopologyRefresher {
.await;
}
pub async fn is_topology_routable(&self) -> bool {
self.topology_accessor.is_routable().await
pub async fn ensure_topology_is_routable(&self) -> Result<(), NymTopologyError> {
self.topology_accessor.ensure_is_routable().await
}
pub fn start(mut self) -> JoinHandle<()> {
tokio::spawn(async move {
loop {
tokio::time::sleep(self.refresh_rate).await;
self.refresh().await;
pub fn start_with_shutdown(mut self, mut shutdown: task::TaskClient) {
spawn_future(async move {
debug!("Started TopologyRefresher with graceful shutdown support");
#[cfg(not(target_arch = "wasm32"))]
let mut interval = tokio_stream::wrappers::IntervalStream::new(tokio::time::interval(
self.refresh_rate,
));
#[cfg(target_arch = "wasm32")]
let mut interval =
gloo_timers::future::IntervalStream::new(self.refresh_rate.as_millis() as u32);
while !shutdown.is_shutdown() {
tokio::select! {
_ = interval.next() => {
self.refresh().await;
},
_ = shutdown.recv() => {
log::trace!("TopologyRefresher: Received shutdown");
},
}
}
shutdown.recv_timeout().await;
log::debug!("TopologyRefresher: Exiting");
})
}
}
@@ -0,0 +1,287 @@
// 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,
};
// 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>>,
}
impl<T> TransmissionBuffer<T> {
pub(crate) fn new() -> Self {
TransmissionBuffer {
buffer: HashMap::new(),
}
}
#[allow(unused)]
pub(crate) fn is_empty(&self) -> bool {
self.buffer.is_empty()
}
pub(crate) fn remove(&mut self, lane: &TransmissionLane) -> Option<LaneBufferEntry<T>> {
self.buffer.remove(lane)
}
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn num_lanes(&self) -> usize {
self.buffer.keys().count()
}
pub(crate) fn lane_length(&self, lane: &TransmissionLane) -> Option<usize> {
self.buffer.get(lane).map(LaneBufferEntry::len)
}
#[allow(unused)]
pub(crate) fn connections(&self) -> HashSet<u64> {
self.buffer
.keys()
.filter_map(|lane| match lane {
TransmissionLane::ConnectionId(id) => Some(id),
_ => None,
})
.copied()
.collect()
}
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,
{
self.buffer
.values()
.map(|lane_buffer_entry| {
lane_buffer_entry
.items
.iter()
.map(|item| item.data_size())
.sum::<usize>()
})
.sum()
}
fn get_oldest_set(&self) -> Vec<TransmissionLane> {
let mut buffer: Vec<_> = self
.buffer
.iter()
.map(|(k, v)| (k, v.messages_transmitted))
.collect();
buffer.sort_by_key(|v| v.1);
buffer
.iter()
.rev()
.map(|(k, _)| *k)
.take(OLDEST_LANE_SET_SIZE)
.copied()
.collect()
}
pub(crate) fn store<I: IntoIterator<Item = T>>(&mut self, lane: &TransmissionLane, items: I) {
if let Some(lane_buffer_entry) = self.buffer.get_mut(lane) {
lane_buffer_entry.extend(items);
} else {
self.buffer
.insert(*lane, LaneBufferEntry::new(items.into_iter().collect()));
}
}
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> {
let lanes: Vec<&TransmissionLane> = self.buffer.keys().collect();
lanes.choose(rng).copied()
}
fn pick_random_small_lane<R: Rng + ?Sized>(&self, rng: &mut R) -> Option<&TransmissionLane> {
let lanes: Vec<&TransmissionLane> = self
.buffer
.iter()
.filter(|(_, v)| v.is_small())
.map(|(k, _)| k)
.collect();
lanes.choose(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> {
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()
}
}
fn pop_front_from_lane(&mut self, lane: &TransmissionLane) -> Option<T> {
let real_msgs_queued = self.buffer.get_mut(lane)?;
let real_next = real_msgs_queued.pop_front()?;
real_msgs_queued.messages_transmitted += 1;
if real_msgs_queued.is_empty() {
self.buffer.remove(lane);
}
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)> {
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) {
*small_lane
} else if let Some(old_lane) = self.pick_random_old_lane(rng) {
old_lane
} else {
*self.pick_random_lane(rng)?
};
let msg = self.pop_front_from_lane(&lane)?;
log::trace!("picking to send from lane: {:?}", lane);
Some((lane, msg))
}
pub(crate) fn prune_stale_connections(&mut self) {
let stale_entries: Vec<_> = self
.buffer
.iter()
.filter_map(|(lane, entry)| if entry.is_stale() { Some(lane) } else { None })
.copied()
.collect();
for lane in stale_entries {
self.remove(&lane);
}
}
}
pub(crate) struct LaneBufferEntry<T> {
pub items: VecDeque<T>,
pub messages_transmitted: usize,
pub time_for_last_activity: Instant,
}
impl<T> LaneBufferEntry<T> {
fn new_empty() -> Self {
LaneBufferEntry {
items: VecDeque::new(),
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);
self.time_for_last_activity = get_time_now();
}
fn pop_front(&mut self) -> Option<T> {
self.items.pop_front()
}
fn is_small(&self) -> bool {
self.items.len() < 100
}
fn is_stale(&self) -> bool {
get_time_now() - self.time_for_last_activity
> Duration::from_secs(MSG_CONSIDERED_STALE_AFTER_SECS)
}
fn len(&self) -> usize {
self.items.len()
}
fn is_empty(&self) -> bool {
self.items.is_empty()
}
}

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