Compare commits

..

923 Commits

Author SHA1 Message Date
Jędrzej Stuczyński 0c1dec4b21 adjusted makefile 2023-02-24 15:55:55 +00:00
Jędrzej Stuczyński 0492af4bf9 bunch of moving things around and feature-locking 2023-02-24 15:46:20 +00:00
Jędrzej Stuczyński 2e6b2b49dc added some sample acceptance tests for mixnet contract 2023-02-24 15:09:00 +00:00
Jędrzej Stuczyński ca180ca6c2 conditionally implementing 'TestableContract' inside corresponding crates 2023-02-24 15:08:45 +00:00
Jędrzej Stuczyński e5efc18912 changed dependencies to dev-dependencies to calm down our build system 2023-02-24 14:45:59 +00:00
Jędrzej Stuczyński f01713c1ff showing different way of reading state 2023-02-24 14:45:59 +00:00
Jędrzej Stuczyński fd19fb529c moved the integration test to contracts directory/workspace 2023-02-24 14:45:59 +00:00
Jędrzej Stuczyński 66b2f1f051 added better sample test assertions + fixed MockApi 2023-02-24 14:45:58 +00:00
Jędrzej Stuczyński 090efa7263 'handlers' -> 'entry_points' 2023-02-24 14:45:58 +00:00
Jędrzej Stuczyński 310de00694 support for contract instantiation 2023-02-24 14:45:58 +00:00
Jędrzej Stuczyński 080356f46b Removed redundant error struct 2023-02-24 14:45:58 +00:00
Jędrzej Stuczyński 7543e4b997 clippy 2023-02-24 14:45:58 +00:00
Jędrzej Stuczyński f42588a985 improved error handling 2023-02-24 14:45:58 +00:00
Jędrzej Stuczyński f8b4faf974 fixed import path in doc test 2023-02-24 14:45:58 +00:00
Jędrzej Stuczyński 2d7b2b1fda sample integration test for mixnet-vesting contracts 2023-02-24 14:45:58 +00:00
Jędrzej Stuczyński fdd5b55e14 initial contract testing utilities 2023-02-24 14:45:58 +00:00
Tommy Verrall aa78bf702c Merge pull request #3104 from nymtech/feature/nym-api-tests
some small api test fixes
2023-02-24 15:09:32 +02:00
benedettadavico cd9cdfa5bb some small api test fixes 2023-02-24 14:06:56 +01:00
Pierre Dommerc 7e1e86bc77 build(nc-mobile): prepare for fdroid inclusion (#3102)
* ci(nc-android): remove uneeded deps

* chore(nc-mobile): improve android build

* ci(nc-mobile): remove useless system deps

* ci(nc-mobile): remove useless system deps

* Revert "ci(nc-mobile): remove useless system deps"

This reverts commit 011db2c58e.

* ci(nc-mobile): restore uneeded sys deps (<3 debian based distro)
2023-02-24 14:06:41 +01:00
Raphaël Walther 2178f2b509 Github Actions: fix notification display issue 2023-02-24 11:12:53 +01:00
Tommy Verrall 8ed808124e Update build-and-upload-binaries-ci.yml
publish credential binary
2023-02-23 17:15:32 +01:00
Tommy Verrall 0deef37778 Update ci-binary-checker.yml
correct positioning on install
2023-02-23 16:56:25 +01:00
Tommy Verrall d759462e4e Update ci-binary-checker.yml
install jq
2023-02-23 16:53:23 +01:00
Tommy Verrall f36cb3a00b Update ci-binary-checker.yml
use custom runner
2023-02-23 16:50:02 +01:00
Tommy Verrall 6428f90b5a Update README.md 2023-02-23 15:38:20 +01:00
Tommy Verrall e2d00fb002 Merge pull request #3098 from nymtech/feature/update-checker-to-use-master
Feature/update checker to use master
2023-02-23 16:37:37 +02:00
Tommy Verrall dc556706c1 Update ci-binary-checker.yml
update the to run from the branch
2023-02-23 13:25:46 +01:00
Tommy Verrall 01f4773a5d update 2023-02-23 14:23:06 +02:00
Tommy Verrall 6d15b444a0 use master on the build agent to fetch the latest release binaries 2023-02-23 14:22:20 +02:00
Tommy Verrall 18a3366cf3 Update ci-binary-checker.yml 2023-02-23 12:37:41 +01:00
Tommy Verrall ea161329dc Update ci-binary-checker.yml
testing manually the changes for the timebeing
2023-02-23 12:34:26 +01:00
Tommy Verrall 02a621ed8b Update ci-binary-checker.yml 2023-02-23 12:16:50 +01:00
Tommy Verrall 5784e7519f Merge pull request #3096 from nymtech/binary-checker-action
Create ci-binary-checker.yml
2023-02-23 13:12:25 +02:00
Tommy Verrall 323d5fbb3c Create ci-binary-checker.yml 2023-02-23 12:10:39 +01:00
Tommy Verrall 2d89ec51c5 Merge pull request #3094 from nymtech/feature/improve-binary-checks
Feature/improve binary checks
2023-02-23 12:32:46 +02:00
Tommy Verrall 8927824d59 make sure the script is executed in the right place 2023-02-23 12:29:42 +02:00
Tommy Verrall 665f093bcf push path changes 2023-02-23 12:22:31 +02:00
Tommy Verrall 4b77312bee fix var naming 2023-02-23 11:57:38 +02:00
Tommy Verrall f4bee0eed0 update readme 2023-02-23 11:53:51 +02:00
Tommy Verrall 905ffc257a remove outputs echos and add remove cosmos from the config check 2023-02-23 11:47:15 +02:00
Tommy Verrall 2419beccaf spurious directory change 2023-02-23 11:38:16 +02:00
Tommy Verrall 2ad5893a78 fix asserts 2023-02-23 11:33:22 +02:00
Tommy Verrall c8e2d25e7a add correct assertion 2023-02-23 11:26:21 +02:00
Tommy Verrall cfea2c3aa3 correct variable names 2023-02-23 11:18:08 +02:00
Tommy Verrall f59dc2a361 push change 2023-02-23 11:11:34 +02:00
Jon Häggblad 72f9f58fce ci: more bandaids for nightly build running out of storage 2023-02-23 10:08:09 +01:00
Jon Häggblad 2f2dfff53d Add nym prefix to a few more crates (#3092)
* Add nym- prefix to execute crate

* Add nym- prefix to nonexhaustive-delayqueue

* Add nym- prefix to config crate

* Update imports

* Update more module paths

* rustfmt

* Add nym- prefix to statistics-common

* Update explicit module paths

* rustfmt
2023-02-23 10:01:46 +01:00
Tommy Verrall c8f8c9cb07 fix urls 2023-02-23 10:58:36 +02:00
Tommy Verrall 9afc21170a fix assertions 2023-02-23 10:44:20 +02:00
Tommy Verrall 97d06d3859 fix up download paths 2023-02-23 10:37:07 +02:00
Tommy Verrall b02ee65870 fix command 2023-02-23 10:35:58 +02:00
Tommy Verrall d9cec11f63 change output here 2023-02-23 10:24:37 +02:00
Tommy Verrall 81028c554f Update README.md 2023-02-23 08:56:39 +01:00
Tommy Verrall ffc6f5e963 Merge pull request #3091 from nymtech/feature/check-binaries
Feature/check binaries
2023-02-23 09:55:03 +02:00
Tommy Verrall 6fdf70c609 merge develop 2023-02-23 09:38:46 +02:00
Tommy Verrall ab2a9f24c3 remove text 2023-02-23 09:37:09 +02:00
Tommy Verrall 73f3f8cfab pushing changes 2023-02-23 09:34:51 +02:00
Jon Häggblad 20c77e6987 Update Cargo.lock files after release bumping versions 2023-02-22 23:00:06 +01:00
farbanas 630b1259d1 Merge branch 'master' into develop 2023-02-22 14:57:44 -05:00
Jon Häggblad 8c50492d43 Update cargo metadata for mixnet and vesting contracts (#3090) 2023-02-22 18:49:56 +01:00
Pierre Dommerc ae56d3685c refactor(nym-connect): new file structure (#3082)
* refactor(nc-android): move nc android into mobile/nym-connect

rename the android app ID to "nym_connect"

* chore(nc-mobile): restore dist directory

* fix: typo

* chore: restore gitkeep

* chore: track Cargo.lock

* ci: trigger ts lint workflow on pull request

* refactor(nym-connect): new structure

move temp mobile version under nym-connect-new/mobile

* refactor(nym-connect): new structure

move temp desktop version under nym-connect-new/desktop

* refactor(nym-connect): new structure

rename nym-connect-new to nym-connect

* refactor(nym-connect): new structure

restore lost .gitkeep

* refactor(nym-connect): new structure

restore lost .gitkeep

* fix(nym-connect-desktop): broken relative paths

* fix(nym-connect-mobile): add todo comment about broken deps

* ci(nym-connect): fix relative paths

* ci(nym-connect): rename workflow
2023-02-22 17:01:46 +01:00
Tommy Verrall 6295d28972 Merge pull request #3088 from nymtech/feature/nym-api-tests 2023-02-22 17:26:13 +02:00
benedettadavico 8a8faf03d1 Merge branch 'develop' into feature/nym-api-tests 2023-02-22 16:20:36 +01:00
Jędrzej Stuczyński e09b2ab7d6 reversed the dependency between 'nym-contracts-common' and 'dkg' (#3089) 2023-02-22 15:19:52 +00:00
benedetta davico 2553d633ae Update run-api-tests.yml 2023-02-22 16:13:27 +01:00
farbanas f5bcb8be6f cleanup after testing and fixing windows builds 2023-02-22 10:06:33 -05:00
Jon Häggblad 24823356fc nym-crypto: update nym-sphinx-types dependency to published (#3086)
* nym-crypto: update nym-sphinx-types dependency to published

* nym-crypto: update cargo metadata
2023-02-22 15:55:00 +01:00
benedettadavico cfa8854ada cleaning up api tests 2023-02-22 15:48:59 +01:00
farbanas 17d5cea636 test if workflow works without adding a safe directory 2023-02-22 09:43:34 -05:00
Jon Häggblad fceef1afa6 nymsphinx: clean up Cargo metadata (#3084) 2023-02-22 15:19:26 +01:00
farbanas 6c62332409 add workflow dispatch to windows10 build 2023-02-22 09:16:19 -05:00
farbanas 650d3eeae0 trying to fix windows build 2023-02-22 09:15:34 -05:00
farbanas 9b7f98518c trying to fix windows build 2023-02-22 09:14:27 -05:00
farbanas 1ba23cf4b5 trying to fix windows build 2023-02-22 09:02:42 -05:00
farbanas 300df601fa trying to fix windows build 2023-02-22 08:34:27 -05:00
farbanas 699b032f2a trying to fix windows build 2023-02-22 08:04:52 -05:00
benedetta davico 7c86ef4cbc Update run-api-tests.yml 2023-02-22 13:22:49 +01:00
benedetta davico 2dc3999c77 Update run-api-tests.yml 2023-02-22 13:20:51 +01:00
benedetta davico 7b7cac5054 Update run-api-tests.yml 2023-02-22 13:15:07 +01:00
benedetta davico 5f7270acc8 Update run-api-tests.yml 2023-02-22 13:12:37 +01:00
benedetta davico 4e829ef540 Update run-api-tests.yml 2023-02-22 13:04:19 +01:00
benedettadavico ba64c4f8b3 Edit broken file 2023-02-22 12:52:06 +01:00
benedettadavico 2b5c426d67 adding CI for api tests 2023-02-22 12:36:47 +01:00
Jon Häggblad ceec4da27d nymsphinx: use published sphinx-packet crate (#3083) 2023-02-22 11:38:07 +01:00
Jon Häggblad af9df88a48 ci: bandaid for running out of disk space on ubuntu 2023-02-22 09:22:35 +01:00
farbanas 4ecd252561 trying to fix windows build 2023-02-21 20:08:27 -05:00
farbanas 19c1ef66c8 trying to fix windows build 2023-02-21 19:44:12 -05:00
farbanas 13e3a79a93 trying to fix windows build 2023-02-21 19:19:27 -05:00
farbanas d867e0e244 trying to fix windows build 2023-02-21 19:13:33 -05:00
farbanas 316e984b0a trying to fix windows build 2023-02-21 18:41:46 -05:00
Jon Häggblad 71b5477334 pemstore: simplify crate metadata 2023-02-21 21:28:10 +01:00
farbanas c15a081e6f trying to fix windows build 2023-02-21 14:50:09 -05:00
farbanas add92c7b5e trying to fix windows build 2023-02-21 14:42:18 -05:00
farbanas 1080cf4afe trying to fix windows build 2023-02-21 14:32:44 -05:00
farbanas 4e2fae8878 trying to fix windows build 2023-02-21 14:26:03 -05:00
farbanas fbae1d7963 trying to fix windows build 2023-02-21 14:10:29 -05:00
farbanas 495aec39f5 trying to fix windows build 2023-02-21 13:43:33 -05:00
farbanas 06c9c54cdb trying to fix windows build 2023-02-21 13:26:53 -05:00
farbanas ba90e740e2 trying to fix windows build 2023-02-21 13:03:25 -05:00
farbanas 1f36b53b64 trying to fix windows build 2023-02-21 13:02:02 -05:00
farbanas 23fb48316a trying to fix windows build 2023-02-21 13:00:29 -05:00
farbanas 312cd65d20 trying to fix windows build 2023-02-21 12:43:37 -05:00
Jon Häggblad b3b4b5ff36 Add nym prefix to inclusion-probability crate (#3079)
* inclusion-probability: update metadata

* Add nym- prefix to inclusion-probability crate
2023-02-21 17:01:36 +01:00
farbanas 79e51252a8 fix: comment out install rust on windows build as it breaks it 2023-02-21 10:44:33 -05:00
Tommy Verrall cc1c9a75b4 remove file 2023-02-21 17:35:11 +02:00
Tommy Verrall 5813e9212b adding socks-5-test 2023-02-21 17:34:34 +02:00
Tommy Verrall 6ce743fbd5 add the nym-client and tidy up the mixnode
next up gateway, socks-5, network-requester
2023-02-21 17:11:20 +02:00
farbanas 025f5da39e Merge branch 'release/v1.1.10' 2023-02-21 09:23:40 -05:00
Jon Häggblad ddd9498c0b gateway: stray println that should be eprintln 2023-02-21 15:21:14 +01:00
Jon Häggblad b62e221aad gateway: stray println that should be eprintln 2023-02-21 15:15:53 +01:00
Raphaël Walther 69c8891f82 Github Actions: disable temporary rust install 2023-02-21 15:12:27 +01:00
Raphaël Walther c2326f35a6 Revert "Github Actions: disable temporary rust install"
This reverts commit 92a755dc6c.
2023-02-21 15:10:42 +01:00
farbanas bda32cfef3 docs: update changelog 2023-02-21 09:07:41 -05:00
farbanas b3425a6a6e chore: bump vesting contract 2023-02-21 09:03:56 -05:00
farbanas 9e7c77ca6a docs: update CHANGELOG.md 2023-02-21 08:59:40 -05:00
Raphaël Walther 92a755dc6c Github Actions: disable temporary rust install 2023-02-21 14:57:07 +01:00
Jędrzej Stuczyński 39e75850ff Problem142 (#3025)
* revamped calculation of spendable coins and behaviour of stakes

* added new queries to the VestingQueryClient

* fixed return types for the query client

* updated wallet commands

* updated common commands

* 🔥 removed dead and commented out code

* comment regarding the 'state_dump_decoder'

* query for withdrawn coins
2023-02-21 13:55:14 +00:00
Jon Häggblad 4587d5da26 Add nym- prefix to network-defaults (#3069)
* network-defaults: update cargo metadata

* Add nym- prefix to network-defaults crate

* Some manual updating

* rustfmt
2023-02-21 14:26:28 +01:00
Jon Häggblad 586d5f658b Move client-connections crate to nym-task (#3068)
* Move client-connections to nym-task

* rustfmt
2023-02-21 13:54:27 +01:00
farbanas 9912e445a4 docs: updated changelogs in preparation for release 2023-02-21 07:53:08 -05:00
farbanas 02397832f4 chore: updated versions as part of preparation for release v1.1.10 2023-02-21 07:44:03 -05:00
farbanas 03fa8c17d7 docs: minor cleanup changes to changelog 2023-02-21 07:32:39 -05:00
Tommy Verrall 964955f740 update calls to binaries 2023-02-21 13:37:11 +02:00
Jon Häggblad b1121dabb9 Merge 4 tiny crates into nym-bin-common (#3065)
* Rename to bin-common

* Merge into new crate

* Merge 3 crates into bin-common

* WIP

* Move build.rs to the correct place

* regex nym_bin_common

* regex nym_bin_common::build_information

* regex nym_version_checker

* Update some explicit mod paths

* Makefile: add nym-connect-android

* Additional fixes

* rustfmt

* Update crate metadata

* Move completions crate into nym-bin-common

* Makefile: add examples

* Fix examples

* rustfmt
2023-02-21 11:30:23 +01:00
Raphaël Walther caff2077ae Github Actions: fix notification display issue 2023-02-21 11:23:10 +01:00
farbanas b980bfcab8 feat: add changelog updater to the update-version-and-changelog GH workflow 2023-02-20 18:35:17 -05:00
farbanas 57822e3c0d fix: version-bumper 2023-02-20 18:25:36 -05:00
farbanas b98bf46675 fix: cargo install 2023-02-20 18:21:27 -05:00
farbanas 1417eeeddb fix: change from custom runner to ubuntu-22.04 2023-02-20 18:20:14 -05:00
farbanas 31389dd886 fix: update working directories 2023-02-20 18:19:04 -05:00
farbanas 36cf36aaae fix: remove --release flag from cargo install 2023-02-20 18:16:44 -05:00
farbanas dd08621329 fix: secret -> secrets 2023-02-20 18:15:09 -05:00
farbanas ca7ee04e47 fix: added access token to access private repos 2023-02-20 18:14:10 -05:00
farbanas 0130881616 fix: added env prefix to variables in GH workflow 2023-02-20 17:59:48 -05:00
farbanas cde247df46 fix: added inputs prefix to variable in GH workflow 2023-02-20 17:59:06 -05:00
farbanas 448b2353ab feat: add workflow for updating versions and changelog 2023-02-20 17:54:41 -05:00
Jon Häggblad 46e2c74a98 Rename crate to nym-task (#3064)
* Rename to nym-task

* Update imports to use nym_task

* Update to nym_task in explicit module prefix

* Touchups and rustfmt

* rustfmt

* crate metadata

* fix nym-connect-android
2023-02-20 21:55:29 +01:00
Jon Häggblad ce79d5a3bc Update crate metadata in nym-version-checker and nym-topology (#3062)
* nym-sphinx: update crate metadata

* Update crate metadata for nym-version-checker and nym-topology
2023-02-20 19:58:25 +01:00
Jon Häggblad fede9cc194 Add nym prefix to topology and version checker crates (#3061)
* Rename crate to nym-topology

* Rename crate to nym-version-checker

* Remove unused topology

* rustfmt
2023-02-20 17:05:08 +01:00
Jon Häggblad c75c5e0903 Rename to crate name to nym-sphinx (#3060)
* nymsphinx: rename to nym- prefix in Cargo.toml files

* regex use nymsphinx to use nym_sphinx

* all: updated explict crate name in a few places
2023-02-20 16:28:08 +01:00
Jon Häggblad ec00918524 Update crate metadata for nym-crypto (#3059)
* dkg: move crate and un-nest

* all: update paths to common/dkg

* crypto: Cargo.toml metadata
2023-02-20 15:44:51 +01:00
pierre 9a43595e04 refactor(nc): fix lint errors 2023-02-20 15:10:59 +01:00
Raphaël Walther 49334c0540 Github Actions: move some notifications to specific rooms 2023-02-20 15:00:22 +01:00
Jon Häggblad 4a2f30a581 Merge remote-tracking branch 'origin/release/v1.1.10' into develop 2023-02-20 13:01:56 +01:00
Jon Häggblad bbb3287029 Add client functionality into nym-network-requester (#2972)
* network-requester: replace websocket with mixnet client

* network-requester: mini tidy

* network-requester: add info line about own address

* network-requester: update to nym-crypto rename
2023-02-20 13:00:34 +01:00
Jon Häggblad 6a82285342 Merge pull request #3054 from nymtech/jon/chore/publish-nym-pemstore
pemstore: update metadata
2023-02-20 10:52:01 +01:00
Tommy Verrall 494f1d5199 Merge pull request #3046 from nymtech/feature/ne-filter-by-minor-version
NE - Filter by version
2023-02-20 08:49:46 +01:00
Jon Häggblad 22ee87d87e Cargo.toml: SPDX format for license 2023-02-17 15:56:09 +01:00
Jon Häggblad a8e62bde26 pemstore: more fields, revert back to pem 0.8 2023-02-17 15:42:11 +01:00
Jon Häggblad 22df65aad7 pemstore: set version to 0.1.0 2023-02-17 14:44:16 +01:00
Pierre Dommerc c4e86337e5 NC Android - minor fix, ui changes, splash screen (#3050)
* fix(nc-android): gateway issue modal does not open

* feat(nc-android): ui changes

* feat(nc-android): add splash screen
2023-02-17 12:36:06 +01:00
Jon Häggblad 2d3bb78819 pemstore: getting it ready for publication 2023-02-17 12:17:21 +01:00
pierre 1ec11dda24 ci(nc-android,ts): use better paths filter 2023-02-16 22:55:03 +01:00
fmtabbara 723b4b4754 small performance optimizations
fix lint error
2023-02-16 19:43:25 +00:00
ON 4e239ac9b7 Update cover_traffic_stream.rs (#2836)
fix log message
2023-02-16 16:20:52 +00:00
Fouad dafb69d2d6 Feature/nym connect logs in app (#3045)
* remove menu bar

* create log view toggle function

* update routes

* update changelog

* fix clippy error
2023-02-16 16:15:53 +01:00
fmtabbara e225c1ee1b use minor version as latest comparator 2023-02-16 15:10:07 +00:00
Jon Häggblad 1feb53cc87 Merge pull request #3043 from nymtech/jon/chore/fix-auto-updated-files
nym-wallet: fix auto-updated files
2023-02-16 13:04:36 +01:00
Jon Häggblad 4c919f520a Merge remote-tracking branch 'origin/release/v1.1.10' into develop 2023-02-16 12:23:43 +01:00
Jon Häggblad bb64d8c03e wallet: minor updates to autogenerated files 2023-02-16 12:20:39 +01:00
Jon Häggblad 580cc58f42 Merge pull request #2855 from nymtech/jon/chore/add-nym-prefix-to-mixnet-and-vesting-contract-packages
contracts: add nym prefix to mixnet and vesting contract packages
2023-02-16 12:14:03 +01:00
Pierre Dommerc bc75dd7e15 NC Android - gateway settings (#3041)
* feat(nc-android): gateway settings (client)

* feat(nc-android): gateway settings (client)

* feat(nc-android): handle init_config failing

* feat(nc-android): some UI changes

* feat(nc-android): some UI changes
2023-02-16 12:11:45 +01:00
fmtabbara 40af0f94b0 correct explorer changelog 2023-02-16 11:08:08 +00:00
Fouad c9c68ab2cb Fix send address bug (#3031)
* remove non-zero and trailing spaces

* update wallet changelog
2023-02-16 11:06:49 +00:00
Fouad 26c5fa7262 NE - Gateway version filter (#3037)
* add version filter

* allow copy gateway identity key

* use dynamic latest version value

* update explorer changelog
2023-02-16 11:03:55 +00:00
Jon Häggblad b5adf2bb42 Merge remote-tracking branch 'origin/release/v1.1.10' into develop 2023-02-16 09:56:11 +01:00
farbanas 254ea6af42 Merge branch 'develop' of github.com:nymtech/nym into develop 2023-02-16 00:08:12 -05:00
farbanas a971694ff7 feat: add a new workflow for triggering the tag and release part of the weekly release pipeline 2023-02-16 00:07:17 -05:00
Jon Häggblad 2d59236ee8 verloc: don't shutdown listener on corrupted connection (#3036) 2023-02-15 18:14:24 +01:00
Jon Häggblad 17322ccda2 ci: update typescript-lint.yml (#3035) 2023-02-15 17:52:33 +01:00
Jon Häggblad 3d2e7d32d9 nym-connect-android fixes 2023-02-15 16:13:53 +01:00
Jon Häggblad 0b93215941 rustfmt 2023-02-15 16:13:53 +01:00
Jon Häggblad 8f4fd62957 rename pemstore to nym-pemstore 2023-02-15 16:13:53 +01:00
Jon Häggblad 4844ac953a rename crypto to nym-crypto 2023-02-15 16:13:53 +01:00
Jon Häggblad aab094984e contracts: add nym- prefix to mixnet and vesting package names 2023-02-15 16:13:53 +01:00
pierre a5056007d4 fix(nc-android): typo 2023-02-15 11:16:58 +01:00
Pierre Dommerc 9c77e15a2c NC Android - UI changes (#3032)
* feat(nc-android): update ui (font size&weight)

* feat(nc-android): update power button

* refactor(nc-android): replace tooltip by dialog

* refactor(nc-android): replace tooltip by dialog
2023-02-15 11:12:43 +01:00
Jon Häggblad c8bd6b99fa nym-wallet: update Cargo.lock 2023-02-15 10:32:20 +01:00
Raphaël Walther 081d6097b6 Github Actions: Remove keybase notifications 2023-02-15 10:02:19 +01:00
farbanas 4820258270 fix: nym-cli-publish GH action resolve 2023-02-14 08:15:26 -05:00
farbanas e41a59fddc merge resolve 2023-02-14 07:50:47 -05:00
Jon Häggblad 130491e80f ci: fix get_release regex for nightly 2023-02-14 13:30:40 +01:00
farbanas 165e7d8b27 Merge branch 'release/v1.1.9' of github.com:nymtech/nym into release/v1.1.9 2023-02-14 07:30:25 -05:00
farbanas 3c97d0d16b Updated changelogs 2023-02-14 07:28:59 -05:00
Jon Häggblad 16ae72fbd9 ci: run check-merge-conflicts nightly 2023-02-14 13:25:06 +01:00
farbanas bc55c10e19 bumped versions for release/v1.1.9 2023-02-14 07:18:03 -05:00
Fouad a925c39642 Wallet - Fix operator cost in playground (#3021)
* remove upper limit restriction

* update validation
2023-02-14 12:13:19 +00:00
Jon Häggblad 4fa018540c ci: get_release name 2023-02-14 12:43:07 +01:00
Jon Häggblad e2b69b79e7 ci: update and rename check-merge-conflicts.yml 2023-02-14 12:38:57 +01:00
Fouad d23fb366e4 update changelog and fix lint errors (#3023)
add unreleased tag into NC changelog
2023-02-14 10:46:10 +00:00
Jon Häggblad be369c2023 ci: another fix to check-git-branches.yml 2023-02-14 11:17:59 +01:00
Bogdan-Ștefan Neacșu 7e90ff8b85 Fix nyxd typo 2023-02-14 12:17:11 +02:00
Jon Häggblad f5c5b342bb ci: fix check-git-branches.yml 2023-02-14 11:15:19 +01:00
Jon Häggblad af9cf52b1e ci: add workflow for checking if branches merge 2023-02-14 11:01:28 +01:00
Bogdan-Ștefan Neacşu 3d500c25c5 Hide coconut runtime flags (#2990) 2023-02-14 11:58:04 +02:00
Jon Häggblad 3b9fb9088d ci: tweak git-merge-check.sh 2023-02-14 10:23:08 +01:00
Jon Häggblad c95b5f0982 ci: add script for checking if branches merge successfully 2023-02-14 10:19:28 +01:00
Jon Häggblad 7cca3c716a mixnode: upgrade sysinfo dependency (#3022)
Fixes build on windows with nightly rustc due to

    https://github.com/MSxDOS/ntapi/issues/11
2023-02-14 06:51:12 +01:00
Fouad 9348722b84 Feature/nym connect pick a gateway (#3008)
* Add new route and initial UI

* allow IdentityKeyFormField to have a small size option

* add disabled prop to the shared IdentityKeyFormField component

* defined custom gateway type

* use custom gateway in state

* set and validate custom gateway in settings page

* validate user gateway when moving away from page

* use storage

* hide gateway input when inactive

* add explorer link to settings page
2023-02-13 22:47:48 +00:00
Jon Häggblad fd1fb7ca7b rust-sdk: fix clippy in example (#3020) 2023-02-13 15:22:39 +01:00
Jon Häggblad 6252b66724 ci: keep the 3 nightly builds in sync (#3018) 2023-02-13 15:00:24 +01:00
Jon Häggblad b770cab3f0 nym-wallet: update Cargo.lock to fix security advisories (#3015) 2023-02-13 13:36:39 +01:00
Fouad 726a406797 update add account instructions (#2981)
* update add account instructions
2023-02-13 10:55:53 +00:00
Fouad 4652d65874 Update password strength checking (#2994)
* use zxcvbn password strength checker

* prevent user from proceeding with a weak password + add tips

* create storybook for password strength component

* update storybook

* update password-strength
2023-02-13 10:27:04 +00:00
Fouad a4ca94ccef dont force user to copy mnemonic (#2992)
* dont force user to copy mnemonic

* add title to mnemonic page
2023-02-13 10:26:37 +00:00
Pierre Dommerc e69552b19d fix(nc-android): disable landscape mode (#3012)
* fix(nc-android): disable landscape mode

* feat(nc-android): UI sizing
2023-02-10 17:43:51 +01:00
pierre e3cc43487a fix(nc-andoird): apk build 2023-02-10 16:13:17 +01:00
pierre 41be555aa6 ci(nc-android): fix build 2023-02-10 13:44:51 +01:00
pierre bdc0bcbd56 ci(nc-android): fix gradle build 2023-02-10 12:29:35 +01:00
Jon Häggblad 0baa8b2c92 rust-sdk: improve send api (#3011)
* nym-sdk: remove unneeded function

* rust-sdk: rework send api a bit

* rust-sdk: add send_wait without impl

* fix doc test failures

* more doctest fixes
2023-02-10 11:07:48 +01:00
pierre 2ab969b2c6 ci(nc-android): debug workflow, use precompiled tauri cli 2023-02-09 22:47:28 +01:00
pierre 9f2e7e16e5 ci(nc-android): fix workflow apk build 2023-02-09 18:53:50 +01:00
pierre 1c99446bcc ci(nc-android): fix workflow for nc android apk upload 2023-02-09 18:21:55 +01:00
Pierre Dommerc 90d9c9ec41 feat(nc-android): add nym icon launchers (#3007) 2023-02-09 17:17:00 +01:00
Jon Häggblad 2e38c5e38e nym-sdk: remove a few unwraps related to creating reply surb storage (#3006) 2023-02-09 16:55:01 +01:00
Bogdan-Ștefan Neacşu dbb7a27441 Feature/stabilize credential deposit (#3002) 2023-02-09 16:55:18 +02:00
Jon Häggblad 89c05387f8 rust-sdk: add two more examples (#3003) 2023-02-09 15:43:12 +01:00
Jon Häggblad 7952277c4b rust-sdk: restructure API to builder pattern (#3000) 2023-02-09 14:58:42 +01:00
Pierre Dommerc c5866db137 feat(nc-android): sync with nc desktop (new design) (#2971)
* feat(nc-android): fit the design to mobile

* refactor(nc-android): resync with nc desktop

* fix(nc-android): tauri version

* refactor(nc-android): resync with nc desktop (rust)

* chore(nc-android): format code

* chore(nc-android): bump version
2023-02-09 14:26:19 +01:00
Dave Hrycyszyn 37187c79cc Merge branch 'master' into develop 2023-02-08 16:54:27 +00:00
Dave Hrycyszyn 24839770ff Fixing Cargo.lock to include updated version of nym-api 2023-02-08 16:54:09 +00:00
Dave Hrycyszyn 0238499e33 Changelog bump to trigger nym-connect build 2023-02-08 16:48:17 +00:00
Dave Hrycyszyn 3363230c4c Building the SDK package and only selected examples 2023-02-08 16:48:17 +00:00
pierre 1f8b373780 fix(nym-connect): lint errors 2023-02-08 16:48:17 +00:00
Dave Hrycyszyn 7ac3ec3598 Merge branch 'release/v1.1.9' 2023-02-08 16:21:57 +00:00
Dave Hrycyszyn 77ae71eba4 Changelog bump to trigger nym-connect build 2023-02-08 16:15:33 +00:00
Dave Hrycyszyn d4b836277e Merge branch 'release/v1.1.9' 2023-02-08 16:04:49 +00:00
Dave Hrycyszyn b92ee84874 Building the SDK package and only selected examples 2023-02-08 15:56:30 +00:00
pierre 2eb0ce381a fix(nym-connect): lint errors 2023-02-08 16:36:00 +01:00
Jon Häggblad 037cd54573 Merge branch 'release/v1.1.9' into develop 2023-02-08 13:45:37 +01:00
Jon Häggblad 9f42f0152b Merge branch 'release/v1.1.9' 2023-02-08 13:27:32 +01:00
Dave Hrycyszyn 5217edcca3 Changelog tweaks 2023-02-08 13:14:12 +01:00
joeiacono2021 e306effdac Merge branch 'release/v1.1.9' of https://github.com/nymtech/nym into release/v1.1.9 2023-02-08 13:14:12 +01:00
joeiacono2021 dc2b1c6d2a changelog changes for release 1.1.9 2023-02-08 13:14:12 +01:00
Jon Häggblad 4232801e80 changelog: add note about fix for unexpected shutdown 2023-02-08 13:14:12 +01:00
Fouad 96df3ad4ce Feature/nym connect health status frontend (#2969)
* filter services on rust side by gateway performance

* format rust code

* create events hook

* use events hook

* remove unused component

remove unused component

update prop names in svg

* display errors in connected screen when needed

update failed health check message
2023-02-08 13:14:12 +01:00
Fouad d614a2b81b link owner field to ng explorer (#2970)
* link owner field to ng explorer
2023-02-08 13:14:12 +01:00
Fouad d27245e184 filter services on rust side by gateway performance (#2966)
* filter services on rust side by gateway performance

* update changelog for NC
2023-02-08 13:14:12 +01:00
Mark Sinclair 5dbfcadfdb GitHub Actions: fix up build-and-upload-binaries-ci.yml 2023-02-08 13:14:12 +01:00
Jędrzej Stuczyński 035dada0e0 introduced '/circulating-supply/total-supply-value' and '/circulating-supply/circulating-supply-value' endpoints (#2965) 2023-02-08 13:14:12 +01:00
Mark Sinclair 1d867156e3 Update build-and-upload-binaries-ci.yml 2023-02-08 13:14:12 +01:00
Mark Sinclair ed9be47ec4 Update build-and-upload-binaries-ci.yml 2023-02-08 13:14:12 +01:00
Mark Sinclair 3aa2e6c54d Update build-and-upload-binaries-ci.yml 2023-02-08 13:14:12 +01:00
Mark Sinclair eb96fc72b9 GitHub Actions: add action to build and upload binaries to CI server 2023-02-08 13:14:12 +01:00
Jon Häggblad 59cec6f03c Don't drop in mixnet connection handlers (#2963) 2023-02-08 13:14:12 +01:00
Fouad c0a0d89a90 NymConnect - Add button animations (#2950)
* add button animations

* pulse and disable button on connecting/disconnecting status

* update button component story

* disabled hover on connecting/disconnecting

* add transition delay

fix up overflow
2023-02-08 13:14:12 +01:00
Bogdan-Ștefan Neacşu 3099f2ead3 Hide coconut runtime flags (#2990) 2023-02-08 13:00:17 +01:00
Bogdan-Ștefan Neacşu baf88ce10a Skip errors on blind sign within threshold (#2976) 2023-02-08 11:45:39 +01:00
Jędrzej Stuczyński 362e7f2fea Added an option to set custom 'host' for the native client (#2939)
* Added an option to set custom 'host' for the native client

* Changelog entry
2023-02-08 08:59:48 +01:00
Bogdan-Ștefan Neacşu d89081d8a1 Feature/dkg reshare (#2936)
* Add resharing parameter

* Fix equality of dealers and members

* Contract resharing handling

* Dealer verification unit test

* Dealing commit unit test

* Epoch state unit tests

* Fix clippy

* Fmt

* Query initial dealer data

* Resharing nym-api changes

* Implement the mockups for nym-api dkg tests

* Dealing test

* Vk unit test

* Fix skipping vk submission

* Fix clippy

* Missing dealing for noninitial resharing dealer

* Check master vk holds after resharing on nym-apis

* Update changelog

* Fix clippy
2023-02-08 08:59:48 +01:00
Pierre Dommerc eeba17a01f build(nc-android): prepare for apk release (#2943)
* chore(nc-android): prepare for production build

* refactor(nc-android): remove dead code

* feat(nc-android): update native color theme

* feat(nc-android): update native color theme

* build(nc-android): fix rfd version issue

* build(nc-android): fix dist dir no such file error

* fix(nc-android): post rebase changes
2023-02-08 08:59:48 +01:00
Jon Häggblad 25762900fa Remove all the .DS_Store files and add to gitignore (#2974) 2023-02-08 08:59:48 +01:00
Bogdan-Ștefan Neacşu 3bc7f281b4 Fix typo during merge back to develop (#2956) 2023-02-08 08:59:48 +01:00
Jędrzej Stuczyński 3e23bdf3c0 Feature/service provider interface (#2934)
* added additional workspace-wide dependencies

* Added conditional serialization on 'BinaryBuildInformationOwned'

* initial framework for service provider messages

* updated request/response tags to account for existing variants of Socks5Message

* handling legacy deserialization

* another serialization revamp to account for legacy version

* legacy client working with versioned network requester

* socks5 client deserializing responses into updated structures

* using new structures for sending in socks5 client

* SendRequest wrapper for Request::Send variant

* created named fields for all variants of 'ControllerCommand'

* Versioning socks5 requests + moving to proper Socks5Request struct

* Updated backwards compatible Socks5Response

* unused imports

* poc ServiceProvider trait

* wip

* implemented 'ServiceProvider' trait on the Network Requester

* Socks5RequestError

* added properly serialized ErrorResponse to ControlResponse

* fixed version serialization + feature selection

* handling of version control requests

* improved SocksProxyError by providing more concrete variants and removing generic case

* got rid of ServiceProviderClient trait and wrote simple example showing control requests

* tests for serialisation backwards compatibility

* post-merge fixes due to method renaming

* enum boxing to make clippy happier

* making sure to not drop buffer channel when starting `DirectClient`

* Using nym-sdk in the example

* Replaced printing version to stdout with proper log call
2023-02-08 08:59:48 +01:00
cgi-bin/ 5a89e894a9 typo: electrum (#2954) 2023-02-08 08:59:48 +01:00
Pierre Dommerc 795977a75d NC Android - setup APK publish (#2967)
* ci(nc-android): init workflow apk build & release

* ci(nc-android): setup nc android project for APK publish

* docs(nc-android): update readme

* ci(nc-android): add note in the workflow
2023-02-08 08:59:48 +01:00
farbanas 8dbddb7b7e fix: formatting 2023-02-08 08:59:48 +01:00
Mark Sinclair 4e057cd250 Update build-and-upload-binaries-ci.yml 2023-02-08 08:59:48 +01:00
farbanas b62c969a7c fix: wrong parameter type for addresses in generator commands (should be AccountId instead of String) 2023-02-08 08:59:48 +01:00
Mark Sinclair be1ec79b01 Update build-and-upload-binaries-ci.yml 2023-02-08 08:59:48 +01:00
Fran Arbanas 5d10e62450 Update CHANGELOG.md 2023-02-08 08:59:48 +01:00
Mark Sinclair 64acddead6 Update build-and-upload-binaries-ci.yml 2023-02-08 08:59:48 +01:00
Mark Sinclair 8bbf766eeb Update build-and-upload-binaries-ci.yml 2023-02-08 08:59:48 +01:00
Mark Sinclair d7cd942dec Update build-and-upload-binaries-ci.yml 2023-02-08 08:59:48 +01:00
Mark Sinclair a9124a63f9 Update build-and-upload-binaries-ci.yml 2023-02-08 08:59:48 +01:00
Mark Sinclair b0d7169b39 Update build-and-upload-binaries-ci.yml 2023-02-08 08:59:48 +01:00
Mark Sinclair d57b486bf4 GitHub Actions: add action to build and upload binaries to CI server 2023-02-08 08:59:48 +01:00
Bogdan-Ștefan Neacșu ef8ecd42a3 Fix flaky dkg test 2023-02-08 08:59:48 +01:00
dependabot[bot] 02e1dc01af build(deps): bump ua-parser-js in /nym-wallet/webdriver (#2909)
Bumps [ua-parser-js](https://github.com/faisalman/ua-parser-js) from 0.7.28 to 0.7.33.
- [Release notes](https://github.com/faisalman/ua-parser-js/releases)
- [Changelog](https://github.com/faisalman/ua-parser-js/blob/master/changelog.md)
- [Commits](https://github.com/faisalman/ua-parser-js/compare/0.7.28...0.7.33)

---
updated-dependencies:
- dependency-name: ua-parser-js
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-08 08:59:48 +01:00
dependabot[bot] b29bd8bcc3 build(deps): bump http-cache-semantics in /nym-wallet/webdriver (#2960)
Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kornelski/http-cache-semantics/releases)
- [Commits](https://github.com/kornelski/http-cache-semantics/commits)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-08 08:59:48 +01:00
dependabot[bot] 9ad9fd36e2 build(deps): bump http-cache-semantics from 4.1.0 to 4.1.1 (#2961)
Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kornelski/http-cache-semantics/releases)
- [Commits](https://github.com/kornelski/http-cache-semantics/commits)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-02-08 08:59:48 +01:00
Tommy Verrall bd61679c58 Binary checker, introduction 2023-02-08 08:59:48 +01:00
Jon Häggblad 21e636616d Merge tag 'nym-binaries-v1.1.8' into develop 2023-02-08 08:25:24 +01:00
farbanas 9881a94757 bumped nym-api version 2023-02-03 15:12:18 +01:00
Jędrzej Stuczyński 76b07d487b introduced '/circulating-supply/total-supply-value' and '/circulating-supply/circulating-supply-value' endpoints (#2965) 2023-02-03 13:37:55 +00:00
farbanas f04fc452dc Merge branch 'release/v1.1.8' of github.com:nymtech/nym into release/v1.1.8 2023-01-31 14:05:53 +01:00
farbanas be90d03129 changelog cleanup 2023-01-31 14:01:25 +01:00
Bogdan-Ștefan Neacşu 0a3e42700c Fix vote soft error everywhere (#2941) 2023-01-31 14:58:47 +02:00
joeiacono2021 55d554701c Merge branch 'release/v1.1.8' of https://github.com/nymtech/nym into release/v1.1.8 2023-01-31 12:55:09 +00:00
joeiacono2021 19c4769260 Changelog Updates for RELEASE 1.1.8 on 31/01 2023-01-31 12:54:55 +00:00
farbanas 71aadc8e1b update versions for the release v1.1.8 2023-01-31 13:44:41 +01:00
Fouad 95340b5817 Feature/nym connect new UI (#2916)
* reduce window size

* use new highlight color

* use react router

* render new routes

* remove old help page

* render app routes

* update connection status UI

* remove service provider info

* remove unneeded additional step

* render title from route

* experimental warning as component

* render connection page

* nym-connect: connectivity status improvements (#2915)

* connect: keep track of connectivity state

* nym-connect: query connection state

* nym-connect: function for kicking of the health check task

* rustfmt

* nym-connect: extract out into function

* nym-connect: extract out events.rs

* add app version to menu page

* help page content and style updates

* update guide content

* use layout component on disconnect page

* handle gateway issues

* only show info modal once after connecting

* power button colors

* update stories and button colors

---------

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
2023-01-31 11:39:38 +00:00
Pierre Dommerc dc2b25f152 fix(nc-android): panic on socks5 client connect (#2929) 2023-01-31 12:08:57 +01:00
Tommy Verrall 12751665bb white space 2023-01-31 09:14:56 -01:00
Tommy Verrall 01b86bcc0d updating qwerty contract addresses 2023-01-31 07:39:18 -01:00
Bogdan-Ștefan Neacşu c6ce8caaf7 Feature/fix soft multisig error (#2938) 2023-01-30 18:44:45 +02:00
Bogdan-Ștefan Neacșu 5370bb9c47 Fix clippy 2023-01-30 17:56:27 +02:00
Jędrzej Stuczyński 265713b9d2 Renamed 'initial_supply' to 'total_supply' in the 'circulating-supply' endpoint (#2932)
* Renamed 'initial_supply' to 'total_supply' in the 'circulating-supply' endpoint

* clippy issue messing with CI
2023-01-30 15:39:55 +00:00
Jędrzej Stuczyński cd3c951572 drop pending messages if we dont have enough surbs and we havent gotten any in long time (#2937)
* drop pending messages if we dont have enough surbs and we havent gotten any in long time

* missing changes to wasm client
2023-01-30 15:39:26 +00:00
Jon Häggblad 7e43ce1aed nym-connect-android: fix CI (#2930) 2023-01-30 11:38:14 +01:00
Jon Häggblad c9af4721f3 wasm-utils: fix clippy 2023-01-30 10:46:11 +01:00
Jon Häggblad 0669369c77 fix commit 044fa93eec 2023-01-28 20:48:50 +01:00
Pierre Dommerc 6f94ab4937 ci(nc-android): try fix (#2928) 2023-01-28 00:12:53 +01:00
Pierre Dommerc 0d3ca99dfa docs(nc-android): update readme (#2924)
* docs(nc-android): update readme

* docs(nc-android): update readme
2023-01-27 21:18:43 +01:00
Pierre Dommerc 509391cde4 ci(nc-android): add gh workflow (#2927)
* ci(nc-android): add gh workflow

* ci(nc-android): fix cargo.toml path
2023-01-27 21:05:50 +01:00
Mark Sinclair 0fc0292b18 WASM client changes (#2925)
* Add rollup config to output CommonJS and ESM packages, simplified interface

* Remove examples from monorepo

---------

Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
2023-01-27 16:48:10 +00:00
Jędrzej Stuczyński 9a2a99e581 removed migrated vesting contract code (#2914) 2023-01-27 14:22:11 +00:00
Jon Häggblad 5ec7beec8a Remove .DS_Store and add to .gitignore 2023-01-27 14:05:08 +01:00
Jon Häggblad 044fa93eec ci: fix nightly clippy
Remove `--all-features` from the clippy command because

1. with the removal of `cocunut` it's not really needed
2. the new `mobile` flag is a bit hacky and mutually incompatible with
   some existing configs
2023-01-27 09:46:37 +01:00
Pierre Dommerc 8c0ab7c697 feat(explorer): add routing score on gateway list (#2913)
* feat: adding routing score on gateway list

* feat(explorer): adding routing score on gateway list

* feat(explorer): add routing score on gateway list
2023-01-26 18:39:26 +01:00
Pierre Dommerc 3e6188ed13 nym-connect-android initial version (#2907)
* feat(nym-connect): add android support

* fix(nym-connect): android linker issue with sqlite3

get rid of sqlite refs as temporary workaround

* fix(nc): fix index.ts (post rebase)

* feat(nc-android): wip

* hack in config removal of read/write

* fix(nc-android): remove more fs read/write calls

* wip

* chore: remove debug comments

* Register gateway

* client-core: remove unneeded changes

* build: revert crate name change

* refactor(socks5-client): add feature mobile

* refactor(gateway-client): rename mobile feature

* socks5: restore default_root_directory

* client-core: further simplifications

* get_config_file_location just return error

* fix(nc-mobile): fix ui mobile

* socks5: minor tweak to default_root_directory

* remove unneeded changes

* nym-connect build fixes

* Use default feature for normal credential storage

* rustfmt

* rustfmt: nym-connect

* restore Cargo.toml

* Remove --all-features from workflow

* Remove some unused use

* Remove two move --all-features from build workflow

* Allow unused

* Add continue-on-error

* another clippy --all-features remove

* remove --all-features from clippy nightly

* fix(nc-mobile): frontend code errors

* feat: restore nc, move mobile under its own dir

* fix(nc-android): build

* fix(nc-android): lint errors

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
2023-01-26 14:17:29 +01:00
Tommy Verrall 45c51636a8 Merge pull request #2920 from nymtech/feature/nym-api-tests
nym-api tests
2023-01-26 13:03:43 +01:00
Tommy Verrall 975af0c79b remove the empty interface and return the array instead 2023-01-26 12:00:25 +00:00
benedettadavico 8d82a11b00 Merge conflicts 2023-01-26 12:50:47 +01:00
Tommy Verrall 854d548c20 Delete yarn-stable-temp.cjs 2023-01-26 12:50:35 +01:00
benedettadavico de55ffd944 pretty 2023-01-26 12:49:43 +01:00
Tommy Verrall c8866b1af2 Delete yarn-stable-temp.cjs 2023-01-26 12:27:59 +01:00
benedettadavico eb31e47e68 nym-api tests 2023-01-26 12:22:07 +01:00
Bogdan-Ștefan Neacșu 92b220ca4b Fix typo 2023-01-26 12:27:11 +02:00
Jon Häggblad 0bcdf99475 ci: update build arguments and some tidy (#2919)
* ci: remove --all-targets where it doesn't make sense anymore

* ci: add cargo clean step for ubuntu

* sdk: add note about the existance of a rust sdk
2023-01-26 09:13:39 +01:00
Jon Häggblad b8e2997c73 nym-connect: connectivity status improvements (#2915)
* connect: keep track of connectivity state

* nym-connect: query connection state

* nym-connect: function for kicking of the health check task

* rustfmt

* nym-connect: extract out into function

* nym-connect: extract out events.rs
2023-01-25 20:55:55 +01:00
Jędrzej Stuczyński c218cba96c Feature/default nym api (#2898)
* Setting default 'id' if not provided

* Modified 'NymConfig' to always require 'id'

* moved creation of nym-api directories away from 'override_config'

* missing optional id usage in nym-connect

* changelog

* Removed default value for '--id' argument
2023-01-25 15:49:28 +01:00
Bogdan-Ștefan Neacşu 8336d0612a Remove coconut feature (#2890)
* Remove coconut feature

* Remove github workflow remainings

* Only run dkg if coconut enabled

* Fix typo

* Update changelog
2023-01-25 15:59:37 +02:00
Jędrzej Stuczyński c958975fff Merge branch 'master' into release/v1.1.8 2023-01-25 13:40:20 +00:00
Jędrzej Stuczyński 33d044dd5a Merge branch 'master' into develop 2023-01-25 13:39:33 +00:00
farbanas c2d28740a5 bump mixnode version 2023-01-25 14:06:11 +01:00
farbanas 58b5f113c6 feat: add a workflow for building and publishing binaries to the artifact storage without attaching them to a release 2023-01-25 13:27:04 +01:00
farbanas 9ab3a133d9 feat: add a workflow for building and publishing binaries to the artifact storage without attaching them to a release 2023-01-25 13:25:06 +01:00
Fran Arbanas 7a9fbbccc6 Merge pull request #2864 from nymtech/2733-hosted-runners-releasing
[#2733] Releasing on our self-hosted runners and less failing actions
2023-01-25 13:12:52 +01:00
farbanas f3b82fa032 updated changelog for the new version of contracts 2023-01-25 13:08:54 +01:00
Drazen Urch 49b8a843a4 Vesting cap (#2903)
* Locked coins definition change

* Adapt tests to new locked

* Typo

* More tests

* Fix withdraw test

* Rollback changes

* Cleanup
2023-01-25 12:36:58 +01:00
Jędrzej Stuczyński 5d385ba10f don't trigger global shutdown upon finishing sending verloc packets (#2910) 2023-01-25 10:40:57 +00:00
Mark Sinclair da9468c36a Update package.json 2023-01-24 16:26:37 +00:00
Fran Arbanas 2bd679c91f feat: refactored GH actions (#2894) 2023-01-24 16:11:01 +00:00
joeiacono2021 f4d0a120bb Merge pull request #2902 from nymtech/release/v1.1.7
Release/v1.1.7
2023-01-24 13:04:53 +00:00
joeiacono2021 027b0dbc39 Merge pull request #2901 from nymtech/release/v1.1.7
Release/v1.1.7
2023-01-24 13:04:22 +00:00
farbanas 130ac50834 Regenerated Cargo.lock and resolved conflicts 2023-01-24 14:03:21 +01:00
Fran Arbanas 5711230ae3 Merge branch 'develop' into release/v1.1.7 2023-01-24 13:53:29 +01:00
joeiacono2021 4db656d074 Version changes for 1.1.7 release , edited versions and changelogs. 2023-01-24 12:41:59 +00:00
farbanas 538bcf1d0a merge resolve 2023-01-24 13:25:25 +01:00
Jon Häggblad 95080c3ecc nym-connect: add connection health test (#2883)
* nym-connect: add connect health test

* nym-connect: redo connection test

* nym-connect: strongly typed response

* Fix clippy

* nym-connect: also send event on connection check success

* nym-connect: tidy
2023-01-24 11:04:30 +01:00
Fouad 17771b5742 Fix NC Build (#2893)
* check if sx prop is array or not

fix sx prop breakage

yarn lock update

* return dist folder

* update lock file
2023-01-24 09:27:38 +01:00
Pierre Dommerc 48af0ae6b4 feat(explorer): copy changes (#2892) 2023-01-24 09:15:07 +01:00
Jon Häggblad 4c19187c78 rust-sdk: start adding rustdoc (#2895)
* rust-sdk: start adding some rustdoc

* rust-sdk: whole bunch of rustdoc

* rustfmt
2023-01-24 08:50:59 +01:00
Fouad e1ec3594ea Fix delegations sorting (#2885)
* map and sort delegations

* allow sorting on profit margin and operator cost

* update wallet changelog
2023-01-23 17:33:53 +01:00
farbanas ded7e51071 fix: add continue-on-error: true to all apt calls since if it fails due to lock those packages most likely already exist 2023-01-23 15:47:42 +01:00
farbanas b75199e4dc added yarn tsc to typescript check 2023-01-23 15:43:49 +01:00
Dave Hrycyszyn a0ed1c8edd Added a few items to the nym-api README 2023-01-23 12:33:53 +00:00
Jędrzej Stuczyński a693fa9190 Handling edge-case for when no vesting accounts exist (#2888) 2023-01-23 11:58:07 +01:00
farbanas e83e83abed Since we have two runners on the same machine apt might get locked. This will allow it to fail, maybe those deps are already installed 2023-01-23 11:56:02 +01:00
Jon Häggblad d03f769b14 nym-api: add endpoint for a list of GatewayBondAnnotated (#2833) 2023-01-23 09:04:23 +01:00
Mark Sinclair 86e9463c42 Typescript: fix eslint errors and add GitHub Action for linting (#2886)
* Fix eslint errors

* GitHub Actions: add Typescript project linting

* Fix dependency

* Revert changes and exclude rule

Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
2023-01-20 18:17:15 +00:00
Mark Sinclair 5376c2a4ba WASM Client: use rollup to bundle web worker (#2884)
* WASM Client: simplify sending of custom messages by always setting headers and a mime-type for the content

* Use rollup to bundle the web worker script to support more downstream bundlers

The WASM bundle is embedded as a base64 encoded resource and loaded synchronously, because this is the only mechanism widely supported to load WASM inside a web worker currently. Hopefully in the future this can be changed to pure modules.

* Suppress errors in build script

* Add Parcel 2.0 example

* WASM client: fix tests

* Update SDK docs and images

* wasm-client: add method to validate a recipient's address

* Revert "Removing unused prestart"

This reverts commit cbeac10383.

* Revert "Removing pointless dependency build command from TypeScript SDK example"

This reverts commit 0e0a62938d.

* Add typing for React 18

* Improve README files

Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com>
2023-01-20 16:46:52 +00:00
Dave Hrycyszyn cbeac10383 Removing unused prestart 2023-01-20 13:30:58 +00:00
Dave Hrycyszyn 63a4bdf5a6 Merge branch 'release/v1.1.6' into develop 2023-01-20 12:38:29 +00:00
Dave Hrycyszyn 0e0a62938d Removing pointless dependency build command from TypeScript SDK example 2023-01-20 12:38:01 +00:00
Bogdan-Ștefan Neacşu f1d0bd0bf4 Feature/dkg rerun tests (#2875)
* Some contract unit tests

* Hook for group queries

* Test epoch advancement

* Use separate process for tests using group global var
2023-01-20 14:03:19 +02:00
Raphaël Walther 404473c128 Github Actions: install npm 2023-01-20 09:05:59 +01:00
Jon Häggblad a980d6f804 rust-sdk: enable reply-SURBs by default (#2874)
* rust-sdk: enable SURBs by default

* changelog: update

* rustfmt
2023-01-19 15:21:02 +01:00
Jon Häggblad c6a5e08188 rust-sdk: handle surb storage (#2870)
* clients: make surb storage more flexible

- in the rust-sdk we make the surb storage generic and pluggable, with
  the fs_backend the default.
- make it possible to disable fs_backend at runtime

* Add comment

* changelog: add note

* client-core: tidy up some minor things
2023-01-19 13:30:43 +01:00
Fouad b2ed078e0f Remove test and earn (#2869)
* remove test and earn

* update changelog
2023-01-19 11:40:37 +01:00
Jon Häggblad 886e2ed5e7 nym-sdk: add nyxd-client feature dependency (#2872) 2023-01-19 11:17:37 +01:00
Dave Hrycyszyn aa545ee6c6 Changing comment to nym-api 2023-01-19 10:09:45 +00:00
Jon Häggblad 62741889bc ci: build rust examples (#2871) 2023-01-19 11:04:12 +01:00
Bogdan-Ștefan Neacşu 64c963e36e Feature/dkg rerun (#2839)
* Reset contract state when dkg needs rerun

* Reset nym-api for rerun

* Gateway updates signer APIs at runtime

* Fix clippy

* Add epoch id

* Use IndexedMap for shares

* Query with epoch id

* Add Clone to client traits

* Pass nyxd client instead of api data

* Get the specific epoch vk

* Make wasm work

* Remove wasm test runs

As there are no wasm tests and the target_arch macros are not compatible
with the cargo test environment, we can safely remove (for now) the wasm
test target runs.

* Put epoch_id in storage pk

* Gateway uses old keys but current verifiers

* Add group contract to env

* Move group msg in common

* Only run DKG if part of group

* Clippy test

* Rename wasm_storage to wasm_mockups

* Update changelog
2023-01-19 11:15:07 +02:00
Raphaël Walther d6f87c40ed Github Actions: fix notifications 2023-01-18 17:36:25 +01:00
Fran Arbanas 39562e653a Merge pull request #2837 from nymtech/ci-clippy-update
chore: added --all-targets --all-features to clippy
2023-01-18 13:17:05 +01:00
Jon Häggblad e548d6f1f8 cargo: try out inheriting workspace metadata (#2853)
* cargo: add log as a workspace dependency

* cargo: add authors to top-level workspace

* cargo: add a few more entried to workspace package
2023-01-18 10:13:11 +01:00
Jon Häggblad 48def795d9 common/logging: fix clippy (#2866)
* common/logging: fix clippy

* network-requester: clippy
2023-01-18 09:55:56 +01:00
farbanas e849cc065a move contracts build to our custom runner 2023-01-17 16:43:36 +01:00
farbanas 95b95b2892 fix: contracts build shouldn't fail on wrong tag 2023-01-17 16:24:03 +01:00
farbanas df4587be62 chore: whitespace 2023-01-17 15:47:46 +01:00
Dave Hrycyszyn 80017d258d Merge branch 'release/v1.1.6' into develop 2023-01-17 14:10:15 +00:00
Bogdan-Ștefan Neacşu 6d6d9d4359 Apply rename refactoring to env files (#2854) 2023-01-17 15:02:22 +02:00
farbanas 59185f3b87 merge resolve 2023-01-17 13:41:56 +01:00
durch c708a7cc12 Merge branch 'release/v1.1.6' of https://github.com/nymtech/nym into release/v1.1.6 2023-01-17 13:39:56 +01:00
durch ea35a37d4c Replace println with eprintln! 2023-01-17 13:39:49 +01:00
farbanas e40d25a97b nym-validator-api -> nym-api 2023-01-17 13:33:30 +01:00
farbanas cf903aa2e5 updated changelogs 2023-01-17 13:30:31 +01:00
farbanas 0a2e0d6a8f bump version for release 2023-01-17 13:17:15 +01:00
Fran Arbanas 8eb3dbd191 Merge pull request #2849 from nymtech/workflows-nym-api
fix: rename validator-api to nym-api
2023-01-17 13:07:24 +01:00
farbanas 58d15429de feat: change Github hosted ubuntu-20.04 runners for our own custom-runner-linux 2023-01-17 13:05:35 +01:00
Raphaël Walther a0661fecb2 Github Actions: fix notifications 2023-01-17 10:38:34 +01:00
Jędrzej Stuczyński ea68d42886 bugfix: set default value for nym-api (and nyxd) for clients (#2822)
* setting default urls in client config

* using the same environmental variable for verloc
2023-01-17 10:27:55 +01:00
Dave Hrycyszyn d4298c61a0 Feature/centralized allow list (#2835)
* Changed `listening_address` to `websocket_address` to make things a bit more clear

Stricly speaking, service providers don't "listen" on a port, they make
an outbound connection to a websocket which is already listening on the
provided port on localhost.

* Using un-imported network_defaults module name as it fits nicely

and reduces guessing as to what's going on in the code

* Using full module path for logs

* Some minor renames and extractions

* Fixing a few clippy warnings about double references

* Ripped the allowed_hosts module out into separate module files

* Removing old comment

* Removing unused import

* Knocking down visibility on function

* Docs on OutboundRequestFilter

* Removing a function that doesn't justify its existence

* Keeping struct with its impl

* Renamed a few modules

* Smoothing and rearranging code, no big changes

* It's now possible to inject a standard allowed_list

* Logging all standard allowed domains at network requester startup

* Fixing printed comment
2023-01-16 15:20:24 +00:00
farbanas 65ed611c24 fix: changelog cleanup and added a UNRELEASED section 2023-01-16 16:00:58 +01:00
Raphaël Walther d713b926f8 Github Actions: fix notifications 2023-01-16 15:31:47 +01:00
Gala f305901a18 Changing the explorers guru link (#2820) 2023-01-16 15:27:44 +01:00
Raphaël Walther 082a8ad8ee Github Actions: fix notifications 2023-01-16 14:38:02 +01:00
farbanas 031092815b fix: rename validator-api to nym-api 2023-01-16 14:05:00 +01:00
farbanas ca8a6150c9 fix: moved the if step to the root of the job, removed unused workflows 2023-01-16 14:01:20 +01:00
Jess 645cb88074 Update CHANGELOG.md 2023-01-16 12:42:51 +00:00
Jędrzej Stuczyński 6b96e474f7 made most of cli boolean arguments optional (#2819)
so that if not provided, they would not overwrite config values
2023-01-16 12:52:29 +01:00
Raphaël Walther f4fd08f64e Github Actions: add audit workflow on trigger 2023-01-16 11:25:28 +01:00
Fouad 78247b973b upgrade storybook to latest (#2840) 2023-01-16 09:49:08 +00:00
Jon Häggblad 6b52132501 gateway: don't shutdown on connection handler drop (#2848) 2023-01-16 10:31:01 +01:00
Raphaël Walther d2f33180e2 Github Actions: fix notifications 2023-01-16 09:40:05 +01:00
Jon Häggblad dc71f6e94d common: dedup and move banner to common/logging (#2846) 2023-01-16 08:32:35 +01:00
Raphaël Walther cc7161c113 Github Actions: fix notifications 2023-01-13 16:54:09 +01:00
Jędrzej Stuczyński bbb46ebd90 chore: upgrade tokio to 1.24.1 (+ tokio-util and tokio-stream) (#2843)
* updated 'tokio' to 1.24.1 in the whole codebase

* ibid for 'tokio-stream'

* ibid for 'tokio-util'

* Removed lock file from verify-signature example
2023-01-13 14:46:10 +00:00
Jon Häggblad bc3fd236d8 client-core: fix bug with force-register-gateway (#2844) 2023-01-13 15:43:29 +01:00
dependabot[bot] ea95288940 build(deps): bump minimatch from 3.0.4 to 3.1.2 in /testnet-faucet (#2775)
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  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-13 13:37:36 +00:00
dependabot[bot] b182ed6925 build(deps): bump luxon from 2.4.0 to 2.5.2 (#2792)
Bumps [luxon](https://github.com/moment/luxon) from 2.4.0 to 2.5.2.
- [Release notes](https://github.com/moment/luxon/releases)
- [Changelog](https://github.com/moment/luxon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/moment/luxon/compare/2.4.0...2.5.2)

---
updated-dependencies:
- dependency-name: luxon
  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-13 13:36:20 +00:00
Fouad 017c9d2504 upgrade tauri to 1.2.3 (#2842) 2023-01-13 13:34:56 +00:00
Jędrzej Stuczyński 50c7d717c0 chore: fixed clippy warnings from the nightly toolchain (#2838) 2023-01-13 13:16:47 +00:00
Jędrzej Stuczyński b473aeb3be Feature/gateway graceful shutdown (#2834)
* task dependency

* unifying some startup code and passing TaskClient around

* graceful shutdown handling for mix socket listener

* graceful shutdown handling for clients listener

* graceful shutdown handling for packet forwarding

* unified waiting for interrupt across binaries

* made 'validate_bech32_address_or_exit' into a function that returns proper Result

* printing formatted message on main error

* fixed failing test

* removed duplicate code that should have been gone ages ago

* ibid

* removed biased selection for authenticated handler

* minor refactoring to 'ensure_config_version_compatibility'
2023-01-13 11:56:37 +00:00
farbanas ac10e03aec chore: added --all-targets --all-features to clippy 2023-01-13 10:31:19 +01:00
Fran Arbanas fe2e1c29a2 Merge pull request #2828 from nymtech/2811-fix-clippy-check-failing
[2811] Fix dependabot clippy-check fails
2023-01-13 10:28:26 +01:00
Fouad 2eee5195cc React / React DOM / Types upgrade to version 18 (#2830)
* new react and reactdom packages in wallet

* new react and reactdom packages in root

* new react and reactdom packages in nym connect

* new react and reactdom packages in root

* update react and reactdom for explorer

* react and react-dom upgrade for ts-packages

remove unused import

fix linting error

* use custom FC typing

move typings folder

* fix type error
2023-01-12 17:15:31 +00:00
Jon Häggblad 3bd4343a39 client-core: tidy by removing some allow dead_code (#2832) 2023-01-12 14:18:46 +01:00
Jon Häggblad 74feb065f9 outfox: fix some clippy warnings in tests (#2831) 2023-01-12 14:03:26 +01:00
Mark Sinclair 65b819c649 GitHub Actions: add directory to fix error on runners with read-only file systems 2023-01-12 12:52:31 +00:00
Jon Häggblad bd12305a68 client-core: add note about msg string 2023-01-12 12:35:40 +01:00
Fouad 4854e929ed link to the ng mixnet explorer for account info (#2823) 2023-01-12 12:33:28 +01:00
Jędrzej Stuczyński 5709c45a50 Feature/circulating supply (#2814)
* Fixed typo in node_status_cache constant

* ibid

* Moved some caching stuff around so I can see what depends on what

* Finishing merge of conflicted files

* Minor smoothing

* Got cache reads working for circ supply and refactored common cache

* Refactored nyxd client usages to make things bit more clear

* Moved caching support stuff into the support folder

* Moved storage code into support module

* Removed dead code

* Tweaks

* Handling cases a little more nicely in circulating supply api

* Renamed nymd_client to nyxd_client

* Pulled CacheNotification into the caching support module

* Pulled some domain-specific helpers out of cache refresher

* Moving some more helper methods out of the cache refresher

* Deleting unused code

* Extracted a few more functions out of the cache refresher

* A few comments as breadcrumbs

* Renaming the anemic "helpers" to "node_sets"

* Renaming the validator_cache module to nym_contract_cache

* Renaming nym contract cache stuff to make things clearer

* Renamging a few things in comments

* Renaming validator_cache to nym_contract_cache

* foomp

* Started refactoring http and cli

* Extracted cli arg parsing into its own module

* Cleanup

* Extracted start methods into various modules to clean main up

* WIP commit

* Build working, swagger not

* Fixed swagger docs metadata

* Removed log statement

* Circulating supply cache now working with simple logic

* Fixed up circulating supply method names

* Starting to work in some (wrong) constants

* Documented the cache

* Renaming circulating-supply route

* nym-api compiling after the rebasing

but most likely not fully working yet

* removed unused imports

* only starting RewardedSetUpdater if the config flag is set

* nym-api compiling with coconut feature

* removed redundant process_runner

* removed generic aspect of nym-api nyxd::Client

* signle entry point for starting nym_contract_cache

* do not eagerly grab instances of managed state

* inlining openapi route spec

* CirculatingSupplyResponse type

* fixed compilation of coconut tests

* calculating circulating supply based on mixmining reserve and vesting tokens

* separated different variants of caching intervals

* allow nym-api to specify address of the vesting contract

* fixed types export

* renamed the query on the vesting contract

* reorganised startup procedure and made all start methods independent from rocket

* cleaned up startup procedure for nym-api

* startup checks for rewarding permisssions

* updated changelog

* added config flag to control whether circulating supply should be updated

Co-authored-by: Dave Hrycyszyn <futurechimp@users.noreply.github.com>
2023-01-12 10:39:21 +00:00
Jon Häggblad a7f1242961 client-core: clean up gateway registration (#2827)
* client-core: clean up gateway registration

* client-core: tidy docs and clippy

* clients: tidy output
2023-01-12 11:35:34 +01:00
Jon Häggblad 8b14321c4a connect,wallet: make fern use same colors as env_pretty_logger (#2829) 2023-01-12 11:35:11 +01:00
Fouad 5f88517e1d Feature/nym connect gateway performance (#2824)
* set up ui for gateway performance in nym-connect

remove duplicated imports

* set and reset (when necessary) gateway performance

* remove unneeded useEffect

* remove log
2023-01-12 10:47:58 +01:00
farbanas dddc6eae57 fix: added continue-on-error for clippy-check since they fail on forked repositories due to permission errors which we won't solve 2023-01-12 10:45:27 +01:00
Jędrzej Stuczyński 8beb33fe92 bugfix: set default value for nym-api (and nyxd) for clients (#2822)
* setting default urls in client config

* using the same environmental variable for verloc
2023-01-11 14:37:05 +00:00
Fouad c7d8f3af97 Feature/nym connect gateway performance (#2815)
* set up ui for gateway performance in nym-connect

* reset gateway performance state periodically

* remove duplicated imports

* set and reset (when necessary) gateway performance

* align gateway performance text left
2023-01-11 14:19:59 +01:00
Gala 1e84f87bf5 Revert "Changing the explorers guru link"
This reverts commit 70ae45b6c9.
2023-01-11 13:33:26 +01:00
Jędrzej Stuczyński bf5b8fab85 made most of cli boolean arguments optional (#2819)
so that if not provided, they would not overwrite config values
2023-01-11 12:14:16 +00:00
Gala 70ae45b6c9 Changing the explorers guru link 2023-01-11 12:59:16 +01:00
Jon Häggblad b0960091c1 Merge pull request #2764 from nymtech/feature/rust-sdk-initial-version
Initial Rust client SDK
2023-01-11 10:06:15 +01:00
Jon Häggblad b97a12186f rust-fmt: append path in error 2023-01-11 00:32:21 +01:00
Jon Häggblad 36496a519a rust-sdk: add additinal example 2023-01-11 00:13:45 +01:00
Jon Häggblad 87fad25ac3 rust-sdk: implement manualy set/get keys 2023-01-11 00:13:28 +01:00
Jon Häggblad df3d478caa rust-sdk: make new_from_dir return result 2023-01-10 23:28:26 +01:00
Jon Häggblad 751e3ccd27 Merge remote-tracking branch 'origin/develop' into feature/rust-sdk-initial-version 2023-01-10 23:14:24 +01:00
Mark Sinclair 74a4546d72 GitHub Actions: post messages to another channel on job failures 2023-01-10 18:25:42 +00:00
Jędrzej Stuczyński 2587d00b9e feature: reduce staking address capabilities + refactor vesting storage (#2796)
* checks for existing staking account

* removed code for v2 migration

* using stronger types for storage keys

* Added type alias for the storage key and documented each `Map`

* remove the hacky way of storing staker information

* allow the staking address account to perform delegations with the additional msg argument

* new unit tests

* updated client code

* modified migrate msg to explicitly require confirming having performed manual checks

* re-ordered arguments
2023-01-10 17:36:27 +00:00
Fouad cf25c331c0 Upgrade webpack (#2800)
* upgrade webpack and remove unused client lib

* upgrade webpack loaders
2023-01-10 17:08:09 +00:00
Mark Sinclair a24c7e4783 Merge pull request #2813 from nymtech/feature/matrix-messages
Send matrix notification messages
2023-01-10 16:40:38 +00:00
Mark Sinclair 9ea725bf83 GitHub Actions: add matrix env vars to all jobs with notifications 2023-01-10 16:36:50 +00:00
Mark Sinclair fe78d4faf0 GitHub Actions: support sending notification messages to matrix 2023-01-10 16:24:23 +00:00
Jędrzej Stuczyński 0df063f9f6 feature: query for obtaining amount of vesting coins for all accounts (#2791)
* wip

* Introduced paged queries for getting list of all vesting accounts and for amount of vesting coins

* Added the queries to VestingQueryClient trait

* Added default implementations to all trait queries

* Fixed naming for the vesting coins query

* Helper functions for dealing with paging

* Updated changelog
2023-01-10 14:58:40 +00:00
Bogdan-Ștefan Neacşu ad8fdbdddf Feature/configurable dkg signup (#2809)
* Refactored consts to config structure

* Nym-cli generate init for dkg contract
2023-01-10 16:33:16 +02:00
Bogdan-Ștefan Neacşu 8d3aea969e Handle case when changed value is 42 (#2808) 2023-01-10 15:01:57 +02:00
farbanas 96444509d0 fix: updated changelog for binaries with the version of the release 2023-01-10 13:53:02 +01:00
farbanas 078ca0b0d1 Merge resolve 2023-01-10 13:52:00 +01:00
farbanas aab91e424e Merge resolve 2023-01-10 13:48:04 +01:00
farbanas 273dc41559 feat: update changelogs 2023-01-10 13:43:09 +01:00
farbanas 61bc74148f Update versions 2023-01-10 13:10:24 +01:00
Jędrzej Stuczyński 5b14eecf82 bugfix: for Default config impl generate fresh mnemonic over using a hardcoded one (#2806) 2023-01-10 10:39:58 +00:00
Jon Häggblad 2746cabecc rust-sdk: reorder in client file 2023-01-10 01:43:50 +01:00
Jon Häggblad 666cbcf2cc rust-sdk: extract out builder 2023-01-10 01:36:27 +01:00
Fran Arbanas 30110aff65 Merge pull request #1827 from nymtech/feat/nym-cli-cosmwasm-generate-init-message
nym-cli generate instantiate message for mixnet and vesting contracts
2023-01-09 19:54:28 +01:00
farbanas 1954c49ac2 merge resolve 2023-01-09 19:38:16 +01:00
farbanas 70328ba114 merge resolve 2023-01-09 19:30:25 +01:00
farbanas c43b2dc117 merge resolve 2023-01-09 16:03:42 +01:00
Drazen Urch 4a8a9096dd Save to JSON in addition to printing (#1864)
* Save to JSON in addition to printing

* Save node details to json for mixnode

* Remove Cargo.locks

* Cli ergonomics

* Json output for gateway
2023-01-09 12:51:21 +01:00
Jon Häggblad 96ab4325e3 rust-sdk: tidy 2023-01-09 12:39:23 +01:00
Jon Häggblad 11e2ba33e7 fix compilation after merge in latest develop 2023-01-09 10:44:02 +01:00
Jon Häggblad 95db26c35b changelog: add note 2023-01-09 10:43:42 +01:00
Jon Häggblad aed96b2d44 Merge remote-tracking branch 'origin/develop' into feature/rust-sdk-initial-version 2023-01-09 10:41:10 +01:00
Jon Häggblad 326d5fcec8 rustfmt 2023-01-09 10:02:46 +01:00
Jędrzej Stuczyński 88d813b9c1 Feature/optional set trait (#2773)
* Defined OptionalSet trait

* extended the trait to handle environment

* sample implementation for the gateway

* implementation for mixnode

* Added the same feature to nym-api config + made some config types stricter

* fixed compilation and linter issues

* keeping track of parsing error

* attempt at using the trait for the client configs

* Streamlined more arguments

* Removed deprecation on setters

* fixed incorrect test constructor

* missed rebase fixes
2023-01-06 18:13:25 +00:00
Pierre Dommerc e181a1cfb1 feat(wallet-buy): pass wallet address as url param (#2780) 2023-01-06 09:38:30 +01:00
Jon Häggblad afae6fc9a5 rust-sdk: move Keys to its own file 2023-01-05 17:44:03 +01:00
Jon Häggblad 23c13a409a rust-sdk: rename key_paths to paths 2023-01-05 17:06:21 +01:00
Dave Hrycyszyn 29091aab8e Feature/rename nymd to nyxd (#2696)
* Renaming all instances of nymd to nyxd

* Might as well get the changelogs too

* Making it clearer that an ApiClient is a NymApiClient

* Lining up config templates with struct keys on gateway

* Changed the last references to validator_urls to nyxd_urls

* Fixed up a few type errors after refactoring

* Changed the changelog

* Fixed typo in changelog

* Further instances of renaming 'nymd' + introducing additional clap aliases

* updated environmental variables and allowed usage of deprecated variants

* missing occurences of coconut-locked environmental variables

Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2023-01-05 15:35:47 +00:00
Jon Häggblad 1d522143a2 rust-sdk: remove more unwraps 2023-01-05 16:18:39 +01:00
Jon Häggblad 775ce0f95d rust-sdk: fix some issues identified during draft review 2023-01-05 16:18:39 +01:00
Jon Häggblad b019786c5a rust-sdk: replace a bunch of unwrap with error return 2023-01-05 16:18:39 +01:00
Jon Häggblad 9b9c01fb8f rust-sdk: initial version 2023-01-05 16:18:39 +01:00
Dave Hrycyszyn 6c857b5daf wip 2023-01-05 16:18:39 +01:00
Dave Hrycyszyn 5ea084d286 Starting with Rust sdk 2023-01-05 16:18:39 +01:00
Pierre Dommerc fdbe3a1f6a fix(explorer,explorer-api): mixnode location (#2763)
* chore(explorer-api): remove useless route (/terms)

* feat(explorer-api-geoip): add coordinates lat&lon

* fix(explorer): mixnode location

* fix: typo

* fix: clippy
2023-01-05 15:53:15 +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 5b15ed6f15 merge resolve 2022-12-22 15:48:40 +01:00
Fouad 9684b7ffbd merge resolve 2022-12-22 15:45:02 +01:00
Fouad 0628565684 Feature/node settings apy playground (#1677) (#2738)
* 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>

Co-authored-by: Jon Häggblad <jon.haggblad@gmail.com>
2022-12-22 15:33:27 +01:00
Gala 57703af642 Merge pull request #2746 from nymtech/revert-1519-339-net-switch-bttn
Revert "NE: Switch button to change the explorer network"
2022-12-22 14:21:24 +01:00
Gala 9dd4c5d871 Revert "NE: Switch button to change the explorer network" 2022-12-22 14:20:21 +01:00
farbanas 4813cf6c18 feat: release v1.1.5 of nym-wallet 2022-12-22 12:14:01 +01:00
farbanas 29f48efe49 feat: release v1.1.5 of nym-wallet 2022-12-22 12:13:44 +01:00
farbanas 280ac34115 feat: release v1.1.5 of nym-wallet 2022-12-22 12:12:46 +01:00
benedetta davico 83b76c6b37 Merge pull request #1519 from nymtech/339-net-switch-bttn
NE: Switch button to change the explorer network
2022-12-22 11:23:00 +01:00
Gala 4120234155 fix build problem 2022-12-22 11:09:55 +01:00
Gala 42b444ddf8 Merge branch '339-net-switch-bttn' of github.com:nymtech/nym into 339-net-switch-bttn 2022-12-22 10:55:03 +01:00
Gala acd832d8e5 cleaning 2022-12-22 10:54:26 +01:00
Gala 75a726ebbe some styles 2022-12-22 10:54:12 +01:00
Gala b9fbab6024 adding button on mov nav and make it smaller 2022-12-22 10:54:12 +01:00
Gala 06ed8716a1 adding a switch between networks 2022-12-22 10:54:12 +01:00
benedetta davico beddd3dcee Merge pull request #2742 from nymtech/feat/2130-tables-update-rebase
Feat/2130 tables update rebase
2022-12-22 10:37:53 +01:00
Drazen Urch bdc285dbbb Add numeric family ids to explorer-api (#2707) 2022-12-21 23:37:32 +01:00
benedetta davico 4d02dfb899 Merge pull request #2741 from nymtech/fix/explorer-gateway-bond-decimals
fix(explorer): set gateway bond 6 decimals
2022-12-21 18:10:47 +01:00
Gala 80d6cb5c12 last small touch 2022-12-21 17:34:26 +01:00
Gala 7422ab69ba Merge branch 'feat/2130-tables-update-rebase' of github.com:nymtech/nym into feat/2130-tables-update-rebase 2022-12-21 17:30:26 +01:00
Gala 60c8185bea cleaning 2022-12-21 17:26:34 +01:00
Gala 9d3c7c0be8 refactor from PR request 2022-12-21 17:26:34 +01:00
Gala d6048fae52 refactor 2022-12-21 17:26:22 +01:00
Gala ddb7b0e872 delegations layout and tooltip when delegate with vesting 2022-12-21 17:26:22 +01:00
Gala 4995dde705 bond table changes 2022-12-21 17:25:09 +01:00
Gala 63bfe4246f fix parameters settings layout 2022-12-21 17:24:23 +01:00
Gala 4654b360e0 cleaning 2022-12-21 17:23:52 +01:00
Gala 7c5c19986a refactor from PR request 2022-12-21 17:23:52 +01:00
Gala 46edca0bd4 refactor 2022-12-21 17:23:52 +01:00
Gala b03a1f922d refactor 2022-12-21 17:23:52 +01:00
Gala 9616c90433 delegations layout and tooltip when delegate with vesting 2022-12-21 17:23:52 +01:00
Gala ea49f0a265 delegations table changes wip 2022-12-21 17:23:52 +01:00
Gala 2470c8b9b5 tidying up 2022-12-21 17:23:52 +01:00
Gala 7d001965ec change date order to dd/mm/yy 2022-12-21 17:22:26 +01:00
Gala 11b1089d83 removing epoch on settings and fixing divider position 2022-12-21 17:22:26 +01:00
Gala 52699d7598 bond table changes 2022-12-21 17:21:51 +01:00
benedetta davico 87443dd624 Merge pull request #2743 from nymtech/feat/2161-ne-gate-version
Feat/2161 ne gate version
2022-12-21 15:25:07 +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
Gala e0f2fa6705 fix indentation 2022-12-21 14:45:14 +01:00
Gala 7949b07213 Merge branch 'feat/2161-ne-gate-version' of github.com:nymtech/nym into feat/2161-ne-gate-version 2022-12-21 14:07:16 +01:00
Gala bd20fd0b1f remove console log 2022-12-21 14:06:32 +01:00
Gala 57d3d6fd0f sdding version number on the gateways list and details 2022-12-21 14:06:32 +01:00
Gala 06eff652dd wip adding gt version 2022-12-21 14:06:32 +01:00
Gala 246decac4a remove console log 2022-12-21 14:01:53 +01:00
Gala a14ae298ae sdding version number on the gateways list and details 2022-12-21 13:59:23 +01:00
Gala 43188051d3 Merge branch 'feat/2130-tables-update-rebase' of github.com:nymtech/nym into feat/2130-tables-update-rebase 2022-12-21 12:48:46 +01:00
Gala 8aa15fa467 fix parameters settings layout 2022-12-21 12:41:12 +01:00
benedetta davico f77b037ef7 Merge pull request #2704 from nymtech/feature/nym-connect-display-info
NymConnect - Display service info in tooltip **1.1.5 Release**
2022-12-21 12:39:44 +01:00
Gala 75dbc5d790 Merge branch 'release/v1.1.5' into feat/2130-tables-update-rebase 2022-12-21 12:20:42 +01:00
Gala e6bcd706ff cleaning 2022-12-21 12:03:46 +01:00
Gala 9a077a0928 refactor from PR request 2022-12-21 12:03:46 +01:00
Gala 11fd42e187 refactor 2022-12-21 12:03:46 +01:00
Gala 6e499e5996 refactor 2022-12-21 12:03:46 +01:00
Gala f98cc73a1f delegations layout and tooltip when delegate with vesting 2022-12-21 12:03:46 +01:00
Gala db9bf4d3fa delegations table changes wip 2022-12-21 12:03:46 +01:00
Gala b30628529d tidying up 2022-12-21 12:03:46 +01:00
Gala 3be615f74f change date order to dd/mm/yy 2022-12-21 12:03:46 +01:00
Gala a8ccd2ec17 removing epoch on settings and fixing divider position 2022-12-21 12:03:46 +01:00
Gala 2d71caf50a bond table changes 2022-12-21 12:03:46 +01:00
Gala 4d08d62fc2 wip adding gt version 2022-12-21 11:54:41 +01:00
pierre 40e5595d65 fix(explorer): set gateway bond 6 decimals 2022-12-21 11:46:12 +01:00
Gala 6780d58a98 cleaning 2022-12-21 11:19:50 +01:00
Gala ccbf06f179 refactor from PR request 2022-12-21 11:19:50 +01:00
Gala e6ecf71cc3 refactor 2022-12-21 11:19:50 +01:00
Gala c66312ee96 refactor 2022-12-21 11:19:50 +01:00
Gala 808802aeb4 delegations layout and tooltip when delegate with vesting 2022-12-21 11:19:50 +01:00
Gala fb38f24e5c delegations table changes wip 2022-12-21 11:19:50 +01:00
Gala 65f148a5ad tidying up 2022-12-21 11:19:50 +01:00
Gala 2bcdc5d11e change date order to dd/mm/yy 2022-12-21 11:19:50 +01:00
Gala 5ecb03ffe9 removing epoch on settings and fixing divider position 2022-12-21 11:19:50 +01:00
Gala 8505989dad bond table changes 2022-12-21 11:19:50 +01:00
benedetta davico ed5e865db7 Merge pull request #2718 from nymtech/feature/wallet-epoch-time-in-unbond-modal
Add epoch info to unbond modal **1.1.5 Release**
2022-12-21 10:37:38 +01:00
benedetta davico ea3194e0c3 Merge pull request #2720 from nymtech/feature/wallet-fix-parameter-input-layout
Fix param input layout **1.1.5 Release**
2022-12-21 10:24:05 +01:00
Gala 190bff4ffe Merge branch 'release/v1.1.5' of github.com:nymtech/nym into release/v1.1.5 2022-12-21 10:21:23 +01:00
fmtabbara c509555d15 fix param input layout 2022-12-21 09:22:01 +01:00
fmtabbara f0d66fdd88 add epoch info to unbond modal 2022-12-21 09:19:39 +01:00
fmtabbara 14847d01b7 remove console.log 2022-12-21 09:17:38 +01:00
fmtabbara f4711902bd display service info in tooltip
trim provider address
2022-12-21 09:17:38 +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 d92d6877a4 Merge branch 'release/v1.1.4' 2022-12-20 12:33:46 +01: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
farbanas 70fcb8c046 feat: added the rest of the generators, updated some fields based on PR comments 2022-12-15 10:07:19 +01: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
farbanas ce676c2bb5 Merge branch 'release/v1.1.3' 2022-12-13 15:18:49 +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 a096f9d54e Merge branch 'release/v1.1.3' 2022-12-13 13:24:01 +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 d9b6823106 Merge branch 'release/v1.1.2' 2022-12-07 12:37:14 +01: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
farbanas 89bcb5649b changed ubuntu-latest on GH actions to ubuntu-20.04 2022-12-06 17:23:08 +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
farbanas 53444cf55a fix: rewarding denom was unyxt by default, it should be unymt 2022-12-05 13:22:21 +01: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
farbanas f2e460a96b chore: import cleanup 2022-12-01 12:17:46 +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
farbanas b5b7b7255b feat: add vesting contract instatiate message generation 2022-12-01 11:41:03 +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
farbanas 894a46688a chore: formatting 2022-12-01 10:21:00 +01:00
farbanas 5d3550a569 fix: remove the debug output for instantiate message as it incorrectly escapes strings 2022-12-01 10:16:36 +01:00
Jon Häggblad 1507938c65 socks5-client: SOCKS4a support (#1822)
* socks5-client: SOCKS4a support

* Tidy
2022-12-01 09:19:17 +01:00
farbanas b43dab4f83 chore: added a couple of debug messages to parseOptionalAccount 2022-11-30 17:24:25 +01:00
farbanas 1bdb58571d feat: refactor cosmwasm nym-cli command a bit to support multiple tiers. Add a generator for mixnet contract instantiate messages 2022-11-30 16:01:35 +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
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
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 0fd178a304 Merge branch 'develop' into 327-nym-connect-colours 2022-09-22 10:37:06 +02: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 28cc772d7b various ui updates 2022-09-08 11:43:59 +02:00
Gala a74a99d81d cleaning 2022-08-10 16:38:56 +02:00
Gala c09d3af92f Merge branch 'develop' into 340-ne-content 2022-08-10 16:35:38 +02:00
Gala 76773c58d7 some styles 2022-08-10 16:34:30 +02:00
Gala fd90175e87 adding button on mov nav and make it smaller 2022-08-10 15:43:42 +02:00
Gala 0eb859467e adding a switch between networks 2022-08-10 15:09:44 +02:00
1727 changed files with 88381 additions and 47270 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ 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
GEOIPUPDATE_EDITION_IDS=GeoLite2-City
# 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
+17 -9
View File
@@ -5,7 +5,7 @@ on:
- cron: '5 9 * * *'
jobs:
cargo-deny:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- name: Checkout repository code
uses: actions/checkout@v2
@@ -16,14 +16,17 @@ jobs:
- name: Install cargo deny
run: cargo install --locked cargo-deny
- name: Run cargo deny
run: cargo deny check advisories --hide-inclusion-graph &> .github/workflows/support-files/notifications/deny.message
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-latest
runs-on: custom-runner-linux
steps:
- name: Check out repository code
uses: actions/checkout@v2
@@ -32,18 +35,23 @@ jobs:
with:
name: report
path: .github/workflows/support-files/notifications
- name: Keybase - Node Install
- name: install npm
uses: actions/setup-node@v3
with:
node-version: 16
- name: Matrix - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
- name: Matrix - 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"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM_AUDIT }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
@@ -0,0 +1,113 @@
name: Build and upload binaries to CI
on:
workflow_dispatch:
push:
paths:
- 'clients/**'
- 'common/**'
- 'contracts/**'
- 'explorer-api/**'
- 'gateway/**'
- 'integrations/**'
- 'mixnode/**'
- 'sdk/rust/nym-sdk/**'
- 'service-providers/**'
- 'nym-api/**'
- 'nym-outfox/**'
- 'tools/nym-cli/**'
- 'tools/ts-rs-cli/**'
pull_request:
paths:
- 'clients/**'
- 'common/**'
- 'contracts/**'
- 'explorer-api/**'
- 'gateway/**'
- 'integrations/**'
- 'mixnode/**'
- 'sdk/rust/nym-sdk/**'
- 'service-providers/**'
- 'nym-api/**'
- 'nym-outfox/**'
- 'tools/nym-cli/**'
- 'tools/ts-rs-cli/**'
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: Prepare build output directory
shell: bash
env:
OUTPUT_DIR: ci-builds/${{ github.ref_name }}
run: |
rm -rf ci-builds || true
mkdir -p $OUTPUT_DIR
echo $OUTPUT_DIR
- 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
continue-on-error: true
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --release --all
- 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: Prepare build output
shell: bash
env:
OUTPUT_DIR: ci-builds/${{ github.ref_name }}
run: |
cp target/release/nym-client $OUTPUT_DIR
cp target/release/nym-gateway $OUTPUT_DIR
cp target/release/nym-mixnode $OUTPUT_DIR
cp target/release/nym-socks5-client $OUTPUT_DIR
cp target/release/nym-api $OUTPUT_DIR
cp target/release/nym-network-requester $OUTPUT_DIR
cp target/release/nym-network-statistics $OUTPUT_DIR
cp target/release/nym-cli $OUTPUT_DIR
cp target/release/credential $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm $OUTPUT_DIR
- 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: "-avzr"
SOURCE: "ci-builds/"
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/
EXCLUDE: "/dist/, /node_modules/"
@@ -0,0 +1,59 @@
name: Build and upload binaries to artifact storage
on:
workflow_dispatch:
inputs:
add_tokio_unstable:
description: 'True to add RUSTFLAGS="--cfg tokio_unstable"'
required: true
default: false
type: boolean
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
continue-on-error: true
- 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
with:
toolchain: stable
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --release
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: nym-binaries-artifacts
path: |
target/release/nym-client
target/release/nym-gateway
target/release/nym-mixnode
target/release/nym-socks5-client
target/release/nym-api
target/release/nym-network-requester
target/release/nym-network-statistics
target/release/nym-cli
retention-days: 30
+8 -6
View File
@@ -12,6 +12,7 @@ jobs:
- uses: actions/checkout@v2
- name: Install rsync
run: sudo apt-get install rsync
continue-on-error: true
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v3
with:
@@ -42,10 +43,10 @@ jobs:
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/ts-${{ env.GITHUB_REF_SLUG }}-example
EXCLUDE: "/dist/, /node_modules/"
- name: Keybase - Node Install
- name: Matrix - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
- name: Matrix - Send Notification
env:
NYM_NOTIFICATION_KIND: ts-packages
NYM_PROJECT_NAME: "ts-packages"
@@ -53,11 +54,12 @@ jobs:
NYM_CI_WWW_LOCATION: "ts-${{ 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-ts-packages"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+56 -44
View File
@@ -2,21 +2,44 @@ name: Continuous integration
on:
push:
paths-ignore:
- 'explorer/**'
paths:
- 'clients/**'
- 'common/**'
- 'explorer-api/**'
- 'gateway/**'
- 'integrations/**'
- 'mixnode/**'
- 'sdk/rust/nym-sdk/**'
- 'service-providers/**'
- 'nym-api/**'
- 'nym-outfox/**'
- 'tools/nym-cli/**'
- 'tools/ts-rs-cli/**'
pull_request:
paths-ignore:
- 'explorer/**'
paths:
- 'clients/**'
- 'common/**'
- 'explorer-api/**'
- 'gateway/**'
- 'integrations/**'
- 'mixnode/**'
- 'sdk/rust/nym-sdk/**'
- 'service-providers/**'
- 'nym-api/**'
- 'nym-outfox/**'
- 'tools/nym-cli/**'
- 'tools/ts-rs-cli/**'
jobs:
build:
runs-on: [ self-hosted, custom-linux ]
# Enable sccache via environment variable
# 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 libudev-dev squashfs-tools
continue-on-error: true
- name: Check out repository code
uses: actions/checkout@v2
@@ -29,57 +52,46 @@ jobs:
override: true
components: rustfmt, clippy
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --all-features
- 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: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace
- name: Build all examples
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --examples
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace
- 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 -- --ignored
- uses: actions-rs/clippy-check@v1
name: Clippy checks
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --workspace --all-features
args: --workspace
- 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: --workspace --all-targets -- -D warnings
+1 -1
View File
@@ -1,6 +1,6 @@
[
{
"os":"ubuntu-latest",
"os":"ubuntu-20.04",
"rust":"stable",
"runOnEvent":"always"
},
-72
View File
@@ -1,72 +0,0 @@
name: Continuous integration on dispatch
on: workflow_dispatch
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
- name: Check out repository code
uses: actions/checkout@v2
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --all-features
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- 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
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
@@ -0,0 +1,61 @@
name: check-merge-conflicts
# Check that the latest release branch merges into master and develop without
# any conflicts that git is not able to resolve
on:
workflow_dispatch:
schedule:
- cron: '5 6 * * *'
jobs:
get_release:
runs-on: ubuntu-latest
outputs:
output1: ${{ steps.step2.outputs.latest_release }}
steps:
- name: Check out repository code
uses: actions/checkout@v3
with:
fetch-depth: 0
- 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]+$' | sort -V | tail -n 1)" >> $GITHUB_OUTPUT
check-merge-release-into-master:
name: Check that the release branch merges into master
needs: get_release
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup git user
run: |
git config --global user.name "ci"
git config --global user.email "ci@localhost"
- name: Check merge release branch into master
run: |
./.github/workflows/support-files/git-merge-check.sh origin/master $branch1
env:
branch1: ${{needs.get_release.outputs.output1}}
check-merge-release-into-develop:
name: Check that the release branch merges into develop
needs: get_release
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Setup git user
run: |
git config --global user.name "ci"
git config --global user.email "ci@localhost"
- name: Check merge release branch into develop
run: |
./.github/workflows/support-files/git-merge-check.sh origin/develop $branch1
env:
branch1: ${{needs.get_release.outputs.output1}}
+56
View File
@@ -0,0 +1,56 @@
name: Run config checks on all binaries
on:
workflow_dispatch:
release:
types: [created]
push:
paths:
- 'clients/**'
- 'common/**'
- 'contracts/**'
- 'integrations/**'
- 'mixnode/**'
- 'sdk/rust/nym-sdk/**'
- 'service-providers/**'
pull_request:
paths:
- 'clients/**'
- 'common/**'
- 'gateway/**'
- 'integrations/**'
- 'mixnode/**'
- 'sdk/rust/nym-sdk/**'
- 'service-providers/**'
env:
NETWORK: mainnet
jobs:
publish-nym:
strategy:
fail-fast: false
matrix:
platform: [custom-runner-linux]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get -y install jq vim libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
continue-on-error: true
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Branch name
run: echo running on branch ${GITHUB_REF##*/}
- name: Run tests against binaries
run: ./build_and_run.sh ${{ github.head_ref || github.ref_name }}
working-directory: tests/
+138
View File
@@ -0,0 +1,138 @@
name: Nym Connect - Android APK Build
on:
workflow_dispatch:
push:
branches:
- "release/nc-android-v[0-9].[0-9].[0-9]*"
jobs:
build:
name: Build APK
runs-on: custom-runner-linux
env:
ANDROID_HOME: ${{ github.workspace }}/android-sdk
NDK_VERSION: 25.1.8937393
NDK_HOME: ${{ github.workspace }}/android-sdk/ndk/25.1.8937393
SDK_PLATFORM_VERSION: android-33
SDK_BUILDTOOLS_VERSION: 33.0.1
steps:
- name: Install Dependencies (Linux)
# https://next--tauri.netlify.app/next/guides/getting-started/prerequisites/linux/#1-system-dependencies
run: |
sudo apt-get update
sudo apt-get -y install \
build-essential \
unzip \
curl \
wget \
libssl-dev \
squashfs-tools \
librsvg2-dev
- name: Checkout
uses: actions/checkout@v3
- name: Install Java
uses: actions/setup-java@v3
with:
distribution: "temurin"
java-version: "17"
- name: Install Android SDK manager
# https://developer.android.com/studio/command-line/sdkmanager
run: |
curl -sS https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip -o cmdline-tools.zip
unzip cmdline-tools.zip
mkdir -p $ANDROID_HOME/cmdline-tools/latest
mv cmdline-tools/* $ANDROID_HOME/cmdline-tools/latest
rm -rf cmdline-tools
- name: Install Android S/NDK
run: |
echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses
echo y | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager \
"platforms;$SDK_PLATFORM_VERSION" \
"platform-tools" \
"ndk;$NDK_VERSION" \
"build-tools;$SDK_BUILDTOOLS_VERSION"
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
# TODO this step takes a considerable amount of time
# We could avoid to compile from source tauri-cli and use instead
# pre-compiled binary provided by the node package `@tauri-apps/cli`
# But when using the later the build fails for some reason
# so keep installing and using tauri-cli
- name: Install tauri cli
run: cargo install tauri-cli --version "^2.0.0-alpha.2"
- name: Install rust android targets
run: |
rustup target add aarch64-linux-android \
armv7-linux-androideabi \
i686-linux-android \
x86_64-linux-android
- name: Setup Nodejs
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install yarn
run: |
npm i -g yarn
yarn --version
- name: Build frontend code
run: |
yarn install --frozen-lockfile
yarn build
yarn workspace @nym/nym-connect-mobile webpack:prod
- name: Build APK
working-directory: nym-connect/mobile
env:
# NODE_TAURI_CLI=${{ github.workspace }}/nym-connect/mobile/node_modules/.bin/tauri
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
WRY_ANDROID_PACKAGE: net.nymtech.nym_connect
WRY_ANDROID_LIBRARY: nym_connect
# TODO build with release profile (--release), it will requires
# to sign the APK. For now build with debug profile to avoid that
# TODO build using `yarn tauri`, provide NODE_TAURI_CLI, see TODO notes above
run: cargo tauri android build --debug --apk --split-per-abi -t aarch64
# TODO add the version number to APK name
- name: Rename APK artifact
run: |
mkdir apk/
mv nym-connect/mobile/src-tauri/gen/android/nym_connect/app/build/outputs/apk/arm64/debug/app-arm64-debug.apk \
apk/nym-connect-arm64-debug.apk
mv nym-connect/mobile/src-tauri/gen/android/nym_connect/app/build/outputs/apk/x86_64/debug/app-x86_64-debug.apk \
apk/nym-connect-x86_64-debug.apk
- name: Upload APK artifact
uses: actions/upload-artifact@v3
with:
name: nc-apk-debug
path: |
apk/nym-connect-arm64-debug.apk
apk/nym-connect-x86_64-debug.apk
# publish:
# name: Publish APK
# needs: build
# runs-on: ubuntu-latest
# steps:
# - name: Checkout
# uses: actions/checkout@v3
# - name: Download binary artifact
# uses: actions/download-artifact@v3
# with:
# name: nc-apk-debug
# path: apk
# # TODO add a step to upload the APK somewhere
# - name: Publish
# uses: ???
@@ -1,13 +1,13 @@
name: CI for nym-connect
name: CI for nym-connect - Desktop
on:
push:
paths:
- 'nym-connect/**'
- 'nym-connect/desktop/**'
defaults:
run:
working-directory: nym-connect
working-directory: nym-connect/desktop
jobs:
build:
@@ -16,6 +16,7 @@ jobs:
- uses: actions/checkout@v2
- name: Install rsync
run: sudo apt-get install rsync
continue-on-error: true
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v3
with:
@@ -33,27 +34,28 @@ jobs:
env:
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "nym-connect/storybook-static/"
SOURCE: "nym-connect/desktop/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
- name: Matrix - 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
- name: Matrix - 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##*/}"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+75
View File
@@ -0,0 +1,75 @@
name: Nym Connect - desktop (Rust)
on:
push:
paths:
- "nym-connect/desktop/src-tauri/**"
- "nym-connect/desktop/src-tauri/Cargo.toml"
- "clients/client-core/**"
- "clients/socks5/**"
- "common/**"
- "gateway/gateway-requests/**"
- "contracts/vesting/**"
- "nym-api/nym-api-requests/**"
pull_request:
paths:
- "nym-connect/desktop/src-tauri/**"
- "nym-connect/desktop/src-tauri/Cargo.toml"
- "clients/client-core/**"
- "clients/socks5/**"
- "common/**"
- "gateway/gateway-requests/**"
- "contracts/vesting/**"
- "nym-api/nym-api-requests/**"
jobs:
build:
runs-on: [self-hosted, custom-linux]
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 libayatana-appindicator3-dev
continue-on-error: true
- name: Check out repository code
uses: actions/checkout@v2
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path nym-connect/desktop/Cargo.toml --workspace
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path nym-connect/desktop/Cargo.toml --workspace
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --manifest-path nym-connect/desktop/Cargo.toml --all -- --check
- uses: actions-rs/clippy-check@v1
name: Clippy checks
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --manifest-path nym-connect/desktop/Cargo.toml --workspace --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --manifest-path nym-connect/desktop/Cargo.toml --workspace --all-features -- -D warnings
+72
View File
@@ -0,0 +1,72 @@
name: Nym Connect - mobile (Rust)
on:
push:
paths:
- "nym-connect/mobile/src-tauri/**"
- "nym-connect/mobile/src-tauri/Cargo.toml"
- "!nym-connect/mobile/src-tauri/gen/**"
- "clients/client-core/**"
- "clients/socks5/**"
- "common/**"
- "gateway/gateway-requests/**"
- "contracts/vesting/**"
- "nym-api/nym-api-requests/**"
pull_request:
paths:
- "nym-connect/mobile/src-tauri/**"
- "nym-connect/mobile/src-tauri/Cargo.toml"
- "!nym-connect/mobile/src-tauri/gen/**"
- "clients/client-core/**"
- "clients/socks5/**"
- "common/**"
- "gateway/gateway-requests/**"
- "contracts/vesting/**"
- "nym-api/nym-api-requests/**"
jobs:
build:
#runs-on: [self-hosted, custom-linux]
runs-on: ubuntu-22.04
#env:
#RUSTC_WRAPPER: /home/ubuntu/.cargo/bin/sccache
#defaults:
#run:
#working-directory: nym-connect/mobile/src-tauri/
steps:
- name: Install Dependencies (Linux)
run: |
sudo apt-get update
sudo apt-get -y install \
libwebkit2gtk-4.1-dev \
build-essential \
curl \
wget \
libssl-dev \
libgtk-3-dev \
squashfs-tools \
libayatana-appindicator3-dev \
librsvg2-dev \
libsoup-3.0-dev \
libjavascriptcoregtk-4.1-dev
- name: Checkout
uses: actions/checkout@v3
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
components: clippy, rustfmt
- name: Check formatting
run: cargo fmt --manifest-path nym-connect/mobile/src-tauri/Cargo.toml -- --check
- name: Build all binaries
run: cargo build --manifest-path nym-connect/mobile/src-tauri/Cargo.toml
- name: Run all tests
run: cargo test --manifest-path nym-connect/mobile/src-tauri/Cargo.toml
- name: Clippy
run: cargo clippy --manifest-path nym-connect/mobile/src-tauri/Cargo.toml --all-targets -- -D warnings
-56
View File
@@ -1,56 +0,0 @@
name: Nym Connect (rust)
on:
push:
paths-ignore:
- 'explorer/**'
jobs:
build:
runs-on: [ self-hosted, custom-linux ]
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 libayatana-appindicator3-dev
- name: Check out repository code
uses: actions/checkout@v2
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path nym-connect/Cargo.toml --workspace
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path nym-connect/Cargo.toml --workspace
- name: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --manifest-path nym-connect/Cargo.toml --all -- --check
- uses: actions-rs/clippy-check@v1
name: Clippy checks
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --manifest-path nym-connect/Cargo.toml --workspace --all-features
- name: Run clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: --manifest-path nym-connect/Cargo.toml --workspace --all-features -- -D warnings
+14 -7
View File
@@ -1,17 +1,16 @@
name: Build release of Nym smart contracts
on:
workflow_dispatch:
defaults:
run:
working-directory: contracts
release:
types: [created]
jobs:
build:
runs-on: ubuntu-latest
if: ${{ startsWith(github.ref, 'refs/tags/nym-contracts-') && github.event_name == 'release' }}
runs-on: [self-hosted, custom-runner-linux]
steps:
- uses: actions/checkout@v2
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
@@ -21,7 +20,7 @@ jobs:
components: rustfmt, clippy
- name: Build release contracts
run: RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown
run: make wasm
- name: Upload Mixnet Contract Artifact
uses: actions/upload-artifact@v3
@@ -36,3 +35,11 @@ jobs:
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
+7 -5
View File
@@ -2,15 +2,17 @@ name: Contracts
on:
push:
paths-ignore:
- 'explorer/**'
paths:
- 'contracts/**'
- 'common/**'
pull_request:
paths-ignore:
- 'explorer/**'
- 'contracts/**'
- 'common/**'
jobs:
matrix_prep:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
@@ -24,7 +26,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,57 @@
name: CI for Network Explorer API
on:
workflow_dispatch:
release:
types: [created]
env:
NETWORK: mainnet
jobs:
publish-nym:
if: ${{ startsWith(github.ref, 'refs/tags/nym-explorer-api-') && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') }}
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
continue-on-error: true
- name: Check the release tag starts with `nym-explorer-api-`
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
+8 -6
View File
@@ -17,6 +17,7 @@ jobs:
- uses: actions/checkout@v2
- name: Install rsync
run: sudo apt-get install rsync
continue-on-error: true
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v3
with:
@@ -56,10 +57,10 @@ jobs:
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/ne-sb-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/"
- name: Keybase - Node Install
- name: Matrix - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
- name: Matrix - Send Notification
env:
NYM_NOTIFICATION_KIND: network-explorer
NYM_PROJECT_NAME: "Network Explorer"
@@ -68,11 +69,12 @@ jobs:
NYM_CI_WWW_LOCATION_STORYBOOK: "ne-sb-${{ 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-network-explorer"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+47 -59
View File
@@ -5,12 +5,12 @@ on:
- cron: '14 1 * * *'
jobs:
matrix_prep:
runs-on: ubuntu-latest
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@v2
- uses: actions/checkout@v3
- id: set-matrix
uses: JoshuaTheMiller/conditional-build-matrix@main
with:
@@ -25,10 +25,11 @@ jobs:
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-latest'
continue-on-error: true
if: matrix.os == 'ubuntu-20.04'
- name: Check out repository code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install rust toolchain
uses: actions-rs/toolchain@v1
@@ -38,15 +39,33 @@ 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:
command: build
args: --workspace
- 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
- name: Build all examples
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --examples
- name: Reclaim some disk space
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
with:
command: clean
@@ -56,9 +75,9 @@ jobs:
command: test
args: --workspace
- 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
@@ -67,25 +86,20 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace --all-features -- --ignored
args: --workspace -- --ignored
- name: Check formatting
- name: Reclaim some disk space
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' }}
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
with:
command: clean
- uses: actions-rs/clippy-check@v1
name: Clippy checks
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
args: --workspace
- name: Run clippy
uses: actions-rs/cargo@v1
@@ -96,42 +110,10 @@ jobs:
- name: Reclaim some disk space
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-latest' }}
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
@@ -160,17 +142,22 @@ jobs:
notification:
needs: build
runs-on: ubuntu-latest
runs-on: custom-runner-linux
steps:
- name: Collect jobs status
uses: technote-space/workflow-conclusion-action@v2
- name: Check out repository code
uses: actions/checkout@v2
- name: Keybase - Node Install
uses: actions/checkout@v3
- name: install npm
uses: actions/setup-node@v3
if: env.WORKFLOW_CONCLUSION == 'failure'
with:
node-version: 16
- name: Matrix - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
- name: Matrix - Send Notification
if: env.WORKFLOW_CONCLUSION == 'failure'
env:
NYM_NOTIFICATION_KIND: nightly
@@ -178,11 +165,12 @@ jobs:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
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-nightly"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM_NIGHTLY }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
@@ -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"
},
@@ -1,50 +0,0 @@
[
{
"os":"ubuntu-latest",
"rust":"stable",
"runOnEvent":"workflow_dispatch"
},
{
"os":"windows-latest",
"rust":"stable",
"runOnEvent":"workflow_dispatch"
},
{
"os":"macos-latest",
"rust":"stable",
"runOnEvent":"workflow_dispatch"
},
{
"os":"ubuntu-latest",
"rust":"beta",
"runOnEvent":"workflow_dispatch"
},
{
"os":"windows-latest",
"rust":"beta",
"runOnEvent":"workflow_dispatch"
},
{
"os":"macos-latest",
"rust":"beta",
"runOnEvent":"workflow_dispatch"
},
{
"os":"ubuntu-latest",
"rust":"nightly",
"runOnEvent":"workflow_dispatch"
},
{
"os":"windows-latest",
"rust":"nightly",
"runOnEvent":"workflow_dispatch"
},
{
"os":"macos-latest",
"rust":"nightly",
"runOnEvent":"workflow_dispatch"
}
]
+191
View File
@@ -0,0 +1,191 @@
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]+$' | sort -V | 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
continue-on-error: true
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: Check formatting
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Build all binaries
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace
- name: Reclaim some disk space
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
with:
command: clean
- name: Build all examples
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --examples
- name: Reclaim some disk space
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
with:
command: clean
- name: Run all tests
uses: actions-rs/cargo@v1
with:
command: test
args: --workspace
- name: Reclaim some disk space
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
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 -- --ignored
- name: Reclaim some disk space
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
with:
command: clean
- uses: actions-rs/clippy-check@v1
name: Clippy checks
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --workspace
- 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
# 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: custom-runner-linux
steps:
- name: Collect jobs status
uses: technote-space/workflow-conclusion-action@v2
- name: Check out repository code
uses: actions/checkout@v3
- name: install npm
uses: actions/setup-node@v3
if: env.WORKFLOW_CONCLUSION == 'failure'
with:
node-version: 16
- name: Matrix - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - 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}}"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM_NIGHTLY }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
@@ -1,32 +1,50 @@
name: Nightly builds on dispatch
name: Nightly builds on second latest release
on: workflow_dispatch
on:
schedule:
- cron: '24 2 * * *'
jobs:
matrix_prep:
runs-on: ubuntu-latest
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@v2
- uses: actions/checkout@v3
- id: set-matrix
uses: JoshuaTheMiller/conditional-build-matrix@main
with:
inputFile: '.github/workflows/nightly_build_matrix_on_dispatch.json'
inputFile: '.github/workflows/nightly_build_matrix_includes.json'
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
build:
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]+$' | sort -V | 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 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
continue-on-error: true
if: matrix.os == 'ubuntu-20.04'
- name: Check out repository code
uses: actions/checkout@v2
- 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
@@ -36,12 +54,36 @@ 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:
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: Build all examples
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --examples
- 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:
@@ -50,7 +92,7 @@ jobs:
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' }}
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-20.04' }}
with:
command: clean
@@ -59,13 +101,7 @@ jobs:
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
args: --workspace -- --ignored
- name: Reclaim some disk space (because Windows is being annoying)
uses: actions-rs/cargo@v1
@@ -75,9 +111,10 @@ jobs:
- uses: actions-rs/clippy-check@v1
name: Clippy checks
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features
args: --workspace
- name: Run clippy
uses: actions-rs/cargo@v1
@@ -88,36 +125,10 @@ jobs:
- name: Reclaim some disk space
uses: actions-rs/cargo@v1
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-latest' }}
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: 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
@@ -145,30 +156,36 @@ jobs:
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-targets -- -D warnings
notification:
needs: build
runs-on: ubuntu-latest
needs: [build,get_release]
runs-on: custom-runner-linux
steps:
- name: Collect jobs status
uses: technote-space/workflow-conclusion-action@v2
- name: Check out repository code
uses: actions/checkout@v2
- name: Keybase - Node Install
uses: actions/checkout@v3
- name: install npm
uses: actions/setup-node@v3
if: env.WORKFLOW_CONCLUSION == 'failure'
with:
node-version: 16
- name: Matrix - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
- name: Matrix - Send Notification
if: env.WORKFLOW_CONCLUSION == 'failure'
env:
NYM_NOTIFICATION_KIND: nightly
NYM_PROJECT_NAME: "Nym nightly build"
NYM_PROJECT_NAME: "Nym nightly build on latest release"
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
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_NYMTECH_TEAM }}"
KEYBASE_NYM_CHANNEL: "${{ secrets.KEYBASE_CHANNEL_DEV_CORE_ID }}"
GIT_BRANCH_NAME: "${{needs.get_release.outputs.output1}}"
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM_NIGHTLY }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+2 -2
View File
@@ -10,17 +10,17 @@ env:
jobs:
publish-nym-cli:
if: ${{ startsWith(github.ref, 'refs/tags/nym-cli-') && (github.event_name == 'release' || github.event_name == 'workflow_dispatch') }}
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest, windows-latest, macos-latest]
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: |
@@ -1,4 +1,4 @@
name: Publish Nym Connect (MacOS)
name: Publish Nym Connect - desktop (MacOS)
on:
workflow_dispatch:
release:
@@ -6,10 +6,11 @@ on:
defaults:
run:
working-directory: nym-connect
working-directory: nym-connect/desktop
jobs:
publish-tauri:
if: ${{ startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release' }}
strategy:
fail-fast: false
matrix:
@@ -19,13 +20,6 @@ jobs:
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:
@@ -79,7 +73,7 @@ jobs:
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
path: nym-connect/desktop/target/release/bundle/dmg/nym-connect_1.0.0_x64.dmg
retention-days: 30
- name: Clean up keychain
@@ -92,5 +86,5 @@ jobs:
if: github.event_name == 'release'
with:
files: |
nym-connect/target/release/bundle/dmg/*.dmg
nym-connect/target/release/bundle/macos/*.app.tar.gz*
nym-connect/desktop/target/release/bundle/dmg/*.dmg
nym-connect/desktop/target/release/bundle/macos/*.app.tar.gz*
@@ -1,4 +1,4 @@
name: Publish Nym Connect (Ubuntu)
name: Publish Nym Connect - desktop (Ubuntu)
on:
workflow_dispatch:
release:
@@ -6,14 +6,15 @@ on:
defaults:
run:
working-directory: nym-connect
working-directory: nym-connect/desktop
jobs:
publish-tauri:
if: ${{ startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release' }}
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]
platform: [custom-runner-linux]
runs-on: ${{ matrix.platform }}
steps:
@@ -23,17 +24,13 @@ jobs:
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-...')
continue-on-error: true
- name: Node v16
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
@@ -56,7 +53,7 @@ jobs:
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
path: nym-connect/desktop/target/release/bundle/appimage/nym-connect_1.0.0_amd64.AppImage
retention-days: 30
- name: Upload to release based on tag name
@@ -64,5 +61,5 @@ jobs:
if: github.event_name == 'release'
with:
files: |
nym-connect/target/release/bundle/appimage/*.AppImage
nym-connect/target/release/bundle/appimage/*.AppImage.tar.gz*
nym-connect/desktop/target/release/bundle/appimage/*.AppImage
nym-connect/desktop/target/release/bundle/appimage/*.AppImage.tar.gz*
@@ -1,4 +1,4 @@
name: Publish Nym Connect (Windows 10)
name: Publish Nym Connect - desktop (Windows 10)
on:
workflow_dispatch:
release:
@@ -6,10 +6,11 @@ on:
defaults:
run:
working-directory: nym-connect
working-directory: nym-connect/desktop
jobs:
publish-tauri:
if: ${{ (startsWith(github.ref, 'refs/tags/nym-connect-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
strategy:
fail-fast: false
matrix:
@@ -27,13 +28,6 @@ jobs:
- 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 }}
@@ -62,7 +56,7 @@ jobs:
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Install app dependencies
run: yarn
run: yarn --network-timeout 100000
- name: Build and sign it
env:
@@ -78,7 +72,7 @@ jobs:
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
path: nym-connect/desktop/target/release/bundle/msi/nym-connect_1.0.0_x64_en-US.msi
retention-days: 30
- name: Upload to release based on tag name
@@ -86,5 +80,5 @@ jobs:
if: github.event_name == 'release'
with:
files: |
nym-connect/target/release/bundle/msi/*.msi
nym-connect/target/release/bundle/msi/*.msi.zip*
nym-connect/desktop/target/release/bundle/msi/*.msi
nym-connect/desktop/target/release/bundle/msi/*.msi.zip*
+9 -9
View File
@@ -16,21 +16,19 @@ env:
jobs:
publish-nym:
if: ${{ startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release' }}
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]
platform: [custom-runner-linux]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v3
- name: Check the release tag starts with `nym-binaries-`
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: 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
continue-on-error: true
- name: Sets env vars for tokio if set in manual dispatch inputs
run: |
@@ -53,11 +51,12 @@ jobs:
with:
name: my-artifact
path: |
target/release/explorer-api
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-api
target/release/nym-network-requester
target/release/nym-network-statistics
target/release/nym-cli
@@ -68,11 +67,12 @@ jobs:
if: github.event_name == 'release'
with:
files: |
target/release/explorer-api
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-api
target/release/nym-network-requester
target/release/nym-network-statistics
target/release/nym-cli
@@ -10,6 +10,7 @@ defaults:
jobs:
publish-tauri:
if: ${{ startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release' }}
strategy:
fail-fast: false
matrix:
@@ -19,13 +20,6 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Check the release tag starts with `nym-wallet-`
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@v3
with:
@@ -9,10 +9,11 @@ defaults:
jobs:
publish-tauri:
if: ${{ startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release' }}
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]
platform: [custom-runner-linux]
runs-on: ${{ matrix.platform }}
steps:
@@ -22,17 +23,13 @@ jobs:
run: >
sudo apt-get update &&
sudo apt-get install -y webkit2gtk-4.0
- name: Check the release tag starts with `nym-wallet-`
if: startsWith(github.ref, 'refs/tags/nym-wallet-') == false
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-wallet-...')
continue-on-error: true
- name: Node v16
uses: actions/setup-node@v3
with:
node-version: 16
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
@@ -1,5 +1,6 @@
name: Publish Nym Wallet (Windows 10)
on:
workflow_dispatch:
release:
types: [created]
@@ -9,6 +10,7 @@ defaults:
jobs:
publish-tauri:
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
strategy:
fail-fast: false
matrix:
@@ -26,13 +28,6 @@ jobs:
- uses: actions/checkout@v3
- name: Check the release tag starts with `nym-wallet-`
if: startsWith(github.ref, 'refs/tags/nym-wallet-') == false
uses: actions/github-script@v3
with:
script: |
core.setFailed('Release tag did not start with nym-wallet-...')
- name: Import signing certificate
env:
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
@@ -61,7 +56,7 @@ jobs:
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Install app dependencies
run: yarn
run: yarn --network-timeout 100000
- name: Build and sign it
env:
@@ -73,8 +68,16 @@ jobs:
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
run: yarn build
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: nym-wallet_1.0.0_x64_en-US.msi
path: nym-wallet/target/release/bundle/msi/nym-wallet_1.*.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-wallet/target/release/bundle/msi/*.msi
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest]
platform: [ubuntu-20.04]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
+8 -6
View File
@@ -12,6 +12,7 @@ jobs:
- uses: actions/checkout@v2
- name: Install rsync
run: sudo apt-get install rsync
continue-on-error: true
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v3
with:
@@ -34,10 +35,10 @@ jobs:
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/wallet-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/"
- name: Keybase - Node Install
- name: Matrix - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Keybase - Send Notification
- name: Matrix - Send Notification
env:
NYM_NOTIFICATION_KIND: nym-wallet
NYM_PROJECT_NAME: "nym-wallet"
@@ -45,11 +46,12 @@ jobs:
NYM_CI_WWW_LOCATION: "wallet-${{ 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-wallet"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
+2 -1
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
@@ -26,6 +26,7 @@ jobs:
libappindicator3-dev
webkit2gtk-driver
xvfb
continue-on-error: true
- name: Install minimal stable
uses: actions-rs/toolchain@v1
+36
View File
@@ -0,0 +1,36 @@
name: CI for Nym API Tests
on:
workflow_dispatch:
push:
paths:
- "nym-api/**"
defaults:
run:
working-directory: nym-api/tests
jobs:
test:
name: nym-api tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install npm
run: npm install
- name: Node v18
uses: actions/setup-node@v3
with:
node-version: 18.1.0
- name: Install yarn
run: yarn install
- name: Run yarn
run: yarn
- name: Run tests
run: yarn test:qa
working-directory: nym-api/tests
+7 -4
View File
@@ -1,6 +1,9 @@
KEYBASE_NYM_CHANNEL=
KEYBASE_NYMBOT_USERNAME=
KEYBASE_NYMBOT_PAPERKEY=
MATRIX_SERVER=
MATRIX_ROOM=
MATRIX_ROOM_OF_SHAME=
MATRIX_USER_ID=
MATRIX_TOKEN=
MATRIX_DEVICE_ID=
NYM_NOTIFICATION_KIND=nightly
NYM_PROJECT_NAME=Nightly Build
@@ -32,4 +35,4 @@ NYM_CI_WWW_BASE=example.com
# Nightly builds
WORKFLOW_CONCLUSION=success
SHOW_DEBUG=true
SHOW_DEBUG=true
+3 -1
View File
@@ -2,4 +2,6 @@ node_modules
.idea
# don't commit the lock file to avoid cross-platform issues
package-lock.json
package-lock.json
scratch
+10 -9
View File
@@ -4,7 +4,7 @@ This is a collection of scripts and files to support GitHub Actions.
## Sending Notifications
These scripts send CI notifications to Keybase by creating messages from templates and env vars passed from GitHub Actions.
These scripts send CI notifications to Matrix by creating messages from templates and env vars passed from GitHub Actions.
### Adding notifications to a GitHub Action
@@ -19,10 +19,11 @@ jobs:
env:
NYM_NOTIFICATION_KIND: "my-component"
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-network-explorer"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
IS_SUCCESS: "${{ job.status == 'success' }}"
uses: docker://keybaseio/client:stable-node
with:
@@ -34,8 +35,8 @@ Notifications are run by adding the snippet above to a GitHub Action, and:
1. Installing node packages needed at run time
2. Set the env vars as required:
- `NYM_NOTIFICATION_KIND` matches the directory in `.github/workflows/support-files/${NYM_NOTIFICATION_KIND}` to provide the templates and extra scripting in `index.js`
- Keybase credentials, channel and other env vars for the status of the build and repo
3. Replacing the default entry point shell script on the `keybaseio/client:stable-node` docker image to run `.github/workflows/support-files/notifications/entry_point.sh`
- Matrix credentials, room and other env vars for the status of the build and repo
3. Replacing the default entry point shell script on the `keybaseio/client:stable-node` docker image to run `.github/workflows/support-files/notifications/entry_point.sh`
### Running locally
@@ -43,7 +44,7 @@ You will need:
- Node 16 LTS
- npm
Copy `.github/workflows/support-files/.env.example` to `.github/workflows/support-files/.env` and valid Keybase credentials.
Copy `.github/workflows/support-files/.env.example` to `.github/workflows/support-files/.env` and valid Matrix credentials.
Then run `npm install` to get dependencies.
@@ -55,4 +56,4 @@ npm install
cp .env.example .env
vi .env
npm run dev
```
```
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
#
# Basic usage:
# ./git-merge-check origin/develop origin/release/v1.1.9
#
set -x
set -o nounset
set -o pipefail
# Start from branch ...
branch1=$1
# ... and try to merge in
branch2=$2
echo "Checking if $branch2 merges without conflicts into $branch1..."
git checkout -q $branch1 || exit 1
# There are two options here as far as I see on what we should check for. Either
#
# (A) check for CONFLICT in any file except whitelist (such as .lock files)
# (B) check for "Automatic merge failed"
#
# Both of these options have drawbacks.
#
# The first (A) has the problem in that maybe we don't want to fail if the
# changes can be automatically merged (duh), but at least we are not pestered
# about constant lock file changes.
# The second (B) has the problem that it's difficult to filter out automatic
# merge fails for files we don't care about (.lock files).
#
# The ideal solution would be to check for automatic merge fails for files
# except those on a whitelist (e.g. lock files).
# For now I choose to use (B) here, because I hope it might be less noisy
# Alternative A
#output=$(git merge --no-commit --no-ff $branch2 | grep -v .lock)
#merge_failed=$(echo $output | grep -v "CONFLICT")
#return_code=$?
# Alternative B
output=$(git merge --no-commit --no-ff $branch2)
merge_failed=$(echo $output | grep -v "Automatic merge failed")
return_code=$?
# Restore
git merge --abort
git checkout -q -
if [ $return_code -eq 0 ]; then
echo "Merge check success"
else
echo "Merge check failed"
fi
exit $return_code
@@ -1,9 +1,14 @@
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
> :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:
```
@@ -1,10 +1,16 @@
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
> :rocket: {{ env.NYM_PROJECT_NAME }} ➡️➡️➡️➡️➡️ **View output:** https://{{ env.NYM_CI_WWW_LOCATION }}.{{ env.NYM_CI_WWW_BASE }}/
>
> `storybook`: https://{{ env.NYM_CI_WWW_LOCATION_STORYBOOK }}.{{ 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 }}:
```
@@ -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,
@@ -151,7 +151,7 @@ async function getMessageBody(context) {
return `${icon} ${job.conclusion}: ${job.name} - ${job.html_url}`;
})
// and join with newlines for display in the template
.join('\n');
.join('\n\n');
return template({ ...context, jobResults });
}
@@ -1,9 +1,15 @@
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
> :rocket: {{ env.NYM_PROJECT_NAME }}
>
> 🔴 **FAILURE** :cry:
>
> `when` {{ timestamp }}
>
> `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 }}
>
{{ jobResults }}
@@ -1,9 +1,15 @@
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
> :rocket: {{ env.NYM_PROJECT_NAME }}
>
> ✅ **SUCCESS**
>
> `when` {{ timestamp }}
>
> `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 }}
>
{{ jobResults }}
{{ jobResults }}
@@ -1,6 +1,6 @@
require('dotenv').config();
const Bot = require('keybase-bot');
const { sendMatrixMessage } = require('./send_message_to_matrix');
let context = {
kinds: ['nym-wallet', 'ts-packages', 'network-explorer', 'nightly', 'nym-connect','security'],
@@ -23,20 +23,27 @@ function validateContext() {
'Please set env var NYM_PROJECT_NAME with the project name for displaying in notification messages',
);
}
if (!context.env.KEYBASE_NYM_CHANNEL) {
throw new Error(
'Please set env var KEYBASE_NYM_CHANNEL with the channel name for the notification message',
);
}
if (!context.env.KEYBASE_NYMBOT_USERNAME) {
throw new Error(
'Username is not defined. Please set env var KEYBASE_NYMBOT_USERNAME',
);
}
if (!context.env.KEYBASE_NYMBOT_PAPERKEY) {
throw new Error(
'Paperkey is not defined. Please set env var KEYBASE_NYMBOT_PAPERKEY',
);
if (context.env.MATRIX_ROOM) {
if (!context.env.MATRIX_SERVER) {
throw new Error(
'Matrix server is not defined. Please set env var MATRIX_SERVER',
);
}
if (!context.env.MATRIX_USER_ID) {
throw new Error(
'Matrix user id is not defined. Please set env var MATRIX_USER_ID',
);
}
if (!context.env.MATRIX_TOKEN) {
throw new Error(
'Matrix token is not defined. Please set env var MATRIX_TOKEN',
);
}
if (!context.env.MATRIX_DEVICE_ID) {
throw new Error(
'Matrix device id is not defined. Please set env var MATRIX_DEVICE_ID',
);
}
}
}
@@ -61,12 +68,6 @@ function createTemplateContext() {
context.kind = context.env.NYM_NOTIFICATION_KIND;
context.keybase = {
channel: context.env.KEYBASE_NYM_CHANNEL,
username: context.env.KEYBASE_NYMBOT_USERNAME,
paperkey: context.env.KEYBASE_NYMBOT_PAPERKEY,
};
if (!context.env.GIT_BRANCH_NAME) {
context.env.GIT_BRANCH_NAME = context.env.GITHUB_REF.split('/')
.slice(2)
@@ -76,40 +77,6 @@ function createTemplateContext() {
context.status = process.env.IS_SUCCESS === 'true' ? 'success' : 'failure';
}
async function sendKeybaseMessage(messageBody) {
const bot = new Bot();
try {
console.log(
`Initialising keybase with user "${
context.keybase.username
}" and key: "${'*'.repeat(context.keybase.paperkey.length)}"...`,
);
await bot.init(context.keybase.username, context.keybase.paperkey, {
verbose: false,
});
const channel = {
name: context.env.KEYBASE_NYMBOT_TEAM || 'nymtech_bot',
membersType: 'team',
topicName: context.keybase.channel,
topic_type: 'CHAT',
};
const message = {
body: messageBody,
};
console.log(`Sending to ${channel.name}#${channel.topicName}...`);
await bot.chat.send(channel, message);
console.log('Message sent!');
} catch (error) {
console.error(error);
process.exitCode = -1;
} finally {
await bot.deinit();
}
}
/**
* Uses the `kind` set in the context to process the context and generate a notification message
* @returns {Promise<string>} A string notification message body
@@ -146,7 +113,13 @@ async function main() {
console.log(messageBody);
console.log('-----------------------------------------');
}
await sendKeybaseMessage(messageBody);
if(context.env.MATRIX_ROOM) {
await sendMatrixMessage(context, messageBody, context.env.MATRIX_ROOM)
}
if(context.env.MATRIX_ROOM_OF_SHAME && context.env.IS_SUCCESS !== 'true') {
// when a job fails
await sendMatrixMessage(context, messageBody, context.env.MATRIX_ROOM_OF_SHAME)
}
}
// call main function and let NodeJS handle the promise
@@ -0,0 +1,67 @@
const sdk = require('matrix-js-sdk');
global.Olm = require('olm');
const { LocalStorage } = require('node-localstorage');
const localStorage = new LocalStorage('./scratch');
const {
LocalStorageCryptoStore,
} = require('matrix-js-sdk/lib/crypto/store/localStorage-crypto-store');
var showdown = require('showdown');
// hide all matrix client output
console.error = (error) => console.log('❌ error: ', error);
process.stderr.write = () => {};
process.stdout.write = () => {};
function createClient(context, room, message) {
const server = context.env.MATRIX_SERVER;
const token = context.env.MATRIX_TOKEN;
const deviceId = context.env.MATRIX_DEVICE_ID;
const userId = context.env.MATRIX_USER_ID;
const client = sdk.createClient({
baseUrl: server,
accessToken: token,
userId,
deviceId,
sessionStore: new sdk.WebStorageSessionStore(localStorage),
cryptoStore: new LocalStorageCryptoStore(localStorage),
});
client.on('sync', async function(state, prevState, res) {
if (state !== 'PREPARED') return;
client.setGlobalErrorOnUnknownDevices(false);
try {
await client.joinRoom(room);
await client.sendEvent(
room,
'm.room.message',
{
msgtype: 'm.text',
format: 'org.matrix.custom.html',
body: message,
formatted_body: message,
},
'',
);
} catch (error) {
console.error('Job failed: ' + error.message);
}
client.stopClient();
process.exit(0);
});
return client;
}
async function sendMatrixMessage(contextArg, messageAsMarkdown, roomId) {
const converter = new showdown.Converter();
const messageAsHtml = converter.makeHtml(messageAsMarkdown);
const client = createClient(contextArg, roomId, messageAsHtml);
await client.initCrypto();
await client.startClient({ initialSyncLimit: 1 });
}
module.exports = {
sendMatrixMessage,
};
@@ -1,9 +1,14 @@
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
> :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:
```
@@ -1,9 +1,14 @@
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
> :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 }}:
```
@@ -1,9 +1,14 @@
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
> :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:
```
@@ -1,13 +1,18 @@
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
> :rocket: {{ env.NYM_PROJECT_NAME }}
>
> ✅ **SUCCESS**
>
> ➡️➡️➡️➡️➡️ **View output:**
>
> `storybook`: https://{{ env.NYM_CI_WWW_LOCATION }}.{{ env.NYM_CI_WWW_BASE }}
>
> `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 }}:
```
+12 -4
View File
@@ -1,6 +1,6 @@
{
"name": "send-keybase-message",
"description": "Sends a notification message with the keybase package that fails when piped into the keybase CLI",
"name": "send-matrix-message",
"description": "Sends a notification message with the matrix sdk",
"version": "1.0.0",
"private": true,
"scripts": {
@@ -10,8 +10,16 @@
"dependencies": {
"dotenv": "^16.0.0",
"handlebars": "^4.7.7",
"keybase-bot": "^3.6.1",
"octokit": "^1.7.1"
"matrix-js-sdk": "^9.3.0",
"node-localstorage": "^2.1.6",
"octokit": "^1.7.1",
"olm": "https://packages.matrix.org/npm/olm/olm-3.2.1.tgz",
"remark-emoji": "^2.2.0",
"remark-html": "^13.0.2",
"remark-parse": "^9.0.0",
"showdown": "^2.1.0",
"to-vfile": "^6.1.0",
"unified": "^9.2.2"
},
"devDependencies": {
"prettier": "2.3.2"
@@ -1,9 +1,14 @@
🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥
> :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:
```
@@ -1,14 +1,20 @@
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩
> :rocket: {{ env.NYM_PROJECT_NAME }}
>
> ✅ **SUCCESS**
>
> ➡️➡️➡️➡️➡️ **View output:**
>
> `storybook`: https://{{ env.NYM_CI_WWW_LOCATION }}.{{ env.NYM_CI_WWW_BASE }}
>
> `example`: https://{{ env.NYM_CI_WWW_LOCATION }}-example.{{ env.NYM_CI_WWW_BASE }}
>
> `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 }}:
```
+46
View File
@@ -0,0 +1,46 @@
name: tag-and-release
on:
workflow_dispatch:
inputs:
nym_binaries_version:
description: 'Version of the nym-binaries tag'
required: false
type: string
nym_wallet_version:
description: 'Version of the nym-wallet tag'
required: false
type: string
nym_connect_version:
description: 'Version of the nym-connect tag'
required: false
type: string
jobs:
tag-components:
uses: nymtech/reusable-workflows/.github/workflows/tag-components.yml@master
with:
nym_binaries_version: ${{ input.nym_binaries_version }}
nym_wallet_version: ${{ input.nym_wallet_version }}
nym_connect_version: ${{ input.nym_connect_version }}
create-nym-binaries-release:
if: ${{ input.nym_binaries_version }}
uses: nymtech/reusable-workflows/.github/workflows/create-binaries-release.yml@master
with:
version: ${{ input.nym_binaries_version }}
needs: ["tag-components"]
create-nym-wallet-release:
if: ${{ input.nym_wallet_version }}
uses: nymtech/reusable-workflows/.github/workflows/create-wallet-release.yml@master
with:
version: ${{ input.nym_wallet_version }}
needs: ["tag-components"]
create-nym-connect-release:
if: ${{ input.nym_connect_version }}
uses: nymtech/reusable-workflows/.github/workflows/create-connect-release.yml@master
with:
version: ${{ input.nym_connect_version }}
needs: ["tag-components"]
+64
View File
@@ -0,0 +1,64 @@
name: CI for linting Typescript
on:
push:
paths:
- 'ts-packages/**'
- 'sdk/typescript/**'
- 'nym-connect/desktop/src/**'
- 'nym-connect/desktop/package.json'
- 'nym-connect/mobile/src/**'
- 'nym-connect/mobile/package.json'
- 'nym-wallet/src/**'
- 'nym-wallet/package.json'
pull_request:
paths:
- 'ts-packages/**'
- 'sdk/typescript/**'
- 'nym-connect/desktop/src/**'
- 'nym-connect/desktop/package.json'
- 'nym-connect/mobile/src/**'
- 'nym-connect/mobile/package.json'
- 'nym-wallet/src/**'
- 'nym-wallet/package.json'
jobs:
build:
runs-on: custom-runner-linux
steps:
- uses: actions/checkout@v2
- name: Install rsync
run: sudo apt-get install rsync
continue-on-error: true
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v3
with:
node-version: 16
- name: Setup yarn
run: npm install -g yarn
- name: Install
run: yarn
- name: Build packages
run: yarn build
- name: Lint
run: yarn lint && yarn tsc
- name: Matrix - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
env:
NYM_NOTIFICATION_KIND: ts-packages
NYM_PROJECT_NAME: "ts-packages"
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
NYM_CI_WWW_LOCATION: "ts-${{ env.GITHUB_REF_SLUG }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}"
IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node
with:
args: .github/workflows/support-files/notifications/entry_point.sh
@@ -0,0 +1,95 @@
name: update-versions-and-changelog
on:
workflow_dispatch:
inputs:
release_version:
description: "Release version, usually the milestone title"
required: true
type: string
milestone_id:
description: "Milestone ID, check the URL when you're on the specific milestone page"
required: true
type: string
env:
CI_BOT_AUTHOR: "Nym bot"
CI_BOT_EMAIL: "nym-bot@users.noreply.github.com"
jobs:
update-versions:
runs-on: ubuntu-22.04
steps:
- name: checkout-source
uses: actions/checkout@v3
with:
ref: "release/${{ inputs.release_version }}"
path: "nym"
- name: checkout-ci-tools-repo
uses: actions/checkout@v3
with:
repository: "nymtech/ci-tools"
ref: "master"
path: "ci-tools"
token: "${{ secrets.ACCESS_TOKEN_PRIVATE_REPOS }}"
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: install-version-bumper
run: "cargo install --path ."
working-directory: "ci-tools/version-bumper"
- name: run-version-bumper
run: "version-bumper bump binaries --nym-repo-directory nym"
- name: push-changes-to-branch
run: |
git config --global user.name "${{ env.CI_BOT_AUTHOR }}"
git config --global user.email "${{ env.CI_BOT_EMAIL }}"
git checkout -b release/${{ inputs.release_version }}-preparation
git commit -am "chore: version bump in preparation for release"
git push -u origin release/${{ inputs.release_version }}-preparation
working-directory: "nym"
update-changelog:
runs-on: ubuntu-22.04
needs: [update-versions]
steps:
- name: checkout-source
uses: actions/checkout@v3
with:
ref: "release/${{ inputs.release_version }}"
path: "nym"
- name: checkout-ci-tools-repo
uses: actions/checkout@v3
with:
repository: "nymtech/ci-tools"
ref: "master"
path: "ci-tools"
token: "${{ secrets.ACCESS_TOKEN_PRIVATE_REPOS }}"
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: install-changelog-updater
run: "cargo install --path ."
working-directory: "ci-tools/changelog-updater"
- name: run-changelog-updater
run: "changelog-updater mix ${{ inputs.milestone_id }} release/${{ inputs.release_version }}"
- name: push-changes-to-branch
run: |
git config --global user.name "${{ env.CI_BOT_AUTHOR }}"
git config --global user.email "${{ env.CI_BOT_EMAIL }}"
git checkout release/${{ inputs.release_version }}-preparation
git commit -am "chore: update changelog preparation for release"
git push
working-directory: "nym"
+12 -4
View File
@@ -2,11 +2,17 @@ name: Nym Wallet (rust)
on:
push:
paths-ignore:
- 'explorer/**'
paths:
- 'nym-wallet/**'
- 'common/**'
- 'contracts/vesting/**'
- 'nym-api/nym-api-requests/**'
pull_request:
paths-ignore:
- 'explorer/**'
paths:
- 'nym-wallet/**'
- 'common/**'
- 'contracts/vesting/**'
- 'nym-api/nym-api-requests/**'
jobs:
build:
@@ -16,6 +22,7 @@ jobs:
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
continue-on-error: true
- name: Check out repository code
uses: actions/checkout@v2
@@ -48,6 +55,7 @@ jobs:
- uses: actions-rs/clippy-check@v1
name: Clippy checks
continue-on-error: true
with:
token: ${{ secrets.GITHUB_TOKEN }}
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-features
+8 -13
View File
@@ -2,12 +2,17 @@ name: Wasm Client
on:
pull_request:
paths-ignore:
- 'explorer/**'
paths:
- 'clients/webassembly/**'
- 'clients/client-core/**'
- 'common/**'
- 'contracts/**'
- 'gateway/gateway-requests/**'
- 'nym-api/nym-api-requests/**'
jobs:
wasm:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
@@ -24,16 +29,6 @@ jobs:
command: build
args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown
- uses: actions-rs/cargo@v1
with:
command: build
args: --manifest-path clients/webassembly/Cargo.toml --target wasm32-unknown-unknown --features=coconut
- uses: actions-rs/cargo@v1
with:
command: test
args: --manifest-path clients/webassembly/Cargo.toml
- uses: actions-rs/cargo@v1
with:
command: fmt
+6 -1
View File
@@ -37,4 +37,9 @@ validator-config
*.patch
validator-api-config.toml
dist
storybook-static
storybook-static
envs/qwerty.env
Cargo.lock
nym-connect/Cargo.lock
.parcel-cache
**/.DS_Store
+7 -5
View File
@@ -1,6 +1,8 @@
{
"mainnet":[{
"nymd_url":"https://rpc.nyx.nodes.guru/",
"api_url":"https://api.nyx.nodes.guru/"
}]
}
"mainnet": [
{
"nyxd_url": "https://rpc.nyx.nodes.guru/",
"api_url": "https://api.nyx.nodes.guru/"
}
]
}
+273 -58
View File
@@ -2,39 +2,260 @@
Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Unreleased
## [Unreleased]
## [v1.1.10] (2023-02-21)
- Verloc listener causing mixnode unexpected shutdown ([#3038])
- rust-sdk - update API following implementation experience with the network-requester ([#3001])
- Prevent coconut deposits in incompatible states ([#2991])
- Support unavailable signer within threshold ([#2987])
- Implement DKG re-sharing ([#2935])
- contracts: add nym prefix to mixnet and vesting contract packages ([#2855])
- Introduce common interface for all service providers to allow obtaining information such as whether they're online, what binary version they're running, etc. ([#2758])
- Add client functionality to nym-network-requester ([#1900])
- nym-api: uptime rework ([#3053])
- ci: update typescript-lint.yml ([#3035])
- contracts: add nym prefix to mixnet and vesting contract packages ([#2855])
[#3038]: https://github.com/nymtech/nym/issues/3038
[#3001]: https://github.com/nymtech/nym/issues/3001
[#2991]: https://github.com/nymtech/nym/issues/2991
[#2987]: https://github.com/nymtech/nym/issues/2987
[#2935]: https://github.com/nymtech/nym/issues/2935
[#2855]: https://github.com/nymtech/nym/pull/2855
[#2758]: https://github.com/nymtech/nym/issues/2758
[#1900]: https://github.com/nymtech/nym/issues/1900
[#3053]: https://github.com/nymtech/nym/pull/3053
[#3035]: https://github.com/nymtech/nym/pull/3035
[#2855]: https://github.com/nymtech/nym/pull/2855
## [v1.1.9] (2023-02-07)
### Added
- nym-cli: added CLI tool for interacting with the Nyx blockchain and Nym mixnet smart contracts ([#1577])
- validator-client: added `query_contract_smart` and `query_contract_raw` on `NymdClient` ([#1558])
- network-requester: added additional Blockstream Green wallet endpoint to `example.allowed.list` ([#1611](https://github.com/nymtech/nym/pull/1611))
- common/ledger: new library for communicating with a Ledger device ([#1640])
- native-client/socks5-client: `disable_loop_cover_traffic_stream` Debug config option to disable the separate loop cover traffic stream ([#1666])
- native-client/socks5-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: `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])
- 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])
- validator-api: add `interval_operating_cost` and `profit_margin_percent` to cmpute reward estimation endpoint
- native-client/socks5-client/network-requester: improve handling error cases ([#1713])
- vesting-contract: optional locked token pledge cap per account ([#1687]), defaults to 100_000 NYM
- clients: add testing-only support for two more extended packet sizes (8kb and 16kb).
### Fixed
- 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])
- socks5-client: fix bug where in some cases packet reordering could trigger a connection being closed too early ([#1702],[#1724])
- Remove Coconut feature flag ([#2793])
- Separate `nym-api` endpoints with values of "total-supply" and "circulating-supply" in `nym` ([#2964])
### Changed
- validator-client: made `fee` argument optional for `execute` and `execute_multiple` ([#1541])
- socks5 client: graceful shutdown should fix error on disconnect in nym-connect ([#1591])
- wasm-client: fixed build errors on MacOS and changed example JS code to use mainnet ([#1585])
- gateway-client: will attempt to read now as many as 8 websocket messages at once, assuming they're already available on the socket ([#1669])
- validator-api: changed error serialization on `inclusion_probability`, `stake-saturation` and `reward-estimation` endpoints to provide more accurate information ([#1681])
- moved `Percent` struct to to `contracts-common`, change affects explorer-api
- clients: bound the sphinx packet channel and reduce sending rate if gateway can't keep up ([#1703],[#1725])
- native-client: is now capable of listening for requests on sockets different than `127.0.0.1` ([#2912]). This can be specified via `--host` flag during `init` or `run`. Alternatively a custom `host` can be set in `config.toml` file under `socket` section.
- mixnode, gateway: fix unexpected shutdown on corrupted connection ([#2963])
[#2793]: https://github.com/nymtech/nym/issues/2793
[#2912]: https://github.com/nymtech/nym/issues/2912
[#2964]: https://github.com/nymtech/nym/issues/2964
[#2963]: https://github.com/nymtech/nym/issues/3017
## [v1.1.8] (2023-01-31)
### Added
- Rust SDK - Support SURBS (anonymous send + storage) ([#2754])
- dkg rerun from scratch and dkg-specific epochs ([#2810])
- Rename `'initial_supply'` field to `'total_supply'` in the circulating supply endpoint ([#2931])
- Circulating supply api endpoint (read the note inside before testing/deploying) ([#1902])
### Changed
- nym-api: an `--id` flag is now always explicitly required ([#2873])
[#2754]: https://github.com/nymtech/nym/issues/2754
[#2810]: https://github.com/nymtech/nym/issues/2810
[#2931]: https://github.com/nymtech/nym/issues/2931
[#1902]: https://github.com/nymtech/nym/issues/1902
[#2873]: https://github.com/nymtech/nym/issues/2873
## [v1.1.7] (2023-01-24)
### Added
- Gateways now shut down gracefully ([#2019]).
- Rust SDK - Initial version for nym-client ([#2669]).
- Introduce vesting contract query for addresses of all vesting accounts (required for the circulating supply calculation) ([#2778]).
- Add threshold value to the contract storage ([#1893])
### Changed
- Refactor vesting account storage (and in particular, ACCOUNTS saving) ([#2795]).
- Move from manual advancing DKG state to an automatic process ([#2670]).
### Fixed
- Gateways now shut down gracefully ([#2019]).
[#2019]: https://github.com/nymtech/nym/issues/2019
[#2669]: https://github.com/nymtech/nym/issues/2669
[#2795]: https://github.com/nymtech/nym/issues/2795
[#2778]: https://github.com/nymtech/nym/issues/2778
[#2670]: https://github.com/nymtech/nym/issues/2670
[#1893]: https://github.com/nymtech/nym/issues/1893
## [v1.1.6] (2023-01-17)
### Added
- nym-sdk: added initial version of a Rust client sdk
- nym-api: added `/circulating-supply` endpoint ([#2814])
- nym-api: add endpoint listing detailed gateway info by @octol in https://github.com/nymtech/nym/pull/2833
### Changed
- streamline override_config functions -> there's a lot of duplicate if statements everywhere ([#2774])
- clean-up nym-api startup arguments/flags to use clap 3 and its macro-derived arguments ([#2772])
- renamed all references to validator_api to nym_api
- renamed all references to nymd to nyxd ([#2696])
- 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])
[#2696]: https://github.com/nymtech/nym/pull/2696
[#2753]: https://github.com/nymtech/nym/pull/2753
[#2762]: https://github.com/nymtech/nym/pull/2762
[#2814]: https://github.com/nymtech/nym/pull/2814
[#2772]: https://github.com/nymtech/nym/pull/2772
[#2774]: https://github.com/nymtech/nym/pull/2774
## [v1.1.5] (2023-01-10)
### Added
- socks5: send status message for service ready, and network-requester error response in https://github.com/nymtech/nym/pull/2715
### Changed
- all-binaries: improved error logging in https://github.com/nymtech/nym/pull/2686
- native client: bring shutdown logic up to the same level as socks5-client in https://github.com/nymtech/nym/pull/2695
- nym-api, coconut-dkg contract: automatic, time-based dkg epoch state advancement in https://github.com/nymtech/nym/pull/2670
- DKG resharing unit test by @neacsu in https://github.com/nymtech/nym/pull/2668
- Renaming validator-api to nym-api by @futurechimp in https://github.com/nymtech/nym/pull/1863
- Modify wasm specific make targets by @neacsu in https://github.com/nymtech/nym/pull/2693
- client: create websocket handler builder by @octol in https://github.com/nymtech/nym/pull/2700
- Outfox and Lion by @durch in https://github.com/nymtech/nym/pull/2730
- Feature/multi surb transmission lanes by @jstuczyn in https://github.com/nymtech/nym/pull/2723
## [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 initialization, 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 `NyxdClient` ([#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
@@ -42,21 +263,19 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
[#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
[#1687]: https://github.com/nymtech/nym/pull/1687
[#1702]: https://github.com/nymtech/nym/pull/1702
[#1703]: https://github.com/nymtech/nym/pull/1703
[#1713]: https://github.com/nymtech/nym/pull/1713
[#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
@@ -109,9 +328,8 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- 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])
- validator-api: rewarder set update fails without panicking on possible nyxd 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
@@ -205,9 +423,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))
@@ -216,7 +434,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))
@@ -256,14 +474,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))
## [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:**
@@ -293,7 +510,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:**
@@ -308,7 +525,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)
@@ -318,7 +535,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)
@@ -374,10 +591,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))
@@ -390,7 +607,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))
@@ -408,7 +625,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))
@@ -424,7 +641,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))
@@ -448,8 +665,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))
@@ -458,14 +675,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))
@@ -477,21 +694,21 @@ 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))
- Feature/update wallet with stake rates [\#739](https://github.com/nymtech/nym/pull/739) ([neacsu](https://github.com/neacsu))
- Add stake reward rates and bump version of client [\#738](https://github.com/nymtech/nym/pull/738) ([neacsu](https://github.com/neacsu))
- Bump next from 10.1.3 to 11.1.0 in /wallet-web [\#737](https://github.com/nymtech/nym/pull/737) ([dependabot[bot]](https://github.com/apps/dependabot))
- Feature/nymd client integration [\#736](https://github.com/nymtech/nym/pull/736) ([jstuczyn](https://github.com/jstuczyn))
- Feature/nyxd client integration [\#736](https://github.com/nymtech/nym/pull/736) ([jstuczyn](https://github.com/jstuczyn))
- Bug/fix parking lot on wasm [\#735](https://github.com/nymtech/nym/pull/735) ([neacsu](https://github.com/neacsu))
- Explorer API: add new HTTP resource to decorate mix nodes with geoip locations [\#734](https://github.com/nymtech/nym/pull/734) ([mmsinclair](https://github.com/mmsinclair))
- Feature/completing nymd client api [\#732](https://github.com/nymtech/nym/pull/732) ([jstuczyn](https://github.com/jstuczyn))
- Feature/completing nyxd client api [\#732](https://github.com/nymtech/nym/pull/732) ([jstuczyn](https://github.com/jstuczyn))
- Explorer API - add port check and node description/stats proxy [\#731](https://github.com/nymtech/nym/pull/731) ([mmsinclair](https://github.com/mmsinclair))
- Feature/nymd client fee handling [\#730](https://github.com/nymtech/nym/pull/730) ([jstuczyn](https://github.com/jstuczyn))
- Feature/nyxd client fee handling [\#730](https://github.com/nymtech/nym/pull/730) ([jstuczyn](https://github.com/jstuczyn))
- Update DelegationCheck.tsx [\#725](https://github.com/nymtech/nym/pull/725) ([jessgess](https://github.com/jessgess))
- Rust nymd/cosmwasm client [\#724](https://github.com/nymtech/nym/pull/724) ([jstuczyn](https://github.com/jstuczyn))
- Rust nyxd/cosmwasm client [\#724](https://github.com/nymtech/nym/pull/724) ([jstuczyn](https://github.com/jstuczyn))
- Removed wasm feature bypassing cyclic dependencies [\#723](https://github.com/nymtech/nym/pull/723) ([jstuczyn](https://github.com/jstuczyn))
- Updated used sphinx dependency to the most recent revision [\#722](https://github.com/nymtech/nym/pull/722) ([jstuczyn](https://github.com/jstuczyn))
- update state management and validation [\#721](https://github.com/nymtech/nym/pull/721) ([fmtabbara](https://github.com/fmtabbara))
@@ -510,10 +727,8 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
- Bond and delegation alerts [\#698](https://github.com/nymtech/nym/pull/698) ([fmtabbara](https://github.com/fmtabbara))
- Bugfix/network monitor version check [\#697](https://github.com/nymtech/nym/pull/697) ([jstuczyn](https://github.com/jstuczyn))
- Feature/other containers [\#692](https://github.com/nymtech/nym/pull/692) ([neacsu](https://github.com/neacsu))
- Using validator API instead of nymd [\#690](https://github.com/nymtech/nym/pull/690) ([futurechimp](https://github.com/futurechimp))
- Using validator API instead of nyxd [\#690](https://github.com/nymtech/nym/pull/690) ([futurechimp](https://github.com/futurechimp))
- 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
+1971 -1499
View File
File diff suppressed because it is too large Load Diff
+36 -7
View File
@@ -23,6 +23,7 @@ members = [
"clients/native/websocket-requests",
"clients/socks5",
"common/bandwidth-claim-contract",
"common/bin-common",
"common/client-libs/gateway-client",
"common/client-libs/mixnet-client",
"common/client-libs/validator-client",
@@ -30,18 +31,21 @@ members = [
"common/commands",
"common/config",
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
"common/cosmwasm-smart-contracts/coconut-dkg",
"common/cosmwasm-smart-contracts/contracts-common",
"common/cosmwasm-smart-contracts/group-contract",
"common/cosmwasm-smart-contracts/mixnet-contract",
"common/cosmwasm-smart-contracts/multisig-contract",
"common/cosmwasm-smart-contracts/testing",
"common/cosmwasm-smart-contracts/vesting-contract",
"common/mobile-storage",
"common/credential-storage",
"common/credentials",
"common/crypto",
"common/crypto/dkg",
"common/dkg",
"common/execute",
"common/inclusion-probability",
"common/ledger",
"common/logging",
"common/mixnode-common",
"common/network-defaults",
"common/nonexhaustive-delayqueue",
@@ -64,16 +68,18 @@ members = [
"common/topology",
"common/types",
"common/wasm-utils",
"common/completions",
"explorer-api",
"gateway",
"gateway/gateway-requests",
"integrations/bity",
"mixnode",
"sdk/rust/nym-sdk",
"service-providers/common",
"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"
]
@@ -85,8 +91,31 @@ default-members = [
"service-providers/network-requester",
"service-providers/network-statistics",
"mixnode",
"validator-api",
"nym-api",
"explorer-api",
]
exclude = ["explorer", "contracts", "clients/webassembly", "nym-wallet", "nym-connect"]
exclude = ["explorer", "contracts", "clients/webassembly", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop"]
[workspace.package]
authors = ["Nym Technologies SA"]
repository = "https://github.com/nymtech/nym"
homepage = "https://nymtech.net"
documentation = "https://nymtech.net"
edition = "2021"
license = "Apache-2.0"
[workspace.dependencies]
async-trait = "0.1.63"
cfg-if = "1.0.0"
dotenv = "0.15.0"
lazy_static = "1.4.0"
log = "0.4"
once_cell = "1.7.2"
rand = "0.8.5"
serde = "1.0.152"
serde_json = "1.0.91"
tap = "1.0.1"
thiserror = "1.0.38"
tokio = "1.24.1"
url = "2.2"
+46 -30
View File
@@ -2,12 +2,12 @@ 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-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-all: clippy-main clippy-main-examples clippy-all-contracts clippy-all-wallet clippy-all-connect clippy-all-connect-mobile clippy-all-wasm-client
clippy-happy: clippy-happy-main clippy-happy-contracts clippy-happy-wallet clippy-happy-connect clippy-happy-connect-mobile
cargo-test: test-main test-contracts test-contracts-integration test-wallet test-connect test-connect-mobile
cargo-test-expensive: test-main-expensive test-contracts-expensive test-wallet-expensive test-connect-expensive
build: build-contracts build-wallet build-main build-main-examples build-connect build-connect-mobile build-wasm-client
fmt: fmt-main fmt-contracts fmt-wallet fmt-connect fmt-connect-mobile fmt-wasm-client
clippy-happy-main:
cargo clippy
@@ -19,26 +19,31 @@ clippy-happy-wallet:
cargo clippy --manifest-path nym-wallet/Cargo.toml
clippy-happy-connect:
cargo clippy --manifest-path nym-connect/Cargo.toml
cargo clippy --manifest-path nym-connect/desktop/Cargo.toml
clippy-happy-connect-mobile:
cargo clippy --manifest-path nym-connect/mobile/src-tauri/Cargo.toml
clippy-main:
cargo clippy --workspace -- -D warnings
clippy-coconut:
cargo clippy --workspace --features coconut -- -D warnings
clippy-main-examples:
cargo clippy --workspace --examples -- -D warnings
clippy-wasm:
cargo clippy --workspace --features wasm -- -D warnings
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
cargo clippy --workspace --manifest-path contracts/Cargo.toml --target wasm32-unknown-unknown -- -D warnings
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
cargo clippy --workspace --manifest-path nym-connect/desktop/Cargo.toml --all-features -- -D warnings
clippy-all-connect-mobile:
cargo clippy --workspace --manifest-path nym-connect/mobile/src-tauri/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
@@ -46,43 +51,42 @@ clippy-all-wasm-client:
test-main:
cargo test --workspace
test-coconut:
cargo test --workspace --features coconut
test-wasm:
cargo test --workspace --features wasm
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-contracts-integration:
cargo test --manifest-path contracts/integration-tests/Cargo.toml
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
cargo test --manifest-path nym-connect/desktop/Cargo.toml --all-features
test-connect-expensive:
cargo test --manifest-path nym-connect/Cargo.toml --all-features -- --ignored
cargo test --manifest-path nym-connect/desktop/Cargo.toml --all-features -- --ignored
test-connect-mobile:
cargo test --manifest-path nym-connect/mobile/src-tauri/Cargo.toml --all-features
test-connect-mobile-expensive:
cargo test --manifest-path nym-connect/mobile/src-tauri/Cargo.toml --all-features -- --ignored
build-main:
cargo build --workspace
build-main-examples:
cargo build --workspace --examples
build-contracts:
cargo build --manifest-path contracts/Cargo.toml --workspace
@@ -90,7 +94,13 @@ build-wallet:
cargo build --manifest-path nym-wallet/Cargo.toml --workspace
build-connect:
cargo build --manifest-path nym-connect/Cargo.toml --workspace
cargo build --manifest-path nym-connect/desktop/Cargo.toml --workspace
build-connect-mobile:
cargo build --manifest-path nym-connect/mobile/src-tauri/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
@@ -108,7 +118,10 @@ fmt-wallet:
cargo fmt --manifest-path nym-wallet/Cargo.toml --all
fmt-connect:
cargo fmt --manifest-path nym-connect/Cargo.toml --all
cargo fmt --manifest-path nym-connect/desktop/Cargo.toml --all
fmt-connect-mobile:
cargo fmt --manifest-path nym-connect/mobile/src-tauri/Cargo.toml --all
fmt-wasm-client:
cargo fmt --manifest-path clients/webassembly/Cargo.toml --all
@@ -122,3 +135,6 @@ mixnet-opt: wasm
generate-typescript:
cd tools/ts-rs-cli && cargo run && cd ../..
yarn types:lint:fix
run-api-tests:
cd nym-api/tests/functional_test && yarn test:qa
+41 -16
View File
@@ -1,36 +1,53 @@
[package]
name = "client-core"
version = "1.0.1"
version = "1.1.10"
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]
async-trait = { version = "0.1.58" }
dirs = "4.0"
dashmap = "5.4.0"
futures = "0.3"
humantime-serde = "1.0"
log = "0.4"
log = { workspace = true }
rand = { version = "0.7.3", features = ["wasm-bindgen"] }
serde = { version = "1.0", features = ["derive"] }
sled = { version = "0.34", optional = true }
serde_json = "1.0.89"
tap = "1.0.1"
thiserror = "1.0.34"
url = { version ="2.2", features = ["serde"] }
tokio = { version = "1.24.1", features = ["macros"]}
time = "0.3.17"
# internal
config = { path = "../../common/config" }
crypto = { path = "../../common/crypto" }
nym-config = { path = "../../common/config" }
nym-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" }
nym-nonexhaustive-delayqueue = { path = "../../common/nonexhaustive-delayqueue" }
nym-sphinx = { path = "../../common/nymsphinx" }
nym-pemstore = { path = "../../common/pemstore" }
nym-topology = { path = "../../common/topology" }
validator-client = { path = "../../common/client-libs/validator-client", default-features = false }
tap = "1.0.1"
nym-task = { path = "../../common/task" }
tokio = { version = "1.21.2", features = ["time", "macros"]}
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream]
version = "0.1.11"
features = ["time"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio]
version = "1.24.1"
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"
@@ -46,14 +63,22 @@ rev = "b9d1a54ad514c2f230a026afe0dde341e98cd7b6"
version = "0.2.4"
features = ["futures"]
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.task]
path = "../../common/task"
[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.24.1", features = ["rt-multi-thread", "macros"] }
sqlx = { version = "0.6.2", features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] }
[features]
default = ["reply-surb"]
default = []
fs-surb-storage = ["sqlx"]
wasm = ["gateway-client/wasm"]
coconut = ["gateway-client/coconut", "gateway-requests/coconut"]
reply-surb = ["sled"]
+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!("{out_dir}/fs-surbs-example.sqlite");
let mut conn = SqliteConnection::connect(&format!("sqlite://{database_path}?mode=rwc"))
.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,11 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
//
use crate::{client::replies::reply_storage, config::DebugConfig};
pub fn setup_empty_reply_surb_backend(debug_config: &DebugConfig) -> reply_storage::Empty {
reply_storage::Empty {
min_surb_threshold: debug_config.minimum_reply_surb_storage_threshold,
max_surb_threshold: debug_config.maximum_reply_surb_storage_threshold,
}
}
@@ -0,0 +1,569 @@
// 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 futures::channel::mpsc;
use gateway_client::bandwidth::BandwidthController;
#[cfg(target_arch = "wasm32")]
use gateway_client::wasm_mockups::CosmWasmClient;
use gateway_client::{
AcknowledgementReceiver, AcknowledgementSender, GatewayClient, MixnetMessageReceiver,
MixnetMessageSender,
};
use log::{debug, info};
use nym_crypto::asymmetric::{encryption, identity};
use nym_sphinx::acknowledgements::AckKey;
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::addressing::nodes::NodeIdentity;
use nym_sphinx::receiver::ReconstructedMessage;
use nym_task::connections::{ConnectionCommandReceiver, ConnectionCommandSender, LaneQueueLengths};
use nym_task::{TaskClient, TaskManager};
use std::sync::Arc;
use std::time::Duration;
use tap::TapFallible;
use url::Url;
#[cfg(not(target_arch = "wasm32"))]
use validator_client::nyxd::CosmWasmClient;
use super::received_buffer::ReceivedBufferMessage;
#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))]
pub mod non_wasm_helpers;
pub mod helpers;
#[derive(Clone)]
pub struct ClientInput {
pub connection_command_sender: ConnectionCommandSender,
pub input_sender: InputMessageSender,
}
impl ClientInput {
pub async fn send(
&self,
message: InputMessage,
) -> Result<(), tokio::sync::mpsc::error::SendError<InputMessage>> {
self.input_sender.send(message).await
}
}
#[derive(Clone)]
pub struct ClientOutput {
pub received_buffer_request_sender: ReceivedBufferRequestSender,
}
impl ClientOutput {
pub fn register_receiver(
&mut self,
) -> Result<mpsc::UnboundedReceiver<Vec<ReconstructedMessage>>, ClientCoreError> {
let (reconstructed_sender, reconstructed_receiver) = mpsc::unbounded();
self.received_buffer_request_sender
.unbounded_send(ReceivedBufferMessage::ReceiverAnnounce(
reconstructed_sender,
))
.map_err(|_| ClientCoreError::FailedToRegisterReceiver)?;
Ok(reconstructed_receiver)
}
}
pub struct ClientState {
pub shared_lane_queue_lengths: LaneQueueLengths,
pub reply_controller_sender: ReplyControllerSender,
}
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"),
}
}
}
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum CredentialsToggle {
Enabled,
Disabled,
}
impl CredentialsToggle {
pub fn is_enabled(&self) -> bool {
self == &CredentialsToggle::Enabled
}
pub fn is_disabled(&self) -> bool {
self == &CredentialsToggle::Disabled
}
}
impl From<bool> for CredentialsToggle {
fn from(value: bool) -> Self {
if value {
CredentialsToggle::Enabled
} else {
CredentialsToggle::Disabled
}
}
}
pub struct BaseClientBuilder<'a, B, C: Clone> {
// 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<C>>,
key_manager: KeyManager,
}
impl<'a, B, C> BaseClientBuilder<'a, B, C>
where
B: ReplyStorageBackend + Send + Sync + 'static,
C: CosmWasmClient + Sync + Send + Clone + 'static,
{
pub fn new_from_base_config<T>(
base_config: &'a Config<T>,
key_manager: KeyManager,
bandwidth_controller: Option<BandwidthController<C>>,
reply_storage_backend: B,
) -> BaseClientBuilder<'a, B, C> {
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<C>>,
reply_storage_backend: B,
credentials_toggle: CredentialsToggle,
nym_api_endpoints: Vec<Url>,
) -> BaseClientBuilder<'a, B, C> {
BaseClientBuilder {
gateway_config,
debug_config,
disabled_credentials: credentials_toggle.is_disabled(),
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<C>, ClientCoreError> {
let gateway_id = self.gateway_config.gateway_id.clone();
if gateway_id.is_empty() {
return Err(ClientCoreError::GatewayIdUnknown);
}
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.is_gateway_key_set() {
Some(self.key_manager.gateway_shared_key())
} else {
log::info!("Gateway key not set! Will proceed anyway.");
None
};
let mut gateway_client = GatewayClient::new(
gateway_address,
self.key_manager.identity_keypair(),
gateway_identity,
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<C>,
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,
{
if backend.is_active() {
log::trace!("Setup persistent reply storage");
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)
} else {
log::trace!("Setup inactive reply storage");
Ok(backend
.get_inactive_storage()
.map_err(|err| ClientCoreError::SurbStorageError {
source: Box::new(err),
})?)
}
}
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 {
received_buffer_request_sender,
},
},
client_state: ClientState {
shared_lane_queue_lengths,
reply_controller_sender,
},
task_manager,
})
}
}
pub struct BaseClient {
pub client_input: ClientInputStatus,
pub client_output: ClientOutputStatus,
pub client_state: ClientState,
pub task_manager: TaskManager,
}
@@ -0,0 +1,100 @@
// 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 setup_inactive_backend(debug_config: &DebugConfig) -> fs_backend::Backend {
info!("creating inactive surb database");
fs_backend::Backend::new_inactive(
debug_config.minimum_reply_surb_storage_threshold,
debug_config.maximum_reply_surb_storage_threshold,
)
}
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: Option<P>,
debug_config: &DebugConfig,
) -> Result<fs_backend::Backend, ClientCoreError> {
if let Some(db_path) = db_path {
// 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
}
} else {
Ok(setup_inactive_backend(debug_config))
}
}
@@ -7,11 +7,11 @@ 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 nym_sphinx::acknowledgements::AckKey;
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::cover::generate_loop_cover_packet;
use nym_sphinx::params::PacketSize;
use nym_sphinx::utils::sample_poisson_duration;
use rand::{rngs::OsRng, CryptoRng, Rng};
use std::pin::Pin;
use std::sync::Arc;
@@ -143,6 +143,16 @@ impl LoopCoverTrafficStream<OsRng> {
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!");
@@ -151,15 +161,16 @@ 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,
@@ -178,6 +189,10 @@ impl LoopCoverTrafficStream<OsRng> {
// 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 gateway can't keep up");
}
TrySendError::Closed(_) => {
log::warn!("Failed to send cover message - channel closed");
@@ -198,12 +213,11 @@ impl LoopCoverTrafficStream<OsRng> {
tokio::task::yield_now().await;
}
#[cfg(not(target_arch = "wasm32"))]
pub fn start_with_shutdown(mut self, mut shutdown: task::ShutdownListener) {
pub fn start_with_shutdown(mut self, mut shutdown: nym_task::TaskClient) {
// we should set initial delay only when we actually start the stream
let sampled =
sample_poisson_duration(&mut self.rng, self.average_cover_message_sending_delay);
self.next_delay = Box::pin(time::sleep(sampled));
self.set_next_delay(sampled);
spawn_future(async move {
debug!("Started LoopCoverTrafficStream with graceful shutdown support");
@@ -224,24 +238,8 @@ impl LoopCoverTrafficStream<OsRng> {
}
}
}
assert!(shutdown.is_shutdown_poll());
shutdown.recv_timeout().await;
log::debug!("LoopCoverTrafficStream: Exiting");
})
}
#[cfg(target_arch = "wasm32")]
pub fn start(mut self) {
// we should set initial delay only when we actually start the stream
let sampled =
sample_poisson_duration(&mut self.rng, self.average_cover_message_sending_delay);
self.next_delay = Box::pin(wasm_timer::Delay::new(sampled));
spawn_future(async move {
debug!("Started LoopCoverTrafficStream without graceful shutdown support");
while self.next().await.is_some() {
self.on_new_message().await;
}
})
}
}
@@ -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,88 @@
use futures::channel::mpsc;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::anonymous_replies::ReplySurb;
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
use nym_task::connections::TransmissionLane;
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,
}
}
pub fn lane(&self) -> &TransmissionLane {
match self {
InputMessage::Regular { lane, .. }
| InputMessage::Anonymous { lane, .. }
| InputMessage::Reply { lane, .. } => lane,
}
}
}
+106 -35
View File
@@ -2,10 +2,10 @@
// SPDX-License-Identifier: Apache-2.0
use crate::config::persistence::key_pathfinder::ClientKeyPathfinder;
use crypto::asymmetric::{encryption, identity};
use gateway_requests::registration::handshake::SharedKeys;
use log::*;
use nymsphinx::acknowledgements::AckKey;
use nym_crypto::asymmetric::{encryption, identity};
use nym_sphinx::acknowledgements::AckKey;
use rand::{CryptoRng, RngCore};
use std::io;
use std::sync::Arc;
@@ -17,6 +17,7 @@ use std::sync::Arc;
// use the old key after new one was issued.
// Remember that Arc<T> has Deref implementation for T
#[derive(Clone)]
pub struct KeyManager {
/// identity key associated with the client instance.
identity_keypair: Arc<identity::KeyPair>,
@@ -41,9 +42,6 @@ pub struct KeyManager {
*/
impl KeyManager {
// this is actually **NOT** dead code
// I have absolutely no idea why the compiler insists it's unused. The call happens during client::init::execute
#[allow(dead_code)]
/// Creates new instance of a [`KeyManager`]
pub fn new<R>(rng: &mut R) -> Self
where
@@ -57,87 +55,161 @@ impl KeyManager {
}
}
// this is actually **NOT** dead code
// I have absolutely no idea why the compiler insists it's unused. The call happens during client::init::execute
#[allow(dead_code)]
/// After shared key with the gateway is derived, puts its ownership to this instance of a [`KeyManager`].
pub fn insert_gateway_shared_key(&mut self, gateway_shared_key: Arc<SharedKeys>) {
self.gateway_shared_key = Some(gateway_shared_key)
pub fn from_keys(
id_keypair: identity::KeyPair,
enc_keypair: encryption::KeyPair,
gateway_shared_key: SharedKeys,
ack_key: AckKey,
) -> Self {
Self {
identity_keypair: Arc::new(id_keypair),
encryption_keypair: Arc::new(enc_keypair),
gateway_shared_key: Some(Arc::new(gateway_shared_key)),
ack_key: Arc::new(ack_key),
}
}
/// Loads previously stored keys from the disk.
pub fn load_keys(client_pathfinder: &ClientKeyPathfinder) -> io::Result<Self> {
/// Loads previously stored client keys from the disk.
fn load_client_keys(client_pathfinder: &ClientKeyPathfinder) -> io::Result<Self> {
let identity_keypair: identity::KeyPair =
pemstore::load_keypair(&pemstore::KeyPairPath::new(
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
client_pathfinder.private_identity_key().to_owned(),
client_pathfinder.public_identity_key().to_owned(),
))?;
let encryption_keypair: encryption::KeyPair =
pemstore::load_keypair(&pemstore::KeyPairPath::new(
nym_pemstore::load_keypair(&nym_pemstore::KeyPairPath::new(
client_pathfinder.private_encryption_key().to_owned(),
client_pathfinder.public_encryption_key().to_owned(),
))?;
let gateway_shared_key: SharedKeys =
pemstore::load_key(client_pathfinder.gateway_shared_key())?;
let ack_key: AckKey = nym_pemstore::load_key(client_pathfinder.ack_key())?;
let ack_key: AckKey = pemstore::load_key(client_pathfinder.ack_key())?;
// TODO: ack key is never stored so it is generated now. But perhaps it should be stored
// after all for consistency sake?
Ok(KeyManager {
identity_keypair: Arc::new(identity_keypair),
encryption_keypair: Arc::new(encryption_keypair),
gateway_shared_key: Some(Arc::new(gateway_shared_key)),
gateway_shared_key: None,
ack_key: Arc::new(ack_key),
})
}
// this is actually **NOT** dead code
// I have absolutely no idea why the compiler insists it's unused. The call happens during client::init::execute
#[allow(dead_code)]
/// Loads previously stored keys from the disk. Fails if not all, including the shared gateway
/// key, is available.
pub fn load_keys(client_pathfinder: &ClientKeyPathfinder) -> io::Result<Self> {
let mut key_manager = Self::load_client_keys(client_pathfinder)?;
let gateway_shared_key: SharedKeys =
nym_pemstore::load_key(client_pathfinder.gateway_shared_key())?;
key_manager.gateway_shared_key = Some(Arc::new(gateway_shared_key));
Ok(key_manager)
}
/// Loads previously stored keys from the disk. Fails if client keys are not availabe, but the
/// shared gateway key is optional.
pub fn load_keys_but_gateway_is_optional(
client_pathfinder: &ClientKeyPathfinder,
) -> io::Result<Self> {
let mut key_manager = Self::load_client_keys(client_pathfinder)?;
let gateway_shared_key: Result<SharedKeys, io::Error> =
nym_pemstore::load_key(client_pathfinder.gateway_shared_key());
// It's ok if the gateway key was not found
let gateway_shared_key = match gateway_shared_key {
Err(err) if err.kind() == io::ErrorKind::NotFound => Ok(None),
Err(err) => Err(err),
Ok(key) => Ok(Some(key)),
}?;
key_manager.gateway_shared_key = gateway_shared_key.map(Arc::new);
Ok(key_manager)
}
/// Stores all available keys on the disk.
// While perhaps there is no much point in storing the `AckKey` on the disk,
// it is done so for the consistency sake so that you wouldn't require an rng instance
// during `load_keys` to generate the said key.
pub fn store_keys(&self, client_pathfinder: &ClientKeyPathfinder) -> io::Result<()> {
pemstore::store_keypair(
nym_pemstore::store_keypair(
self.identity_keypair.as_ref(),
&pemstore::KeyPairPath::new(
&nym_pemstore::KeyPairPath::new(
client_pathfinder.private_identity_key().to_owned(),
client_pathfinder.public_identity_key().to_owned(),
),
)?;
pemstore::store_keypair(
nym_pemstore::store_keypair(
self.encryption_keypair.as_ref(),
&pemstore::KeyPairPath::new(
&nym_pemstore::KeyPairPath::new(
client_pathfinder.private_encryption_key().to_owned(),
client_pathfinder.public_encryption_key().to_owned(),
),
)?;
pemstore::store_key(self.ack_key.as_ref(), client_pathfinder.ack_key())?;
nym_pemstore::store_key(self.ack_key.as_ref(), client_pathfinder.ack_key())?;
match self.gateway_shared_key.as_ref() {
None => warn!("No gateway shared key available to store!"),
None => debug!("No gateway shared key available to store!"),
Some(gate_key) => {
pemstore::store_key(gate_key.as_ref(), client_pathfinder.gateway_shared_key())?
nym_pemstore::store_key(gate_key.as_ref(), client_pathfinder.gateway_shared_key())?
}
}
Ok(())
}
pub fn store_gateway_key(&self, client_pathfinder: &ClientKeyPathfinder) -> io::Result<()> {
match self.gateway_shared_key.as_ref() {
None => {
return Err(io::Error::new(
io::ErrorKind::Other,
"trying to store a non-existing key",
))
}
Some(gate_key) => {
nym_pemstore::store_key(gate_key.as_ref(), client_pathfinder.gateway_shared_key())?
}
}
Ok(())
}
/// Overwrite the existing identity keypair
pub fn set_identity_keypair(&mut self, id_keypair: identity::KeyPair) {
self.identity_keypair = Arc::new(id_keypair);
}
/// Gets an atomically reference counted pointer to [`identity::KeyPair`].
pub fn identity_keypair(&self) -> Arc<identity::KeyPair> {
Arc::clone(&self.identity_keypair)
}
/// Overwrite the existing encryption keypair
pub fn set_encryption_keypair(&mut self, enc_keypair: encryption::KeyPair) {
self.encryption_keypair = Arc::new(enc_keypair);
}
/// Gets an atomically reference counted pointer to [`encryption::KeyPair`].
pub fn encryption_keypair(&self) -> Arc<encryption::KeyPair> {
Arc::clone(&self.encryption_keypair)
}
/// Overwrite the existing ack key
pub fn set_ack_key(&mut self, ack_key: AckKey) {
self.ack_key = Arc::new(ack_key);
}
/// Gets an atomically reference counted pointer to [`AckKey`].
pub fn ack_key(&self) -> Arc<AckKey> {
Arc::clone(&self.ack_key)
}
/// After shared key with the gateway is derived, puts its ownership to this instance of a [`KeyManager`].
pub fn insert_gateway_shared_key(&mut self, gateway_shared_key: Arc<SharedKeys>) {
self.gateway_shared_key = Some(gateway_shared_key)
}
/// Gets an atomically reference counted pointer to [`SharedKey`].
// since this function is not fully public, it is not expected to be used externally and
// hence it's up to us to ensure it's called in correct context
@@ -149,8 +221,7 @@ impl KeyManager {
)
}
/// Gets an atomically reference counted pointer to [`AckKey`].
pub fn ack_key(&self) -> Arc<AckKey> {
Arc::clone(&self.ack_key)
pub fn is_gateway_key_set(&self) -> bool {
self.gateway_shared_key.is_some()
}
}
+22 -24
View File
@@ -2,9 +2,13 @@
// SPDX-License-Identifier: Apache-2.0
use crate::spawn_future;
#[cfg(target_arch = "wasm32")]
use gateway_client::wasm_mockups::CosmWasmClient;
use gateway_client::GatewayClient;
use log::*;
use nymsphinx::forwarding::packet::MixPacket;
use nym_sphinx::forwarding::packet::MixPacket;
#[cfg(not(target_arch = "wasm32"))]
use validator_client::nyxd::CosmWasmClient;
pub type BatchMixMessageSender = tokio::sync::mpsc::Sender<Vec<MixPacket>>;
pub type BatchMixMessageReceiver = tokio::sync::mpsc::Receiver<Vec<MixPacket>>;
@@ -13,10 +17,10 @@ pub type BatchMixMessageReceiver = tokio::sync::mpsc::Receiver<Vec<MixPacket>>;
pub const MIX_MESSAGE_RECEIVER_BUFFER_SIZE: usize = 32;
const MAX_FAILURE_COUNT: usize = 100;
pub struct MixTrafficController {
pub struct MixTrafficController<C: Clone> {
// TODO: most likely to be replaced by some higher level construct as
// later on gateway_client will need to be accessible by other entities
gateway_client: GatewayClient,
gateway_client: GatewayClient<C>,
mix_rx: BatchMixMessageReceiver,
// TODO: this is temporary work-around.
@@ -24,8 +28,13 @@ pub struct MixTrafficController {
consecutive_gateway_failure_count: usize,
}
impl MixTrafficController {
pub fn new(gateway_client: GatewayClient) -> (MixTrafficController, BatchMixMessageSender) {
impl<C> MixTrafficController<C>
where
C: CosmWasmClient + Sync + Send + Clone + 'static,
{
pub fn new(
gateway_client: GatewayClient<C>,
) -> (MixTrafficController<C>, BatchMixMessageSender) {
let (sphinx_message_sender, sphinx_message_receiver) =
tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE);
(
@@ -51,13 +60,13 @@ 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
// to reconnect?
panic!("failed to send sphinx packet to the gateway {} times in a row - assuming the gateway is dead. Can't do anything about it yet :(", MAX_FAILURE_COUNT)
panic!("failed to send sphinx packet to the gateway {MAX_FAILURE_COUNT} times in a row - assuming the gateway is dead. Can't do anything about it yet :(")
}
}
Ok(_) => {
@@ -67,12 +76,11 @@ impl MixTrafficController {
}
}
#[cfg(not(target_arch = "wasm32"))]
pub fn start_with_shutdown(mut self, mut shutdown: task::ShutdownListener) {
pub fn start_with_shutdown(mut self, mut shutdown: nym_task::TaskClient) {
spawn_future(async move {
debug!("Started MixTrafficController with graceful shutdown support");
while !shutdown.is_shutdown() {
loop {
tokio::select! {
mix_packets = self.mix_rx.recv() => match mix_packets {
Some(mix_packets) => {
@@ -83,24 +91,14 @@ impl MixTrafficController {
break;
}
},
_ = shutdown.recv() => {
_ = shutdown.recv_with_delay() => {
log::trace!("MixTrafficController: Received shutdown");
break;
}
}
}
assert!(shutdown.is_shutdown_poll());
shutdown.recv_timeout().await;
log::debug!("MixTrafficController: Exiting");
})
}
#[cfg(target_arch = "wasm32")]
pub fn start(mut self) {
spawn_future(async move {
debug!("Started MixTrafficController without graceful shutdown support");
while let Some(mix_packets) = self.mix_rx.recv().await {
self.on_messages(mix_packets).await;
}
})
}
}
+6 -10
View File
@@ -1,18 +1,14 @@
use std::sync::atomic::AtomicBool;
// 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;
#[cfg(feature = "reply-surb")]
pub mod reply_key_storage;
pub mod replies;
pub mod topology_control;
// This is *NOT* used to signal shutdown.
// It's critical that we don't have any tasks finishing early, this is an additional safety check
// that tasks exiting are doing so because shutdown has been signalled, and no other reason.
// In particular for tasks that rely on their associated channel being closed to signal shutdown,
// and don't have access to a shutdown listener channel.
pub static SHUTDOWN_HAS_BEEN_SIGNALLED: AtomicBool = AtomicBool::new(false);
pub(crate) mod transmission_buffer;
@@ -1,11 +1,11 @@
// 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::*;
use nymsphinx::{
use nym_sphinx::{
acknowledgements::{identifier::recover_identifier, AckKey},
chunking::fragment::{FragmentIdentifier, COVER_FRAG_ID},
};
@@ -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);
@@ -70,8 +65,7 @@ impl AcknowledgementListener {
}
}
#[cfg(not(target_arch = "wasm32"))]
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::ShutdownListener) {
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) {
debug!("Started AcknowledgementListener with graceful shutdown support");
while !shutdown.is_shutdown() {
@@ -83,21 +77,12 @@ impl AcknowledgementListener {
break;
}
},
_ = shutdown.recv() => {
_ = shutdown.recv_with_delay() => {
log::trace!("AcknowledgementListener: Received shutdown");
}
}
}
assert!(shutdown.is_shutdown_poll());
shutdown.recv_timeout().await;
log::debug!("AcknowledgementListener: Exiting");
}
#[cfg(target_arch = "wasm32")]
pub(super) async fn run(&mut self) {
debug!("Started AcknowledgementListener without graceful shutdown support");
while let Some(acks) = self.ack_receiver.next().await {
self.handle_ack_receiver_item(acks).await
}
}
}
@@ -3,17 +3,18 @@
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};
use nymsphinx::chunking::fragment::FragmentIdentifier;
use nymsphinx::Delay as SphinxDelay;
use nym_nonexhaustive_delayqueue::{Expired, NonExhaustiveDelayQueue, QueueKey};
use nym_sphinx::chunking::fragment::FragmentIdentifier;
use nym_sphinx::Delay as SphinxDelay;
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();
@@ -209,7 +213,11 @@ impl ActionController {
}
// note: when the entry expires it's automatically removed from pending_acks_timers
fn handle_expired_ack_timer(&mut self, expired_ack: Expired<FragmentIdentifier>) {
fn handle_expired_ack_timer(
&mut self,
expired_ack: Expired<FragmentIdentifier>,
task_client: &mut nym_task::TaskClient,
) {
// I'm honestly not sure how to handle it, because getting it means other things in our
// system are already misbehaving. If we ever see this panic, then I guess we should worry
// about it. Perhaps just reschedule it at later point?
@@ -227,9 +235,16 @@ impl ActionController {
// downgrading an arc and then upgrading vs cloning is difference of 30ns vs 15ns
// so it's literally a NO difference while it might prevent us from unnecessarily
// resending data (in maybe 1 in 1 million cases, but it's something)
self.retransmission_sender
if self
.retransmission_sender
.unbounded_send(Arc::downgrade(pending_ack_data))
.unwrap()
.is_err()
{
assert!(
task_client.is_shutdown_poll(),
"Failed to send pending ack for retransmission"
);
}
} else {
// this shouldn't cause any issues but shouldn't have happened to begin with!
error!("An already removed pending ack has expired")
@@ -245,8 +260,7 @@ impl ActionController {
}
}
#[cfg(not(target_arch = "wasm32"))]
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::ShutdownListener) {
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) {
debug!("Started ActionController with graceful shutdown support");
while !shutdown.is_shutdown() {
@@ -261,30 +275,18 @@ impl ActionController {
}
},
expired_ack = self.pending_acks_timers.next() => match expired_ack {
Some(expired_ack) => self.handle_expired_ack_timer(expired_ack),
Some(expired_ack) => self.handle_expired_ack_timer(expired_ack, &mut shutdown),
None => {
log::trace!("ActionController: Stopping since ack channel closed");
break;
}
},
_ = shutdown.recv() => {
_ = shutdown.recv_with_delay() => {
log::trace!("ActionController: Received shutdown");
}
}
}
assert!(shutdown.is_shutdown_poll());
shutdown.recv_timeout().await;
log::debug!("ActionController: Exiting");
}
#[cfg(target_arch = "wasm32")]
pub(super) async fn run(&mut self) {
debug!("Started ActionController without graceful shutdown support");
loop {
tokio::select! {
action = self.incoming_actions.next() => self.process_action(action.unwrap()),
expired_ack = self.pending_acks_timers.next() => self.handle_expired_ack_timer(expired_ack.unwrap())
}
}
}
}
@@ -1,23 +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::{
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 log::*;
use nymsphinx::anonymous_replies::ReplySurb;
use nymsphinx::preparer::MessagePreparer;
use nymsphinx::{acknowledgements::AckKey, addressing::clients::Recipient};
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
use nym_task::connections::TransmissionLane;
use rand::{CryptoRng, Rng};
use std::sync::Arc;
#[cfg(feature = "reply-surb")]
use crate::client::reply_key_storage::ReplyKeyStorage;
/// Module responsible for dealing with the received messages: splitting them, creating acknowledgements,
/// putting everything into sphinx packets, etc.
@@ -26,15 +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,
#[cfg(feature = "reply-surb")]
reply_key_storage: ReplyKeyStorage,
message_handler: MessageHandler<R>,
reply_controller_sender: ReplyControllerSender,
}
impl<R> InputMessageListener<R>
@@ -45,156 +30,91 @@ 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,
#[cfg(feature = "reply-surb")] 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,
#[cfg(feature = "reply-surb")]
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!");
#[cfg(feature = "reply-surb")]
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}")
}
}
#[cfg(not(feature = "reply-surb"))]
let _reply_key = reply_key;
// 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)
.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();
}
}
#[cfg(not(target_arch = "wasm32"))]
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::ShutdownListener) {
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) {
debug!("Started InputMessageListener with graceful shutdown support");
while !shutdown.is_shutdown() {
tokio::select! {
input_msg = self.input_receiver.next() => match input_msg {
input_msg = self.input_receiver.recv() => match input_msg {
Some(input_msg) => {
self.on_input_message(input_msg).await;
},
@@ -203,20 +123,12 @@ where
break;
}
},
_ = shutdown.recv() => {
_ = shutdown.recv_with_delay() => {
log::trace!("InputMessageListener: Received shutdown");
}
}
}
assert!(shutdown.is_shutdown_poll());
shutdown.recv_timeout().await;
log::debug!("InputMessageListener: Exiting");
}
#[cfg(target_arch = "wasm32")]
pub(super) async fn run(&mut self) {
debug!("Started InputMessageListener without graceful shutdown support");
while let Some(input_msg) = self.input_receiver.next().await {
self.on_input_message(input_msg).await;
}
}
}
@@ -7,18 +7,20 @@ use self::{
retransmission_request_listener::RetransmissionRequestListener,
sent_notification_listener::SentNotificationListener,
};
use super::real_traffic_stream::BatchRealMessageSender;
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::params::PacketSize;
use nymsphinx::{
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
use nym_sphinx::params::PacketSize;
use nym_sphinx::{
acknowledgements::AckKey,
addressing::clients::Recipient,
chunking::fragment::{Fragment, FragmentIdentifier},
preparer::MessagePreparer,
Delay as SphinxDelay,
};
use rand::{CryptoRng, Rng};
@@ -27,8 +29,7 @@ use std::{
time::Duration,
};
#[cfg(feature = "reply-surb")]
use crate::client::reply_key_storage::ReplyKeyStorage;
pub(crate) use action_controller::{AckActionSender, Action};
mod acknowledgement_listener;
mod action_controller;
@@ -50,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;
}
@@ -76,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,
@@ -91,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,
}
}
}
@@ -117,28 +162,15 @@ 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(),
}
}
@@ -162,68 +194,51 @@ where
impl<R> AcknowledgementController<R>
where
R: 'static + CryptoRng + Rng + Clone + Send,
R: 'static + CryptoRng + Rng + Clone + Send + Sync,
{
#[allow(clippy::too_many_arguments)]
pub(super) fn new(
config: Config,
rng: R,
topology_access: TopologyAccessor,
ack_key: Arc<AckKey>,
ack_recipient: Recipient,
connectors: AcknowledgementControllerConnectors,
#[cfg(feature = "reply-surb")] reply_key_storage: ReplyKeyStorage,
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,
)
.with_custom_real_message_packet_size(config.packet_size);
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(),
#[cfg(feature = "reply-surb")]
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,
@@ -234,8 +249,7 @@ where
}
}
#[cfg(not(target_arch = "wasm32"))]
pub(super) fn start_with_shutdown(self, shutdown: task::ShutdownListener) {
pub(super) fn start_with_shutdown(self, shutdown: nym_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;
@@ -279,34 +293,4 @@ where
debug!("The controller has finished execution!");
});
}
#[cfg(target_arch = "wasm32")]
pub(super) fn start(self) {
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;
spawn_future(async move {
acknowledgement_listener.run().await;
error!("The acknowledgement listener has finished execution!");
});
spawn_future(async move {
input_message_listener.run().await;
error!("The input listener has finished execution!");
});
spawn_future(async move {
retransmission_request_listener.run().await;
error!("The retransmission request listener has finished execution!");
});
spawn_future(async move {
sent_notification_listener.run().await;
error!("The sent notification listener has finished execution!");
});
spawn_future(async move {
action_controller.run().await;
error!("The controller has finished execution!");
});
}
}
@@ -1,78 +1,101 @@
// 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 futures::StreamExt;
use log::*;
use nymsphinx::preparer::MessagePreparer;
use nymsphinx::{acknowledgements::AckKey, addressing::clients::Recipient};
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::chunking::fragment::Fragment;
use nym_sphinx::preparer::PreparedFragment;
use nym_task::connections::TransmissionLane;
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>
where
R: CryptoRng + Rng,
{
#[allow(clippy::too_many_arguments)]
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))
@@ -81,11 +104,6 @@ where
}
};
let prepared_fragment = self
.message_preparer
.prepare_chunk_for_sending(chunk_clone, topology_ref, &self.ack_key, packet_recipient)
.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,16 +129,15 @@ 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
}
#[cfg(not(target_arch = "wasm32"))]
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::ShutdownListener) {
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) {
debug!("Started RetransmissionRequestListener with graceful shutdown support");
while !shutdown.is_shutdown() {
@@ -138,16 +154,7 @@ where
}
}
}
assert!(shutdown.is_shutdown_poll());
shutdown.recv_timeout().await;
log::debug!("RetransmissionRequestListener: Exiting");
}
#[cfg(target_arch = "wasm32")]
pub(super) async fn run(&mut self) {
debug!("Started RetransmissionRequestListener without graceful shutdown support");
while let Some(timed_out_ack) = self.request_receiver.next().await {
self.on_retransmission_request(timed_out_ack).await;
}
}
}
@@ -1,11 +1,11 @@
// 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::*;
use nymsphinx::chunking::fragment::{FragmentIdentifier, COVER_FRAG_ID};
use nym_sphinx::chunking::fragment::{FragmentIdentifier, COVER_FRAG_ID};
/// Module responsible for starting up retransmission timers.
/// It is required because when we send our packet to the `real traffic stream` controlled
@@ -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,19 +31,13 @@ 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();
}
#[cfg(not(target_arch = "wasm32"))]
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::ShutdownListener) {
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) {
debug!("Started SentNotificationListener with graceful shutdown support");
while !shutdown.is_shutdown() {
@@ -57,7 +51,7 @@ impl SentNotificationListener {
break;
}
},
_ = shutdown.recv() => {
_ = shutdown.recv_with_delay() => {
log::trace!("SentNotificationListener: Received shutdown");
}
}
@@ -65,13 +59,4 @@ impl SentNotificationListener {
assert!(shutdown.is_shutdown_poll());
log::debug!("SentNotificationListener: Exiting");
}
#[cfg(target_arch = "wasm32")]
pub(super) async fn run(&mut self) {
debug!("Started SentNotificationListener without graceful shutdown support");
while let Some(frag_id) = self.sent_notifier.next().await {
self.on_sent_message(frag_id).await;
}
}
}
@@ -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 log::{debug, error, info, trace, warn};
use nym_sphinx::acknowledgements::AckKey;
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::anonymous_replies::requests::{AnonymousSenderTag, RepliableMessage, ReplyMessage};
use nym_sphinx::anonymous_replies::{ReplySurb, SurbEncryptionKey};
use nym_sphinx::chunking::fragment::{Fragment, FragmentIdentifier};
use nym_sphinx::message::NymMessage;
use nym_sphinx::params::{PacketSize, DEFAULT_NUM_MIX_HOPS};
use nym_sphinx::preparer::{MessagePreparer, PreparedFragment};
use nym_sphinx::Delay;
use nym_task::connections::TransmissionLane;
use nym_topology::{NymTopology, NymTopologyError};
use rand::{CryptoRng, Rng};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::Duration;
use thiserror::Error;
// 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,27 +8,37 @@
use self::{
acknowledgement_control::AcknowledgementController, real_traffic_stream::OutQueueControl,
};
use crate::client::real_messages_control::acknowledgement_control::AcknowledgementControllerConnectors;
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 crate::spawn_future;
use futures::channel::mpsc;
use gateway_client::AcknowledgementReceiver;
use log::*;
use nymsphinx::acknowledgements::AckKey;
use nymsphinx::addressing::clients::Recipient;
use nymsphinx::params::PacketSize;
use nym_sphinx::acknowledgements::AckKey;
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::params::PacketSize;
use nym_task::connections::{ConnectionCommandReceiver, LaneQueueLengths};
use rand::{rngs::OsRng, CryptoRng, Rng};
use std::sync::Arc;
use std::time::Duration;
#[cfg(feature = "reply-surb")]
use crate::client::reply_key_storage::ReplyKeyStorage;
use crate::client::replies::reply_controller;
use crate::config;
pub(crate) use acknowledgement_control::{AckActionSender, Action};
mod acknowledgement_control;
mod real_traffic_stream;
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 {
@@ -59,31 +69,109 @@ pub struct Config {
/// 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_rerequest_waiting_period: Duration,
/// Defines maximum amount of time the client is going to wait for reply surbs before
/// deciding it's never going to get them and would drop all pending messages
maximum_reply_surb_drop_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_rerequest_waiting_period,
cfg.maximum_reply_surb_drop_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 {
// TODO: change the config into a builder
#[allow(clippy::too_many_arguments)]
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,
disable_main_poisson_packet_distribution: bool,
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,
disable_main_poisson_packet_distribution,
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_rerequest_waiting_period: base_client_debug_config
.maximum_reply_surb_rerequest_waiting_period,
maximum_reply_surb_drop_waiting_period: base_client_debug_config
.maximum_reply_surb_drop_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,
}
}
@@ -92,103 +180,112 @@ impl Config {
}
}
pub struct RealMessagesController<R>
pub(crate) struct RealMessagesController<R>
where
R: CryptoRng + Rng,
{
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,
#[cfg(feature = "reply-surb")] 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,
)
.with_custom_packet_size(config.packet_size);
// 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,
ack_controller_connectors,
#[cfg(feature = "reply-surb")]
reply_key_storage,
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,
config.disable_main_poisson_packet_distribution,
)
.with_custom_cover_packet_size(config.packet_size);
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,
ack_control,
reply_control,
}
}
#[cfg(not(target_arch = "wasm32"))]
pub fn start_with_shutdown(self, shutdown: task::ShutdownListener) {
pub fn start_with_shutdown(self, shutdown: nym_task::TaskClient) {
let mut out_queue_control = self.out_queue_control;
let ack_control = self.ack_control;
let mut reply_control = self.reply_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 shutdown_handle = shutdown.clone();
spawn_future(async move {
reply_control.run_with_shutdown(shutdown_handle).await;
debug!("The reply controller has finished execution!");
});
ack_control.start_with_shutdown(shutdown);
}
#[cfg(target_arch = "wasm32")]
pub fn start(self) {
let mut out_queue_control = self.out_queue_control;
let ack_control = self.ack_control;
spawn_future(async move {
out_queue_control.run().await;
debug!("The out queue controller has finished execution!");
});
ack_control.start();
}
}
@@ -1,22 +1,26 @@
// 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 futures::task::{Context, Poll};
use futures::{Future, Stream, StreamExt};
use log::*;
use nymsphinx::acknowledgements::AckKey;
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::utils::sample_poisson_duration;
use nym_sphinx::acknowledgements::AckKey;
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::chunking::fragment::FragmentIdentifier;
use nym_sphinx::cover::generate_loop_cover_packet;
use nym_sphinx::forwarding::packet::MixPacket;
use nym_sphinx::params::PacketSize;
use nym_sphinx::preparer::PreparedFragment;
use nym_sphinx::utils::sample_poisson_duration;
use nym_task::connections::{
ConnectionCommand, ConnectionCommandReceiver, ConnectionId, LaneQueueLengths, TransmissionLane,
};
use rand::{CryptoRng, Rng};
use std::collections::VecDeque;
use std::pin::Pin;
use std::sync::Arc;
use std::time::Duration;
@@ -27,25 +31,16 @@ use tokio::time;
#[cfg(target_arch = "wasm32")]
use wasm_timer;
// The minimum time between increasing the average delay between packets. If we hit the ceiling in
// the available buffer space we want to take somewhat swift action, but we still need to give a
// short time to give the channel a chance reduce pressure.
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;
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,
@@ -65,12 +60,16 @@ pub(crate) struct Config {
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,
@@ -85,101 +84,6 @@ impl Config {
}
}
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
#[cfg(not(target_arch = "wasm32"))]
time_when_changed: time::Instant,
#[cfg(target_arch = "wasm32")]
time_when_changed: wasm_timer::Instant,
/// If we have a long enough time without any backpressure detected we try reducing the sending
/// delay multiplier
#[cfg(not(target_arch = "wasm32"))]
time_when_backpressure_detected: time::Instant,
#[cfg(target_arch = "wasm32")]
time_when_backpressure_detected: wasm_timer::Instant,
}
#[cfg(not(target_arch = "wasm32"))]
fn get_time_now() -> time::Instant {
time::Instant::now()
}
#[cfg(target_arch = "wasm32")]
fn get_time_now() -> wasm_timer::Instant {
wasm_timer::Instant::now()
}
impl SendingDelayController {
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,
}
}
fn current_multiplier(&self) -> u32 {
self.current_multiplier
}
fn increase_delay_multiplier(&mut self) {
self.current_multiplier =
(self.current_multiplier + 1).clamp(self.lower_bound, self.upper_bound);
self.time_when_changed = get_time_now();
log::debug!(
"Increasing sending delay multiplier to: {}",
self.current_multiplier
);
}
fn decrease_delay_multiplier(&mut self) {
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
);
}
fn record_backpressure_detected(&mut self) {
self.time_when_backpressure_detected = get_time_now();
}
fn not_increased_delay_recently(&self) -> bool {
get_time_now()
> self.time_when_changed + Duration::from_secs(INCREASE_DELAY_MIN_CHANGE_INTERVAL_SECS)
}
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
}
}
pub(crate) struct OutQueueControl<R>
where
R: CryptoRng + Rng,
@@ -187,9 +91,6 @@ 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,
@@ -203,7 +104,7 @@ where
// To make sure we don't overload the mix_tx channel, we limit the rate we are pushing
// messages.
sending_rate_controller: SendingDelayController,
sending_delay_controller: SendingDelayController,
/// Channel used for sending prepared sphinx packets to `MixTrafficController` that sends them
/// out to the network without any further delays.
@@ -213,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,
@@ -242,8 +163,9 @@ 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,
@@ -259,29 +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: None,
sending_rate_controller: SendingDelayController::new(
MIN_DELAY_MULTIPLIER,
MAX_DELAY_MULTIPLIER,
),
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,
}
}
@@ -303,24 +222,23 @@ where
// 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.ack_key,
&self.config.our_full_destination,
self.config.average_ack_delay,
self.config.average_packet_delay,
self.config.cover_packet_size,
@@ -337,7 +255,7 @@ where
};
if let Err(err) = self.mix_tx.send(vec![next_message]).await {
log::error!("Failed to send - channel closed: {}", err);
log::error!("Failed to send: {err}");
}
// notify ack controller about sending our message only after we actually managed to push it
@@ -346,6 +264,10 @@ where
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
@@ -357,44 +279,72 @@ where
tokio::task::yield_now().await;
}
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));
}
fn current_average_message_sending_delay(&self) -> Duration {
self.config.average_message_sending_delay
* self.sending_rate_controller.current_multiplier()
* 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_rate_controller.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_rate_controller.record_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_rate_controller.not_increased_delay_recently()
&& self.sending_delay_controller.not_increased_delay_recently()
{
self.sending_rate_controller.increase_delay_multiplier();
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_rate_controller.is_sending_reliable() {
self.sending_rate_controller.decrease_delay_multiplier();
if self.sending_delay_controller.is_sending_reliable() {
self.sending_delay_controller.decrease_delay_multiplier();
}
}
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),
}
}
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() {
@@ -419,28 +369,32 @@ where
next_delay.as_mut().reset(next_poisson_delay);
}
// 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) {
// 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),
// 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(),
))))
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))))
}
// otherwise construct a dummy one
Poll::Pending => Poll::Ready(Some(StreamMessage::Cover)),
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
@@ -462,32 +416,35 @@ where
}
fn poll_immediate(&mut self, cx: &mut Context<'_>) -> Poll<Option<StreamMessage>> {
// check if we have anything immediately available
if let Some(real_available) = self.received_buffer.pop_front() {
// if there are more messages immediately available, notify the runtime
// because we should be polled again
if !self.received_buffer.is_empty() {
cx.waker().wake_by_ref()
// 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),
}
return Poll::Ready(Some(StreamMessage::Real(Box::new(real_available))));
}
match Pin::new(&mut self.real_receiver).poll_next(cx) {
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),
// 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(),
))))
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))))
}
// if there's nothing, then there's nothing
Poll::Pending => Poll::Pending,
Poll::Pending => {
if let Some(real_next) = self.pop_next_message() {
Poll::Ready(Some(StreamMessage::Real(Box::new(real_next))))
} else {
Poll::Pending
}
}
}
}
@@ -503,38 +460,97 @@ where
}
#[cfg(not(target_arch = "wasm32"))]
pub(super) async fn run_with_shutdown(&mut self, mut shutdown: task::ShutdownListener) {
fn log_status(&self, shutdown: &mut nym_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: {backlog:.2} kiB ({packets}), no delay")
} else {
format!(
"Status: {lanes} lanes, backlog: {backlog:.2} kiB ({packets}), avg delay: {delay}ms ({mult})"
)
};
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: nym_task::TaskClient) {
debug!("Started OutQueueControl with graceful shutdown support");
while !shutdown.is_shutdown() {
tokio::select! {
biased;
_ = shutdown.recv() => {
log::trace!("OutQueueControl: Received shutdown");
}
next_message = self.next() => match next_message {
Some(next_message) => {
#[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;
},
None => {
} else {
log::trace!("OutQueueControl: Stopping since channel closed");
break;
}
}
}
shutdown.recv_timeout().await;
}
#[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;
}
}
}
}
assert!(shutdown.is_shutdown_poll());
log::debug!("OutQueueControl: Exiting");
}
#[cfg(target_arch = "wasm32")]
pub(super) async fn run(&mut self) {
debug!("Started OutQueueControl without graceful shutdown support");
while let Some(next_message) = self.next().await {
self.on_message(next_message).await;
}
}
}
impl<R> Stream for OutQueueControl<R>
@@ -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
}
}
+215 -170
View File
@@ -1,26 +1,26 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::replies::reply_controller::ReplyControllerSender;
use crate::client::replies::reply_storage::SentReplyKeys;
use crate::spawn_future;
use crypto::asymmetric::encryption;
use futures::channel::mpsc;
use futures::lock::Mutex;
use futures::StreamExt;
use gateway_client::MixnetMessageReceiver;
use log::*;
use nymsphinx::receiver::{MessageReceiver, MessageRecoveryError, ReconstructedMessage};
use nym_crypto::asymmetric::encryption;
use nym_crypto::Digest;
use nym_sphinx::anonymous_replies::requests::{
RepliableMessage, RepliableMessageContent, ReplyMessage, ReplyMessageContent,
};
use nym_sphinx::anonymous_replies::{encryption_key::EncryptionKeyDigest, SurbEncryptionKey};
use nym_sphinx::message::{NymMessage, PlainMessage};
use nym_sphinx::params::ReplySurbKeyDigestAlgorithm;
use nym_sphinx::receiver::{MessageReceiver, MessageRecoveryError, ReconstructedMessage};
use std::collections::HashSet;
use std::sync::Arc;
#[cfg(feature = "reply-surb")]
use crate::client::reply_key_storage::ReplyKeyStorage;
#[cfg(feature = "reply-surb")]
use crypto::{symmetric::stream_cipher, Digest};
#[cfg(feature = "reply-surb")]
use nymsphinx::anonymous_replies::{encryption_key::EncryptionKeyDigest, SurbEncryptionKey};
#[cfg(feature = "reply-surb")]
use nymsphinx::params::{ReplySurbEncryptionAlgorithm, ReplySurbKeyDigestAlgorithm};
// 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"
pub type ReceivedBufferRequestSender = mpsc::UnboundedSender<ReceivedBufferMessage>;
@@ -46,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 nym_sphinx::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,
@@ -79,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!")
@@ -107,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)]
@@ -114,17 +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
#[cfg(feature = "reply-surb")]
reply_key_storage: ReplyKeyStorage,
reply_key_storage: SentReplyKeys,
reply_controller_sender: ReplyControllerSender,
}
impl ReceivedMessagesBuffer {
fn new(
local_encryption_keypair: Arc<encryption::KeyPair>,
#[cfg(feature = "reply-surb")] reply_key_storage: ReplyKeyStorage,
reply_key_storage: SentReplyKeys,
reply_controller_sender: ReplyControllerSender,
) -> Self {
ReceivedMessagesBuffer {
inner: Arc::new(Mutex::new(ReceivedMessagesBufferInner {
@@ -134,8 +150,8 @@ impl ReceivedMessagesBuffer {
message_sender: None,
recently_reconstructed: HashSet::new(),
})),
#[cfg(feature = "reply-surb")]
reply_key_storage,
reply_controller_sender,
}
}
@@ -177,38 +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()
}
#[cfg(feature = "reply-surb")]
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()
);
@@ -217,69 +338,27 @@ impl ReceivedMessagesBuffer {
let mut inner_guard = self.inner.lock().await;
// 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 {
// TODO:
// 1. make it nicer
// 2. make it not feature-locked
#[cfg(feature = "reply-surb")]
{
let reply_surb_digest_size = ReplySurbKeyDigestAlgorithm::output_size();
let possible_key_digest =
EncryptionKeyDigest::clone_from_slice(&msg[..reply_surb_digest_size]);
// check first `HasherOutputSize` bytes if they correspond to known encryption key
// if yes - this is a reply message
// 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)
}
// 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 {
// otherwise - it's a 'normal' message
if let Some(completed_message) = inner_guard.process_received_fragment(msg) {
completed_messages.push(completed_message)
}
}
}
inner_guard.process_received_regular_packet(msg)
};
#[cfg(not(feature = "reply-surb"))]
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
}
}
}
@@ -320,38 +399,27 @@ impl RequestReceiver {
}
}
#[cfg(not(target_arch = "wasm32"))]
async fn run_with_shutdown(&mut self, mut shutdown: task::ShutdownListener) {
async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) {
debug!("Started RequestReceiver with graceful shutdown support");
while !shutdown.is_shutdown() {
tokio::select! {
biased;
_ = shutdown.recv() => {
_ = shutdown.recv_with_delay() => {
log::trace!("RequestReceiver: Received shutdown");
}
request = self.query_receiver.next() => {
match request {
Some(message) => self.handle_message(message).await,
None => {
log::trace!("RequestReceiver: Stopping since channel closed");
break;
},
if let Some(message) = request {
self.handle_message(message).await
} else {
log::trace!("RequestReceiver: Stopping since channel closed");
break;
}
},
}
}
assert!(shutdown.is_shutdown_poll());
shutdown.recv_timeout().await;
log::debug!("RequestReceiver: Exiting");
}
#[cfg(target_arch = "wasm32")]
async fn run(&mut self) {
debug!("Started RequestReceiver without graceful shutdown support");
while let Some(message) = self.query_receiver.next().await {
self.handle_message(message).await
}
}
}
struct FragmentedMessageReceiver {
@@ -370,55 +438,45 @@ impl FragmentedMessageReceiver {
}
}
#[cfg(not(target_arch = "wasm32"))]
async fn run_with_shutdown(&mut self, mut shutdown: task::ShutdownListener) {
async fn run_with_shutdown(&mut self, mut shutdown: nym_task::TaskClient) {
debug!("Started FragmentedMessageReceiver with graceful shutdown support");
while !shutdown.is_shutdown() {
tokio::select! {
new_messages = self.mixnet_packet_receiver.next() => match new_messages {
Some(new_messages) => {
new_messages = self.mixnet_packet_receiver.next() => {
if let Some(new_messages) = new_messages {
self.received_buffer.handle_new_received(new_messages).await;
}
None => {
} else {
log::trace!("FragmentedMessageReceiver: Stopping since channel closed");
break;
}
},
_ = shutdown.recv() => {
_ = shutdown.recv_with_delay() => {
log::trace!("FragmentedMessageReceiver: Received shutdown");
}
}
}
assert!(shutdown.is_shutdown_poll());
shutdown.recv_timeout().await;
log::debug!("FragmentedMessageReceiver: Exiting");
}
#[cfg(target_arch = "wasm32")]
async fn run(&mut self) {
debug!("Started FragmentedMessageReceiver without graceful shutdown support");
while let Some(new_messages) = self.mixnet_packet_receiver.next().await {
self.received_buffer.handle_new_received(new_messages).await;
}
}
}
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,
#[cfg(feature = "reply-surb")] reply_key_storage: ReplyKeyStorage,
reply_key_storage: SentReplyKeys,
reply_controller_sender: ReplyControllerSender,
) -> Self {
let received_buffer = ReceivedMessagesBuffer::new(
local_encryption_keypair,
#[cfg(feature = "reply-surb")]
reply_key_storage,
reply_controller_sender,
);
ReceivedMessagesBufferController {
@@ -430,8 +488,7 @@ impl ReceivedMessagesBufferController {
}
}
#[cfg(not(target_arch = "wasm32"))]
pub fn start_with_shutdown(self, shutdown: task::ShutdownListener) {
pub fn start_with_shutdown(self, shutdown: nym_task::TaskClient) {
let mut fragmented_message_receiver = self.fragmented_message_receiver;
let mut request_receiver = self.request_receiver;
@@ -445,16 +502,4 @@ impl ReceivedMessagesBufferController {
request_receiver.run_with_shutdown(shutdown).await;
});
}
#[cfg(target_arch = "wasm32")]
pub fn start(self) {
let mut fragmented_message_receiver = self.fragmented_message_receiver;
let mut request_receiver = self.request_receiver;
spawn_future(async move {
fragmented_message_receiver.run().await;
});
spawn_future(async move {
request_receiver.run().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,872 @@
// 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 futures::channel::oneshot;
use futures::StreamExt;
use log::{debug, error, info, trace, warn};
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
use nym_sphinx::anonymous_replies::ReplySurb;
use nym_sphinx::chunking::fragment::{Fragment, FragmentIdentifier};
use nym_task::connections::{ConnectionId, TransmissionLane};
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_rerequest_waiting_period: Duration,
max_surb_drop_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_rerequest_waiting_period: Duration,
max_surb_drop_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_rerequest_waiting_period,
max_surb_drop_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_rerequest_waiting_period {
if diff > self.config.max_surb_drop_waiting_period {
to_remove.push(*pending_reply_target)
} else {
debug!("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: nym_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,154 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::real_messages_control::acknowledgement_control::PendingAcknowledgement;
use futures::channel::{mpsc, oneshot};
use log::error;
use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
use nym_sphinx::anonymous_replies::ReplySurb;
use nym_task::connections::{ConnectionId, TransmissionLane};
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 struct ReplyQueueLengths {
reply_controller_sender: ReplyControllerSender,
}
impl ReplyQueueLengths {
pub fn new(reply_controller_sender: ReplyControllerSender) -> Self {
Self {
reply_controller_sender,
}
}
pub async fn get_lane_queue_length(&self, connection_id: ConnectionId) -> usize {
self.reply_controller_sender
.get_lane_queue_length(connection_id)
.await
}
}
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,62 @@
// 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;
use std::path::PathBuf;
// well, right now we don't have the browser storage : (
// so we keep everything in memory
#[derive(Debug)]
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 new(
debug_config: &crate::config::DebugConfig,
_db_path: Option<PathBuf>,
) -> Result<Self, Self::StorageError> {
Ok(Backend {
empty: Empty {
min_surb_threshold: debug_config.minimum_reply_surb_storage_threshold,
max_surb_threshold: debug_config.maximum_reply_surb_storage_threshold,
},
})
}
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
}
fn get_inactive_storage(&self) -> Result<CombinedReplyStorage, Self::StorageError> {
self.empty.get_inactive_storage()
}
}
@@ -0,0 +1,64 @@
// 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("unable to create the directory for the database")]
DatabasePathUnableToCreateParentDirectory {
provided_path: PathBuf,
source: io::Error,
},
#[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>>
},
#[error("failed to create storage")]
FailedToCreateStorage {
source: Box<dyn std::error::Error + Send + Sync>,
},
}
@@ -0,0 +1,267 @@
// 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> {
// ensure the whole directory structure exists
if let Some(parent_dir) = database_path.as_ref().parent() {
std::fs::create_dir_all(parent_dir).map_err(|source| {
StorageError::DatabasePathUnableToCreateParentDirectory {
provided_path: database_path.as_ref().to_path_buf(),
source,
}
})?;
}
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,441 @@
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::client::base_client::non_wasm_helpers;
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 nym_sphinx::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)]
enum StorageManagerState {
Storage(StorageManager),
Inactive(InactiveMetadata),
}
// When the storage backaed is initialized as inactive, it will still contain metadata parameters
// that will be needed when the in-mem storage is fetched for use.
#[derive(Debug)]
struct InactiveMetadata {
pub minimum_reply_surb_storage_threshold: usize,
pub maximum_reply_surb_storage_threshold: usize,
}
impl StorageManagerState {
fn get(&self) -> &StorageManager {
match self {
StorageManagerState::Storage(manager) => manager,
StorageManagerState::Inactive(_) => {
panic!("tried to get storage of an inactive backend")
}
}
}
fn get_mut(&mut self) -> &mut StorageManager {
match self {
StorageManagerState::Storage(manager) => manager,
StorageManagerState::Inactive(_) => {
panic!("tried to get storage of an inactive backend")
}
}
}
fn is_active(&self) -> bool {
matches!(self, StorageManagerState::Storage(_))
}
}
#[derive(Debug)]
pub struct Backend {
temporary_old_path: Option<PathBuf>,
database_path: PathBuf,
manager: StorageManagerState,
}
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 manager = StorageManager::init(database_path, true).await?;
manager.create_status_table().await?;
let backend = Backend {
temporary_old_path: None,
database_path: owned_path,
manager: StorageManagerState::Storage(manager),
};
Ok(backend)
}
pub fn new_inactive(
minimum_reply_surb_storage_threshold: usize,
maximum_reply_surb_storage_threshold: usize,
) -> Self {
Backend {
temporary_old_path: None,
database_path: PathBuf::new(),
manager: StorageManagerState::Inactive(InactiveMetadata {
minimum_reply_surb_storage_threshold,
maximum_reply_surb_storage_threshold,
}),
}
}
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: StorageManagerState::Storage(manager),
})
}
async fn close_pool(&mut self) {
self.manager.get_mut().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 =
StorageManagerState::Storage(StorageManager::init(&self.database_path, true).await?);
self.manager.get_mut().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.get().set_flush_status(true).await?)
}
async fn end_storage_flush(&self) -> Result<(), StorageError> {
self.manager
.get()
.set_previous_flush_timestamp(OffsetDateTime::now_utc().unix_timestamp())
.await?;
Ok(self.manager.get().set_flush_status(false).await?)
}
async fn start_client_use(&self) -> Result<(), StorageError> {
Ok(self.manager.get().set_client_in_use_status(true).await?)
}
async fn stop_client_use(&self) -> Result<(), StorageError> {
Ok(self.manager.get().set_client_in_use_status(false).await?)
}
async fn get_stored_tags(&self) -> Result<UsedSenderTags, StorageError> {
let stored = self.manager.get().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
.get()
.insert_tag(StoredSenderTag::new(*recipient, *tag))
.await?;
}
Ok(())
}
async fn get_stored_reply_keys(&self) -> Result<SentReplyKeys, StorageError> {
let stored = self.manager.get().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
.get()
.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().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()
.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
.get()
.insert_surb_sender(StoredSurbSender::new(
*tag,
received_surbs.surbs_last_received_at(),
))
.await?;
for reply_surb in received_surbs.surbs_ref() {
self.manager
.get()
.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()
.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
.get()
.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 new(
debug_config: &crate::config::DebugConfig,
db_path: Option<PathBuf>,
) -> Result<Self, Self::StorageError> {
non_wasm_helpers::setup_fs_reply_surb_backend(db_path, debug_config)
.await
.map_err(|err| {
log::error!("Failed to create storage: {err}");
Self::StorageError::FailedToCreateStorage {
source: Box::new(err),
}
})
}
fn is_active(&self) -> bool {
self.manager.is_active()
}
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))
}
fn get_inactive_storage(&self) -> Result<CombinedReplyStorage, Self::StorageError> {
match self.manager {
StorageManagerState::Storage(_) => {
panic!("tried to get inactive storage from an active storage backend")
}
StorageManagerState::Inactive(ref state) => Ok(CombinedReplyStorage::new(
state.minimum_reply_surb_storage_threshold,
state.maximum_reply_surb_storage_threshold,
)),
}
}
async fn stop_storage_session(self) -> Result<(), Self::StorageError> {
self.stop_client_use().await
}
}
@@ -0,0 +1,183 @@
// 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 nym_crypto::generic_array::typenum::Unsigned;
use nym_crypto::Digest;
use nym_sphinx::addressing::clients::{Recipient, RecipientBytes};
use nym_sphinx::anonymous_replies::encryption_key::EncryptionKeyDigest;
use nym_sphinx::anonymous_replies::requests::{AnonymousSenderTag, SENDER_TAG_SIZE};
use nym_sphinx::anonymous_replies::{ReplySurb, SurbEncryptionKey, SurbEncryptionKeySize};
use nym_sphinx::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 {SENDER_TAG_SIZE} was expected",
),
});
};
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 {SENDER_TAG_SIZE} was expected",
),
});
};
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,110 @@
// 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, path::PathBuf};
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;
#[derive(Debug)]
pub struct Empty {
// we need to keep 'basic' metadata here to "load" the CombinedReplyStorage
pub min_surb_threshold: usize,
pub max_surb_threshold: usize,
}
#[async_trait]
impl ReplyStorageBackend for Empty {
type StorageError = UndefinedError;
async fn new(
debug_config: &crate::config::DebugConfig,
_db_path: Option<PathBuf>,
) -> Result<Self, Self::StorageError> {
Ok(Self {
min_surb_threshold: debug_config.minimum_reply_surb_storage_threshold,
max_surb_threshold: debug_config.maximum_reply_surb_storage_threshold,
})
}
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,
))
}
fn get_inactive_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 new(
debug_config: &crate::config::DebugConfig,
db_path: Option<PathBuf>,
) -> Result<Self, Self::StorageError>;
fn is_active(&self) -> bool {
true
}
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>;
/// In the case the storage backend is initialized in an inactive state (persisting data is
/// disabled), we might still need to fetch the (in-mem) storage and the parameters it was
/// created with.
fn get_inactive_storage(&self) -> Result<CombinedReplyStorage, Self::StorageError>;
async fn stop_storage_session(self) -> Result<(), Self::StorageError> {
Ok(())
}
}

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