Compare commits

...

249 Commits

Author SHA1 Message Date
Bogdan-Ștefan Neacşu 7a448e87d5 Verify seen credentials on top ups 2025-05-20 11:55:46 +03:00
Bogdan-Ștefan Neacşu aa58c80db9 Add a cache for the credentials seen before on top-up 2025-05-20 11:55:40 +03:00
benedetta davico 7a9c41ad73 bump nym-api version 2025-05-14 10:04:28 +02:00
Jędrzej Stuczyński ea0d2f8c66 feat: expires header for /active nym-api responses (#5755)
* refactor FormattedResponse to allow attaching additional headers

* helper method for including expiration headers

* add expires header for /active nodes responses

* added additional 'with_expires_header_delta' builder to FormattedResponse to allow setting expiration header with time delta
2025-05-13 16:03:44 +01:00
Jędrzej Stuczyński e849e608b2 feat: nym-api bincode + yaml support (#5745)
* introduce 'Bincode' variant for FormattedResponse

* allow nym-api to return responses in bincode (and also yaml)

* client parsing support

* cargo fmt

* missing changes to nym-api tests

* fixed node status api build + adjusted NymApiClient construction

* NMv2 fixes + further api changes

* feature-locking http-api-common to fix wasm build
2025-05-13 16:03:22 +01:00
benedettadavico 3f6acbfd66 update changelog 2025-05-13 11:42:50 +02:00
benedettadavico 899a2bfc8a bump binary versions 2025-05-07 11:22:45 +02:00
import this 3049abf4f1 [DOCs/operators]: Tokenomics hotfix 2025-05-05 12:20:44 +00:00
benedetta davico 1dc42df59c Merge pull request #5734 from nymtech/release/2025.8-tourist
Merge release/2025.8-tourist to develop
2025-05-05 12:11:28 +02:00
import this e2b85c91df [DOCs]: TimeNow and Vars value sync up (#5736) 2025-04-30 12:38:31 +00:00
import this 796a7fba0a [DOCs/operators]: Tokenomics updates & v2025.8-tourist release notes (#5732)
* initialise tokenomics update

* ready for review

* move info block lower down

* edit phrasing and add formulas

* delete extra syntax

* update syntax

* add release notes
2025-04-30 12:13:41 +00:00
dynco-nym fbcf44eeb9 Add /account/{address} (#5673)
* Add /account/{address}

* Don't query vesting info

* Don't query rewards

* Remove unused code

* Fix clippy

* Fix build.rs build on Windows

* Addressing PR feedback
- not cloning nym nodes from cache
- reduced number of nym nodes kept in memory
- reduced number of iterations to read all data
- removed some fields

* Fix total_delegations

* Optimize nym_nodes hashmap

* Split flow into functions

* Remove vesting info

* Add caching for endpoint

* Cache optimizations

* Return early if balance is 0

* Refactor state cloning shenanigans
2025-04-29 13:23:14 +02:00
benedettadavico e594630314 update changelog 2025-04-29 12:19:54 +02:00
dynco-nym f4785099c2 Add nodes/delegations endpoint (#5733)
* WIP

* Add /delegations endpoint

* Bump package version

* Remove node_id field
2025-04-28 23:59:40 +02:00
benedettadavico 9c2595d9ef bump versions 2025-04-25 15:47:20 +02:00
Jędrzej Stuczyński b04d3ba376 add reserved byte to reply surb serialisation (#5731) 2025-04-25 10:05:38 +01:00
Jędrzej Stuczyński 5ad1f0b61a add reserved byte to reply surb serialisation (#5731) 2025-04-25 10:02:32 +01:00
Jędrzej Stuczyński b2dfdda210 NET-271: bugfix: use node saturation instead of its stake for selection weight (#5717) 2025-04-24 15:39:14 +01:00
dependabot[bot] 41ef3a26f5 build(deps-dev): bump http-proxy-middleware in /wasm/client/internal-dev (#5719)
Bumps [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware) from 2.0.6 to 2.0.9.
- [Release notes](https://github.com/chimurai/http-proxy-middleware/releases)
- [Changelog](https://github.com/chimurai/http-proxy-middleware/blob/v2.0.9/CHANGELOG.md)
- [Commits](https://github.com/chimurai/http-proxy-middleware/compare/v2.0.6...v2.0.9)

---
updated-dependencies:
- dependency-name: http-proxy-middleware
  dependency-version: 2.0.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-24 10:27:12 +01:00
dependabot[bot] bae1b488de build(deps): bump golang.org/x/net in /wasm/mix-fetch/go-mix-conn (#5720)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.36.0 to 0.38.0.
- [Commits](https://github.com/golang/net/compare/v0.36.0...v0.38.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.38.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-24 10:26:52 +01:00
dependabot[bot] 40cf2c441a build(deps): bump clap from 4.5.36 to 4.5.37 in the patch-updates group (#5722)
Bumps the patch-updates group with 1 update: [clap](https://github.com/clap-rs/clap).


Updates `clap` from 4.5.36 to 4.5.37
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.36...clap_complete-v4.5.37)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.37
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-24 10:26:32 +01:00
windy-ux 34871b14b3 / change landing page tab title to "Nym docs" (#5729) 2025-04-23 15:32:34 +00:00
dynco-nym c14b010f9e Eliminate duplicate node_ids from endpoint (#5728)
* Improve swagger definitions

* Sort data in DB

* Improve logging

* Store gw description to nym nodes table

* Move explorer related path to /explorer

* Bump package version
2025-04-23 15:19:15 +02:00
benedetta davico 04f75e7e48 Merge pull request #5726 from nymtech/release/2025.7-tex
Merge tex to develop
2025-04-22 10:50:40 +02:00
Bogdan-Ștefan Neacşu 866dcd1e39 Peer handle should die more gracefully (#5704)
* Don't exit handle without having peer removed

* Kernel going back to 0 is not an error

* Fix build

* Add stronger message for failure on last resort remove
2025-04-22 10:34:46 +03:00
Bogdan-Ștefan Neacşu a8526d698e Remove inactive peers (#5721) 2025-04-17 12:49:43 +03:00
import this 3f5e0cdb1f [DOCs/operators]: Release notes for v2025.7 tex (#5718)
* bump version in setup pafe

* testing menu changes propagation

* add release notes to changelog

* add NSL announcement

* add announcement for debian versions

* sync up styling
2025-04-16 12:56:05 +00:00
Jack Wampler 96239a7812 allow client to specify whether to include mix hops or not in MixnetClient Debug Config (#5696) 2025-04-15 10:49:11 -06:00
windy-ux 762cfb8709 Merge branch 'locale/add_docs_favicon' (#5716) 2025-04-15 16:16:28 +00:00
dependabot[bot] 9835ad3396 build(deps): bump next from 14.2.21 to 14.2.25 (#5655)
Bumps [next](https://github.com/vercel/next.js) from 14.2.21 to 14.2.25.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v14.2.21...v14.2.25)

---
updated-dependencies:
- dependency-name: next
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 16:49:05 +01:00
dependabot[bot] f73a3ac932 build(deps): bump openssl from 0.10.70 to 0.10.72 in /nym-wallet (#5688)
Bumps [openssl](https://github.com/sfackler/rust-openssl) from 0.10.70 to 0.10.72.
- [Release notes](https://github.com/sfackler/rust-openssl/releases)
- [Commits](https://github.com/sfackler/rust-openssl/compare/openssl-v0.10.70...openssl-v0.10.72)

---
updated-dependencies:
- dependency-name: openssl
  dependency-version: 0.10.72
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 16:48:56 +01:00
dependabot[bot] 5af4d8d862 build(deps): bump actions/checkout from 3 to 4 (#5700)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 16:48:45 +01:00
Jack Wampler 2c81195e79 Update Hickory DNS "0.24.4" to "0.25" (#5709)
update the dependency on hickory dns to the latest minor version
2025-04-15 09:30:23 -06:00
dependabot[bot] 4a9066fb6b build(deps): bump pnpm/action-setup from 4.0.0 to 4.1.0 (#5436)
Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](https://github.com/pnpm/action-setup/compare/v4.0.0...v4.1.0)

---
updated-dependencies:
- dependency-name: pnpm/action-setup
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 16:24:17 +01:00
dependabot[bot] 86cc600ea3 build(deps): bump crossbeam-channel from 0.5.14 to 0.5.15 in /nym-wallet (#5703)
Bumps [crossbeam-channel](https://github.com/crossbeam-rs/crossbeam) from 0.5.14 to 0.5.15.
- [Release notes](https://github.com/crossbeam-rs/crossbeam/releases)
- [Changelog](https://github.com/crossbeam-rs/crossbeam/blob/master/CHANGELOG.md)
- [Commits](https://github.com/crossbeam-rs/crossbeam/compare/crossbeam-channel-0.5.14...crossbeam-channel-0.5.15)

---
updated-dependencies:
- dependency-name: crossbeam-channel
  dependency-version: 0.5.15
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 16:22:39 +01:00
dependabot[bot] 459b109b5c build(deps): bump the patch-updates group across 1 directory with 7 updates (#5708)
Bumps the patch-updates group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [anyhow](https://github.com/dtolnay/anyhow) | `1.0.97` | `1.0.98` |
| [clap](https://github.com/clap-rs/clap) | `4.5.34` | `4.5.36` |
| [env_logger](https://github.com/rust-cli/env_logger) | `0.11.7` | `0.11.8` |
| [flate2](https://github.com/rust-lang/flate2-rs) | `1.1.0` | `1.1.1` |
| [hyper-util](https://github.com/hyperium/hyper-util) | `0.1.10` | `0.1.11` |
| [tendermint](https://github.com/informalsystems/tendermint-rs) | `0.40.1` | `0.40.3` |
| [tendermint-rpc](https://github.com/informalsystems/tendermint-rs) | `0.40.1` | `0.40.3` |



Updates `anyhow` from 1.0.97 to 1.0.98
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.97...1.0.98)

Updates `clap` from 4.5.34 to 4.5.36
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.34...clap_complete-v4.5.36)

Updates `env_logger` from 0.11.7 to 0.11.8
- [Release notes](https://github.com/rust-cli/env_logger/releases)
- [Changelog](https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rust-cli/env_logger/compare/v0.11.7...v0.11.8)

Updates `flate2` from 1.1.0 to 1.1.1
- [Release notes](https://github.com/rust-lang/flate2-rs/releases)
- [Commits](https://github.com/rust-lang/flate2-rs/compare/1.1.0...1.1.1)

Updates `hyper-util` from 0.1.10 to 0.1.11
- [Release notes](https://github.com/hyperium/hyper-util/releases)
- [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.10...v0.1.11)

Updates `tendermint` from 0.40.1 to 0.40.3
- [Release notes](https://github.com/informalsystems/tendermint-rs/releases)
- [Changelog](https://github.com/informalsystems/tendermint-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/informalsystems/tendermint-rs/compare/v0.40.1...v0.40.3)

Updates `tendermint-rpc` from 0.40.1 to 0.40.3
- [Release notes](https://github.com/informalsystems/tendermint-rs/releases)
- [Changelog](https://github.com/informalsystems/tendermint-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/informalsystems/tendermint-rs/compare/v0.40.1...v0.40.3)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-version: 1.0.98
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: clap
  dependency-version: 4.5.36
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: env_logger
  dependency-version: 0.11.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: flate2
  dependency-version: 1.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: hyper-util
  dependency-version: 0.1.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: tendermint
  dependency-version: 0.40.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: tendermint-rpc
  dependency-version: 0.40.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-15 16:22:00 +01:00
benedetta davico 08b6be93c4 Update publish-nym-binaries.yml 2025-04-15 15:29:46 +02:00
benedetta davico f0d3d41a1f Update publish-nym-binaries.yml 2025-04-15 14:27:34 +02:00
import this 9a42cab16d testing menu change (#5711) 2025-04-15 12:17:11 +00:00
import this 970db22702 [DOCs]: Menu change (#5710) 2025-04-15 12:00:33 +00:00
Yana Matrosova 2c7df5766c Merge pull request #5706 from nymtech/yana/explorer-caching
Yana/explorer caching
2025-04-14 10:03:44 -07:00
Yana 7ca2559f99 Add caching on tanstack queries
clean up

Another try

clean up

fix build

fix build

fix build

fix build

Refactor Node page to accept identity_key in params
fix build

fix build

fix buggy data on landing page graphs

Try fix gas fee for redeem all rewards

Another try to fix gas fee for redeem rewards

Add fees "auto" to the cosmWasm client with offline signer

comment out unused option

add getOfflineSigner dependency to the callback fn

comment out for good

clean up, optimise homepage layout

Dark theme
fix build

fix build

add fixes
Rebase onto develop, fix lint error

fix build

Fix tooltip

Fix switch button on mobile header

fix build

clean up

fix build

Fix switch component

fix build

Add moniker to Magic Search, fix tooltip hover on landing page

refactor urls

fix build

edit placeholder

Fix styles

fix error message
2025-04-14 17:01:44 +03:00
benedettadavico b9dcafa04f update wallet changelog 2025-04-14 15:39:16 +02:00
benedettadavico 260a7de083 update changelog 2025-04-14 15:06:28 +02:00
benedetta davico 51ca727ff2 revert nym-api version bump 2025-04-14 15:03:37 +02:00
Jędrzej Stuczyński 84db9f6bcd chore: rename 'identity' module to 'ed25519' and 'encryption' to 'x25519' (#5707) 2025-04-13 11:58:25 +01:00
dynco-nym 660463908d Expand /v3/nym-nodes with geodata (#5686)
* Expand /v3/nym-nodes
- includes node description and geodata
- expanded scope of included geodata

* Fetch geodata for all nodes

* Bump package version
2025-04-10 21:12:33 +02:00
dependabot[bot] 0be844e015 build(deps): bump crossbeam-channel from 0.5.14 to 0.5.15 (#5702) 2025-04-10 20:06:50 +02:00
Yana Matrosova efa6e7d7c7 Merge pull request #5669 from nymtech/yana/explorer-caching
Yana/explorer caching
2025-04-10 18:41:31 +03:00
dynco-nym 33c783bb7c Bump package version 2025-04-10 17:22:21 +02:00
Bogdan-Ștefan Neacşu 16059211b9 Add contains ticketbook data db query (#5670)
* Add contains ticketbook data db query

* Fix clippy

* Use exists for better performance
2025-04-10 18:21:50 +03:00
Yana bb6c920767 fix build 2025-04-10 17:24:40 +03:00
Yana 8c4df963c9 Fix switch button on mobile header 2025-04-10 17:23:04 +03:00
Yana af737596ca Fix tooltip 2025-04-10 16:50:45 +03:00
Jędrzej Stuczyński af2c4f50b6 Feature/updated sphinx payload keys (#5698)
* removed support for legacy packet types from NymCodec

I think nodes had plenty of time to upgrade given versioned variant was introduced in 2022

* temp: use local sphinx packet for development

* introduce new messages that use more efficient reply surbs encoding

* checks for incorrect encoding

* generate correct message depending on config value

* fixed current packet version

* made packet type selection configurable

* updated sphinx packet crate to the published version

* fixed wasm build

* fixes in outfox due to sphinx api changes

* additional tests

* clippy

* fixed log/tracing import
2025-04-10 13:43:29 +01:00
Jędrzej Stuczyński 02ed64557d chore: removed old explorer-api (#5701) 2025-04-10 11:26:24 +01:00
Yana 38dabd8d0d fix build 2025-04-10 11:38:43 +03:00
Yana d9de5cfa33 Rebase onto develop, fix lint error 2025-04-10 11:29:13 +03:00
Yana bdfbfde463 add fixes 2025-04-10 11:14:58 +03:00
Yana 5179f38ad2 fix build 2025-04-10 11:14:54 +03:00
Yana f4e9abcd22 fix build 2025-04-10 11:14:54 +03:00
Yana 46ebd84b02 Dark theme 2025-04-10 11:14:54 +03:00
Yana d8d2f99a18 clean up, optimise homepage layout 2025-04-10 11:14:49 +03:00
Yana cd3ec5f3bd comment out for good 2025-04-10 11:14:49 +03:00
Yana 32a16ef025 add getOfflineSigner dependency to the callback fn 2025-04-10 11:14:48 +03:00
Yana 6af4e44f55 comment out unused option 2025-04-10 11:14:48 +03:00
Yana 3cddc594b4 Add fees "auto" to the cosmWasm client with offline signer 2025-04-10 11:14:48 +03:00
Yana d11aaed392 Another try to fix gas fee for redeem rewards 2025-04-10 11:14:48 +03:00
Yana 1bead28150 Try fix gas fee for redeem all rewards 2025-04-10 11:14:48 +03:00
Yana 735bed5cd7 fix buggy data on landing page graphs 2025-04-10 11:14:48 +03:00
Yana 12e0d34885 fix build 2025-04-10 11:14:48 +03:00
Yana 43af3b8a3b fix build 2025-04-10 11:14:48 +03:00
Yana 8ff96b11c9 Refactor Node page to accept identity_key in params 2025-04-10 11:14:48 +03:00
Yana df453158d6 fix build 2025-04-10 11:14:36 +03:00
Yana abeeadb661 fix build 2025-04-10 11:14:36 +03:00
Yana 752fe7fa0f fix build 2025-04-10 11:14:36 +03:00
Yana c5ec682088 fix build 2025-04-10 11:14:36 +03:00
Yana 58a569cd26 clean up 2025-04-10 11:14:36 +03:00
Yana 2e767a2586 Another try 2025-04-10 11:14:35 +03:00
Yana dc772d8759 clean up 2025-04-10 11:14:35 +03:00
Yana 9e70c7a32d Add caching on tanstack queries 2025-04-10 11:14:35 +03:00
Jon Häggblad ba5e86e842 Bump the nym-vpn deb metapackage to 1.0 (#5697) 2025-04-09 18:07:55 +02:00
Tommy Verrall b7313656e9 Merge pull request #5699 from nymtech/fix/sign-in-page-wallet
Allow copy and paste on logins fields for the wallet
2025-04-09 15:15:28 +01:00
Tommy Verrall 2eb695088f linting and yarn
- modify log screen
2025-04-09 16:14:11 +02:00
Tommy Verrall eb612d47c0 Allow copy and paste on logins
- allow shell open for linking - some platforms it's not working as expected
2025-04-09 14:55:12 +02:00
benedetta davico 2ba7b26e5d Merge pull request #5659 from nymtech/benny/revamp-api-tests
Adding fresh nym-api tests and workflow
2025-04-09 13:13:24 +02:00
Tommy Verrall 4cd0f7b56f Merge pull request #5687 from nymtech/feature/test-v2
Tauri V2 - Wallet Migration
2025-04-09 12:09:41 +01:00
Tommy Verrall 600bf42a95 conflicts 2025-04-09 12:51:31 +02:00
Tommy Verrall 748e3e4248 fix remaining lint and cargo clippy errors 2025-04-09 12:46:03 +02:00
dependabot[bot] 8cf1b6427a build(deps): bump tokio from 1.44.0 to 1.44.2 in /nym-wallet (#5694) 2025-04-09 12:40:37 +02:00
Tommy Verrall 7a888c6fdf fix wallet ci 2025-04-09 12:17:02 +02:00
Tommy Verrall 9a9bb89d89 fix lint again 2025-04-09 12:14:49 +02:00
Tommy Verrall 4cc14ddcc4 cargo fmt
- hopefully the last
2025-04-09 11:53:47 +02:00
Tommy Verrall 2dbf9d97cb yarn lint fix 2025-04-09 11:47:10 +02:00
Tommy Verrall 91b6f3cc3e paste not working from currency form
- removed shellhelper too
2025-04-09 11:22:09 +02:00
Tommy Verrall 84cccffcbd Fix PR comments
- removed the shell open in favour of the tauri plugin for opening
- cleaned up some code
- added a few packages
2025-04-09 10:27:25 +02:00
benedetta davico 7de346cf89 add env 2025-04-09 10:07:55 +02:00
benedetta davico d6c40aee01 add env 2025-04-09 10:07:49 +02:00
Tommy Verrall af16b3f059 first code review comments 2025-04-09 09:12:21 +02:00
Tommy Verrall b1cde0716e Fix delegation list 2025-04-08 20:10:05 +02:00
Tommy Verrall 45bcdb03d8 fix delegations page - after overflow 2025-04-08 19:29:32 +02:00
benedetta davico 0841b8701d change path 2025-04-08 19:04:47 +02:00
benedetta davico 7ae228d8f4 change path 2025-04-08 19:03:58 +02:00
benedetta davico 916d33c8c0 Update nym-api-integration-tests.yml 2025-04-08 18:55:57 +02:00
benedetta davico 9b4b2d1a46 Update Makefile 2025-04-08 18:55:25 +02:00
benedettadavico aef0a52c4b fix workflow typo 2025-04-08 18:49:40 +02:00
Tommy Verrall 44682b5ef0 removed duplicates and reverted back to 1.2.18 as a version 2025-04-08 18:46:52 +02:00
benedettadavico f282ffd8a6 remove missed line 2025-04-08 18:42:44 +02:00
benedettadavico dfbeb8b1f8 reformatting, tidying up 2025-04-08 18:38:18 +02:00
benedettadavico fc06fe39a2 more clippy fixes 2025-04-08 17:43:36 +02:00
benedettadavico caa94c142f fix clippy 2025-04-08 17:15:47 +02:00
benedettadavico 1a5c54084e fmt 2025-04-08 17:01:46 +02:00
benedettadavico 49d203e18d better response handling 2025-04-08 16:59:30 +02:00
Tommy Verrall 51c9b012e2 merge conflicts 2025-04-08 16:50:45 +02:00
Tommy Verrall 50b1175622 Merge branch 'develop' into feature/test-v2 2025-04-08 16:40:00 +02:00
Tommy Verrall 29ee5984fb fix all workflows 2025-04-08 16:21:15 +02:00
Tommy Verrall e542b25ffc bump to version 2.0.0
- it's a big release therefore let's semver it correctly
2025-04-08 16:03:36 +02:00
Tommy Verrall 516d3f04cf No need to publish these to the build server just use the artifacts 2025-04-08 15:57:20 +02:00
benedetta davico 9225e0a630 Merge branch 'develop' into benny/revamp-api-tests 2025-04-08 15:43:31 +02:00
Tommy Verrall 08c09781c7 Fixing all yarn lint errors 2025-04-08 14:36:42 +02:00
benedettadavico 36a4d96f34 cargo fmt 2025-04-08 13:48:42 +02:00
benedettadavico 139c911350 use env var for api url and make asserts uniform 2025-04-08 13:40:17 +02:00
Tommy Verrall c92de832e4 remove arg 2025-04-08 12:12:13 +02:00
Tommy Verrall d9d62195cb try again 2025-04-08 12:05:28 +02:00
Tommy Verrall da9115d51b format 2025-04-08 11:58:48 +02:00
benedettadavico bfddc1e4c1 clean up the test dir 2025-04-08 11:56:45 +02:00
benedettadavico 080d75204e first commit to cleaning up nym-api tests 2025-04-08 11:56:45 +02:00
Tommy Verrall 1367cad99d another attempt 2025-04-08 11:54:47 +02:00
Tommy Verrall 4f6d65ab95 revert previous add more logging 2025-04-08 11:50:27 +02:00
Tommy Verrall 4292d8ac03 update windows build 2025-04-08 11:40:50 +02:00
Tommy Verrall dcb6de2421 tauri path 2025-04-08 11:22:38 +02:00
Tommy Verrall 1f5ed41bb3 correct tauri path 2025-04-08 11:21:53 +02:00
Tommy Verrall 091e98aa74 attempt windows build 2025-04-08 11:14:19 +02:00
Jędrzej Stuczyński 0e38126fc5 Feature/replay protection (#5682)
* remove old packettype + fix: apply routing filter BEFORE delaying

* updated sphinx crate for allow usage of reply tags

* full pipeline for placeholder checking of packet replay

* replay protection with batched insertion

* running background task for clearing/flushing the BF

* allow disabling the replay detection + cleanup

* allow unwrap in bench code
2025-04-08 09:50:25 +01:00
Tommy Verrall ecbe192a88 try 22.04 2025-04-08 10:20:50 +02:00
Tommy Verrall f0ee49788c test old runner first 2025-04-08 10:18:32 +02:00
Tommy Verrall d2ff3cb88d fix app deps 2025-04-08 10:15:27 +02:00
Tommy Verrall 873d15a5e1 update runner platform 2025-04-08 10:13:30 +02:00
Tommy Verrall 53792cc839 Update runner for linux 2025-04-08 10:00:22 +02:00
Tommy Verrall 415ef1bf13 attempt to push to ci 2025-04-08 09:53:35 +02:00
benedettadavico edfe29b738 bump versions 2025-04-08 09:46:48 +02:00
Tommy Verrall a4f6426bf9 Update account display 2025-04-08 09:32:46 +02:00
dependabot[bot] 0870911b3c build(deps): bump tokio from 1.44.1 to 1.44.2 (#5693) 2025-04-08 08:01:40 +02:00
Tommy Verrall 9f23887cc0 Input fields 2025-04-07 20:07:15 +02:00
Tommy Verrall 8ab269fa05 Jazz up receive modal 2025-04-07 17:16:22 +02:00
Tommy Verrall 7b75f22a8e Remove legacy 2025-04-07 15:27:54 +02:00
Tommy Verrall ca0449e03d Init clipboard manager 2025-04-07 14:22:55 +02:00
Tommy Verrall 224e63d275 Rename and update 2025-04-07 11:37:22 +02:00
Tommy Verrall 3d77283056 Add pruning warning errors 2025-04-07 10:29:03 +02:00
Tommy Verrall 7cc473005b More permissions errors
- fix more perm errors
- enabled the version in the wallet
2025-04-07 10:09:47 +02:00
Tommy Verrall f874284850 - Update beyond tauri v2
- use the latest and greatest
- fixed links to use the command shell
- app version changes, need to be fixed to allow the auto updater too work
2025-04-04 18:47:35 +02:00
Tommy Verrall 7b6077ba64 update to log in
- next up fix hyperlinks
2025-04-04 13:56:20 +02:00
dynco-nym 0d4188785b Fetch geodata for all nodes 2025-04-04 13:00:25 +02:00
Jędrzej Stuczyński 12026305d5 chore: clippy for 1.86 (#5685)
* chore: clippy for 1.86

* clippy inside wallet
2025-04-04 10:43:21 +01:00
import this 257e36ddcb Featrure: Bash scripts to init and configure VMs conveniently and update docs (#5681)
* create VM init and config scripts

* PR ready for review

* address review comments

* syntax fix
2025-04-04 09:17:30 +00:00
Jon Häggblad ad81c6d27e Move all workflows on ubuntu-20 to ubuntu-22 (#5455)
* Move all workflows on ubuntu-20 to ubuntu-22

* Add missing -y for installing rsync in ci-docs

* Install rsync with --yes

* Switch two jobs to github hosted free tier runners
2025-04-04 11:05:02 +02:00
Tommy Verrall ae52b7b71f Merge pull request #5483 from nymtech/dependabot/npm_and_yarn/elliptic-6.6.1
build(deps): bump elliptic from 6.5.5 to 6.6.1
2025-04-04 08:48:29 +00:00
Tommy Verrall 854d3cceac Merge pull request #5665 from nymtech/dependabot/npm_and_yarn/sdk/typescript/tests/integration-tests/mix-fetch/multi-eeeba236cb
build(deps): bump tar-fs and puppeteer in /sdk/typescript/tests/integration-tests/mix-fetch
2025-04-04 08:45:49 +00:00
benedetta davico 1bdf867fdb Merge pull request #5684 from nymtech/benny/fix-mac-build
Fix the mac build of the wallet
2025-04-04 10:45:05 +02:00
benedetta davico 5a88b5b6a8 upper case 2025-04-04 10:39:40 +02:00
benedettadavico 5ab4d3c22c bump wallet version 2025-04-04 10:12:00 +02:00
benedetta davico b529883b81 Update package.json 2025-04-04 10:11:03 +02:00
benedetta davico 07f624660c Update Cargo.toml 2025-04-04 10:10:37 +02:00
benedetta davico 71f8e736d8 Update publish-nym-wallet-macos.yml 2025-04-04 10:09:58 +02:00
benedetta davico d3573e78e0 Merge pull request #5677 from nymtech/benny/update-node-versions
Update node versions in CI
2025-04-04 09:26:47 +02:00
dynco-nym 86c05267c2 Expand /v3/nym-nodes
- includes node description and geodata
- expanded scope of included geodata
2025-04-03 22:45:28 +02:00
import this e6e74855af [DOCs/operators]: Release notes 2025.6-chuckles (#5678)
* release notes finished

* add explorer info
2025-04-02 14:28:31 +00:00
Tommy Verrall b4865520a4 Revert "add the base points back in"
This reverts commit 400aa6ba6d.
2025-04-02 15:36:49 +02:00
Tommy Verrall f52ebfb9c3 Merge remote-tracking branch 'origin/feature/test-v2' into feature/test-v2 2025-04-02 15:34:12 +02:00
Tommy Verrall 6ca2a3c539 migrate to v2
- lots to check and do
2025-04-02 15:22:27 +02:00
Tommy Verrall 717c9066d6 Merge remote-tracking branch 'origin/feature/test-v2' into feature/test-v2 2025-04-02 15:18:26 +02:00
Tommy Verrall 2760a17323 add the base points back in
- now i've reverted back to the original two here, as the compiler is failing around `tauri::api::path` however, looking into the new design for the path resolver in tower this tasks, requires pratically changing the whole wallet_strorage and config set up
- it seems pretty straight forward https://v2.tauri.app/start/migrate/from-tauri-1/#migrate-path-to-tauri-manager - however, I would need a second set of eyes on this
2025-04-02 15:18:11 +02:00
Tommy Verrall 4e9f1bc0ed migrate to v2
- lots to check and do
2025-04-02 15:17:44 +02:00
Tommy Verrall d35023d14b Merge remote-tracking branch 'origin/feature/test-v2' into feature/test-v2 2025-04-02 15:14:02 +02:00
Tommy Verrall 400aa6ba6d add the base points back in
- now i've reverted back to the original two here, as the compiler is failing around `tauri::api::path` however, looking into the new design for the path resolver in tower this tasks, requires pratically changing the whole wallet_strorage and config set up
- it seems pretty straight forward https://v2.tauri.app/start/migrate/from-tauri-1/#migrate-path-to-tauri-manager - however, I would need a second set of eyes on this
2025-04-02 15:13:42 +02:00
Tommy Verrall 2ba74ae120 migrate to v2
- lots to check and do
2025-04-02 15:13:42 +02:00
fmtabbara 99d8aebea9 fix build 2025-04-02 13:08:16 +01:00
benedettadavico 0bde4dfc84 update to node v20 2025-04-02 11:41:27 +02:00
benedetta davico a56068e28a Merge pull request #5671 from nymtech/release/2025.6-chuckles
Merge release/2025.6-chuckles into develop
2025-04-02 10:35:16 +02:00
Tommy Verrall 9a4293a5b9 add the base points back in
- now i've reverted back to the original two here, as the compiler is failing around `tauri::api::path` however, looking into the new design for the path resolver in tower this tasks, requires pratically changing the whole wallet_strorage and config set up
- it seems pretty straight forward https://v2.tauri.app/start/migrate/from-tauri-1/#migrate-path-to-tauri-manager - however, I would need a second set of eyes on this
2025-04-02 08:53:40 +02:00
Tommy Verrall cdddb44099 migrate to v2
- lots to check and do
2025-04-01 17:06:21 +02:00
Jack Wampler d309b44ad7 Minor fixes involving key cloning and hashing (#5664) 2025-04-01 08:34:39 -06:00
benedetta davico 22539c3e7d Update wallet mac runner 2025-04-01 15:41:12 +02:00
benedetta davico edde411568 Update publish-nym-wallet-macos.yml 2025-04-01 15:29:25 +02:00
benedetta davico 75f2fb7039 Update publish-nym-wallet-macos.yml 2025-04-01 12:14:48 +02:00
benedetta davico f768c8e8e2 Update publish-nym-wallet-ubuntu.yml 2025-04-01 12:14:12 +02:00
benedetta davico 200efebc37 Update publish-nym-wallet-win11.yml 2025-04-01 12:12:14 +02:00
benedettadavico a429d6528e bump wallet version 2025-04-01 11:41:15 +02:00
benedettadavico ebed210de2 update wallet changelog 2025-04-01 10:16:08 +02:00
Jędrzej Stuczyński d062524d32 mix throughput tester (#5661)
* wip: sending with single client

* tag packets to measure latency

* constantly logging rates

* concurrency

* adjusting some values

* write results to files upon completion
2025-03-31 15:57:24 +01:00
benedettadavico f1d3c33391 Update changelog 2025-03-31 16:20:56 +02:00
dependabot[bot] 89eea3100e build(deps): bump the patch-updates group across 1 directory with 8 updates (#5668)
Bumps the patch-updates group with 7 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [clap](https://github.com/clap-rs/clap) | `4.5.32` | `4.5.34` |
| [clap_complete](https://github.com/clap-rs/clap) | `4.5.46` | `4.5.47` |
| [once_cell](https://github.com/matklad/once_cell) | `1.21.1` | `1.21.3` |
| [reqwest](https://github.com/seanmonstar/reqwest) | `0.12.4` | `0.12.15` |
| [tempfile](https://github.com/Stebalien/tempfile) | `3.19.0` | `3.19.1` |
| [time](https://github.com/time-rs/time) | `0.3.39` | `0.3.41` |
| [uniffi](https://github.com/mozilla/uniffi-rs) | `0.29.0` | `0.29.1` |



Updates `clap` from 4.5.32 to 4.5.34
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.32...clap_complete-v4.5.34)

Updates `clap_complete` from 4.5.46 to 4.5.47
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.46...clap_complete-v4.5.47)

Updates `once_cell` from 1.21.1 to 1.21.3
- [Changelog](https://github.com/matklad/once_cell/blob/master/CHANGELOG.md)
- [Commits](https://github.com/matklad/once_cell/compare/v1.21.1...v1.21.3)

Updates `reqwest` from 0.12.4 to 0.12.15
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.12.4...v0.12.15)

Updates `tempfile` from 3.19.0 to 3.19.1
- [Changelog](https://github.com/Stebalien/tempfile/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Stebalien/tempfile/compare/v3.19.0...v3.19.1)

Updates `time` from 0.3.39 to 0.3.41
- [Release notes](https://github.com/time-rs/time/releases)
- [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md)
- [Commits](https://github.com/time-rs/time/compare/v0.3.39...v0.3.41)

Updates `uniffi` from 0.29.0 to 0.29.1
- [Changelog](https://github.com/mozilla/uniffi-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mozilla/uniffi-rs/compare/v0.29.0...v0.29.1)

Updates `uniffi_build` from 0.29.0 to 0.29.1
- [Changelog](https://github.com/mozilla/uniffi-rs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mozilla/uniffi-rs/compare/v0.29.0...v0.29.1)

---
updated-dependencies:
- dependency-name: clap
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: clap_complete
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: once_cell
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: reqwest
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: tempfile
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: time
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: uniffi
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
- dependency-name: uniffi_build
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: patch-updates
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 15:51:06 +02:00
Jon Häggblad d893c806c2 Update log crate (#5667) 2025-03-31 14:44:47 +02:00
dependabot[bot] 7846058802 build(deps): bump blake3 from 1.6.1 to 1.7.0 (#5658)
Bumps [blake3](https://github.com/BLAKE3-team/BLAKE3) from 1.6.1 to 1.7.0.
- [Release notes](https://github.com/BLAKE3-team/BLAKE3/releases)
- [Commits](https://github.com/BLAKE3-team/BLAKE3/compare/1.6.1...1.7.0)

---
updated-dependencies:
- dependency-name: blake3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-31 13:57:26 +02:00
dependabot[bot] 3c98c9021e build(deps): bump tar-fs and puppeteer
Bumps [tar-fs](https://github.com/mafintosh/tar-fs) to 3.0.8 and updates ancestor dependency [puppeteer](https://github.com/puppeteer/puppeteer). These dependencies need to be updated together.


Updates `tar-fs` from 3.0.4 to 3.0.8
- [Commits](https://github.com/mafintosh/tar-fs/compare/v3.0.4...v3.0.8)

Updates `puppeteer` from 21.1.1 to 24.4.0
- [Release notes](https://github.com/puppeteer/puppeteer/releases)
- [Changelog](https://github.com/puppeteer/puppeteer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/puppeteer/puppeteer/compare/puppeteer-v21.1.1...puppeteer-v24.4.0)

---
updated-dependencies:
- dependency-name: tar-fs
  dependency-type: indirect
- dependency-name: puppeteer
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-28 22:42:24 +00:00
benedettadavico 42fbb6684d update issued-ticketbook-count to be GET 2025-03-27 12:58:04 +01:00
import this f705884a53 [DOCs/operators]: fix typo and add url (#5662) 2025-03-27 11:50:16 +00:00
Andrej Mihajlov 2f55c031da Remove Google public DNS (#5660) 2025-03-25 11:47:02 -06:00
benedettadavico a9eb6052ff bump binary versions 2025-03-25 11:41:30 +01:00
dynco-nym 3bc7ced2cf Remove UNIQUE constraint on node pubkey (#5649)
* Migration to remove UNIQUE constraint

* Don't remove old nodes

* Bump package version

* Update function name
2025-03-24 11:21:09 +01:00
Bogdan-Ștefan Neacşu 8abcc58055 Add fd callback for initial authentication (#5654) 2025-03-24 11:24:38 +02:00
Jon Häggblad 76ff03b248 Revert using AsyncWrite sink in IPR (#5656) 2025-03-24 10:19:04 +01:00
Tommy Verrall ccf3420aab Merge pull request #5653 from nymtech/feature/wallet-revamp
Wallet-revamp to be in line with new nym-theming
2025-03-21 14:02:22 +00:00
Jędrzej Stuczyński 5df76ea2a9 Feature/paginated ticketbooks challenge (#5619)
* change ticketbook data request to allow for pagination

* implemented api endpoints on nym-api side

* auxiliary nym-api queries for number of issued ticketbooks

* ensure that challenged issuers support new queries

* addeed persistent identity to the rewarder

* clippy

* stupid chrono feature workaround

* clippy

* debugging issuance verification

* remove redundant closure

* added a minimum issuance threshold
2025-03-21 13:44:25 +00:00
Jędrzej Stuczyński 33992542b1 feature: upgrade cosmwasm to 2.2 (#5479)
* updated contracts to cosmwasm2.2 and fixed build issues

* removed old coconut contract code + additional dkg fixes

* replace deprecated to_binary and from_binary functions

* mixnet contract tests compiling

some are failing due to incorrect addresses

* made other contract tests compile

* fixed remaining tests

* allow usage of manually dispatching contract replies

* nym-api test fixes

* removed old toolchain from contracts CI

* linter fixes

* regenerated contract schema

* fixed easy_addr

* further license fixes

* post rebase fixes + update to 2.2.2

* change ci runner

* minor CI adjustments

* change wallet CI to use node 20

* more CI changes...

* run cosmwasm-check against release contracts

* test ci changes

* wip...
2025-03-21 13:43:35 +00:00
Tommy Verrall a95ee3f334 wallet-revamp to be in line with new nym-theming
- updating colour pallete to match the nym.com sites
- used the same font too
- updated icons
2025-03-21 14:07:50 +01:00
Tommy Verrall 0a92f04048 Merge pull request #5652 from nymtech/feature/params
Update wallet to include Interval Operator Cost and Profit Margin
2025-03-21 12:08:19 +00:00
Tommy Verrall 368b105e27 few more broken links 2025-03-21 12:55:31 +01:00
Tommy Verrall 813cbda891 lint of delegations 2025-03-21 12:43:17 +01:00
Tommy Verrall a8af641ec4 fix up all broken links 2025-03-21 12:32:35 +01:00
Tommy Verrall f41a2d3a99 Update all deprecated links and use different explorers 2025-03-21 12:26:08 +01:00
Tommy Verrall a3b7cb52c9 Merge remote-tracking branch 'origin/feature/params' into feature/params 2025-03-21 11:54:57 +01:00
Tommy Verrall 60846b57f6 yarn linting 2025-03-21 11:54:44 +01:00
Jon Häggblad 8ed09d74b3 Add RUSTUP_PERMIT_COPY_RENAME to ci-lint-typescript 2025-03-21 11:39:58 +01:00
Tommy Verrall cd52bc577c Merge branch 'develop' into feature/params 2025-03-21 10:36:43 +00:00
Tommy Verrall ed021ff467 fix issues with profit margin throwing non required errors
- all is working
2025-03-21 11:26:45 +01:00
Tommy Verrall 4f67998127 adjust memo field again
- add additional warning about profit margin changing
2025-03-21 10:23:59 +01:00
Tommy Verrall d06a8e0b21 working with a few errors in the console at present
- successful blockchain txs though
2025-03-21 09:58:54 +01:00
dynco-nym 3f05c0d4b9 Add concurrency limit to CI (#5651) 2025-03-20 20:13:41 +01:00
Jon Häggblad 1a37e60483 Add max_retransmissions flag on each message (#5642) 2025-03-20 19:54:07 +01:00
Tommy Verrall 19775cf917 remove duplicate file
- simulated txs fee works
- now the method just needs to be called
2025-03-20 19:09:58 +01:00
Yana Matrosova 0abc07c96f Merge pull request #5636 from nymtech/BugFix/explorer_styling_broken
/ regenerated yarn.lock
2025-03-20 19:08:02 +02:00
Jędrzej Stuczyński fbfeacf539 fixed type conversion 2025-03-20 16:03:43 +00:00
Tommy Verrall e1583daaa3 no need for everything else 2025-03-20 16:43:31 +01:00
Tommy Verrall e904627513 operator interval cost and profit margin
- the submission to the chain probably needs changing to create a new nym-node rust type for updating the cost params
- a few things may been changing in terms of display and submission
- the simulate txs fee is failing - because i don't know what to put
2025-03-20 16:42:04 +01:00
Jon Häggblad 04664c8ae1 Rework IPR codec to extract out timer and implement AsyncWrite (#5632)
* Update ipr codec

* Tweak conditional

* Fix sending empty packet for flush

* Remove unneeded log

* Bump mix_traffic and real_message channel from size 1 to 8
2025-03-20 15:59:44 +01:00
import this 4da68438c0 [DOCs/operators]: Monor fix (#5650) 2025-03-20 13:13:55 +01:00
Tommy Verrall 05c1554109 test 2025-03-20 12:51:12 +01:00
import this 2b83442a6d [DOCs/operators]: Updates and release notes for v2025.5-chokito (#5648)
* replace dead token page with live dashboard

* add dev release notes

* fix urls

* add IPv6 KVM guide

* simplify node setup command

* add operator updates

* PR finished: add WG exit policy steps andfinish changelog

* PR finished: fix typo

* add components to the branch

* fix styling
2025-03-20 10:55:33 +00:00
Yana f982cb49c2 Fix NS api endpoint for dev and prod, add env variables 2025-03-20 11:57:50 +02:00
dependabot[bot] 0c05727e58 build(deps): bump dtolnay/rust-toolchain from 1.90.0 to 1.100.0 (#5638)
Bumps [dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) from 1.90.0 to 1.100.0.
- [Release notes](https://github.com/dtolnay/rust-toolchain/releases)
- [Commits](https://github.com/dtolnay/rust-toolchain/compare/1.90.0...1.100.0)

---
updated-dependencies:
- dependency-name: dtolnay/rust-toolchain
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-20 09:52:50 +00:00
Jon Häggblad 3c432ac073 Clean stale partially received buffers (#5536)
* Clean stale partially received buffers

* Tweak timeout

* Do cleanup after handling new messages instead of in the select loop

* Debug logging and remove unreachable

* Downgrade log

* Tweak logs

* tweak whitespace

* Only run the stale check every 10 sec
2025-03-20 10:01:42 +01:00
Yana 52ffd2e798 fix build 2025-03-19 15:30:39 +02:00
dependabot[bot] be8c7b4953 build(deps): bump golang.org/x/net from 0.23.0 to 0.36.0 in /wasm/mix-fetch/go-mix-conn (#5613)
* build(deps): bump golang.org/x/net in /wasm/mix-fetch/go-mix-conn

Bumps [golang.org/x/net](https://github.com/golang/net) from 0.23.0 to 0.36.0.
- [Commits](https://github.com/golang/net/compare/v0.23.0...v0.36.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
...

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

* update used go compiler

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
2025-03-19 11:00:55 +00:00
dependabot[bot] 8e4bc12b87 Bump http-proxy-middleware from 2.0.6 to 2.0.7 (#5019)
Bumps [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware) from 2.0.6 to 2.0.7.
- [Release notes](https://github.com/chimurai/http-proxy-middleware/releases)
- [Changelog](https://github.com/chimurai/http-proxy-middleware/blob/v2.0.7/CHANGELOG.md)
- [Commits](https://github.com/chimurai/http-proxy-middleware/compare/v2.0.6...v2.0.7)

---
updated-dependencies:
- dependency-name: http-proxy-middleware
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 10:10:17 +00:00
dependabot[bot] 4895820985 build(deps): bump next from 13.5.7 to 14.2.15 in /documentation/docs (#5281)
Bumps [next](https://github.com/vercel/next.js) from 13.5.7 to 14.2.15.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v13.5.7...v14.2.15)

---
updated-dependencies:
- dependency-name: next
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 10:10:02 +00:00
dependabot[bot] 8500618fe9 build(deps): bump next from 14.1.4 to 14.2.21 in /explorer-nextjs (#5308)
Bumps [next](https://github.com/vercel/next.js) from 14.1.4 to 14.2.21.
- [Release notes](https://github.com/vercel/next.js/releases)
- [Changelog](https://github.com/vercel/next.js/blob/canary/release.js)
- [Commits](https://github.com/vercel/next.js/compare/v14.1.4...v14.2.21)

---
updated-dependencies:
- dependency-name: next
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 10:09:54 +00:00
dependabot[bot] a5b390b98f build(deps): bump nanoid from 3.3.7 to 3.3.8 in /documentation/docs (#5335)
Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.7 to 3.3.8.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.7...3.3.8)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 10:09:46 +00:00
dependabot[bot] ff66674f61 build(deps): bump store2 from 2.14.3 to 2.14.4 (#5391)
Bumps [store2](https://github.com/nbubna/store) from 2.14.3 to 2.14.4.
- [Commits](https://github.com/nbubna/store/compare/2.14.3...2.14.4)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 10:09:38 +00:00
dependabot[bot] a7cf34e812 build(deps): bump @octokit/plugin-paginate-rest and @actions/github (#5488)
Bumps [@octokit/plugin-paginate-rest](https://github.com/octokit/plugin-paginate-rest.js) to 9.2.2 and updates ancestor dependency [@actions/github](https://github.com/actions/toolkit/tree/HEAD/packages/github). These dependencies need to be updated together.


Updates `@octokit/plugin-paginate-rest` from 9.2.1 to 9.2.2
- [Release notes](https://github.com/octokit/plugin-paginate-rest.js/releases)
- [Commits](https://github.com/octokit/plugin-paginate-rest.js/compare/v9.2.1...v9.2.2)

Updates `@actions/github` from 5.1.1 to 6.0.0
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/github/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/github)

---
updated-dependencies:
- dependency-name: "@octokit/plugin-paginate-rest"
  dependency-type: indirect
- dependency-name: "@actions/github"
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 10:09:05 +00:00
dependabot[bot] a85dad6bd7 build(deps): bump braces in /sdk/typescript/packages/mix-fetch-node (#5612)
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 10:08:56 +00:00
dependabot[bot] 5b8a14f74b build(deps-dev): bump ws in /wasm/client/internal-dev (#5614)
Bumps [ws](https://github.com/websockets/ws) from 8.13.0 to 8.18.1.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/8.13.0...8.18.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 10:08:45 +00:00
dependabot[bot] 730c2efea6 build(deps-dev): bump webpack in /wasm/client/internal-dev (#5615)
Bumps [webpack](https://github.com/webpack/webpack) from 5.77.0 to 5.98.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.77.0...v5.98.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 10:08:36 +00:00
dependabot[bot] c9d6a8cc25 build(deps): bump @babel/runtime in /testnet-faucet (#5621)
Bumps [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) from 7.16.3 to 7.26.10.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.10/packages/babel-runtime)

---
updated-dependencies:
- dependency-name: "@babel/runtime"
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-19 10:06:52 +00:00
Jon Häggblad 230b2b1784 Upgrade sha2 to workspace version or validator-client (#5644) 2025-03-19 10:46:15 +01:00
Jon Häggblad e4e9615535 Add RUSTUP_PERMIT_COPY_RENAME in two workflows that we forgot about (#5646) 2025-03-19 09:18:25 +01:00
Yana 7bf1adff28 Fixes 2025-03-18 17:45:38 +02:00
RadekSabacky e4fd87be2c / regenerated yarn.lock 2025-03-17 19:04:51 +01:00
dependabot[bot] 84b6068ac9 build(deps): bump elliptic from 6.5.5 to 6.6.1
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.5 to 6.6.1.
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.5...v6.6.1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-17 23:26:04 +00:00
960 changed files with 39779 additions and 46257 deletions
+149 -265
View File
@@ -9,7 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"@actions/core": "^1.10.1", "@actions/core": "^1.10.1",
"@actions/github": "^5.1.1", "@actions/github": "^6.0.0",
"@octokit/auth-action": "^4.0.1", "@octokit/auth-action": "^4.0.1",
"@octokit/rest": "^20.0.2", "@octokit/rest": "^20.0.2",
"hasha": "^5.2.0", "hasha": "^5.2.0",
@@ -29,22 +29,34 @@
} }
}, },
"node_modules/@actions/github": { "node_modules/@actions/github": {
"version": "5.1.1", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/@actions/github/-/github-5.1.1.tgz", "resolved": "https://registry.npmjs.org/@actions/github/-/github-6.0.0.tgz",
"integrity": "sha512-Nk59rMDoJaV+mHCOJPXuvB1zIbomlKS0dmSIqPGxd0enAXBnOfn4VWF+CGtRCwXZG9Epa54tZA7VIRlJDS8A6g==", "integrity": "sha512-alScpSVnYmjNEXboZjarjukQEzgCRmjMv6Xj47fsdnqGS73bjJNDpiiXmp8jr0UZLdUB6d9jW63IcmddUP+l0g==",
"license": "MIT",
"dependencies": { "dependencies": {
"@actions/http-client": "^2.0.1", "@actions/http-client": "^2.2.0",
"@octokit/core": "^3.6.0", "@octokit/core": "^5.0.1",
"@octokit/plugin-paginate-rest": "^2.17.0", "@octokit/plugin-paginate-rest": "^9.0.0",
"@octokit/plugin-rest-endpoint-methods": "^5.13.0" "@octokit/plugin-rest-endpoint-methods": "^10.0.0"
} }
}, },
"node_modules/@actions/http-client": { "node_modules/@actions/http-client": {
"version": "2.1.1", "version": "2.2.3",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.1.1.tgz", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.3.tgz",
"integrity": "sha512-qhrkRMB40bbbLo7gF+0vu+X+UawOvQQqNAA/5Unx774RS8poaOhThDOG6BGmxvAnxhQnDp2BG/ZUm65xZILTpw==", "integrity": "sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==",
"license": "MIT",
"dependencies": { "dependencies": {
"tunnel": "^0.0.6" "tunnel": "^0.0.6",
"undici": "^5.25.4"
}
},
"node_modules/@fastify/busboy": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz",
"integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
"license": "MIT",
"engines": {
"node": ">=14"
} }
}, },
"node_modules/@octokit/auth-action": { "node_modules/@octokit/auth-action": {
@@ -59,14 +71,6 @@
"node": ">= 18" "node": ">= 18"
} }
}, },
"node_modules/@octokit/auth-action/node_modules/@octokit/auth-token": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/auth-action/node_modules/@octokit/openapi-types": { "node_modules/@octokit/auth-action/node_modules/@octokit/openapi-types": {
"version": "20.0.0", "version": "20.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
@@ -81,115 +85,152 @@
} }
}, },
"node_modules/@octokit/auth-token": { "node_modules/@octokit/auth-token": {
"version": "2.5.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
"integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
"dependencies": { "license": "MIT",
"@octokit/types": "^6.0.3" "engines": {
"node": ">= 18"
} }
}, },
"node_modules/@octokit/core": { "node_modules/@octokit/core": {
"version": "3.6.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.2.0.tgz",
"integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", "integrity": "sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/auth-token": "^2.4.4", "@octokit/auth-token": "^4.0.0",
"@octokit/graphql": "^4.5.8", "@octokit/graphql": "^7.1.0",
"@octokit/request": "^5.6.3", "@octokit/request": "^8.3.1",
"@octokit/request-error": "^2.0.5", "@octokit/request-error": "^5.1.0",
"@octokit/types": "^6.0.3", "@octokit/types": "^13.0.0",
"before-after-hook": "^2.2.0", "before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0" "universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
} }
}, },
"node_modules/@octokit/endpoint": { "node_modules/@octokit/endpoint": {
"version": "6.0.12", "version": "9.0.6",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.6.tgz",
"integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", "integrity": "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/types": "^6.0.3", "@octokit/types": "^13.1.0",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0" "universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
} }
}, },
"node_modules/@octokit/graphql": { "node_modules/@octokit/graphql": {
"version": "4.8.0", "version": "7.1.0",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.1.0.tgz",
"integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", "integrity": "sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/request": "^5.6.0", "@octokit/request": "^8.3.0",
"@octokit/types": "^6.0.3", "@octokit/types": "^13.0.0",
"universal-user-agent": "^6.0.0" "universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
} }
}, },
"node_modules/@octokit/openapi-types": { "node_modules/@octokit/openapi-types": {
"version": "12.11.0", "version": "23.0.1",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-23.0.1.tgz",
"integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==" "integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==",
"license": "MIT"
}, },
"node_modules/@octokit/plugin-paginate-rest": { "node_modules/@octokit/plugin-paginate-rest": {
"version": "2.21.3", "version": "9.2.2",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.2.tgz",
"integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", "integrity": "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/types": "^6.40.0" "@octokit/types": "^12.6.0"
},
"engines": {
"node": ">= 18"
}, },
"peerDependencies": { "peerDependencies": {
"@octokit/core": ">=2" "@octokit/core": "5"
}
},
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
"license": "MIT"
},
"node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^20.0.0"
} }
}, },
"node_modules/@octokit/plugin-rest-endpoint-methods": { "node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "5.16.2", "version": "10.4.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
"integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", "integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/types": "^6.39.0", "@octokit/types": "^12.6.0"
"deprecation": "^2.3.1" },
"engines": {
"node": ">= 18"
}, },
"peerDependencies": { "peerDependencies": {
"@octokit/core": ">=3" "@octokit/core": "5"
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
"license": "MIT"
},
"node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
"license": "MIT",
"dependencies": {
"@octokit/openapi-types": "^20.0.0"
} }
}, },
"node_modules/@octokit/request": { "node_modules/@octokit/request": {
"version": "5.6.3", "version": "8.4.1",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.1.tgz",
"integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", "integrity": "sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/endpoint": "^6.0.1", "@octokit/endpoint": "^9.0.6",
"@octokit/request-error": "^2.1.0", "@octokit/request-error": "^5.1.1",
"@octokit/types": "^6.16.1", "@octokit/types": "^13.1.0",
"is-plain-object": "^5.0.0",
"node-fetch": "^2.6.7",
"universal-user-agent": "^6.0.0" "universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
} }
}, },
"node_modules/@octokit/request-error": { "node_modules/@octokit/request-error": {
"version": "2.1.0", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.1.1.tgz",
"integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", "integrity": "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/types": "^6.0.3", "@octokit/types": "^13.1.0",
"deprecation": "^2.0.0", "deprecation": "^2.0.0",
"once": "^1.4.0" "once": "^1.4.0"
}
},
"node_modules/@octokit/request/node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dependencies": {
"whatwg-url": "^5.0.0"
}, },
"engines": { "engines": {
"node": "4.x || >=6.0.0" "node": ">= 18"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
} }
}, },
"node_modules/@octokit/rest": { "node_modules/@octokit/rest": {
@@ -206,89 +247,6 @@
"node": ">= 18" "node": ">= 18"
} }
}, },
"node_modules/@octokit/rest/node_modules/@octokit/auth-token": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
"integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/core": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.0.tgz",
"integrity": "sha512-YbAtMWIrbZ9FCXbLwT9wWB8TyLjq9mxpKdgB3dUNxQcIVTf9hJ70gRPwAcqGZdY6WdJPZ0I7jLaaNDCiloGN2A==",
"dependencies": {
"@octokit/auth-token": "^4.0.0",
"@octokit/graphql": "^7.0.0",
"@octokit/request": "^8.0.2",
"@octokit/request-error": "^5.0.0",
"@octokit/types": "^11.0.0",
"before-after-hook": "^2.2.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/endpoint": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.0.tgz",
"integrity": "sha512-szrQhiqJ88gghWY2Htt8MqUDO6++E/EIXqJ2ZEp5ma3uGS46o7LZAzSLt49myB7rT+Hfw5Y6gO3LmOxGzHijAQ==",
"dependencies": {
"@octokit/types": "^11.0.0",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/graphql": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.1.tgz",
"integrity": "sha512-T5S3oZ1JOE58gom6MIcrgwZXzTaxRnxBso58xhozxHpOqSTgDS6YNeEUvZ/kRvXgPrRz/KHnZhtb7jUMRi9E6w==",
"dependencies": {
"@octokit/request": "^8.0.1",
"@octokit/types": "^11.0.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/openapi-types": {
"version": "18.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz",
"integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw=="
},
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest": {
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz",
"integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==",
"dependencies": {
"@octokit/types": "^12.6.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": "5"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="
},
"node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
"dependencies": {
"@octokit/openapi-types": "^20.0.0"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": { "node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz",
@@ -300,75 +258,13 @@
"@octokit/core": ">=5" "@octokit/core": ">=5"
} }
}, },
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods": {
"version": "10.4.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
"integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
"dependencies": {
"@octokit/types": "^12.6.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
"@octokit/core": "5"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
"version": "20.0.0",
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
"integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="
},
"node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
"version": "12.6.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
"integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
"dependencies": {
"@octokit/openapi-types": "^20.0.0"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/request": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.1.tgz",
"integrity": "sha512-8N+tdUz4aCqQmXl8FpHYfKG9GelDFd7XGVzyN8rc6WxVlYcfpHECnuRkgquzz+WzvHTK62co5di8gSXnzASZPQ==",
"dependencies": {
"@octokit/endpoint": "^9.0.0",
"@octokit/request-error": "^5.0.0",
"@octokit/types": "^11.1.0",
"is-plain-object": "^5.0.0",
"universal-user-agent": "^6.0.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/request-error": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.0.tgz",
"integrity": "sha512-1ue0DH0Lif5iEqT52+Rf/hf0RmGO9NWFjrzmrkArpG9trFfDM/efx00BJHdLGuro4BR/gECxCU2Twf5OKrRFsQ==",
"dependencies": {
"@octokit/types": "^11.0.0",
"deprecation": "^2.0.0",
"once": "^1.4.0"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/rest/node_modules/@octokit/types": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz",
"integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==",
"dependencies": {
"@octokit/openapi-types": "^18.0.0"
}
},
"node_modules/@octokit/types": { "node_modules/@octokit/types": {
"version": "6.41.0", "version": "13.8.0",
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.8.0.tgz",
"integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", "integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==",
"license": "MIT",
"dependencies": { "dependencies": {
"@octokit/openapi-types": "^12.11.0" "@octokit/openapi-types": "^23.0.1"
} }
}, },
"node_modules/@vercel/ncc": { "node_modules/@vercel/ncc": {
@@ -396,7 +292,8 @@
"node_modules/deprecation": { "node_modules/deprecation": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
"license": "ISC"
}, },
"node_modules/fetch-blob": { "node_modules/fetch-blob": {
"version": "3.2.0", "version": "3.2.0",
@@ -446,14 +343,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/is-plain-object": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-stream": { "node_modules/is-stream": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -504,15 +393,11 @@
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"license": "ISC",
"dependencies": { "dependencies": {
"wrappy": "1" "wrappy": "1"
} }
}, },
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/tunnel": { "node_modules/tunnel": {
"version": "0.0.6", "version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
@@ -529,6 +414,18 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/undici": {
"version": "5.28.5",
"resolved": "https://registry.npmjs.org/undici/-/undici-5.28.5.tgz",
"integrity": "sha512-zICwjrDrcrUE0pyyJc1I2QzBkLM8FINsgOrt6WjA+BgajVq9Nxu2PbFFXUrAggLfDXlZGZBVZYw7WNV5KiBiBA==",
"license": "MIT",
"dependencies": {
"@fastify/busboy": "^2.0.0"
},
"engines": {
"node": ">=14.0"
}
},
"node_modules/universal-user-agent": { "node_modules/universal-user-agent": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
@@ -550,24 +447,11 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/wrappy": { "node_modules/wrappy": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC"
} }
} }
} }
@@ -11,7 +11,7 @@
}, },
"dependencies": { "dependencies": {
"@actions/core": "^1.10.1", "@actions/core": "^1.10.1",
"@actions/github": "^5.1.1", "@actions/github": "^6.0.0",
"@octokit/auth-action": "^4.0.1", "@octokit/auth-action": "^4.0.1",
"@octokit/rest": "^20.0.2", "@octokit/rest": "^20.0.2",
"hasha": "^5.2.0", "hasha": "^5.2.0",
+3 -3
View File
@@ -5,7 +5,7 @@ on:
jobs: jobs:
build: build:
runs-on: arc-ubuntu-20.04 runs-on: arc-ubuntu-22.04
defaults: defaults:
run: run:
working-directory: documentation/docs working-directory: documentation/docs
@@ -18,10 +18,10 @@ jobs:
- name: Install Python3 modules - name: Install Python3 modules
run: sudo pip3 install pandas tabulate run: sudo pip3 install pandas tabulate
- name: Install rsync - name: Install rsync
run: sudo apt-get install rsync run: sudo apt-get install -y rsync
- uses: rlespinasse/github-slug-action@v3.x - uses: rlespinasse/github-slug-action@v3.x
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4.0.0 uses: pnpm/action-setup@v4.1.0
with: with:
version: 9 version: 9
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
@@ -33,7 +33,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
platform: [arc-ubuntu-20.04] platform: [arc-ubuntu-22.04]
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
steps: steps:
+2 -2
View File
@@ -10,7 +10,7 @@ on:
jobs: jobs:
build: build:
runs-on: arc-ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install rsync - name: Install rsync
@@ -19,7 +19,7 @@ jobs:
- uses: rlespinasse/github-slug-action@v3.x - uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 20
- name: Setup yarn - name: Setup yarn
run: npm install -g yarn run: npm install -g yarn
- name: Build - name: Build
@@ -21,7 +21,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
platform: [ arc-ubuntu-20.04 ] platform: [ arc-ubuntu-22.04 ]
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
env: env:
+9 -1
View File
@@ -27,12 +27,18 @@ on:
- '.github/workflows/ci-build.yml' - '.github/workflows/ci-build.yml'
workflow_dispatch: workflow_dispatch:
concurrency:
# only 1 concurrent `ci-build` allowed per branch
# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#example-using-concurrency-and-the-default-behavior
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs: jobs:
build: build:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ arc-ubuntu-20.04, custom-windows-11, custom-runner-mac-m1 ] os: [ arc-ubuntu-22.04, custom-windows-11, custom-runner-mac-m1 ]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
@@ -96,6 +102,8 @@ jobs:
- name: Run all tests - name: Run all tests
if: contains(matrix.os, 'ubuntu') if: contains(matrix.os, 'ubuntu')
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
env:
NYM_API: https://sandbox-nym-api1.nymtech.net/api
with: with:
command: test command: test
args: --workspace args: --workspace
@@ -1,6 +0,0 @@
[
{
"rust":"stable",
"runOnEvent":"always"
}
]
+1 -1
View File
@@ -11,7 +11,7 @@ on:
jobs: jobs:
check-schema: check-schema:
name: Generate and check schema name: Generate and check schema
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
steps: steps:
@@ -11,7 +11,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
platform: [ arc-ubuntu-20.04 ] platform: [ arc-ubuntu-22.04 ]
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
env: env:
@@ -31,7 +31,6 @@ jobs:
- name: Install Rust stable - name: Install Rust stable
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: 1.77
target: wasm32-unknown-unknown target: wasm32-unknown-unknown
override: true override: true
@@ -40,6 +39,9 @@ jobs:
with: with:
version: '114' version: '114'
- name: Install cosmwasm-check
run: cargo install cosmwasm-check
- name: Build release contracts - name: Build release contracts
run: make contracts run: make contracts
@@ -50,7 +52,6 @@ jobs:
run: | run: |
cp contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm $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 cp contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_bandwidth.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR cp contracts/target/wasm32-unknown-unknown/release/nym_coconut_dkg.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR cp contracts/target/wasm32-unknown-unknown/release/cw3_flex_multisig.wasm $OUTPUT_DIR
cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR
+14 -18
View File
@@ -14,28 +14,12 @@ on:
- '.github/workflows/ci-contracts.yml' - '.github/workflows/ci-contracts.yml'
jobs: jobs:
matrix_prep:
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
# creates the matrix strategy from ci-contracts-matrix-includes.json
- uses: actions/checkout@v4
- id: set-matrix
uses: JoshuaTheMiller/conditional-build-matrix@main
with:
inputFile: '.github/workflows/ci-contracts-matrix-includes.json'
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
build: build:
# since it's going to be compiled into wasm, there's absolutely # since it's going to be compiled into wasm, there's absolutely
# no point in running CI on different OS-es # no point in running CI on different OS-es
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
needs: matrix_prep
strategy:
fail-fast: false
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -43,11 +27,19 @@ jobs:
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
profile: minimal profile: minimal
toolchain: ${{ matrix.rust }} toolchain: stable
target: wasm32-unknown-unknown target: wasm32-unknown-unknown
override: true override: true
components: rustfmt, clippy components: rustfmt, clippy
- name: Install cosmwasm-check
run: cargo install cosmwasm-check
- name: Install wasm-opt
uses: ./.github/actions/install-wasm-opt
with:
version: '114'
- name: Build contracts - name: Build contracts
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
env: env:
@@ -73,3 +65,7 @@ jobs:
with: with:
command: clippy command: clippy
args: --lib --manifest-path contracts/Cargo.toml --workspace --all-targets -- -D warnings args: --lib --manifest-path contracts/Cargo.toml --workspace --all-targets -- -D warnings
- name: Check chain compatibility against release build
# this will build contracts in release mode, run wasm-opt and finally cosmwasm-check
run: make contracts
+5 -3
View File
@@ -10,7 +10,9 @@ on:
jobs: jobs:
build: build:
runs-on: arc-ubuntu-20.04 runs-on: arc-ubuntu-22.04
env:
RUSTUP_PERMIT_COPY_RENAME: 1
defaults: defaults:
run: run:
working-directory: documentation/docs working-directory: documentation/docs
@@ -23,10 +25,10 @@ jobs:
- name: Install Python3 modules - name: Install Python3 modules
run: sudo pip3 install pandas tabulate run: sudo pip3 install pandas tabulate
- name: Install rsync - name: Install rsync
run: sudo apt-get install rsync run: sudo apt-get install -y rsync
- uses: rlespinasse/github-slug-action@v3.x - uses: rlespinasse/github-slug-action@v3.x
- name: Setup pnpm - name: Setup pnpm
uses: pnpm/action-setup@v4.0.0 uses: pnpm/action-setup@v4.1.0
with: with:
version: 9 version: 9
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
+5 -3
View File
@@ -15,14 +15,16 @@ on:
jobs: jobs:
build: build:
runs-on: arc-ubuntu-20.04 runs-on: ubuntu-22.04
env:
RUSTUP_PERMIT_COPY_RENAME: 1
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: rlespinasse/github-slug-action@v3.x - uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 20
- name: Setup yarn - name: Setup yarn
run: npm install -g yarn run: npm install -g yarn
@@ -42,7 +44,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.20' go-version: "1.23.7"
- name: Install - name: Install
run: yarn run: yarn
@@ -1,92 +0,0 @@
name: ci-nym-network-explorer
on:
workflow_dispatch:
push:
paths:
- 'explorer/**'
- '.github/workflows/ci-nym-network-explorer.yml'
defaults:
run:
working-directory: explorer
jobs:
build:
runs-on: custom-linux
steps:
- uses: actions/checkout@v4
- name: Install rsync
run: sudo apt-get install rsync
continue-on-error: true
- uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v4
with:
node-version: 18
- name: Setup yarn
run: npm install -g yarn
continue-on-error: true
- name: Build shared packages
run: cd .. && yarn && yarn build
- name: Set environment from the example
run: cp .env.prod .env
# - run: yarn test
# continue-on-error: true
- run: yarn && yarn build
continue-on-error: true
- run: yarn storybook:build
name: Build storybook
- name: Deploy branch to CI www
continue-on-error: true
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "explorer/dist/"
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/network-explorer-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/"
- name: Deploy storybook to CI www
continue-on-error: true
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "explorer/storybook-static/"
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/ne-sb-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/"
- name: Matrix - Node Install
run: npm install
working-directory: .github/workflows/support-files
- name: Matrix - Send Notification
env:
NYM_NOTIFICATION_KIND: network-explorer
NYM_PROJECT_NAME: "Network Explorer"
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
NYM_CI_WWW_LOCATION: "network-explorer-${{ env.GITHUB_REF_SLUG }}"
NYM_CI_WWW_LOCATION_STORYBOOK: "ne-sb-${{ 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
- name: Deploy
if: github.event_name == 'workflow_dispatch'
uses: easingthemes/ssh-deploy@main
env:
SSH_PRIVATE_KEY: ${{ secrets.CD_PROD_NE_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete"
SOURCE: "explorer/dist/"
REMOTE_HOST: ${{ secrets.CD_PROD_NE_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CD_PROD_NE_REMOTE_USER }}
TARGET: ${{ secrets.CD_PROD_NE_REMOTE_TARGET }}
EXCLUDE: "/dist/, /node_modules/"
+8 -3
View File
@@ -11,12 +11,17 @@ on:
jobs: jobs:
build: build:
runs-on: arc-ubuntu-20.04 runs-on: arc-ubuntu-22.04
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
RUSTUP_PERMIT_COPY_RENAME: 1
steps: steps:
- name: Install Dependencies (Linux) - name: Install system dependencies
run: sudo apt-get update && sudo apt-get -y install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools run: |
sudo apt-get update && sudo apt-get install -y libdbus-1-dev libmnl-dev libnftnl-dev \
libwebkit2gtk-4.1-dev build-essential curl wget libssl-dev jq \
libgtk-3-dev squashfs-tools libayatana-appindicator3-dev make libfuse2 unzip librsvg2-dev file \
libsoup-3.0-dev libjavascriptcoregtk-4.1-dev
continue-on-error: true continue-on-error: true
- name: Check out repository code - name: Check out repository code
+52 -52
View File
@@ -10,66 +10,66 @@ jobs:
build: build:
runs-on: custom-linux runs-on: custom-linux
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install rsync - name: Install rsync
run: sudo apt-get install rsync run: sudo apt-get install rsync
continue-on-error: true continue-on-error: true
- uses: rlespinasse/github-slug-action@v3.x - uses: rlespinasse/github-slug-action@v3.x
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 20
- name: Setup yarn - name: Setup yarn
run: npm install -g yarn run: npm install -g yarn
- name: Install Rust stable - name: Install Rust stable
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: stable toolchain: stable
- name: Install wasm-pack - name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Build dependencies - name: Build dependencies
run: yarn && yarn build run: yarn && yarn build
- name: Build storybook - name: Build storybook
run: yarn storybook:build run: yarn storybook:build
working-directory: ./nym-wallet working-directory: ./nym-wallet
- name: Deploy branch to CI www (storybook) - name: Deploy branch to CI www (storybook)
continue-on-error: true continue-on-error: true
uses: easingthemes/ssh-deploy@main uses: easingthemes/ssh-deploy@main
env: env:
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }} SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }}
ARGS: "-rltgoDzvO --delete" ARGS: "-rltgoDzvO --delete"
SOURCE: "nym-wallet/storybook-static/" SOURCE: "nym-wallet/storybook-static/"
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }} REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }} REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/wallet-${{ env.GITHUB_REF_SLUG }} TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/wallet-${{ env.GITHUB_REF_SLUG }}
EXCLUDE: "/dist/, /node_modules/" EXCLUDE: "/dist/, /node_modules/"
- name: Matrix - Node Install - name: Matrix - Node Install
run: npm install run: npm install
working-directory: .github/workflows/support-files working-directory: .github/workflows/support-files
- name: Matrix - Send Notification - name: Matrix - Send Notification
env: env:
NYM_NOTIFICATION_KIND: nym-wallet NYM_NOTIFICATION_KIND: nym-wallet
NYM_PROJECT_NAME: "nym-wallet" NYM_PROJECT_NAME: "nym-wallet"
NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}" NYM_CI_WWW_BASE: "${{ secrets.NYM_CI_WWW_BASE }}"
NYM_CI_WWW_LOCATION: "wallet-${{ env.GITHUB_REF_SLUG }}" NYM_CI_WWW_LOCATION: "wallet-${{ env.GITHUB_REF_SLUG }}"
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}" GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
GIT_BRANCH: "${GITHUB_REF##*/}" GIT_BRANCH: "${GITHUB_REF##*/}"
IS_SUCCESS: "${{ job.status == 'success' }}" IS_SUCCESS: "${{ job.status == 'success' }}"
MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}" MATRIX_SERVER: "${{ secrets.MATRIX_SERVER }}"
MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}" MATRIX_ROOM: "${{ secrets.MATRIX_ROOM }}"
MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}" MATRIX_USER_ID: "${{ secrets.MATRIX_USER_ID }}"
MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}" MATRIX_TOKEN: "${{ secrets.MATRIX_TOKEN }}"
MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}" MATRIX_DEVICE_ID: "${{ secrets.MATRIX_DEVICE_ID }}"
uses: docker://keybaseio/client:stable-node uses: docker://keybaseio/client:stable-node
with: with:
args: .github/workflows/support-files/notifications/entry_point.sh args: .github/workflows/support-files/notifications/entry_point.sh
+4 -3
View File
@@ -11,15 +11,16 @@ on:
jobs: jobs:
wasm: wasm:
runs-on: arc-ubuntu-20.04 runs-on: arc-ubuntu-22.04
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
RUSTUP_PERMIT_COPY_RENAME: 1
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 20
- uses: actions-rs/toolchain@v1 - uses: actions-rs/toolchain@v1
with: with:
@@ -32,7 +33,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '1.20' go-version: "1.23.7"
- name: Install wasm-pack - name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
+4 -4
View File
@@ -11,7 +11,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
rust: [stable, beta] rust: [stable, beta]
os: [ubuntu-20.04, windows-latest, macos-latest] os: [ubuntu-22.04, windows-latest, macos-latest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
@@ -23,7 +23,7 @@ jobs:
- name: Install Dependencies (Linux) - name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler run: sudo apt-get update && sudo apt-get install -y build-essential curl wget libssl-dev libudev-dev squashfs-tools protobuf-compiler
if: matrix.os == 'ubuntu-20.04' if: matrix.os == 'ubuntu-22.04'
- name: Install Rust toolchain - name: Install Rust toolchain
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
@@ -59,7 +59,7 @@ jobs:
# To avoid running out of disk space, skip generating debug symbols # To avoid running out of disk space, skip generating debug symbols
- name: Set debug to false (unix) - name: Set debug to false (unix)
if: matrix.os == 'ubuntu-20.04' || matrix.os == 'macos-latest' if: matrix.os == 'ubuntu-22.04' || matrix.os == 'macos-latest'
run: | run: |
sed -i.bak 's/\[profile.dev\]/\[profile.dev\]\ndebug = false/' Cargo.toml sed -i.bak 's/\[profile.dev\]/\[profile.dev\]\ndebug = false/' Cargo.toml
git diff git diff
@@ -106,7 +106,7 @@ jobs:
uses: actions/setup-node@v4 uses: actions/setup-node@v4
if: env.WORKFLOW_CONCLUSION == 'failure' if: env.WORKFLOW_CONCLUSION == 'failure'
with: with:
node-version: 18 node-version: 20
- name: Matrix - Node Install - name: Matrix - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure' if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install run: npm install
@@ -10,7 +10,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-20.04, macos-latest, windows-latest] os: [ubuntu-22.04, macos-latest, windows-latest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
@@ -22,7 +22,7 @@ jobs:
- name: Install Dependencies (Linux) - name: Install Dependencies (Linux)
run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools run: sudo apt-get update && sudo apt-get install -y libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev squashfs-tools
if: matrix.os == 'ubuntu-20.04' if: matrix.os == 'ubuntu-22.04'
- name: Install rust toolchain - name: Install rust toolchain
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
@@ -68,7 +68,7 @@ jobs:
uses: actions/setup-node@v4 uses: actions/setup-node@v4
if: env.WORKFLOW_CONCLUSION == 'failure' if: env.WORKFLOW_CONCLUSION == 'failure'
with: with:
node-version: 18 node-version: 20
- name: Matrix - Node Install - name: Matrix - Node Install
if: env.WORKFLOW_CONCLUSION == 'failure' if: env.WORKFLOW_CONCLUSION == 'failure'
run: npm install run: npm install
+2 -2
View File
@@ -5,7 +5,7 @@ on:
- cron: '5 9 * * *' - cron: '5 9 * * *'
jobs: jobs:
cargo-deny: cargo-deny:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- name: Checkout repository code - name: Checkout repository code
uses: actions/checkout@v4 uses: actions/checkout@v4
@@ -38,7 +38,7 @@ jobs:
- name: install npm - name: install npm
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 20
- name: Matrix - Node Install - name: Matrix - Node Install
run: npm install run: npm install
working-directory: .github/workflows/support-files working-directory: .github/workflows/support-files
@@ -0,0 +1,47 @@
name: Integration Tests
on:
pull_request:
paths:
- "nym-api/**"
- "tests/**"
workflow_dispatch:
jobs:
integration-tests:
runs-on: ubuntu-latest
env:
API_BASE_URL: http://localhost:8000
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install -y pkg-config libssl-dev
- name: Build nym-api
run: cargo build --package nym-api
- name: Run nym-api in the background
run: |
./target/debug/nym-api &
- name: Wait for nym-api to come alive
run: |
for i in {1..20}; do
curl -sSf http://localhost:8000/v1/status/config-score-details && break
echo "Waiting for nym-api to start..."
sleep 2
done
- name: Run integration tests
env:
NYM_API: https://sandbox-nym-api1.nymtech.net/api
run: cargo test --test public-api-tests -- --nocapture
+1 -3
View File
@@ -19,9 +19,7 @@ jobs:
if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: runs-on: arc-ubuntu-22.04
platform: [custom-ubuntu-20.04]
runs-on: ${{ matrix.platform }}
outputs: outputs:
release_id: ${{ steps.create-release.outputs.id }} release_id: ${{ steps.create-release.outputs.id }}
+2 -3
View File
@@ -2,19 +2,18 @@ name: publish-nym-contracts
on: on:
workflow_dispatch: workflow_dispatch:
release: release:
types: [created] types: [ created ]
jobs: jobs:
build: build:
if: ${{ (startsWith(github.ref, 'refs/tags/nym-contracts-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} if: ${{ (startsWith(github.ref, 'refs/tags/nym-contracts-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
runs-on: [self-hosted, custom-ubuntu-20.04] runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install Rust stable - name: Install Rust stable
uses: actions-rs/toolchain@v1 uses: actions-rs/toolchain@v1
with: with:
toolchain: 1.77
target: wasm32-unknown-unknown target: wasm32-unknown-unknown
override: true override: true
+43 -29
View File
@@ -14,15 +14,11 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
platform: [macos-12-large] platform: [macos-15]
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
outputs: outputs:
release_id: ${{ steps.create-release.outputs.id }} release_tag: ${{ github.ref_name }}
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
version: ${{ steps.release-info.outputs.version }}
filename: ${{ steps.release-info.outputs.filename }}
file_hash: ${{ steps.release-info.outputs.file_hash }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -30,11 +26,19 @@ jobs:
- name: Node - name: Node
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 21
- name: Install Rust stable - name: Install Rust stable
uses: actions-rs/toolchain@v1 uses: dtolnay/rust-toolchain@stable
with: with:
toolchain: stable toolchain: stable
- name: Add Rust target for x86_64-apple-darwin
run: rustup target add x86_64-apple-darwin
- name: Set Cargo build target to x86_64
run: echo "CARGO_BUILD_TARGET=x86_64-apple-darwin" >> $GITHUB_ENV
- name: Install the Apple developer certificate for code signing - name: Install the Apple developer certificate for code signing
env: env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
@@ -64,11 +68,19 @@ jobs:
fileName: '.env' fileName: '.env'
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Yarn cache clean
shell: bash
run: cd .. && yarn cache clean
- name: Install project dependencies - name: Install project dependencies
shell: bash shell: bash
run: cd .. && yarn --network-timeout 100000 run: cd .. && yarn --network-timeout 100000
- name: Install app dependencies and build it - name: Yarn build
shell: bash
run: cd .. && yarn build
- name: Install dependencies and build it
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }} ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
@@ -78,46 +90,48 @@ jobs:
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_IDENTITY_ID }} APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_IDENTITY_ID }}
APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} # Tauri v2 specific environment variables
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
run: yarn && yarn build TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
TAURI_NOTARIZATION_USERNAME: ${{ secrets.APPLE_ID }}
TAURI_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
TAURI_NOTARIZATION_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
yarn build-macx86
- name: Create app tarball
run: |
# Navigate to where the app bundle is and create the tarball
cd target/x86_64-apple-darwin/release/bundle/macos
echo "Creating tarball from app bundle"
tar -czf nym-wallet.app.tar.gz NymWallet.app
cd -
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: nym-wallet.app.tar.gz name: nym-wallet.app.tar.gz
path: nym-wallet/target/release/bundle/macos/nym-wallet.app.tar.gz path: nym-wallet/target/x86_64-apple-darwin/release/bundle/macos/nym-wallet.app.tar.gz
retention-days: 5 retention-days: 5
- name: Clean up keychain - name: Clean up keychain
if: ${{ always() }} if: ${{ always() }}
run: | run: |
security delete-keychain $RUNNER_TEMP/app-signing.keychain-db security delete-keychain $RUNNER_TEMP/app-signing.keychain-db
- id: create-release - id: create-release
name: Upload to release based on tag name name: Upload to release based on tag name
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
if: github.event_name == 'release' if: github.event_name == 'release'
with: with:
files: | files: |
nym-wallet/target/release/bundle/dmg/*.dmg nym-wallet/target/x86_64-apple-darwin/release/bundle/dmg/*.dmg
nym-wallet/target/release/bundle/macos/*.app.tar.gz* nym-wallet/target/x86_64-apple-darwin/release/bundle/macos/*.app.tar.gz*
- name: Deploy artifacts 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: "nym-wallet/target/release/bundle/macos/nym-wallet.app.tar.gz"
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }}
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }}
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/${{ github.ref_name }}/nym-wallet
EXCLUDE: "/dist/, /node_modules/"
push-release-data: push-release-data:
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
uses: ./.github/workflows/release-calculate-hash.yml uses: ./.github/workflows/release-calculate-hash.yml
needs: publish-tauri needs: publish-tauri
with: with:
release_tag: ${{ github.ref_name }} release_tag: ${{ needs.publish-tauri.outputs.release_tag || github.ref_name }}
secrets: inherit secrets: inherit
+82 -43
View File
@@ -3,71 +3,108 @@ on:
workflow_dispatch: workflow_dispatch:
release: release:
types: [created] types: [created]
defaults: defaults:
run: run:
working-directory: nym-wallet working-directory: nym-wallet
jobs: jobs:
publish-tauri: publish-tauri:
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
platform: [custom-ubuntu-20.04] platform: [ubuntu-22.04]
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
outputs: outputs:
release_id: ${{ steps.create-release.outputs.id }} release_tag: ${{ github.ref_name }}
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
version: ${{ steps.release-info.outputs.version }}
filename: ${{ steps.release-info.outputs.filename }}
file_hash: ${{ steps.release-info.outputs.file_hash }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Tauri dependencies - name: Install system dependencies
run: > run: |
sudo apt-get update && sudo apt-get update && sudo apt-get install -y libdbus-1-dev libmnl-dev libnftnl-dev \
sudo apt-get install -y webkit2gtk-4.0 libwebkit2gtk-4.1-dev build-essential curl wget libssl-dev jq \
continue-on-error: true libgtk-3-dev squashfs-tools libayatana-appindicator3-dev make libfuse2 unzip librsvg2-dev file \
libsoup-3.0-dev libjavascriptcoregtk-4.1-dev
- name: Node - name: Node
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 21
cache: 'yarn'
- name: Install Rust stable - name: Install Rust stable
uses: actions-rs/toolchain@v1 uses: dtolnay/rust-toolchain@stable
with: with:
toolchain: stable toolchain: stable
- name: Install project dependencies - name: Install project dependencies
shell: bash shell: bash
run: cd .. && yarn --network-timeout 100000 run: cd .. && yarn --network-timeout 100000
- name: Install app dependencies - name: Install app dependencies
run: yarn run: yarn
- name: Create env file - name: Create env file
uses: timheuer/base64-to-file@v1.2 uses: timheuer/base64-to-file@v1.2
with: with:
fileName: '.env' fileName: '.env'
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Build app - name: Build app
run: yarn build run: yarn build
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
- name: Check bundle directory
run: |
echo "Checking bundle directory structure"
ls -la target/release/bundle || echo "Bundle directory not found"
if [ -d "target/release/bundle/appimage" ]; then
echo "AppImage bundle directory exists, checking contents:"
ls -la target/release/bundle/appimage
else
echo "AppImage bundle directory not found, checking alternatives:"
find target/release/bundle -type d -name "*appimage*" -o -name "*AppImage*" || echo "No AppImage directories found"
find target/release/bundle -name "*.AppImage" -o -name "*.appimage" || echo "No AppImage files found"
fi
- name: Create AppImage tarball if needed
run: |
# Find the AppImage file
APPIMAGE_FILE=$(find target/release/bundle -name "*.AppImage" | head -n 1)
if [ -n "$APPIMAGE_FILE" ]; then
echo "Found AppImage file: $APPIMAGE_FILE"
APPIMAGE_DIR=$(dirname "$APPIMAGE_FILE")
APPIMAGE_NAME=$(basename "$APPIMAGE_FILE")
# Create tarball if it doesn't exist
if [ ! -f "${APPIMAGE_FILE}.tar.gz" ]; then
echo "Creating tarball for $APPIMAGE_NAME"
cd "$APPIMAGE_DIR"
tar -czf "${APPIMAGE_NAME}.tar.gz" "$APPIMAGE_NAME"
cd -
echo "Created tarball: ${APPIMAGE_FILE}.tar.gz"
else
echo "Tarball already exists: ${APPIMAGE_FILE}.tar.gz"
fi
else
echo "WARNING: No AppImage file found!"
fi
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: nym-wallet_1.0.0_amd64.AppImage.tar.gz name: nym-wallet-appimage.tar.gz
path: nym-wallet/target/release/bundle/appimage/nym-wallet*.AppImage.tar.gz path: |
nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz
nym-wallet/target/release/bundle/*/nym-wallet*.AppImage.tar.gz
retention-days: 30 retention-days: 30
- id: create-release - id: create-release
name: Upload to release based on tag name name: Upload to release based on tag name
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
@@ -75,24 +112,26 @@ jobs:
with: with:
files: | files: |
nym-wallet/target/release/bundle/appimage/*.AppImage nym-wallet/target/release/bundle/appimage/*.AppImage
nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz* nym-wallet/target/release/bundle/appimage/*.AppImage.tar.gz
nym-wallet/target/release/bundle/*/nym-wallet*.AppImage
- name: Deploy artifacts to CI www nym-wallet/target/release/bundle/*/nym-wallet*.AppImage.tar.gz
continue-on-error: true
uses: easingthemes/ssh-deploy@main - name: Find AppImage tarball path for deployment
env: id: find-appimage
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }} run: |
ARGS: "-avzr" APPIMAGE_TARBALL=$(find target/release/bundle -name "*.AppImage.tar.gz" | head -n 1)
SOURCE: "nym-wallet/target/release/bundle/appimage/nym-wallet*.AppImage.tar.gz" if [ -n "$APPIMAGE_TARBALL" ]; then
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }} echo "Found AppImage tarball: $APPIMAGE_TARBALL"
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }} echo "appimage_path=$APPIMAGE_TARBALL" >> $GITHUB_OUTPUT
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/${{ github.ref_name }}/nym-wallet else
EXCLUDE: "/dist/, /node_modules/" echo "WARNING: No AppImage tarball found for deployment!"
echo "appimage_path=target/release/bundle/appimage/nym-wallet*.AppImage.tar.gz" >> $GITHUB_OUTPUT
fi
push-release-data: push-release-data:
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
uses: ./.github/workflows/release-calculate-hash.yml uses: ./.github/workflows/release-calculate-hash.yml
needs: publish-tauri needs: publish-tauri
with: with:
release_tag: ${{ github.ref_name }} release_tag: ${{ needs.publish-tauri.outputs.release_tag || github.ref_name }}
secrets: inherit secrets: inherit
+111 -62
View File
@@ -1,6 +1,12 @@
name: publish-nym-wallet-win11 name: publish-nym-wallet-win11
on: on:
workflow_dispatch: workflow_dispatch:
inputs:
sign:
description: "Sign this build using SSL.com. Signing is billed per signature so be careful"
required: false
type: boolean
default: true
release: release:
types: [created] types: [created]
@@ -18,53 +24,61 @@ jobs:
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.platform }}
outputs: outputs:
release_id: ${{ steps.create-release.outputs.id }} release_tag: ${{ github.ref_name }}
release_date: ${{ fromJSON(steps.create-release.outputs.assets)[0].created_at }}
version: ${{ steps.release-info.outputs.version }}
filename: ${{ steps.release-info.outputs.filename }}
file_hash: ${{ steps.release-info.outputs.file_hash }}
steps: steps:
- name: Clean up first
continue-on-error: true
working-directory: .
run: |
cd ..
del /s /q /A:H nym
rmdir /s /q nym
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Import signing certificate - name: Install Rust stable
env: uses: dtolnay/rust-toolchain@stable
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }} with:
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} toolchain: stable
run: |
New-Item -ItemType directory -Path certificate - name: Setup MSBuild.exe
Set-Content -Path certificate/tempCert.txt -Value $env:WINDOWS_CERTIFICATE uses: microsoft/setup-msbuild@v2
certutil -decode certificate/tempCert.txt certificate/certificate.pfx
Remove-Item -path certificate -include tempCert.txt
Import-PfxCertificate -FilePath certificate/certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText)
- name: Node - name: Node
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 21
- name: Install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Create env file
uses: timheuer/base64-to-file@v1.2
with:
fileName: '.env'
encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }}
- name: Install Yarn
run: npm install -g yarn
- name: Download EV CodeSignTool from ssl.com
working-directory: nym-wallet/src-tauri
if: ${{ inputs.sign }}
shell: bash
run: |
curl -L0 https://www.ssl.com/download/codesigntool-for-linux-and-macos/ -o codesigntool.zip
unzip codesigntool.zip
- name: Get EV certificate credential id
working-directory: nym-wallet/src-tauri
if: ${{ inputs.sign }}
id: get_credential_ids
shell: bash
run: |
echo "SSL_COM_CREDENTIAL_ID=$(./CodeSignTool.sh get_credential_ids -username=${{ secrets.SSL_COM_USERNAME }} -password=${{ secrets.SSL_COM_PASSWORD }} | sed -n '1!p' | sed 's/- //')" >> "$GITHUB_OUTPUT"
- name: Add custom sign command to tauri.conf.json
working-directory: nym-wallet/src-tauri
if: ${{ inputs.sign }}
shell: bash
run: |
yq eval --inplace '.bundle.windows +=
{
"signCommand": {
"cmd": "C:\Program Files\Git\bin\bash.EXE",
"args": [
"/c/actions-runner/_work/nym/nym/nym-wallet/src-tauri/CodeSignTool.sh",
"sign",
"-username ${{ secrets.SSL_COM_USERNAME }}",
"-password ${{ secrets.SSL_COM_PASSWORD }}",
"-credential_id ${{ steps.get_credential_ids.outputs.SSL_COM_CREDENTIAL_ID }}",
"-totp_secret ${{ secrets.SSL_COM_TOTP_SECRET }}",
"-program_name NymWallet",
"-input_file_path",
"%1",
"-override"
]
}
}' tauri.conf.json
- name: Install project dependencies - name: Install project dependencies
shell: bash shell: bash
run: cd .. && yarn --network-timeout 100000 run: cd .. && yarn --network-timeout 100000
@@ -77,18 +91,50 @@ jobs:
shell: bash shell: bash
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ENABLE_CODE_SIGNING: ${{ secrets.WINDOWS_CERTIFICATE }} TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }} SSL_COM_USERNAME: ${{ inputs.sign && secrets.SSL_COM_USERNAME }}
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} SSL_COM_PASSWORD: ${{ inputs.sign && secrets.SSL_COM_PASSWORD }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} SSL_COM_CREDENTIAL_ID: ${{ inputs.sign && steps.get_credential_ids.outputs.SSL_COM_CREDENTIAL_ID }}
run: yarn build SSL_COM_TOTP_SECRET: ${{ inputs.sign && secrets.SSL_COM_TOTP_SECRET }}
run: |
echo "Starting build process..."
yarn build
- name: Check bundle directory
shell: bash
run: |
echo "Checking bundle directory structure"
# Check standard location
if [ -d "target/release/bundle" ]; then
echo "Found bundle directory at standard location"
ls -la target/release/bundle || echo "Failed to list bundle directory"
fi
# Check src-tauri location
if [ -d "src-tauri/target/release/bundle" ]; then
echo "Found bundle directory in src-tauri"
ls -la src-tauri/target/release/bundle || echo "Failed to list src-tauri bundle directory"
# Use this path for future steps
echo "BUNDLE_PATH=src-tauri/target/release/bundle" >> $GITHUB_ENV
else
echo "Using standard bundle path"
echo "BUNDLE_PATH=target/release/bundle" >> $GITHUB_ENV
fi
# Check for MSI files in any location
find . -name "*.msi" -type f
- name: Upload Artifact - name: Upload Artifact
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: nym-wallet_1.0.0_x64_en-US.msi name: nym-wallet.msi
path: nym-wallet/target/release/bundle/msi/nym-wallet_1.*.msi path: |
nym-wallet/${{ env.BUNDLE_PATH }}/msi/*.msi
nym-wallet/${{ env.BUNDLE_PATH }}/*/nym-wallet*.msi
nym-wallet/src-tauri/target/release/bundle/msi/*.msi
retention-days: 30 retention-days: 30
- id: create-release - id: create-release
@@ -97,25 +143,28 @@ jobs:
if: github.event_name == 'release' if: github.event_name == 'release'
with: with:
files: | files: |
nym-wallet/target/release/bundle/msi/*.msi nym-wallet/${{ env.BUNDLE_PATH }}/msi/*.msi
nym-wallet/target/release/bundle/msi/*.msi.zip* nym-wallet/${{ env.BUNDLE_PATH }}/msi/*.msi.zip*
nym-wallet/${{ env.BUNDLE_PATH }}/*/nym-wallet*.msi
- name: Deploy artifacts to CI www nym-wallet/src-tauri/target/release/bundle/msi/*.msi
continue-on-error: true
uses: easingthemes/ssh-deploy@main - name: Find MSI path for deployment
env: id: find-msi
SSH_PRIVATE_KEY: ${{ secrets.CI_WWW_SSH_PRIVATE_KEY }} shell: bash
ARGS: "-avzr" run: |
SOURCE: "nym-wallet/target/release/bundle/msi/nym-wallet_1.*.msi" MSI_FILE=$(find . -name "*.msi" -type f | head -n 1)
REMOTE_HOST: ${{ secrets.CI_WWW_REMOTE_HOST }} if [ -n "$MSI_FILE" ]; then
REMOTE_USER: ${{ secrets.CI_WWW_REMOTE_USER }} echo "Found MSI file: $MSI_FILE"
TARGET: ${{ secrets.CI_WWW_REMOTE_TARGET }}/builds/${{ github.ref_name }}/nym-wallet echo "msi_path=$MSI_FILE" >> $GITHUB_OUTPUT
EXCLUDE: "/dist/, /node_modules/" else
echo "WARNING: No MSI file found for deployment!"
echo "msi_path=${{ env.BUNDLE_PATH }}/msi/nym-wallet*.msi" >> $GITHUB_OUTPUT
fi
push-release-data: push-release-data:
if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }} if: ${{ (startsWith(github.ref, 'refs/tags/nym-wallet-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}
uses: ./.github/workflows/release-calculate-hash.yml uses: ./.github/workflows/release-calculate-hash.yml
needs: publish-tauri needs: publish-tauri
with: with:
release_tag: ${{ github.ref_name }} release_tag: ${{ needs.publish-tauri.outputs.release_tag || github.ref_name }}
secrets: inherit secrets: inherit
@@ -12,7 +12,7 @@ on:
jobs: jobs:
build: build:
name: Build APK name: Build APK
runs-on: custom-ubuntu-20.04 runs-on: custom-ubuntu-22.04
env: env:
ANDROID_HOME: ${{ github.workspace }}/android-sdk ANDROID_HOME: ${{ github.workspace }}/android-sdk
NDK_VERSION: 25.2.9519653 NDK_VERSION: 25.2.9519653
@@ -49,7 +49,7 @@ jobs:
"build-tools;$SDK_BUILDTOOLS_VERSION" "build-tools;$SDK_BUILDTOOLS_VERSION"
- name: Install Rust toolchain - name: Install Rust toolchain
uses: dtolnay/rust-toolchain@1.90.0 uses: dtolnay/rust-toolchain@1.100.0
- name: Install rust android targets - name: Install rust android targets
run: | run: |
+3 -8
View File
@@ -4,14 +4,14 @@ on:
jobs: jobs:
publish: publish:
runs-on: arc-ubuntu-20.04 runs-on: arc-ubuntu-22.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install Node - name: Install Node
uses: actions/setup-node@v4 uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 20
registry-url: "https://registry.npmjs.org" registry-url: "https://registry.npmjs.org"
- name: Setup yarn - name: Setup yarn
@@ -31,12 +31,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: "1.20" go-version: "1.23.7"
- name: Install TinyGo
uses: acifani/setup-tinygo@v2
with:
tinygo-version: "0.27.0"
- name: Install dependencies - name: Install dependencies
run: yarn run: yarn
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
- uses: actions/setup-node@v4 - uses: actions/setup-node@v4
with: with:
node-version: 18 node-version: 20
- uses: nymtech/nym/.github/actions/nym-hash-releases@develop - uses: nymtech/nym/.github/actions/nym-hash-releases@develop
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+3
View File
@@ -59,3 +59,6 @@ nym-api/redocly/formatted-openapi.json
*.sqlite *.sqlite
.build .build
**/settings.sql
**/enter_db.sh
+150
View File
@@ -4,6 +4,156 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
## [Unreleased] ## [Unreleased]
## [2025.9-appenzeller] (2025-05-13)
- build(deps): bump clap from 4.5.36 to 4.5.37 in the patch-updates group ([#5722])
- build(deps): bump golang.org/x/net from 0.36.0 to 0.38.0 in /wasm/mix-fetch/go-mix-conn ([#5720])
- build(deps-dev): bump http-proxy-middleware from 2.0.6 to 2.0.9 in /wasm/client/internal-dev ([#5719])
- Add /account/{address} ([#5673])
- Add contains ticketbook data db query ([#5670])
[#5722]: https://github.com/nymtech/nym/pull/5722
[#5720]: https://github.com/nymtech/nym/pull/5720
[#5719]: https://github.com/nymtech/nym/pull/5719
[#5673]: https://github.com/nymtech/nym/pull/5673
[#5670]: https://github.com/nymtech/nym/pull/5670
## [2025.8-tourist] (2025-04-29)
- add reserved byte to reply surb serialisation ([#5731])
- Remove inactive peers ([#5721])
- Update Hickory DNS "0.24.4" to "0.25" ([#5709])
- build(deps): bump the patch-updates group across 1 directory with 7 updates ([#5708])
- Peer handle should die more gracefully ([#5704])
- build(deps): bump crossbeam-channel from 0.5.14 to 0.5.15 ([#5702])
- build(deps): bump actions/checkout from 3 to 4 ([#5700])
- Feature/updated sphinx payload keys ([#5698])
- Bump the nym-vpn deb metapackage to 1.0 ([#5697])
- Make mix hops optional for Mixnet Client ([#5696])
- build(deps): bump tokio from 1.44.1 to 1.44.2 ([#5693])
- Feature/replay protection ([#5682])
- Adding fresh nym-api tests and workflow ([#5659])
- build(deps): bump next from 14.2.21 to 14.2.25 ([#5655])
- build(deps): bump pnpm/action-setup from 4.0.0 to 4.1.0 ([#5436])
[#5731]: https://github.com/nymtech/nym/pull/5731
[#5721]: https://github.com/nymtech/nym/pull/5721
[#5709]: https://github.com/nymtech/nym/pull/5709
[#5708]: https://github.com/nymtech/nym/pull/5708
[#5704]: https://github.com/nymtech/nym/pull/5704
[#5702]: https://github.com/nymtech/nym/pull/5702
[#5700]: https://github.com/nymtech/nym/pull/5700
[#5698]: https://github.com/nymtech/nym/pull/5698
[#5697]: https://github.com/nymtech/nym/pull/5697
[#5696]: https://github.com/nymtech/nym/pull/5696
[#5693]: https://github.com/nymtech/nym/pull/5693
[#5682]: https://github.com/nymtech/nym/pull/5682
[#5659]: https://github.com/nymtech/nym/pull/5659
[#5655]: https://github.com/nymtech/nym/pull/5655
[#5436]: https://github.com/nymtech/nym/pull/5436
## [2025.7-tex] (2025-04-14)
- Expand /v3/nym-nodes with geodata ([#5686])
- chore: clippy for 1.86 ([#5685])
- Featrure: Bash scripts to init and configure VMs conveniently and update docs ([#5681])
- Update node versions in CI ([#5677])
- build(deps): bump the patch-updates group across 1 directory with 8 updates ([#5668])
- Update log crate ([#5667])
- Minor fixes involving key cloning and hashing ([#5664])
- mix throughput tester ([#5661])
- build(deps): bump blake3 from 1.6.1 to 1.7.0 ([#5658])
- build(deps): bump elliptic from 6.5.5 to 6.6.1 ([#5483])
- Move all workflows on ubuntu-20 to ubuntu-22 ([#5455])
[#5686]: https://github.com/nymtech/nym/pull/5686
[#5685]: https://github.com/nymtech/nym/pull/5685
[#5681]: https://github.com/nymtech/nym/pull/5681
[#5677]: https://github.com/nymtech/nym/pull/5677
[#5668]: https://github.com/nymtech/nym/pull/5668
[#5667]: https://github.com/nymtech/nym/pull/5667
[#5664]: https://github.com/nymtech/nym/pull/5664
[#5661]: https://github.com/nymtech/nym/pull/5661
[#5658]: https://github.com/nymtech/nym/pull/5658
[#5483]: https://github.com/nymtech/nym/pull/5483
[#5455]: https://github.com/nymtech/nym/pull/5455
## [2025.6-chuckles] (2025-03-31)
- Remove Google public DNS ([#5660])
- Revert using AsyncWrite sink in IPR ([#5656])
- Add fd callback for initial authentication ([#5654])
- Add concurrency limit to CI ([#5651])
- Remove UNIQUE constraint on node pubkey ([#5649])
- Add RUSTUP_PERMIT_COPY_RENAME in two workflows that we forgot about ([#5646])
- Upgrade sha2 to workspace version for validator-client ([#5644])
- Add max_retransmissions flag on each message ([#5642])
- build(deps): bump zip from 2.2.2 to 2.4.1 ([#5639])
- build(deps): bump dtolnay/rust-toolchain from 1.90.0 to 1.100.0 ([#5638])
- / regenerated yarn.lock ([#5636])
- Rework IPR codec to extract out timer and implement AsyncWrite ([#5632])
- build(deps): bump tempfile from 3.18.0 to 3.19.0 ([#5631])
- build(deps): bump zeroize from 1.6.0 to 1.8.1 ([#5630])
- build(deps): bump once_cell from 1.20.3 to 1.21.1 ([#5629])
- build(deps): bump uuid from 1.15.1 to 1.16.0 ([#5628])
- build(deps): bump celes from 2.5.0 to 2.6.0 ([#5627])
- build(deps): bump http from 1.2.0 to 1.3.1 ([#5626])
- build(deps): bump humantime from 2.1.0 to 2.2.0 ([#5625])
- build(deps): bump the patch-updates group with 8 updates ([#5624])
- build(deps): bump @babel/runtime from 7.16.3 to 7.26.10 in /testnet-faucet ([#5621])
- Feature/paginated ticketbooks challenge ([#5619])
- build(deps-dev): bump webpack from 5.77.0 to 5.98.0 in /wasm/client/internal-dev ([#5615])
- build(deps-dev): bump ws from 8.13.0 to 8.18.1 in /wasm/client/internal-dev ([#5614])
- build(deps): bump golang.org/x/net from 0.23.0 to 0.36.0 in /wasm/mix-fetch/go-mix-conn ([#5613])
- build(deps): bump braces from 3.0.2 to 3.0.3 in /sdk/typescript/packages/mix-fetch-node ([#5612])
- Wireguard exit policies (and tests) ([#5557])
- Explorer V2 ([#5548])
- Clean stale partially received buffers ([#5536])
- Corrected typos ([#5497])
- build(deps): bump @octokit/plugin-paginate-rest and @actions/github in /.github/actions/nym-hash-releases/src ([#5488])
- feature: upgrade cosmwasm to 2.2 ([#5479])
- build(deps): bump store2 from 2.14.3 to 2.14.4 ([#5391])
- build(deps): bump nanoid from 3.3.7 to 3.3.8 in /documentation/docs ([#5335])
- build(deps): bump next from 13.5.7 to 14.2.15 in /documentation/docs ([#5281])
- Bump http-proxy-middleware from 2.0.6 to 2.0.7 ([#5019])
[#5660]: https://github.com/nymtech/nym/pull/5660
[#5656]: https://github.com/nymtech/nym/pull/5656
[#5654]: https://github.com/nymtech/nym/pull/5654
[#5651]: https://github.com/nymtech/nym/pull/5651
[#5649]: https://github.com/nymtech/nym/pull/5649
[#5646]: https://github.com/nymtech/nym/pull/5646
[#5644]: https://github.com/nymtech/nym/pull/5644
[#5642]: https://github.com/nymtech/nym/pull/5642
[#5639]: https://github.com/nymtech/nym/pull/5639
[#5638]: https://github.com/nymtech/nym/pull/5638
[#5636]: https://github.com/nymtech/nym/pull/5636
[#5632]: https://github.com/nymtech/nym/pull/5632
[#5631]: https://github.com/nymtech/nym/pull/5631
[#5630]: https://github.com/nymtech/nym/pull/5630
[#5629]: https://github.com/nymtech/nym/pull/5629
[#5628]: https://github.com/nymtech/nym/pull/5628
[#5627]: https://github.com/nymtech/nym/pull/5627
[#5626]: https://github.com/nymtech/nym/pull/5626
[#5625]: https://github.com/nymtech/nym/pull/5625
[#5624]: https://github.com/nymtech/nym/pull/5624
[#5621]: https://github.com/nymtech/nym/pull/5621
[#5619]: https://github.com/nymtech/nym/pull/5619
[#5615]: https://github.com/nymtech/nym/pull/5615
[#5614]: https://github.com/nymtech/nym/pull/5614
[#5613]: https://github.com/nymtech/nym/pull/5613
[#5612]: https://github.com/nymtech/nym/pull/5612
[#5557]: https://github.com/nymtech/nym/pull/5557
[#5548]: https://github.com/nymtech/nym/pull/5548
[#5536]: https://github.com/nymtech/nym/pull/5536
[#5497]: https://github.com/nymtech/nym/pull/5497
[#5488]: https://github.com/nymtech/nym/pull/5488
[#5479]: https://github.com/nymtech/nym/pull/5479
[#5391]: https://github.com/nymtech/nym/pull/5391
[#5335]: https://github.com/nymtech/nym/pull/5335
[#5281]: https://github.com/nymtech/nym/pull/5281
[#5019]: https://github.com/nymtech/nym/pull/5019
## [2025.5-chokito] (2025-03-18) ## [2025.5-chokito] (2025-03-18)
- build(deps): bump braces from 3.0.2 to 3.0.3 in /sdk/typescript/packages/nodejs-client ([#5611]) - build(deps): bump braces from 3.0.2 to 3.0.3 in /sdk/typescript/packages/nodejs-client ([#5611])
Generated
+781 -473
View File
File diff suppressed because it is too large Load Diff
+32 -36
View File
@@ -32,15 +32,13 @@ members = [
"common/client-libs/validator-client", "common/client-libs/validator-client",
"common/commands", "common/commands",
"common/config", "common/config",
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
"common/cosmwasm-smart-contracts/coconut-dkg", "common/cosmwasm-smart-contracts/coconut-dkg",
"common/cosmwasm-smart-contracts/contracts-common", "common/cosmwasm-smart-contracts/contracts-common", "common/cosmwasm-smart-contracts/easy_addr",
"common/cosmwasm-smart-contracts/ecash-contract", "common/cosmwasm-smart-contracts/ecash-contract",
"common/cosmwasm-smart-contracts/group-contract", "common/cosmwasm-smart-contracts/group-contract",
"common/cosmwasm-smart-contracts/mixnet-contract", "common/cosmwasm-smart-contracts/mixnet-contract",
"common/cosmwasm-smart-contracts/multisig-contract", "common/cosmwasm-smart-contracts/multisig-contract",
"common/cosmwasm-smart-contracts/vesting-contract", "common/cosmwasm-smart-contracts/vesting-contract",
"common/country-group",
"common/credential-storage", "common/credential-storage",
"common/credential-utils", "common/credential-utils",
"common/credential-verification", "common/credential-verification",
@@ -98,9 +96,6 @@ members = [
"common/wireguard", "common/wireguard",
"common/wireguard-types", "common/wireguard-types",
"documentation/autodoc", "documentation/autodoc",
# "explorer-api",
# "explorer-api/explorer-api-requests",
# "explorer-api/explorer-client",
"gateway", "gateway",
"integrations/bity", "integrations/bity",
"nym-api", "nym-api",
@@ -190,7 +185,7 @@ aes = "0.8.1"
aes-gcm = "0.10.1" aes-gcm = "0.10.1"
aes-gcm-siv = "0.11.1" aes-gcm-siv = "0.11.1"
ammonia = "4" ammonia = "4"
anyhow = "1.0.97" anyhow = "1.0.98"
arc-swap = "1.7.1" arc-swap = "1.7.1"
argon2 = "0.5.0" argon2 = "0.5.0"
async-trait = "0.1.88" async-trait = "0.1.88"
@@ -204,8 +199,8 @@ bincode = "1.3.3"
bip39 = { version = "2.0.0", features = ["zeroize"] } bip39 = { version = "2.0.0", features = ["zeroize"] }
bit-vec = "0.7.0" # can we unify those? bit-vec = "0.7.0" # can we unify those?
bitvec = "1.0.0" bitvec = "1.0.0"
blake3 = "1.6.1" blake3 = "1.7.0"
bloomfilter = "1.0.14" bloomfilter = "3.0.1"
bs58 = "0.5.1" bs58 = "0.5.1"
bytecodec = "0.4.15" bytecodec = "0.4.15"
bytes = "1.10.1" bytes = "1.10.1"
@@ -216,7 +211,7 @@ chacha20 = "0.9.0"
chacha20poly1305 = "0.10.1" chacha20poly1305 = "0.10.1"
chrono = "0.4.40" chrono = "0.4.40"
cipher = "0.4.3" cipher = "0.4.3"
clap = "4.5.32" clap = "4.5.37"
clap_complete = "4.5" clap_complete = "4.5"
clap_complete_fig = "4.5" clap_complete_fig = "4.5"
colored = "2.2" colored = "2.2"
@@ -241,12 +236,12 @@ dotenvy = "0.15.6"
ecdsa = "0.16" ecdsa = "0.16"
ed25519-dalek = "2.1" ed25519-dalek = "2.1"
encoding_rs = "0.8.35" encoding_rs = "0.8.35"
env_logger = "0.11.7" env_logger = "0.11.8"
envy = "0.4" envy = "0.4"
etherparse = "0.13.0" etherparse = "0.13.0"
eyre = "0.6.9" eyre = "0.6.9"
fastrand = "2.1.1" fastrand = "2.1.1"
flate2 = "1.1.0" flate2 = "1.1.1"
futures = "0.3.31" futures = "0.3.31"
futures-util = "0.3" futures-util = "0.3"
generic-array = "0.14.7" generic-array = "0.14.7"
@@ -256,7 +251,7 @@ handlebars = "3.5.5"
headers = "0.4.0" headers = "0.4.0"
hex = "0.4.3" hex = "0.4.3"
hex-literal = "0.3.3" hex-literal = "0.3.3"
hickory-resolver = "0.24.4" hickory-resolver = "0.25"
hkdf = "0.12.3" hkdf = "0.12.3"
hmac = "0.12.1" hmac = "0.12.1"
http = "1" http = "1"
@@ -271,7 +266,6 @@ indicatif = "0.17.11"
inquire = "0.6.2" inquire = "0.6.2"
ip_network = "0.4.1" ip_network = "0.4.1"
ipnetwork = "0.20" ipnetwork = "0.20"
isocountry = "0.3.2"
itertools = "0.14.0" itertools = "0.14.0"
k256 = "0.13" k256 = "0.13"
lazy_static = "1.5.0" lazy_static = "1.5.0"
@@ -284,7 +278,7 @@ moka = { version = "0.12", features = ["future"] }
nix = "0.27.1" nix = "0.27.1"
notify = "5.1.0" notify = "5.1.0"
okapi = "0.7.0" okapi = "0.7.0"
once_cell = "1.21.1" once_cell = "1.21.3"
opentelemetry = "0.19.0" opentelemetry = "0.19.0"
opentelemetry-jaeger = "0.18.0" opentelemetry-jaeger = "0.18.0"
parking_lot = "0.12.3" parking_lot = "0.12.3"
@@ -303,10 +297,7 @@ rand_pcg = "0.3.1"
rand_seeder = "0.2.3" rand_seeder = "0.2.3"
rayon = "1.5.1" rayon = "1.5.1"
regex = "1.10.6" regex = "1.10.6"
reqwest = { version = "0.12.4", default-features = false } reqwest = { version = "0.12.15", default-features = false }
rocket = "0.5.0"
rocket_cors = "0.6.0"
rocket_okapi = "0.8.0"
rs_merkle = "1.5.0" rs_merkle = "1.5.0"
safer-ffi = "0.1.13" safer-ffi = "0.1.13"
schemars = "0.8.22" schemars = "0.8.22"
@@ -321,7 +312,7 @@ serde_with = "3.9.0"
serde_yaml = "0.9.25" serde_yaml = "0.9.25"
sha2 = "0.10.8" sha2 = "0.10.8"
si-scale = "0.2.3" si-scale = "0.2.3"
sphinx-packet = "=0.3.2" sphinx-packet = "=0.6.0"
sqlx = "0.7.4" sqlx = "0.7.4"
strum = "0.26" strum = "0.26"
strum_macros = "0.26" strum_macros = "0.26"
@@ -332,7 +323,7 @@ tap = "1.0.1"
tar = "0.4.44" tar = "0.4.44"
tempfile = "3.19" tempfile = "3.19"
thiserror = "2.0" thiserror = "2.0"
time = "0.3.39" time = "0.3.41"
tokio = "1.44" tokio = "1.44"
tokio-postgres = "0.7" tokio-postgres = "0.7"
tokio-stream = "0.1.17" tokio-stream = "0.1.17"
@@ -348,9 +339,10 @@ tracing-log = "0.2"
tracing-opentelemetry = "0.19.0" tracing-opentelemetry = "0.19.0"
tracing-subscriber = "0.3.19" tracing-subscriber = "0.3.19"
tracing-tree = "0.2.2" tracing-tree = "0.2.2"
tracing-indicatif = "0.3.9"
ts-rs = "10.1.0" ts-rs = "10.1.0"
tungstenite = { version = "0.20.1", default-features = false } tungstenite = { version = "0.20.1", default-features = false }
uniffi = "0.29.0" uniffi = "0.29.1"
uniffi_build = "0.29.0" uniffi_build = "0.29.0"
url = "2.5" url = "2.5"
utoipa = "5.2" utoipa = "5.2"
@@ -361,7 +353,7 @@ vergen = { version = "=8.3.1", default-features = false }
walkdir = "2" walkdir = "2"
wasm-bindgen-test = "0.3.49" wasm-bindgen-test = "0.3.49"
x25519-dalek = "2.0.0" x25519-dalek = "2.0.0"
zeroize = "1.8.1" zeroize = "1.7.0"
prometheus = { version = "0.13.0" } prometheus = { version = "0.13.0" }
@@ -375,27 +367,26 @@ ff = { version = "0.13.1", default-features = false }
subtle = "2.5.0" subtle = "2.5.0"
# cosmwasm-related # cosmwasm-related
cosmwasm-schema = "=1.4.3" cosmwasm-schema = "=2.2.2"
cosmwasm-std = "=1.4.3" cosmwasm-std = "=2.2.2"
# use 0.5.0 as that's the version used by cosmwasm-std 1.4.3 # use 1.0.1 as that's the version used by cosmwasm-std 2.2.1
# (and ideally we don't want to pull the same dependency twice) # (and ideally we don't want to pull the same dependency twice)
serde-json-wasm = "=0.5.0" serde-json-wasm = "=1.0.1"
cosmwasm-storage = "=1.4.3"
# same version as used by cosmwasm # same version as used by cosmwasm
cw-utils = "=1.0.1" cw-utils = "=2.0.0"
cw-storage-plus = "=1.2.0" cw-storage-plus = "=2.0.0"
cw2 = { version = "=1.1.2" } cw2 = { version = "=2.0.0" }
cw3 = { version = "=1.1.2" } cw3 = { version = "=2.0.0" }
cw4 = { version = "=1.1.2" } cw4 = { version = "=2.0.0" }
cw-controllers = { version = "=1.1.0" } cw-controllers = { version = "=2.0.0" }
# cosmrs-related # cosmrs-related
bip32 = { version = "0.5.3", default-features = false } bip32 = { version = "0.5.3", default-features = false }
cosmrs = { version = "0.21.1" } cosmrs = { version = "0.21.1" }
tendermint = "0.40.0" tendermint = "0.40.3"
tendermint-rpc = "0.40.0" tendermint-rpc = "0.40.3"
prost = { version = "0.13", default-features = false } prost = { version = "0.13", default-features = false }
# wasm-related dependencies # wasm-related dependencies
@@ -411,6 +402,11 @@ wasm-bindgen-futures = "0.4.49"
wasmtimer = "0.4.1" wasmtimer = "0.4.1"
web-sys = "0.3.76" web-sys = "0.3.76"
# for local development:
#[patch.crates-io]
#sphinx-packet = { path = "../sphinx" }
# Profile settings for individual crates # Profile settings for individual crates
# Compile-time verified queries do quite a bit of work at compile time. Incremental # Compile-time verified queries do quite a bit of work at compile time. Incremental
+10 -19
View File
@@ -133,17 +133,22 @@ clippy: sdk-wasm-lint
# Build contracts ready for deploy # Build contracts ready for deploy
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
CONTRACTS=vesting_contract mixnet_contract nym_ecash CONTRACTS=vesting_contract mixnet_contract nym_ecash cw3_flex_multisig cw4_group nym_coconut_dkg
CONTRACTS_WASM=$(addsuffix .wasm, $(CONTRACTS)) CONTRACTS_WASM=$(addsuffix .wasm, $(CONTRACTS))
CONTRACTS_OUT_DIR=contracts/target/wasm32-unknown-unknown/release CONTRACTS_OUT_DIR=contracts/target/wasm32-unknown-unknown/release
contracts: build-release-contracts wasm-opt-contracts contracts: build-release-contracts wasm-opt-contracts cosmwasm-check-contracts
wasm-opt-contracts: wasm-opt-contracts:
for contract in $(CONTRACTS_WASM); do \ for contract in $(CONTRACTS_WASM); do \
wasm-opt --signext-lowering -Os $(CONTRACTS_OUT_DIR)/$$contract -o $(CONTRACTS_OUT_DIR)/$$contract; \ wasm-opt --signext-lowering -Os $(CONTRACTS_OUT_DIR)/$$contract -o $(CONTRACTS_OUT_DIR)/$$contract; \
done done
cosmwasm-check-contracts:
for contract in $(CONTRACTS_WASM); do \
cosmwasm-check $(CONTRACTS_OUT_DIR)/$$contract; \
done
# Consider adding 's' to make plural consistent (beware: used in github workflow) # Consider adding 's' to make plural consistent (beware: used in github workflow)
contract-schema: contract-schema:
$(MAKE) -C contracts schema $(MAKE) -C contracts schema
@@ -152,18 +157,9 @@ contract-schema:
# Convenience targets for crates that are already part of the main workspace # Convenience targets for crates that are already part of the main workspace
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
build-explorer-api:
cargo build -p explorer-api
build-nym-cli: build-nym-cli:
cargo build -p nym-cli --release cargo build -p nym-cli --release
build-nym-gateway:
cargo build -p nym-gateway --release
build-nym-mixnode:
cargo build -p nym-mixnode --release
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
# Misc # Misc
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
@@ -172,17 +168,12 @@ generate-typescript:
cd tools/ts-rs-cli && cargo run && cd ../.. cd tools/ts-rs-cli && cargo run && cd ../..
yarn types:lint:fix yarn types:lint:fix
# Run the integration tests for public nym-api endpoints
run-api-tests: run-api-tests:
cd nym-api/tests/functional_test && yarn test:qa dotenv -f envs/sandbox.env -- cargo test --test public-api-tests
# Build debian package, and update PPA # Build debian package, and update PPA
deb-mixnode: build-nym-mixnode
cargo deb -p nym-mixnode
deb-gateway: build-nym-gateway
cargo deb -p nym-gateway
deb-cli: build-nym-cli deb-cli: build-nym-cli
cargo deb -p nym-cli cargo deb -p nym-cli
deb: deb-mixnode deb-gateway deb-cli deb: deb-cli
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "nym-client" name = "nym-client"
version = "1.1.51" version = "1.1.55"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"] authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
description = "Implementation of the Nym Client" description = "Implementation of the Nym Client"
edition = "2021" edition = "2021"
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "nym-socks5-client" name = "nym-socks5-client"
version = "1.1.51" version = "1.1.55"
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"] authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
edition = "2021" edition = "2021"
-1
View File
@@ -87,7 +87,6 @@ impl From<Init> for OverrideConfig {
use_anonymous_replies: init_config.use_reply_surbs, use_anonymous_replies: init_config.use_reply_surbs,
fastmode: init_config.common_args.fastmode, fastmode: init_config.common_args.fastmode,
no_cover: init_config.common_args.no_cover, no_cover: init_config.common_args.no_cover,
geo_routing: None,
medium_toggle: false, medium_toggle: false,
nyxd_urls: init_config.common_args.nyxd_urls, nyxd_urls: init_config.common_args.nyxd_urls,
enabled_credentials_mode: init_config.common_args.enabled_credentials_mode, enabled_credentials_mode: init_config.common_args.enabled_credentials_mode,
+1 -22
View File
@@ -16,8 +16,7 @@ use nym_bin_common::bin_info;
use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::completions::{fig_generate, ArgShell};
use nym_client_core::cli_helpers::CliClient; use nym_client_core::cli_helpers::CliClient;
use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33;
use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup; use nym_client_core::config::ForgetMe;
use nym_client_core::config::{ForgetMe, GroupBy, TopologyStructure};
use nym_config::OptionalSet; use nym_config::OptionalSet;
use nym_sphinx::addressing::Recipient; use nym_sphinx::addressing::Recipient;
use nym_sphinx::params::{PacketSize, PacketType}; use nym_sphinx::params::{PacketSize, PacketType};
@@ -107,7 +106,6 @@ pub(crate) struct OverrideConfig {
use_anonymous_replies: Option<bool>, use_anonymous_replies: Option<bool>,
fastmode: bool, fastmode: bool,
no_cover: bool, no_cover: bool,
geo_routing: Option<CountryGroup>,
medium_toggle: bool, medium_toggle: bool,
nyxd_urls: Option<Vec<url::Url>>, nyxd_urls: Option<Vec<url::Url>>,
enabled_credentials_mode: Option<bool>, enabled_credentials_mode: Option<bool>,
@@ -138,21 +136,6 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
let secondary_packet_size = args.medium_toggle.then_some(PacketSize::ExtendedPacket16); let secondary_packet_size = args.medium_toggle.then_some(PacketSize::ExtendedPacket16);
let no_per_hop_delays = args.medium_toggle; let no_per_hop_delays = args.medium_toggle;
let topology_structure = if args.medium_toggle {
// Use the location of the network-requester
let address = config
.core
.socks5
.provider_mix_address
.parse()
.expect("failed to parse provider mix address");
TopologyStructure::GeoAware(GroupBy::NymAddress(address))
} else if let Some(code) = args.geo_routing {
TopologyStructure::GeoAware(GroupBy::CountryGroup(code))
} else {
TopologyStructure::default()
};
let packet_type = if args.outfox { let packet_type = if args.outfox {
PacketType::Outfox PacketType::Outfox
} else { } else {
@@ -176,10 +159,6 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
// NOTE: see comment above about the order of the other disble cover traffic config // NOTE: see comment above about the order of the other disble cover traffic config
.with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover) .with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover)
.with_base(BaseClientConfig::with_packet_type, packet_type) .with_base(BaseClientConfig::with_packet_type, packet_type)
.with_base(
BaseClientConfig::with_topology_structure,
topology_structure,
)
.with_base(BaseClientConfig::with_forget_me, args.forget_me) .with_base(BaseClientConfig::with_forget_me, args.forget_me)
.with_optional(Config::with_anonymous_replies, args.use_anonymous_replies) .with_optional(Config::with_anonymous_replies, args.use_anonymous_replies)
.with_optional(Config::with_port, args.port) .with_optional(Config::with_port, args.port)
-13
View File
@@ -6,7 +6,6 @@ use crate::commands::{override_config, OverrideConfig};
use clap::Args; use clap::Args;
use nym_client_core::cli_helpers::client_run::CommonClientRunArgs; use nym_client_core::cli_helpers::client_run::CommonClientRunArgs;
use nym_client_core::client::base_client::storage::OnDiskPersistent; use nym_client_core::client::base_client::storage::OnDiskPersistent;
use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup;
use nym_socks5_client_core::NymClient; use nym_socks5_client_core::NymClient;
use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::addressing::clients::Recipient;
use std::net::IpAddr; use std::net::IpAddr;
@@ -37,10 +36,6 @@ pub(crate) struct Run {
#[clap(long)] #[clap(long)]
host: Option<IpAddr>, host: Option<IpAddr>,
/// Set geo-aware mixnode selection when sending mixnet traffic, for experiments only.
#[clap(long, hide = true, value_parser = validate_country_group, group="routing")]
geo_routing: Option<CountryGroup>,
/// Enable medium mixnet traffic, for experiments only. /// Enable medium mixnet traffic, for experiments only.
/// This includes things like disabling cover traffic, no per hop delays, etc. /// This includes things like disabling cover traffic, no per hop delays, etc.
#[clap(long, hide = true)] #[clap(long, hide = true)]
@@ -59,7 +54,6 @@ impl From<Run> for OverrideConfig {
use_anonymous_replies: run_config.use_anonymous_replies, use_anonymous_replies: run_config.use_anonymous_replies,
fastmode: run_config.common_args.fastmode, fastmode: run_config.common_args.fastmode,
no_cover: run_config.common_args.no_cover, no_cover: run_config.common_args.no_cover,
geo_routing: run_config.geo_routing,
medium_toggle: run_config.medium_toggle, medium_toggle: run_config.medium_toggle,
nyxd_urls: run_config.common_args.nyxd_urls, nyxd_urls: run_config.common_args.nyxd_urls,
enabled_credentials_mode: run_config.common_args.enabled_credentials_mode, enabled_credentials_mode: run_config.common_args.enabled_credentials_mode,
@@ -70,13 +64,6 @@ impl From<Run> for OverrideConfig {
} }
} }
fn validate_country_group(s: &str) -> Result<CountryGroup, String> {
match s.parse() {
Ok(cg) => Ok(cg),
Err(_) => Err(format!("failed to parse country group: {}", s)),
}
}
pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
eprintln!("Starting client {}...", args.common_args.id); eprintln!("Starting client {}...", args.common_args.id);
@@ -13,7 +13,7 @@ use std::{fmt, ops::Deref, str::FromStr};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use hmac::{Hmac, Mac}; use hmac::{Hmac, Mac};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use nym_crypto::asymmetric::encryption::PrivateKey; use nym_crypto::asymmetric::x25519::{PrivateKey, PublicKey};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use sha2::Sha256; use sha2::Sha256;
@@ -82,16 +82,14 @@ impl GatewayClient {
private_ip: IpAddr, private_ip: IpAddr,
nonce: u64, nonce: u64,
) -> Self { ) -> Self {
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek let local_public = PublicKey::from(local_secret);
#[allow(clippy::expect_used)] let remote_public = PublicKey::from(remote_public);
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
let dh = static_secret.diffie_hellman(&remote_public); let dh = local_secret.diffie_hellman(&remote_public);
// TODO: change that to use our nym_crypto::hmac module instead // TODO: change that to use our nym_crypto::hmac module instead
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
let mut mac = HmacSha256::new_from_slice(dh.as_bytes()) let mut mac = HmacSha256::new_from_slice(&dh[..])
.expect("x25519 shared secret is always 32 bytes long"); .expect("x25519 shared secret is always 32 bytes long");
mac.update(local_public.as_bytes()); mac.update(local_public.as_bytes());
@@ -99,7 +97,7 @@ impl GatewayClient {
mac.update(&nonce.to_le_bytes()); mac.update(&nonce.to_le_bytes());
GatewayClient { GatewayClient {
pub_key: PeerPublicKey::new(local_public), pub_key: PeerPublicKey::new(local_public.into()),
private_ip, private_ip,
mac: ClientMac(mac.finalize().into_bytes().to_vec()), mac: ClientMac(mac.finalize().into_bytes().to_vec()),
} }
@@ -109,11 +107,8 @@ impl GatewayClient {
// Client should perform this step when generating its payload, using its own WG PK // Client should perform this step when generating its payload, using its own WG PK
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> { pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek // use gateways key as a ref to an x25519_dalek key
#[allow(clippy::expect_used)] let dh = (gateway_key.as_ref()).diffie_hellman(&self.pub_key);
let static_secret = x25519_dalek::StaticSecret::from(gateway_key.to_bytes());
let dh = static_secret.diffie_hellman(&self.pub_key);
// TODO: change that to use our nym_crypto::hmac module instead // TODO: change that to use our nym_crypto::hmac module instead
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
@@ -195,15 +190,15 @@ impl<'de> Deserialize<'de> for ClientMac {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use nym_crypto::asymmetric::encryption; use nym_crypto::asymmetric::x25519;
#[test] #[test]
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
fn client_request_roundtrip() { fn client_request_roundtrip() {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let gateway_key_pair = encryption::KeyPair::new(&mut rng); let gateway_key_pair = x25519::KeyPair::new(&mut rng);
let client_key_pair = encryption::KeyPair::new(&mut rng); let client_key_pair = x25519::KeyPair::new(&mut rng);
let nonce = 1234567890; let nonce = 1234567890;
@@ -14,7 +14,7 @@ use std::{fmt, ops::Deref, str::FromStr};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use hmac::{Hmac, Mac}; use hmac::{Hmac, Mac};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use nym_crypto::asymmetric::encryption::PrivateKey; use nym_crypto::asymmetric::x25519::{PrivateKey, PublicKey};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use sha2::Sha256; use sha2::Sha256;
@@ -91,16 +91,14 @@ impl GatewayClient {
private_ip: IpAddr, private_ip: IpAddr,
nonce: u64, nonce: u64,
) -> Self { ) -> Self {
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek let local_public = PublicKey::from(local_secret);
#[allow(clippy::expect_used)] let remote_public = PublicKey::from(remote_public);
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
let dh = static_secret.diffie_hellman(&remote_public); let dh = local_secret.diffie_hellman(&remote_public);
// TODO: change that to use our nym_crypto::hmac module instead // TODO: change that to use our nym_crypto::hmac module instead
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
let mut mac = HmacSha256::new_from_slice(dh.as_bytes()) let mut mac = HmacSha256::new_from_slice(&dh[..])
.expect("x25519 shared secret is always 32 bytes long"); .expect("x25519 shared secret is always 32 bytes long");
mac.update(local_public.as_bytes()); mac.update(local_public.as_bytes());
@@ -108,7 +106,7 @@ impl GatewayClient {
mac.update(&nonce.to_le_bytes()); mac.update(&nonce.to_le_bytes());
GatewayClient { GatewayClient {
pub_key: PeerPublicKey::new(local_public), pub_key: PeerPublicKey::new(local_public.into()),
private_ip, private_ip,
mac: ClientMac(mac.finalize().into_bytes().to_vec()), mac: ClientMac(mac.finalize().into_bytes().to_vec()),
} }
@@ -118,11 +116,8 @@ impl GatewayClient {
// Client should perform this step when generating its payload, using its own WG PK // Client should perform this step when generating its payload, using its own WG PK
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> { pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek // use gateways key as a ref to an x25519_dalek key
#[allow(clippy::expect_used)] let dh = (gateway_key.as_ref()).diffie_hellman(&self.pub_key);
let static_secret = x25519_dalek::StaticSecret::from(gateway_key.to_bytes());
let dh = static_secret.diffie_hellman(&self.pub_key);
// TODO: change that to use our nym_crypto::hmac module instead // TODO: change that to use our nym_crypto::hmac module instead
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
@@ -204,15 +199,15 @@ impl<'de> Deserialize<'de> for ClientMac {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use nym_crypto::asymmetric::encryption; use nym_crypto::asymmetric::x25519;
#[test] #[test]
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
fn client_request_roundtrip() { fn client_request_roundtrip() {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let gateway_key_pair = encryption::KeyPair::new(&mut rng); let gateway_key_pair = x25519::KeyPair::new(&mut rng);
let client_key_pair = encryption::KeyPair::new(&mut rng); let client_key_pair = x25519::KeyPair::new(&mut rng);
let nonce = 1234567890; let nonce = 1234567890;
@@ -340,7 +340,7 @@ mod tests {
use std::{net::IpAddr, str::FromStr}; use std::{net::IpAddr, str::FromStr};
use nym_credentials_interface::CredentialSpendingData; use nym_credentials_interface::CredentialSpendingData;
use nym_crypto::asymmetric::encryption::PrivateKey; use nym_crypto::asymmetric::x25519::PrivateKey;
use nym_sphinx::addressing::Recipient; use nym_sphinx::addressing::Recipient;
use nym_wireguard_types::PeerPublicKey; use nym_wireguard_types::PeerPublicKey;
use x25519_dalek::PublicKey; use x25519_dalek::PublicKey;
@@ -14,7 +14,7 @@ use std::{fmt, ops::Deref, str::FromStr};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use hmac::{Hmac, Mac}; use hmac::{Hmac, Mac};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use nym_crypto::asymmetric::encryption::PrivateKey; use nym_crypto::asymmetric::x25519::{PrivateKey, PublicKey};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use sha2::Sha256; use sha2::Sha256;
@@ -91,16 +91,14 @@ impl GatewayClient {
private_ip: IpAddr, private_ip: IpAddr,
nonce: u64, nonce: u64,
) -> Self { ) -> Self {
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek let local_public = PublicKey::from(local_secret);
#[allow(clippy::expect_used)] let remote_public = PublicKey::from(remote_public);
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
let dh = static_secret.diffie_hellman(&remote_public); let dh = local_secret.diffie_hellman(&remote_public);
// TODO: change that to use our nym_crypto::hmac module instead // TODO: change that to use our nym_crypto::hmac module instead
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
let mut mac = HmacSha256::new_from_slice(dh.as_bytes()) let mut mac = HmacSha256::new_from_slice(&dh[..])
.expect("x25519 shared secret is always 32 bytes long"); .expect("x25519 shared secret is always 32 bytes long");
mac.update(local_public.as_bytes()); mac.update(local_public.as_bytes());
@@ -108,7 +106,7 @@ impl GatewayClient {
mac.update(&nonce.to_le_bytes()); mac.update(&nonce.to_le_bytes());
GatewayClient { GatewayClient {
pub_key: PeerPublicKey::new(local_public), pub_key: PeerPublicKey::new(local_public.into()),
private_ip, private_ip,
mac: ClientMac(mac.finalize().into_bytes().to_vec()), mac: ClientMac(mac.finalize().into_bytes().to_vec()),
} }
@@ -118,11 +116,8 @@ impl GatewayClient {
// Client should perform this step when generating its payload, using its own WG PK // Client should perform this step when generating its payload, using its own WG PK
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> { pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek // use gateways key as a ref to an x25519_dalek key
#[allow(clippy::expect_used)] let dh = (gateway_key.as_ref()).diffie_hellman(&self.pub_key);
let static_secret = x25519_dalek::StaticSecret::from(gateway_key.to_bytes());
let dh = static_secret.diffie_hellman(&self.pub_key);
// TODO: change that to use our nym_crypto::hmac module instead // TODO: change that to use our nym_crypto::hmac module instead
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
@@ -204,15 +199,15 @@ impl<'de> Deserialize<'de> for ClientMac {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use nym_crypto::asymmetric::encryption; use nym_crypto::asymmetric::x25519;
#[test] #[test]
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
fn client_request_roundtrip() { fn client_request_roundtrip() {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let gateway_key_pair = encryption::KeyPair::new(&mut rng); let gateway_key_pair = x25519::KeyPair::new(&mut rng);
let client_key_pair = encryption::KeyPair::new(&mut rng); let client_key_pair = x25519::KeyPair::new(&mut rng);
let nonce = 1234567890; let nonce = 1234567890;
@@ -306,7 +306,7 @@ mod tests {
}; };
use nym_credentials_interface::CredentialSpendingData; use nym_credentials_interface::CredentialSpendingData;
use nym_crypto::asymmetric::encryption::PrivateKey; use nym_crypto::asymmetric::x25519::PrivateKey;
use nym_sphinx::addressing::Recipient; use nym_sphinx::addressing::Recipient;
use nym_wireguard_types::PeerPublicKey; use nym_wireguard_types::PeerPublicKey;
use x25519_dalek::PublicKey; use x25519_dalek::PublicKey;
@@ -15,7 +15,7 @@ use std::{fmt, ops::Deref, str::FromStr};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use hmac::{Hmac, Mac}; use hmac::{Hmac, Mac};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use nym_crypto::asymmetric::encryption::PrivateKey; use nym_crypto::asymmetric::x25519::{PrivateKey, PublicKey};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use sha2::Sha256; use sha2::Sha256;
@@ -143,16 +143,14 @@ impl GatewayClient {
private_ips: IpPair, private_ips: IpPair,
nonce: u64, nonce: u64,
) -> Self { ) -> Self {
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek let local_public = PublicKey::from(local_secret);
#[allow(clippy::expect_used)] let remote_public = PublicKey::from(remote_public);
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
let dh = static_secret.diffie_hellman(&remote_public); let dh = local_secret.diffie_hellman(&remote_public);
// TODO: change that to use our nym_crypto::hmac module instead // TODO: change that to use our nym_crypto::hmac module instead
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
let mut mac = HmacSha256::new_from_slice(dh.as_bytes()) let mut mac = HmacSha256::new_from_slice(&dh[..])
.expect("x25519 shared secret is always 32 bytes long"); .expect("x25519 shared secret is always 32 bytes long");
mac.update(local_public.as_bytes()); mac.update(local_public.as_bytes());
@@ -160,7 +158,7 @@ impl GatewayClient {
mac.update(&nonce.to_le_bytes()); mac.update(&nonce.to_le_bytes());
GatewayClient { GatewayClient {
pub_key: PeerPublicKey::new(local_public), pub_key: PeerPublicKey::new(local_public.into()),
private_ips, private_ips,
mac: ClientMac(mac.finalize().into_bytes().to_vec()), mac: ClientMac(mac.finalize().into_bytes().to_vec()),
} }
@@ -170,11 +168,8 @@ impl GatewayClient {
// Client should perform this step when generating its payload, using its own WG PK // Client should perform this step when generating its payload, using its own WG PK
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> { pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek // use gateways key as a ref to an x25519_dalek key
#[allow(clippy::expect_used)] let dh = (gateway_key.as_ref()).diffie_hellman(&self.pub_key);
let static_secret = x25519_dalek::StaticSecret::from(gateway_key.to_bytes());
let dh = static_secret.diffie_hellman(&self.pub_key);
// TODO: change that to use our nym_crypto::hmac module instead // TODO: change that to use our nym_crypto::hmac module instead
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
@@ -256,7 +251,7 @@ impl<'de> Deserialize<'de> for ClientMac {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use nym_crypto::asymmetric::encryption; use nym_crypto::asymmetric::x25519;
#[test] #[test]
fn create_ip_pair() { fn create_ip_pair() {
@@ -271,8 +266,8 @@ mod tests {
fn client_request_roundtrip() { fn client_request_roundtrip() {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let gateway_key_pair = encryption::KeyPair::new(&mut rng); let gateway_key_pair = x25519::KeyPair::new(&mut rng);
let client_key_pair = encryption::KeyPair::new(&mut rng); let client_key_pair = x25519::KeyPair::new(&mut rng);
let nonce = 1234567890; let nonce = 1234567890;
@@ -230,7 +230,7 @@ mod tests {
}; };
use nym_credentials_interface::CredentialSpendingData; use nym_credentials_interface::CredentialSpendingData;
use nym_crypto::asymmetric::encryption::PrivateKey; use nym_crypto::asymmetric::x25519::PrivateKey;
use nym_sphinx::addressing::Recipient; use nym_sphinx::addressing::Recipient;
use nym_wireguard_types::PeerPublicKey; use nym_wireguard_types::PeerPublicKey;
use x25519_dalek::PublicKey; use x25519_dalek::PublicKey;
@@ -15,7 +15,7 @@ use std::{fmt, ops::Deref, str::FromStr};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use hmac::{Hmac, Mac}; use hmac::{Hmac, Mac};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use nym_crypto::asymmetric::encryption::PrivateKey; use nym_crypto::asymmetric::x25519::{PrivateKey, PublicKey};
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
use sha2::Sha256; use sha2::Sha256;
@@ -143,16 +143,14 @@ impl GatewayClient {
private_ips: IpPair, private_ips: IpPair,
nonce: u64, nonce: u64,
) -> Self { ) -> Self {
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek let local_public = PublicKey::from(local_secret);
#[allow(clippy::expect_used)] let remote_public = PublicKey::from(remote_public);
let static_secret = x25519_dalek::StaticSecret::from(local_secret.to_bytes());
let local_public: x25519_dalek::PublicKey = (&static_secret).into();
let dh = static_secret.diffie_hellman(&remote_public); let dh = local_secret.diffie_hellman(&remote_public);
// TODO: change that to use our nym_crypto::hmac module instead // TODO: change that to use our nym_crypto::hmac module instead
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
let mut mac = HmacSha256::new_from_slice(dh.as_bytes()) let mut mac = HmacSha256::new_from_slice(&dh[..])
.expect("x25519 shared secret is always 32 bytes long"); .expect("x25519 shared secret is always 32 bytes long");
mac.update(local_public.as_bytes()); mac.update(local_public.as_bytes());
@@ -160,7 +158,7 @@ impl GatewayClient {
mac.update(&nonce.to_le_bytes()); mac.update(&nonce.to_le_bytes());
GatewayClient { GatewayClient {
pub_key: PeerPublicKey::new(local_public), pub_key: PeerPublicKey::new(local_public.into()),
private_ips, private_ips,
mac: ClientMac(mac.finalize().into_bytes().to_vec()), mac: ClientMac(mac.finalize().into_bytes().to_vec()),
} }
@@ -170,11 +168,8 @@ impl GatewayClient {
// Client should perform this step when generating its payload, using its own WG PK // Client should perform this step when generating its payload, using its own WG PK
#[cfg(feature = "verify")] #[cfg(feature = "verify")]
pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> { pub fn verify(&self, gateway_key: &PrivateKey, nonce: u64) -> Result<(), Error> {
// convert from 1.0 x25519-dalek private key into 2.0 x25519-dalek // use gateways key as a ref to an x25519_dalek key
#[allow(clippy::expect_used)] let dh = (gateway_key.as_ref()).diffie_hellman(&self.pub_key);
let static_secret = x25519_dalek::StaticSecret::from(gateway_key.to_bytes());
let dh = static_secret.diffie_hellman(&self.pub_key);
// TODO: change that to use our nym_crypto::hmac module instead // TODO: change that to use our nym_crypto::hmac module instead
#[allow(clippy::expect_used)] #[allow(clippy::expect_used)]
@@ -256,7 +251,7 @@ impl<'de> Deserialize<'de> for ClientMac {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use nym_crypto::asymmetric::encryption; use nym_crypto::asymmetric::x25519;
#[test] #[test]
fn create_ip_pair() { fn create_ip_pair() {
@@ -271,8 +266,8 @@ mod tests {
fn client_request_roundtrip() { fn client_request_roundtrip() {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let gateway_key_pair = encryption::KeyPair::new(&mut rng); let gateway_key_pair = x25519::KeyPair::new(&mut rng);
let client_key_pair = encryption::KeyPair::new(&mut rng); let client_key_pair = x25519::KeyPair::new(&mut rng);
let nonce = 1234567890; let nonce = 1234567890;
@@ -11,7 +11,7 @@ use nym_credentials::ecash::bandwidth::IssuanceTicketBook;
use nym_credentials::ecash::utils::obtain_aggregate_wallet; use nym_credentials::ecash::utils::obtain_aggregate_wallet;
use nym_credentials::IssuedTicketBook; use nym_credentials::IssuedTicketBook;
use nym_credentials_interface::TicketType; use nym_credentials_interface::TicketType;
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use nym_ecash_time::{ecash_default_expiration_date, Date}; use nym_ecash_time::{ecash_default_expiration_date, Date};
use nym_validator_client::coconut::all_ecash_api_clients; use nym_validator_client::coconut::all_ecash_api_clients;
use nym_validator_client::nym_api::EpochId; use nym_validator_client::nym_api::EpochId;
@@ -31,7 +31,7 @@ where
C: EcashSigningClient + EcashQueryClient + Sync, C: EcashSigningClient + EcashQueryClient + Sync,
{ {
let mut rng = OsRng; let mut rng = OsRng;
let signing_key = identity::PrivateKey::new(&mut rng); let signing_key = ed25519::PrivateKey::new(&mut rng);
let expiration = expiration.unwrap_or_else(ecash_default_expiration_date); let expiration = expiration.unwrap_or_else(ecash_default_expiration_date);
let deposit_amount = client.get_required_deposit_amount().await?; let deposit_amount = client.get_required_deposit_amount().await?;
+2 -2
View File
@@ -4,8 +4,8 @@
use nym_credential_storage::error::StorageError; use nym_credential_storage::error::StorageError;
use nym_credentials::error::Error as CredentialsError; use nym_credentials::error::Error as CredentialsError;
use nym_credentials_interface::CompactEcashError; use nym_credentials_interface::CompactEcashError;
use nym_crypto::asymmetric::encryption::KeyRecoveryError; use nym_crypto::asymmetric::ed25519::Ed25519RecoveryError;
use nym_crypto::asymmetric::identity::Ed25519RecoveryError; use nym_crypto::asymmetric::x25519::KeyRecoveryError;
use nym_validator_client::coconut::EcashApiError; use nym_validator_client::coconut::EcashApiError;
use nym_validator_client::error::ValidatorClientError; use nym_validator_client::error::ValidatorClientError;
use thiserror::Error; use thiserror::Error;
+2 -1
View File
@@ -21,6 +21,7 @@ serde_json = { workspace = true, optional = true }
## tracing ## tracing
tracing-subscriber = { workspace = true, features = ["env-filter"], optional = true } tracing-subscriber = { workspace = true, features = ["env-filter"], optional = true }
tracing-tree = { workspace = true, optional = true } tracing-tree = { workspace = true, optional = true }
tracing = { workspace = true, optional = true }
opentelemetry-jaeger = { workspace = true, features = ["rt-tokio", "collector_client", "isahc_collector_client"], optional = true } opentelemetry-jaeger = { workspace = true, features = ["rt-tokio", "collector_client", "isahc_collector_client"], optional = true }
tracing-opentelemetry = { workspace = true, optional = true } tracing-opentelemetry = { workspace = true, optional = true }
utoipa = { workspace = true, optional = true } utoipa = { workspace = true, optional = true }
@@ -35,7 +36,7 @@ default = []
openapi = ["utoipa"] openapi = ["utoipa"]
output_format = ["serde_json", "dep:clap"] output_format = ["serde_json", "dep:clap"]
bin_info_schema = ["schemars"] bin_info_schema = ["schemars"]
basic_tracing = ["tracing-subscriber"] basic_tracing = ["dep:tracing", "tracing-subscriber"]
tracing = [ tracing = [
"basic_tracing", "basic_tracing",
"tracing-tree", "tracing-tree",
+37 -14
View File
@@ -44,10 +44,38 @@ pub fn setup_logging() {
.init(); .init();
} }
// don't call init so that we could attach additional layers
#[cfg(feature = "basic_tracing")] #[cfg(feature = "basic_tracing")]
pub fn setup_tracing_logger() { pub fn build_tracing_logger() -> impl tracing_subscriber::layer::SubscriberExt {
let log_builder = tracing_subscriber::fmt() use tracing_subscriber::prelude::*;
.with_writer(std::io::stderr)
tracing_subscriber::registry()
.with(default_tracing_fmt_layer(std::io::stderr))
.with(default_tracing_env_filter())
}
#[cfg(feature = "basic_tracing")]
pub fn default_tracing_env_filter() -> tracing_subscriber::filter::EnvFilter {
if ::std::env::var("RUST_LOG").is_ok() {
tracing_subscriber::filter::EnvFilter::from_default_env()
} else {
// if the env value was not found, default to `INFO` level rather than `ERROR`
tracing_subscriber::filter::EnvFilter::builder()
.with_default_directive(tracing_subscriber::filter::LevelFilter::INFO.into())
.parse_lossy("")
}
}
#[cfg(feature = "basic_tracing")]
pub fn default_tracing_fmt_layer<S, W>(
writer: W,
) -> impl tracing_subscriber::Layer<S> + Sync + Send + 'static
where
S: tracing::Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
W: for<'writer> tracing_subscriber::fmt::MakeWriter<'writer> + Sync + Send + 'static,
{
tracing_subscriber::fmt::layer()
.with_writer(writer)
// Use a more compact, abbreviated log format // Use a more compact, abbreviated log format
.compact() .compact()
// Display source code file paths // Display source code file paths
@@ -55,18 +83,13 @@ pub fn setup_tracing_logger() {
// Display source code line numbers // Display source code line numbers
.with_line_number(true) .with_line_number(true)
// Don't display the event's target (module path) // Don't display the event's target (module path)
.with_target(false); .with_target(false)
}
if ::std::env::var("RUST_LOG").is_ok() { #[cfg(feature = "basic_tracing")]
log_builder pub fn setup_tracing_logger() {
.with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env()) use tracing_subscriber::util::SubscriberInitExt;
.init() build_tracing_logger().init()
} else {
// default to 'Info
log_builder
.with_max_level(tracing_subscriber::filter::LevelFilter::INFO)
.init()
}
} }
// TODO: This has to be a macro, running it as a function does not work for the file_appender for some reason // TODO: This has to be a macro, running it as a function does not work for the file_appender for some reason
+1 -4
View File
@@ -12,7 +12,6 @@ license.workspace = true
async-trait = { workspace = true } async-trait = { workspace = true }
base64 = { workspace = true } base64 = { workspace = true }
bs58 = { workspace = true } bs58 = { workspace = true }
cfg-if = { workspace = true }
clap = { workspace = true, optional = true } clap = { workspace = true, optional = true }
comfy-table = { workspace = true, optional = true } comfy-table = { workspace = true, optional = true }
futures = { workspace = true } futures = { workspace = true }
@@ -24,20 +23,18 @@ serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true } serde_json = { workspace = true }
sha2 = { workspace = true } sha2 = { workspace = true }
si-scale = { workspace = true } si-scale = { workspace = true }
tap = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
url = { workspace = true, features = ["serde"] } url = { workspace = true, features = ["serde"] }
tokio = { workspace = true, features = ["macros"] } tokio = { workspace = true, features = ["macros"] }
time = { workspace = true } time = { workspace = true }
tracing = { workspace = true }
zeroize = { workspace = true } zeroize = { workspace = true }
# internal # internal
nym-id = { path = "../nym-id" } nym-id = { path = "../nym-id" }
nym-bandwidth-controller = { path = "../bandwidth-controller" } nym-bandwidth-controller = { path = "../bandwidth-controller" }
nym-config = { path = "../config" } nym-config = { path = "../config" }
nym-country-group = { path = "../country-group" }
nym-crypto = { path = "../crypto" } nym-crypto = { path = "../crypto" }
nym-explorer-client = { path = "../../explorer-api/explorer-client" }
nym-gateway-client = { path = "../client-libs/gateway-client" } nym-gateway-client = { path = "../client-libs/gateway-client" }
nym-gateway-requests = { path = "../gateway-requests" } nym-gateway-requests = { path = "../gateway-requests" }
nym-http-api-client = { path = "../http-api-client" } nym-http-api-client = { path = "../http-api-client" }
@@ -14,7 +14,6 @@ url = { workspace = true, features = ["serde"] }
nym-config = { path = "../../config" } nym-config = { path = "../../config" }
nym-country-group = { path = "../../country-group" }
nym-pemstore = { path = "../../pemstore", optional = true } nym-pemstore = { path = "../../pemstore", optional = true }
# those are pulling so many deps T.T # those are pulling so many deps T.T
+20 -39
View File
@@ -65,11 +65,10 @@ const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60
// stats reporting related // stats reporting related
/// Time interval between reporting statistics to the given provider if it exist /// Time interval between reporting statistics to the given provider if it exists
const STATS_REPORT_INTERVAL_SECS: Duration = Duration::from_secs(300); const STATS_REPORT_INTERVAL_SECS: Duration = Duration::from_secs(300);
use crate::error::InvalidTrafficModeFailure; use crate::error::InvalidTrafficModeFailure;
pub use nym_country_group::CountryGroup;
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
@@ -258,15 +257,6 @@ impl Config {
self self
} }
pub fn with_topology_structure(mut self, topology_structure: TopologyStructure) -> Self {
self.set_topology_structure(topology_structure);
self
}
pub fn set_topology_structure(&mut self, topology_structure: TopologyStructure) {
self.debug.topology.topology_structure = topology_structure;
}
pub fn with_no_per_hop_delays(mut self, no_per_hop_delays: bool) -> Self { pub fn with_no_per_hop_delays(mut self, no_per_hop_delays: bool) -> Self {
if no_per_hop_delays { if no_per_hop_delays {
self.set_no_per_hop_delays() self.set_no_per_hop_delays()
@@ -415,7 +405,21 @@ pub struct Traffic {
/// Do not set it unless you understand the consequences of that change. /// Do not set it unless you understand the consequences of that change.
pub secondary_packet_size: Option<PacketSize>, pub secondary_packet_size: Option<PacketSize>,
/// Specify whether any constructed sphinx packets should use the legacy format,
/// where the payload keys are explicitly attached rather than using the seeds
/// this affects any forward packets, acks and reply surbs
/// this flag should remain disabled until sufficient number of nodes on the network has upgraded
/// and support updated format.
/// in the case of reply surbs, the recipient must also understand the new encoding
pub use_legacy_sphinx_format: bool,
pub packet_type: PacketType, pub packet_type: PacketType,
/// Indicates whether to mix hops or not. If mix hops are enabled, traffic
/// will be routed as usual, to the entry gateway, through three mix nodes, egressing
/// through the exit gateway. If mix hops are disabled, traffic will be routed directly
/// from the entry gateway to the exit gateway, bypassing the mix nodes.
pub disable_mix_hops: bool,
} }
impl Traffic { impl Traffic {
@@ -442,6 +446,11 @@ impl Default for Traffic {
primary_packet_size: PacketSize::RegularPacket, primary_packet_size: PacketSize::RegularPacket,
secondary_packet_size: None, secondary_packet_size: None,
packet_type: PacketType::Mix, packet_type: PacketType::Mix,
// we should use the legacy format until sufficient number of nodes understand the
// improved encoding
use_legacy_sphinx_format: true,
disable_mix_hops: false,
} }
} }
} }
@@ -546,9 +555,6 @@ pub struct Topology {
#[serde(with = "humantime_serde")] #[serde(with = "humantime_serde")]
pub max_startup_gateway_waiting_period: Duration, pub max_startup_gateway_waiting_period: Duration,
/// Specifies the mixnode topology to be used for sending packets.
pub topology_structure: TopologyStructure,
/// Specifies a minimum performance of a mixnode that is used on route construction. /// Specifies a minimum performance of a mixnode that is used on route construction.
/// This setting is only applicable when `NymApi` topology is used. /// This setting is only applicable when `NymApi` topology is used.
pub minimum_mixnode_performance: u8, pub minimum_mixnode_performance: u8,
@@ -570,30 +576,6 @@ pub struct Topology {
pub ignore_ingress_epoch_role: bool, pub ignore_ingress_epoch_role: bool,
} }
#[allow(clippy::large_enum_variant)]
#[derive(Default, Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum TopologyStructure {
#[default]
NymApi,
GeoAware(GroupBy),
}
#[allow(clippy::large_enum_variant)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum GroupBy {
CountryGroup(CountryGroup),
NymAddress(Recipient),
}
impl std::fmt::Display for GroupBy {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
GroupBy::CountryGroup(group) => write!(f, "group: {group}"),
GroupBy::NymAddress(address) => write!(f, "address: {address}"),
}
}
}
impl Default for Topology { impl Default for Topology {
fn default() -> Self { fn default() -> Self {
Topology { Topology {
@@ -601,7 +583,6 @@ impl Default for Topology {
topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT, topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT,
disable_refreshing: false, disable_refreshing: false,
max_startup_gateway_waiting_period: DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD, max_startup_gateway_waiting_period: DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD,
topology_structure: TopologyStructure::default(),
minimum_mixnode_performance: DEFAULT_MIN_MIXNODE_PERFORMANCE, minimum_mixnode_performance: DEFAULT_MIN_MIXNODE_PERFORMANCE,
minimum_gateway_performance: DEFAULT_MIN_GATEWAY_PERFORMANCE, minimum_gateway_performance: DEFAULT_MIN_GATEWAY_PERFORMANCE,
use_extended_topology: false, use_extended_topology: false,
+29 -14
View File
@@ -2,10 +2,9 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::old::v5::{ use crate::old::v5::{
AcknowledgementsV5, ClientV5, ConfigV5, CoverTrafficV5, DebugConfigV5, GatewayConnectionV5, AcknowledgementsV5, ClientV5, ConfigV5, CountryGroupV5, CoverTrafficV5, DebugConfigV5,
GroupByV5, ReplySurbsV5, TopologyStructureV5, TopologyV5, TrafficV5, GatewayConnectionV5, GroupByV5, ReplySurbsV5, TopologyStructureV5, TopologyV5, TrafficV5,
}; };
use crate::CountryGroup;
use nym_sphinx_addressing::Recipient; use nym_sphinx_addressing::Recipient;
use nym_sphinx_params::{PacketSize, PacketType}; use nym_sphinx_params::{PacketSize, PacketType};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@@ -369,31 +368,47 @@ impl From<TopologyStructureV4> for TopologyStructureV5 {
} }
} }
#[derive(Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub enum CountryGroupV4 {
Europe,
NorthAmerica,
SouthAmerica,
Oceania,
Asia,
Africa,
Unknown,
}
impl From<CountryGroupV4> for CountryGroupV5 {
fn from(value: CountryGroupV4) -> Self {
match value {
CountryGroupV4::Europe => CountryGroupV5::Europe,
CountryGroupV4::NorthAmerica => CountryGroupV5::NorthAmerica,
CountryGroupV4::SouthAmerica => CountryGroupV5::SouthAmerica,
CountryGroupV4::Oceania => CountryGroupV5::Oceania,
CountryGroupV4::Asia => CountryGroupV5::Asia,
CountryGroupV4::Africa => CountryGroupV5::Africa,
CountryGroupV4::Unknown => CountryGroupV5::Unknown,
}
}
}
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum GroupByV4 { pub enum GroupByV4 {
CountryGroup(CountryGroup), CountryGroup(CountryGroupV4),
NymAddress(Recipient), NymAddress(Recipient),
} }
impl From<GroupByV4> for GroupByV5 { impl From<GroupByV4> for GroupByV5 {
fn from(value: GroupByV4) -> Self { fn from(value: GroupByV4) -> Self {
match value { match value {
GroupByV4::CountryGroup(country) => GroupByV5::CountryGroup(country), GroupByV4::CountryGroup(country) => GroupByV5::CountryGroup(country.into()),
GroupByV4::NymAddress(addr) => GroupByV5::NymAddress(addr), GroupByV4::NymAddress(addr) => GroupByV5::NymAddress(addr),
} }
} }
} }
impl std::fmt::Display for GroupByV4 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
GroupByV4::CountryGroup(group) => write!(f, "group: {}", group),
GroupByV4::NymAddress(address) => write!(f, "address: {}", address),
}
}
}
impl Default for TopologyV4 { impl Default for TopologyV4 {
fn default() -> Self { fn default() -> Self {
TopologyV4 { TopologyV4 {
+12 -29
View File
@@ -2,8 +2,8 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::{ use crate::{
Acknowledgements, Client, Config, CountryGroup, CoverTraffic, DebugConfig, GatewayConnection, Acknowledgements, Client, Config, CoverTraffic, DebugConfig, GatewayConnection, ReplySurbs,
GroupBy, ReplySurbs, Topology, TopologyStructure, Traffic, Topology, Traffic,
}; };
use nym_sphinx_addressing::Recipient; use nym_sphinx_addressing::Recipient;
use nym_sphinx_params::{PacketSize, PacketType}; use nym_sphinx_params::{PacketSize, PacketType};
@@ -146,7 +146,6 @@ impl From<ConfigV5> for Config {
.debug .debug
.topology .topology
.max_startup_gateway_waiting_period, .max_startup_gateway_waiting_period,
topology_structure: value.debug.topology.topology_structure.into(),
..Default::default() ..Default::default()
}, },
reply_surbs: ReplySurbs { reply_surbs: ReplySurbs {
@@ -372,40 +371,24 @@ pub enum TopologyStructureV5 {
GeoAware(GroupByV5), GeoAware(GroupByV5),
} }
impl From<TopologyStructureV5> for TopologyStructure { #[derive(Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, Debug)]
fn from(value: TopologyStructureV5) -> Self { pub enum CountryGroupV5 {
match value { Europe,
TopologyStructureV5::NymApi => TopologyStructure::NymApi, NorthAmerica,
TopologyStructureV5::GeoAware(group_by) => TopologyStructure::GeoAware(group_by.into()), SouthAmerica,
} Oceania,
} Asia,
Africa,
Unknown,
} }
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum GroupByV5 { pub enum GroupByV5 {
CountryGroup(CountryGroup), CountryGroup(CountryGroupV5),
NymAddress(Recipient), NymAddress(Recipient),
} }
impl From<GroupByV5> for GroupBy {
fn from(value: GroupByV5) -> Self {
match value {
GroupByV5::CountryGroup(country) => GroupBy::CountryGroup(country),
GroupByV5::NymAddress(addr) => GroupBy::NymAddress(addr),
}
}
}
impl std::fmt::Display for GroupByV5 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
GroupByV5::CountryGroup(group) => write!(f, "group: {}", group),
GroupByV5::NymAddress(address) => write!(f, "address: {}", address),
}
}
}
impl Default for TopologyV5 { impl Default for TopologyV5 {
fn default() -> Self { fn default() -> Self {
TopologyV5 { TopologyV5 {
@@ -1,7 +1,7 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use nym_crypto::asymmetric::identity::Ed25519RecoveryError; use nym_crypto::asymmetric::ed25519::Ed25519RecoveryError;
use nym_gateway_requests::shared_key::SharedKeyConversionError; use nym_gateway_requests::shared_key::SharedKeyConversionError;
use thiserror::Error; use thiserror::Error;
@@ -5,7 +5,7 @@
#![warn(clippy::unwrap_used)] #![warn(clippy::unwrap_used)]
use async_trait::async_trait; use async_trait::async_trait;
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use nym_gateway_requests::SharedSymmetricKey; use nym_gateway_requests::SharedSymmetricKey;
use std::error::Error; use std::error::Error;
@@ -36,9 +36,7 @@ pub trait GatewaysDetailsStore {
async fn all_gateways(&self) -> Result<Vec<GatewayRegistration>, Self::StorageError>; async fn all_gateways(&self) -> Result<Vec<GatewayRegistration>, Self::StorageError>;
/// Return identity keys of all registered gateways. /// Return identity keys of all registered gateways.
async fn all_gateways_identities( async fn all_gateways_identities(&self) -> Result<Vec<ed25519::PublicKey>, Self::StorageError> {
&self,
) -> Result<Vec<identity::PublicKey>, Self::StorageError> {
Ok(self Ok(self
.all_gateways() .all_gateways()
.await? .await?
@@ -64,7 +62,7 @@ pub trait GatewaysDetailsStore {
async fn upgrade_stored_remote_gateway_key( async fn upgrade_stored_remote_gateway_key(
&self, &self,
gateway_id: identity::PublicKey, gateway_id: ed25519::PublicKey,
updated_key: &SharedSymmetricKey, updated_key: &SharedSymmetricKey,
) -> Result<(), Self::StorageError>; ) -> Result<(), Self::StorageError>;
@@ -3,7 +3,7 @@
use crate::BadGateway; use crate::BadGateway;
use cosmrs::AccountId; use cosmrs::AccountId;
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use nym_gateway_requests::shared_key::{LegacySharedKeys, SharedGatewayKey, SharedSymmetricKey}; use nym_gateway_requests::shared_key::{LegacySharedKeys, SharedGatewayKey, SharedSymmetricKey};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
@@ -29,7 +29,7 @@ pub struct GatewayRegistration {
} }
impl GatewayRegistration { impl GatewayRegistration {
pub fn gateway_id(&self) -> identity::PublicKey { pub fn gateway_id(&self) -> ed25519::PublicKey {
self.details.gateway_id() self.details.gateway_id()
} }
} }
@@ -64,7 +64,7 @@ impl From<GatewayDetails> for GatewayRegistration {
impl GatewayDetails { impl GatewayDetails {
pub fn new_remote( pub fn new_remote(
gateway_id: identity::PublicKey, gateway_id: ed25519::PublicKey,
shared_key: Arc<SharedGatewayKey>, shared_key: Arc<SharedGatewayKey>,
gateway_owner_address: Option<AccountId>, gateway_owner_address: Option<AccountId>,
gateway_listener: Url, gateway_listener: Url,
@@ -77,11 +77,11 @@ impl GatewayDetails {
}) })
} }
pub fn new_custom(gateway_id: identity::PublicKey, data: Option<Vec<u8>>) -> Self { pub fn new_custom(gateway_id: ed25519::PublicKey, data: Option<Vec<u8>>) -> Self {
GatewayDetails::Custom(CustomGatewayDetails { gateway_id, data }) GatewayDetails::Custom(CustomGatewayDetails { gateway_id, data })
} }
pub fn gateway_id(&self) -> identity::PublicKey { pub fn gateway_id(&self) -> ed25519::PublicKey {
match self { match self {
GatewayDetails::Remote(details) => details.gateway_id, GatewayDetails::Remote(details) => details.gateway_id,
GatewayDetails::Custom(details) => details.gateway_id, GatewayDetails::Custom(details) => details.gateway_id,
@@ -157,7 +157,7 @@ pub struct RawRegisteredGateway {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct RegisteredGateway { pub struct RegisteredGateway {
pub gateway_id: identity::PublicKey, pub gateway_id: ed25519::PublicKey,
pub registration_timestamp: OffsetDateTime, pub registration_timestamp: OffsetDateTime,
@@ -179,7 +179,7 @@ impl TryFrom<RawRemoteGatewayDetails> for RemoteGatewayDetails {
fn try_from(value: RawRemoteGatewayDetails) -> Result<Self, Self::Error> { fn try_from(value: RawRemoteGatewayDetails) -> Result<Self, Self::Error> {
let gateway_id = let gateway_id =
identity::PublicKey::from_base58_string(&value.gateway_id_bs58).map_err(|source| { ed25519::PublicKey::from_base58_string(&value.gateway_id_bs58).map_err(|source| {
BadGateway::MalformedGatewayIdentity { BadGateway::MalformedGatewayIdentity {
gateway_id: value.gateway_id_bs58.clone(), gateway_id: value.gateway_id_bs58.clone(),
source, source,
@@ -267,7 +267,7 @@ impl<'a> From<&'a RemoteGatewayDetails> for RawRemoteGatewayDetails {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct RemoteGatewayDetails { pub struct RemoteGatewayDetails {
pub gateway_id: identity::PublicKey, pub gateway_id: ed25519::PublicKey,
pub shared_key: Arc<SharedGatewayKey>, pub shared_key: Arc<SharedGatewayKey>,
@@ -288,7 +288,7 @@ impl TryFrom<RawCustomGatewayDetails> for CustomGatewayDetails {
fn try_from(value: RawCustomGatewayDetails) -> Result<Self, Self::Error> { fn try_from(value: RawCustomGatewayDetails) -> Result<Self, Self::Error> {
let gateway_id = let gateway_id =
identity::PublicKey::from_base58_string(&value.gateway_id_bs58).map_err(|source| { ed25519::PublicKey::from_base58_string(&value.gateway_id_bs58).map_err(|source| {
BadGateway::MalformedGatewayIdentity { BadGateway::MalformedGatewayIdentity {
gateway_id: value.gateway_id_bs58.clone(), gateway_id: value.gateway_id_bs58.clone(),
source, source,
@@ -314,12 +314,12 @@ impl<'a> From<&'a CustomGatewayDetails> for RawCustomGatewayDetails {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct CustomGatewayDetails { pub struct CustomGatewayDetails {
pub gateway_id: identity::PublicKey, pub gateway_id: ed25519::PublicKey,
pub data: Option<Vec<u8>>, pub data: Option<Vec<u8>>,
} }
impl CustomGatewayDetails { impl CustomGatewayDetails {
pub fn new(gateway_id: identity::PublicKey) -> CustomGatewayDetails { pub fn new(gateway_id: ed25519::PublicKey) -> CustomGatewayDetails {
Self { Self {
gateway_id, gateway_id,
data: None, data: None,
@@ -14,7 +14,7 @@ use crate::{
}; };
use log::info; use log::info;
use nym_client_core_gateways_storage::GatewayDetails; use nym_client_core_gateways_storage::GatewayDetails;
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use nym_topology::NymTopology; use nym_topology::NymTopology;
use nym_validator_client::UserAgent; use nym_validator_client::UserAgent;
use std::path::PathBuf; use std::path::PathBuf;
@@ -29,7 +29,7 @@ pub struct CommonClientAddGatewayArgs {
/// Explicitly specify id of the gateway to register with. /// Explicitly specify id of the gateway to register with.
/// If unspecified, a random gateway will be chosen instead. /// If unspecified, a random gateway will be chosen instead.
#[cfg_attr(feature = "cli", clap(long, alias = "gateway"))] #[cfg_attr(feature = "cli", clap(long, alias = "gateway"))]
pub gateway_id: Option<identity::PublicKey>, pub gateway_id: Option<ed25519::PublicKey>,
/// Specifies whether the client will attempt to enforce tls connection to the desired gateway. /// Specifies whether the client will attempt to enforce tls connection to the desired gateway.
#[cfg_attr(feature = "cli", clap(long))] #[cfg_attr(feature = "cli", clap(long))]
@@ -139,6 +139,8 @@ where
let gateway_setup = GatewaySetup::New { let gateway_setup = GatewaySetup::New {
specification: selection_spec, specification: selection_spec,
available_gateways, available_gateways,
#[cfg(unix)]
connection_fd_callback: None,
}; };
let init_details = let init_details =
@@ -14,7 +14,7 @@ use crate::{
}; };
use log::info; use log::info;
use nym_client_core_gateways_storage::GatewayDetails; use nym_client_core_gateways_storage::GatewayDetails;
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use nym_sphinx::addressing::Recipient; use nym_sphinx::addressing::Recipient;
use nym_topology::NymTopology; use nym_topology::NymTopology;
use nym_validator_client::UserAgent; use nym_validator_client::UserAgent;
@@ -42,7 +42,7 @@ pub struct CommonClientInitArgs {
/// Id of the gateway we are going to connect to. /// Id of the gateway we are going to connect to.
#[cfg_attr(feature = "cli", clap(long))] #[cfg_attr(feature = "cli", clap(long))]
pub gateway: Option<identity::PublicKey>, pub gateway: Option<ed25519::PublicKey>,
/// Specifies whether the client will attempt to enforce tls connection to the desired gateway. /// Specifies whether the client will attempt to enforce tls connection to the desired gateway.
#[cfg_attr(feature = "cli", clap(long))] #[cfg_attr(feature = "cli", clap(long))]
@@ -187,6 +187,8 @@ where
let gateway_setup = GatewaySetup::New { let gateway_setup = GatewaySetup::New {
specification: selection_spec, specification: selection_spec,
available_gateways, available_gateways,
#[cfg(unix)]
connection_fd_callback: None,
}; };
let init_details = let init_details =
@@ -1,7 +1,7 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use nym_sphinx::addressing::Recipient; use nym_sphinx::addressing::Recipient;
use std::path::PathBuf; use std::path::PathBuf;
@@ -15,7 +15,7 @@ pub struct CommonClientRunArgs {
/// Id of the gateway we want to connect to. If overridden, it is user's responsibility to /// Id of the gateway we want to connect to. If overridden, it is user's responsibility to
/// ensure prior registration happened /// ensure prior registration happened
#[cfg_attr(feature = "cli", clap(long))] #[cfg_attr(feature = "cli", clap(long))]
pub gateway: Option<identity::PublicKey>, pub gateway: Option<ed25519::PublicKey>,
/// Comma separated list of rest endpoints of the nyxd validators /// Comma separated list of rest endpoints of the nyxd validators
#[cfg_attr( #[cfg_attr(
@@ -4,7 +4,7 @@
use crate::cli_helpers::{CliClient, CliClientConfig}; use crate::cli_helpers::{CliClient, CliClientConfig};
use crate::client::base_client::non_wasm_helpers::setup_fs_gateways_storage; use crate::client::base_client::non_wasm_helpers::setup_fs_gateways_storage;
use crate::client::base_client::storage::helpers::set_active_gateway; use crate::client::base_client::storage::helpers::set_active_gateway;
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
#[cfg_attr(feature = "cli", derive(clap::Args))] #[cfg_attr(feature = "cli", derive(clap::Args))]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -15,7 +15,7 @@ pub struct CommonClientSwitchGatewaysArgs {
/// Id of the gateway we want to switch to. /// Id of the gateway we want to switch to.
#[cfg_attr(feature = "cli", clap(long))] #[cfg_attr(feature = "cli", clap(long))]
pub gateway_id: identity::PublicKey, pub gateway_id: ed25519::PublicKey,
} }
pub async fn switch_gateway<C, A>(args: A) -> Result<(), C::Error> pub async fn switch_gateway<C, A>(args: A) -> Result<(), C::Error>
+2 -2
View File
@@ -1,7 +1,7 @@
// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // Copyright 2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use time::OffsetDateTime; use time::OffsetDateTime;
@@ -10,7 +10,7 @@ use url::Url;
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct GatewayInfo { pub struct GatewayInfo {
pub registration: OffsetDateTime, pub registration: OffsetDateTime,
pub identity: identity::PublicKey, pub identity: ed25519::PublicKey,
pub active: bool, pub active: bool,
pub typ: String, pub typ: String,
@@ -39,7 +39,7 @@ use nym_bandwidth_controller::BandwidthController;
use nym_client_core_config_types::ForgetMe; use nym_client_core_config_types::ForgetMe;
use nym_client_core_gateways_storage::{GatewayDetails, GatewaysDetailsStore}; use nym_client_core_gateways_storage::{GatewayDetails, GatewaysDetailsStore};
use nym_credential_storage::storage::Storage as CredentialStorage; use nym_credential_storage::storage::Storage as CredentialStorage;
use nym_crypto::asymmetric::{encryption, identity}; use nym_crypto::asymmetric::{ed25519, x25519};
use nym_crypto::hkdf::DerivationMaterial; use nym_crypto::hkdf::DerivationMaterial;
use nym_gateway_client::client::config::GatewayClientConfig; use nym_gateway_client::client::config::GatewayClientConfig;
use nym_gateway_client::{ use nym_gateway_client::{
@@ -367,7 +367,7 @@ where
// buffer controlling all messages fetched from provider // buffer controlling all messages fetched from provider
// required so that other components would be able to use them (say the websocket) // required so that other components would be able to use them (say the websocket)
fn start_received_messages_buffer_controller( fn start_received_messages_buffer_controller(
local_encryption_keypair: Arc<encryption::KeyPair>, local_encryption_keypair: Arc<x25519::KeyPair>,
query_receiver: ReceivedBufferRequestReceiver, query_receiver: ReceivedBufferRequestReceiver,
mixnet_receiver: MixnetMessageReceiver, mixnet_receiver: MixnetMessageReceiver,
reply_key_storage: SentReplyKeys, reply_key_storage: SentReplyKeys,
@@ -552,18 +552,12 @@ where
user_agent: Option<UserAgent>, user_agent: Option<UserAgent>,
) -> Box<dyn TopologyProvider + Send + Sync> { ) -> Box<dyn TopologyProvider + Send + Sync> {
// if no custom provider was ... provided ..., create one using nym-api // if no custom provider was ... provided ..., create one using nym-api
custom_provider.unwrap_or_else(|| match config_topology.topology_structure { custom_provider.unwrap_or_else(|| {
config::TopologyStructure::NymApi => Box::new(NymApiTopologyProvider::new( Box::new(NymApiTopologyProvider::new(
config_topology, config_topology,
nym_api_urls, nym_api_urls,
user_agent, user_agent,
)), ))
config::TopologyStructure::GeoAware(group_by) => {
warn!("using deprecated 'GeoAware' topology provider - this option will be removed very soon");
#[allow(deprecated)]
Box::new(crate::client::topology_control::GeoAwareTopologyProvider::new(nym_api_urls, group_by))
}
}) })
} }
@@ -942,7 +936,7 @@ where
pub struct BaseClient { pub struct BaseClient {
pub address: Recipient, pub address: Recipient,
pub identity_keys: Arc<identity::KeyPair>, pub identity_keys: Arc<ed25519::KeyPair>,
pub client_input: ClientInputStatus, pub client_input: ClientInputStatus,
pub client_output: ClientOutputStatus, pub client_output: ClientOutputStatus,
pub client_state: ClientState, pub client_state: ClientState,
@@ -5,7 +5,7 @@ use crate::client::key_manager::persistence::KeyStore;
use crate::client::key_manager::ClientKeys; use crate::client::key_manager::ClientKeys;
use crate::error::ClientCoreError; use crate::error::ClientCoreError;
use nym_client_core_gateways_storage::{ActiveGateway, GatewayRegistration, GatewaysDetailsStore}; use nym_client_core_gateways_storage::{ActiveGateway, GatewayRegistration, GatewaysDetailsStore};
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
// helpers for error wrapping // helpers for error wrapping
pub async fn set_active_gateway<D>( pub async fn set_active_gateway<D>(
@@ -26,7 +26,7 @@ where
pub async fn get_active_gateway_identity<D>( pub async fn get_active_gateway_identity<D>(
details_store: &D, details_store: &D,
) -> Result<Option<identity::PublicKey>, ClientCoreError> ) -> Result<Option<ed25519::PublicKey>, ClientCoreError>
where where
D: GatewaysDetailsStore, D: GatewaysDetailsStore,
D::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static,
@@ -42,7 +42,7 @@ where
pub async fn get_all_registered_identities<D>( pub async fn get_all_registered_identities<D>(
details_store: &D, details_store: &D,
) -> Result<Vec<identity::PublicKey>, ClientCoreError> ) -> Result<Vec<ed25519::PublicKey>, ClientCoreError>
where where
D: GatewaysDetailsStore + Sync, D: GatewaysDetailsStore + Sync,
D::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static,
@@ -62,6 +62,10 @@ where
/// Optional secondary predefined packet size used for the loop cover messages. /// Optional secondary predefined packet size used for the loop cover messages.
secondary_packet_size: Option<PacketSize>, secondary_packet_size: Option<PacketSize>,
/// Specify whether any constructed packets should use the legacy format,
/// where the payload keys are explicitly attached rather than using the seeds
use_legacy_sphinx_format: bool,
packet_type: PacketType, packet_type: PacketType,
stats_tx: ClientStatsSender, stats_tx: ClientStatsSender,
@@ -130,6 +134,7 @@ impl LoopCoverTrafficStream<OsRng> {
topology_access, topology_access,
primary_packet_size: traffic_config.primary_packet_size, primary_packet_size: traffic_config.primary_packet_size,
secondary_packet_size: traffic_config.secondary_packet_size, secondary_packet_size: traffic_config.secondary_packet_size,
use_legacy_sphinx_format: traffic_config.use_legacy_sphinx_format,
packet_type: traffic_config.packet_type, packet_type: traffic_config.packet_type,
stats_tx, stats_tx,
task_client, task_client,
@@ -182,6 +187,7 @@ impl LoopCoverTrafficStream<OsRng> {
let cover_message = match generate_loop_cover_packet( let cover_message = match generate_loop_cover_packet(
&mut self.rng, &mut self.rng,
self.use_legacy_sphinx_format,
topology_ref, topology_ref,
&self.ack_key, &self.ack_key,
&self.our_full_destination, &self.our_full_destination,
@@ -28,6 +28,7 @@ pub enum InputMessage {
recipient: Recipient, recipient: Recipient,
data: Vec<u8>, data: Vec<u8>,
lane: TransmissionLane, lane: TransmissionLane,
max_retransmissions: Option<u32>,
}, },
/// Creates a message used for a duplex anonymous communication where the recipient /// Creates a message used for a duplex anonymous communication where the recipient
@@ -43,6 +44,7 @@ pub enum InputMessage {
data: Vec<u8>, data: Vec<u8>,
reply_surbs: u32, reply_surbs: u32,
lane: TransmissionLane, lane: TransmissionLane,
max_retransmissions: Option<u32>,
}, },
/// Attempt to use our internally received and stored `ReplySurb` to send the message back /// Attempt to use our internally received and stored `ReplySurb` to send the message back
@@ -53,6 +55,7 @@ pub enum InputMessage {
recipient_tag: AnonymousSenderTag, recipient_tag: AnonymousSenderTag,
data: Vec<u8>, data: Vec<u8>,
lane: TransmissionLane, lane: TransmissionLane,
max_retransmissions: Option<u32>,
}, },
MessageWrapper { MessageWrapper {
@@ -92,6 +95,7 @@ impl InputMessage {
recipient, recipient,
data, data,
lane, lane,
max_retransmissions: None,
}; };
if let Some(packet_type) = packet_type { if let Some(packet_type) = packet_type {
InputMessage::new_wrapper(message, packet_type) InputMessage::new_wrapper(message, packet_type)
@@ -112,28 +116,7 @@ impl InputMessage {
data, data,
reply_surbs, reply_surbs,
lane, lane,
}; max_retransmissions: None,
if let Some(packet_type) = packet_type {
InputMessage::new_wrapper(message, packet_type)
} else {
message
}
}
// IMHO `new_anonymous` should take `mix_hops: Option<u8>` as an argument instead of creating
// this function, but that would potentially break backwards compatibility with the current API
pub fn new_anonymous_with_custom_hops(
recipient: Recipient,
data: Vec<u8>,
reply_surbs: u32,
lane: TransmissionLane,
packet_type: Option<PacketType>,
) -> Self {
let message = InputMessage::Anonymous {
recipient,
data,
reply_surbs,
lane,
}; };
if let Some(packet_type) = packet_type { if let Some(packet_type) = packet_type {
InputMessage::new_wrapper(message, packet_type) InputMessage::new_wrapper(message, packet_type)
@@ -152,6 +135,7 @@ impl InputMessage {
recipient_tag, recipient_tag,
data, data,
lane, lane,
max_retransmissions: None,
}; };
if let Some(packet_type) = packet_type { if let Some(packet_type) = packet_type {
InputMessage::new_wrapper(message, packet_type) InputMessage::new_wrapper(message, packet_type)
@@ -169,4 +153,34 @@ impl InputMessage {
InputMessage::MessageWrapper { message, .. } => message.lane(), InputMessage::MessageWrapper { message, .. } => message.lane(),
} }
} }
pub fn set_max_retransmissions(&mut self, max_retransmissions: u32) -> &mut Self {
match self {
InputMessage::Regular {
max_retransmissions: m,
..
}
| InputMessage::Anonymous {
max_retransmissions: m,
..
}
| InputMessage::Reply {
max_retransmissions: m,
..
} => {
*m = Some(max_retransmissions);
}
InputMessage::Premade { .. } => {}
InputMessage::MessageWrapper { message, .. } => {
message.set_max_retransmissions(max_retransmissions);
}
}
self
}
pub fn with_max_retransmissions(mut self, max_retransmissions: u32) -> Self {
self.set_max_retransmissions(max_retransmissions);
self
}
} }
@@ -3,7 +3,7 @@
use crate::client::key_manager::persistence::KeyStore; use crate::client::key_manager::persistence::KeyStore;
use nym_crypto::{ use nym_crypto::{
asymmetric::{encryption, identity}, asymmetric::{ed25519, x25519},
hkdf::{DerivationMaterial, InvalidLength}, hkdf::{DerivationMaterial, InvalidLength},
}; };
use nym_gateway_requests::shared_key::{LegacySharedKeys, SharedGatewayKey, SharedSymmetricKey}; use nym_gateway_requests::shared_key::{LegacySharedKeys, SharedGatewayKey, SharedSymmetricKey};
@@ -25,10 +25,10 @@ mod test;
#[derive(Clone)] #[derive(Clone)]
pub struct ClientKeys { pub struct ClientKeys {
/// identity key associated with the client instance. /// identity key associated with the client instance.
identity_keypair: Arc<identity::KeyPair>, identity_keypair: Arc<ed25519::KeyPair>,
/// encryption key associated with the client instance. /// encryption key associated with the client instance.
encryption_keypair: Arc<encryption::KeyPair>, encryption_keypair: Arc<x25519::KeyPair>,
/// key used for producing and processing acknowledgement packets. /// key used for producing and processing acknowledgement packets.
ack_key: Arc<AckKey>, ack_key: Arc<AckKey>,
@@ -41,8 +41,8 @@ impl ClientKeys {
R: RngCore + CryptoRng, R: RngCore + CryptoRng,
{ {
ClientKeys { ClientKeys {
identity_keypair: Arc::new(identity::KeyPair::new(rng)), identity_keypair: Arc::new(ed25519::KeyPair::new(rng)),
encryption_keypair: Arc::new(encryption::KeyPair::new(rng)), encryption_keypair: Arc::new(x25519::KeyPair::new(rng)),
ack_key: Arc::new(AckKey::new(rng)), ack_key: Arc::new(AckKey::new(rng)),
} }
} }
@@ -56,18 +56,18 @@ impl ClientKeys {
{ {
let secret = derivation_material.derive_secret()?; let secret = derivation_material.derive_secret()?;
Ok(ClientKeys { Ok(ClientKeys {
identity_keypair: Arc::new(identity::KeyPair::from_secret( identity_keypair: Arc::new(ed25519::KeyPair::from_secret(
secret, secret,
derivation_material.index(), derivation_material.index(),
)), )),
encryption_keypair: Arc::new(encryption::KeyPair::new(rng)), encryption_keypair: Arc::new(x25519::KeyPair::new(rng)),
ack_key: Arc::new(AckKey::new(rng)), ack_key: Arc::new(AckKey::new(rng)),
}) })
} }
pub fn from_keys( pub fn from_keys(
id_keypair: identity::KeyPair, id_keypair: ed25519::KeyPair,
enc_keypair: encryption::KeyPair, enc_keypair: x25519::KeyPair,
ack_key: AckKey, ack_key: AckKey,
) -> Self { ) -> Self {
Self { Self {
@@ -85,13 +85,13 @@ impl ClientKeys {
store.store_keys(self).await store.store_keys(self).await
} }
/// Gets an atomically reference counted pointer to [`identity::KeyPair`]. /// Gets an atomically reference counted pointer to [`ed25519::KeyPair`].
pub fn identity_keypair(&self) -> Arc<identity::KeyPair> { pub fn identity_keypair(&self) -> Arc<ed25519::KeyPair> {
Arc::clone(&self.identity_keypair) Arc::clone(&self.identity_keypair)
} }
/// Gets an atomically reference counted pointer to [`encryption::KeyPair`]. /// Gets an atomically reference counted pointer to [`x25519::KeyPair`].
pub fn encryption_keypair(&self) -> Arc<encryption::KeyPair> { pub fn encryption_keypair(&self) -> Arc<x25519::KeyPair> {
Arc::clone(&self.encryption_keypair) Arc::clone(&self.encryption_keypair)
} }
/// Gets an atomically reference counted pointer to [`AckKey`]. /// Gets an atomically reference counted pointer to [`AckKey`].
@@ -103,8 +103,8 @@ impl ClientKeys {
fn _assert_keys_zeroize_on_drop() { fn _assert_keys_zeroize_on_drop() {
fn _assert_zeroize_on_drop<T: ZeroizeOnDrop>() {} fn _assert_zeroize_on_drop<T: ZeroizeOnDrop>() {}
_assert_zeroize_on_drop::<identity::KeyPair>(); _assert_zeroize_on_drop::<ed25519::KeyPair>();
_assert_zeroize_on_drop::<encryption::KeyPair>(); _assert_zeroize_on_drop::<x25519::KeyPair>();
_assert_zeroize_on_drop::<AckKey>(); _assert_zeroize_on_drop::<AckKey>();
_assert_zeroize_on_drop::<LegacySharedKeys>(); _assert_zeroize_on_drop::<LegacySharedKeys>();
_assert_zeroize_on_drop::<SharedSymmetricKey>(); _assert_zeroize_on_drop::<SharedSymmetricKey>();
@@ -11,7 +11,7 @@ use tokio::sync::Mutex;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use crate::config::disk_persistence::ClientKeysPaths; use crate::config::disk_persistence::ClientKeysPaths;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use nym_crypto::asymmetric::{encryption, identity}; use nym_crypto::asymmetric::{ed25519, x25519};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair}; use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@@ -86,13 +86,13 @@ impl OnDiskKeys {
} }
#[doc(hidden)] #[doc(hidden)]
pub fn load_encryption_keypair(&self) -> Result<encryption::KeyPair, OnDiskKeysError> { pub fn load_encryption_keypair(&self) -> Result<x25519::KeyPair, OnDiskKeysError> {
let encryption_paths = self.paths.encryption_key_pair_path(); let encryption_paths = self.paths.encryption_key_pair_path();
self.load_keypair(encryption_paths, "encryption") self.load_keypair(encryption_paths, "encryption")
} }
#[doc(hidden)] #[doc(hidden)]
pub fn load_identity_keypair(&self) -> Result<identity::KeyPair, OnDiskKeysError> { pub fn load_identity_keypair(&self) -> Result<ed25519::KeyPair, OnDiskKeysError> {
let identity_paths = self.paths.identity_key_pair_path(); let identity_paths = self.paths.identity_key_pair_path();
self.load_keypair(identity_paths, "identity") self.load_keypair(identity_paths, "identity")
} }
@@ -52,7 +52,7 @@ impl MixTrafficController {
let (message_sender, message_receiver) = let (message_sender, message_receiver) =
tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE); tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE);
let (client_sender, client_receiver) = tokio::sync::mpsc::channel(1); let (client_sender, client_receiver) = tokio::sync::mpsc::channel(8);
( (
MixTrafficController { MixTrafficController {
@@ -77,7 +77,7 @@ impl MixTrafficController {
) { ) {
let (message_sender, message_receiver) = let (message_sender, message_receiver) =
tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE); tokio::sync::mpsc::channel(MIX_MESSAGE_RECEIVER_BUFFER_SIZE);
let (client_sender, client_receiver) = tokio::sync::mpsc::channel(1); let (client_sender, client_receiver) = tokio::sync::mpsc::channel(8);
( (
MixTrafficController { MixTrafficController {
gateway_transceiver, gateway_transceiver,
@@ -4,7 +4,7 @@
use async_trait::async_trait; use async_trait::async_trait;
use log::{debug, error}; use log::{debug, error};
use nym_credential_storage::storage::Storage as CredentialStorage; use nym_credential_storage::storage::Storage as CredentialStorage;
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use nym_gateway_client::error::GatewayClientError; use nym_gateway_client::error::GatewayClientError;
use nym_gateway_client::GatewayClient; use nym_gateway_client::GatewayClient;
pub use nym_gateway_client::{GatewayPacketRouter, PacketRouter}; pub use nym_gateway_client::{GatewayPacketRouter, PacketRouter};
@@ -30,7 +30,7 @@ fn erase_err<E: std::error::Error + Send + Sync + 'static>(err: E) -> ErasedGate
/// This combines combines the functionalities of being able to send and receive mix packets. /// This combines combines the functionalities of being able to send and receive mix packets.
#[async_trait] #[async_trait]
pub trait GatewayTransceiver: GatewaySender + GatewayReceiver { pub trait GatewayTransceiver: GatewaySender + GatewayReceiver {
fn gateway_identity(&self) -> identity::PublicKey; fn gateway_identity(&self) -> ed25519::PublicKey;
fn ws_fd(&self) -> Option<RawFd>; fn ws_fd(&self) -> Option<RawFd>;
async fn send_client_request( async fn send_client_request(
&mut self, &mut self,
@@ -75,7 +75,7 @@ pub trait GatewayReceiver {
#[async_trait] #[async_trait]
impl<G: GatewayTransceiver + ?Sized + Send> GatewayTransceiver for Box<G> { impl<G: GatewayTransceiver + ?Sized + Send> GatewayTransceiver for Box<G> {
#[inline] #[inline]
fn gateway_identity(&self) -> identity::PublicKey { fn gateway_identity(&self) -> ed25519::PublicKey {
(**self).gateway_identity() (**self).gateway_identity()
} }
fn ws_fd(&self) -> Option<RawFd> { fn ws_fd(&self) -> Option<RawFd> {
@@ -134,7 +134,7 @@ where
St: CredentialStorage, St: CredentialStorage,
<St as CredentialStorage>::StorageError: Send + Sync + 'static, <St as CredentialStorage>::StorageError: Send + Sync + 'static,
{ {
fn gateway_identity(&self) -> identity::PublicKey { fn gateway_identity(&self) -> ed25519::PublicKey {
self.gateway_client.gateway_identity() self.gateway_client.gateway_identity()
} }
fn ws_fd(&self) -> Option<RawFd> { fn ws_fd(&self) -> Option<RawFd> {
@@ -190,7 +190,7 @@ pub enum LocalGatewayError {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
pub struct LocalGateway { pub struct LocalGateway {
/// Identity of the locally managed gateway /// Identity of the locally managed gateway
local_identity: identity::PublicKey, local_identity: ed25519::PublicKey,
// 'sender' part // 'sender' part
/// Channel responsible for taking mix packets and forwarding them further into the further mixnet layers. /// Channel responsible for taking mix packets and forwarding them further into the further mixnet layers.
@@ -203,7 +203,7 @@ pub struct LocalGateway {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
impl LocalGateway { impl LocalGateway {
pub fn new( pub fn new(
local_identity: identity::PublicKey, local_identity: ed25519::PublicKey,
packet_forwarder: nym_mixnet_client::forwarder::MixForwardingSender, packet_forwarder: nym_mixnet_client::forwarder::MixForwardingSender,
packet_router_tx: oneshot::Sender<PacketRouter>, packet_router_tx: oneshot::Sender<PacketRouter>,
) -> Self { ) -> Self {
@@ -221,7 +221,7 @@ mod nonwasm_sealed {
#[async_trait] #[async_trait]
impl GatewayTransceiver for LocalGateway { impl GatewayTransceiver for LocalGateway {
fn gateway_identity(&self) -> identity::PublicKey { fn gateway_identity(&self) -> ed25519::PublicKey {
self.local_identity self.local_identity
} }
fn ws_fd(&self) -> Option<RawFd> { fn ws_fd(&self) -> Option<RawFd> {
@@ -263,7 +263,7 @@ mod nonwasm_sealed {
// if we ever decided to start writing unit tests... : ) // if we ever decided to start writing unit tests... : )
pub struct MockGateway { pub struct MockGateway {
dummy_identity: identity::PublicKey, dummy_identity: ed25519::PublicKey,
packet_router: Option<PacketRouter>, packet_router: Option<PacketRouter>,
sent: Vec<MixPacket>, sent: Vec<MixPacket>,
} }
@@ -303,7 +303,7 @@ impl GatewaySender for MockGateway {
#[async_trait] #[async_trait]
impl GatewayTransceiver for MockGateway { impl GatewayTransceiver for MockGateway {
fn gateway_identity(&self) -> identity::PublicKey { fn gateway_identity(&self) -> ed25519::PublicKey {
self.dummy_identity self.dummy_identity
} }
fn ws_fd(&self) -> Option<RawFd> { fn ws_fd(&self) -> Option<RawFd> {
@@ -222,9 +222,6 @@ impl ActionController {
// note: when the entry expires it's automatically removed from pending_acks_timers // 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>) {
// 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?
let frag_id = expired_ack.into_inner(); let frag_id = expired_ack.into_inner();
trace!("{frag_id} has expired"); trace!("{frag_id} has expired");
@@ -65,11 +65,12 @@ where
recipient_tag: AnonymousSenderTag, recipient_tag: AnonymousSenderTag,
data: Vec<u8>, data: Vec<u8>,
lane: TransmissionLane, lane: TransmissionLane,
max_retransmissions: Option<u32>,
) { ) {
// offload reply handling to the dedicated task // offload reply handling to the dedicated task
if let Err(err) = self if let Err(err) =
.reply_controller_sender self.reply_controller_sender
.send_reply(recipient_tag, data, lane) .send_reply(recipient_tag, data, lane, max_retransmissions)
{ {
if !self.task_client.is_shutdown_poll() { if !self.task_client.is_shutdown_poll() {
error!("failed to send a reply - {err}"); error!("failed to send a reply - {err}");
@@ -83,10 +84,11 @@ where
content: Vec<u8>, content: Vec<u8>,
lane: TransmissionLane, lane: TransmissionLane,
packet_type: PacketType, packet_type: PacketType,
max_retransmissions: Option<u32>,
) { ) {
if let Err(err) = self if let Err(err) = self
.message_handler .message_handler
.try_send_plain_message(recipient, content, lane, packet_type) .try_send_plain_message(recipient, content, lane, packet_type, max_retransmissions)
.await .await
{ {
warn!("failed to send a plain message - {err}") warn!("failed to send a plain message - {err}")
@@ -100,10 +102,18 @@ where
reply_surbs: u32, reply_surbs: u32,
lane: TransmissionLane, lane: TransmissionLane,
packet_type: PacketType, packet_type: PacketType,
max_retransmissions: Option<u32>,
) { ) {
if let Err(err) = self if let Err(err) = self
.message_handler .message_handler
.try_send_message_with_reply_surbs(recipient, content, reply_surbs, lane, packet_type) .try_send_message_with_reply_surbs(
recipient,
content,
reply_surbs,
lane,
packet_type,
max_retransmissions,
)
.await .await
{ {
warn!("failed to send a repliable message - {err}") warn!("failed to send a repliable message - {err}")
@@ -116,25 +126,42 @@ where
recipient, recipient,
data, data,
lane, lane,
max_retransmissions,
} => { } => {
self.handle_plain_message(recipient, data, lane, PacketType::Mix) self.handle_plain_message(
.await recipient,
data,
lane,
PacketType::Mix,
max_retransmissions,
)
.await
} }
InputMessage::Anonymous { InputMessage::Anonymous {
recipient, recipient,
data, data,
reply_surbs, reply_surbs,
lane, lane,
max_retransmissions,
} => { } => {
self.handle_repliable_message(recipient, data, reply_surbs, lane, PacketType::Mix) self.handle_repliable_message(
.await recipient,
data,
reply_surbs,
lane,
PacketType::Mix,
max_retransmissions,
)
.await
} }
InputMessage::Reply { InputMessage::Reply {
recipient_tag, recipient_tag,
data, data,
lane, lane,
max_retransmissions,
} => { } => {
self.handle_reply(recipient_tag, data, lane).await; self.handle_reply(recipient_tag, data, lane, max_retransmissions)
.await;
} }
InputMessage::Premade { msgs, lane } => self.handle_premade_packets(msgs, lane).await, InputMessage::Premade { msgs, lane } => self.handle_premade_packets(msgs, lane).await,
InputMessage::MessageWrapper { InputMessage::MessageWrapper {
@@ -145,25 +172,42 @@ where
recipient, recipient,
data, data,
lane, lane,
max_retransmissions,
} => { } => {
self.handle_plain_message(recipient, data, lane, packet_type) self.handle_plain_message(
.await recipient,
data,
lane,
packet_type,
max_retransmissions,
)
.await
} }
InputMessage::Anonymous { InputMessage::Anonymous {
recipient, recipient,
data, data,
reply_surbs, reply_surbs,
lane, lane,
max_retransmissions,
} => { } => {
self.handle_repliable_message(recipient, data, reply_surbs, lane, packet_type) self.handle_repliable_message(
.await recipient,
data,
reply_surbs,
lane,
packet_type,
max_retransmissions,
)
.await
} }
InputMessage::Reply { InputMessage::Reply {
recipient_tag, recipient_tag,
data, data,
lane, lane,
max_retransmissions,
} => { } => {
self.handle_reply(recipient_tag, data, lane).await; self.handle_reply(recipient_tag, data, lane, max_retransmissions)
.await;
} }
InputMessage::Premade { msgs, lane } => { InputMessage::Premade { msgs, lane } => {
self.handle_premade_packets(msgs, lane).await self.handle_premade_packets(msgs, lane).await
@@ -72,6 +72,7 @@ pub struct PendingAcknowledgement {
delay: SphinxDelay, delay: SphinxDelay,
destination: PacketDestination, destination: PacketDestination,
retransmissions: u32, retransmissions: u32,
max_retransmissions: Option<u32>,
} }
impl PendingAcknowledgement { impl PendingAcknowledgement {
@@ -80,12 +81,14 @@ impl PendingAcknowledgement {
message_chunk: Fragment, message_chunk: Fragment,
delay: SphinxDelay, delay: SphinxDelay,
recipient: Recipient, recipient: Recipient,
max_retransmissions: Option<u32>,
) -> Self { ) -> Self {
PendingAcknowledgement { PendingAcknowledgement {
message_chunk, message_chunk,
delay, delay,
destination: PacketDestination::KnownRecipient(recipient.into()), destination: PacketDestination::KnownRecipient(recipient.into()),
retransmissions: 0, retransmissions: 0,
max_retransmissions,
} }
} }
@@ -94,6 +97,7 @@ impl PendingAcknowledgement {
delay: SphinxDelay, delay: SphinxDelay,
recipient_tag: AnonymousSenderTag, recipient_tag: AnonymousSenderTag,
extra_surb_request: bool, extra_surb_request: bool,
max_retransmissions: Option<u32>,
) -> Self { ) -> Self {
PendingAcknowledgement { PendingAcknowledgement {
message_chunk, message_chunk,
@@ -103,6 +107,7 @@ impl PendingAcknowledgement {
extra_surb_request, extra_surb_request,
}, },
retransmissions: 0, retransmissions: 0,
max_retransmissions,
} }
} }
@@ -118,6 +123,18 @@ impl PendingAcknowledgement {
self.delay = new_delay; self.delay = new_delay;
self.retransmissions += 1; self.retransmissions += 1;
} }
pub(crate) fn reached_max_retransmissions(
&self,
global_max_retransmissions: Option<u32>,
) -> bool {
let reached_local_max = self
.max_retransmissions
.is_some_and(|limit| self.retransmissions >= limit);
let reached_global_max =
global_max_retransmissions.is_some_and(|limit| self.retransmissions >= limit);
reached_local_max || reached_global_max
}
} }
/// AcknowledgementControllerConnectors represents set of channels for communication with /// AcknowledgementControllerConnectors represents set of channels for communication with
@@ -79,17 +79,15 @@ where
let frag_id = timed_out_ack.message_chunk.fragment_identifier(); let frag_id = timed_out_ack.message_chunk.fragment_identifier();
if let Some(limit) = self.maximum_retransmissions { if timed_out_ack.reached_max_retransmissions(self.maximum_retransmissions) {
if timed_out_ack.retransmissions >= limit { debug!("reached maximum number of allowed retransmissions for the packet");
warn!("reached maximum number of allowed retransmissions for the packet"); if let Err(err) = self
if let Err(err) = self .action_sender
.action_sender .unbounded_send(Action::new_remove(frag_id))
.unbounded_send(Action::new_remove(frag_id)) {
{ error!("Failed to send remove action to the controller: {err}");
error!("Failed to send remove action to the controller: {err}");
}
return;
} }
return;
} }
let maybe_prepared_fragment = match &timed_out_ack.destination { let maybe_prepared_fragment = match &timed_out_ack.destination {
@@ -6,9 +6,9 @@ use crate::client::real_messages_control::real_traffic_stream::{
BatchRealMessageSender, RealMessage, BatchRealMessageSender, RealMessage,
}; };
use crate::client::real_messages_control::{AckActionSender, Action}; use crate::client::real_messages_control::{AckActionSender, Action};
use crate::client::replies::reply_controller::MaxRetransmissions;
use crate::client::replies::reply_storage::{ReceivedReplySurbsMap, SentReplyKeys, UsedSenderTags}; use crate::client::replies::reply_storage::{ReceivedReplySurbsMap, SentReplyKeys, UsedSenderTags};
use crate::client::topology_control::{TopologyAccessor, TopologyReadPermit}; use crate::client::topology_control::{TopologyAccessor, TopologyReadPermit};
use log::{debug, error, info, trace, warn};
use nym_sphinx::acknowledgements::AckKey; use nym_sphinx::acknowledgements::AckKey;
use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::anonymous_replies::requests::{AnonymousSenderTag, RepliableMessage, ReplyMessage}; use nym_sphinx::anonymous_replies::requests::{AnonymousSenderTag, RepliableMessage, ReplyMessage};
@@ -26,6 +26,7 @@ use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use thiserror::Error; use thiserror::Error;
use tracing::{debug, error, info, trace, warn};
// TODO: move that error elsewhere since it seems to be contaminating different files // TODO: move that error elsewhere since it seems to be contaminating different files
#[derive(Debug, Error)] #[derive(Debug, Error)]
@@ -97,6 +98,12 @@ pub(crate) struct Config {
/// Specify whether route selection should be determined by the packet header. /// Specify whether route selection should be determined by the packet header.
deterministic_route_selection: bool, deterministic_route_selection: bool,
/// Indicates whether to mix hops or not. If mix hops are enabled, traffic
/// will be routed as usual, to the entry gateway, through three mix nodes, egressing
/// through the exit gateway. If mix hops are disabled, traffic will be routed directly
/// from the entry gateway to the exit gateway, bypassing the mix nodes.
disable_mix_hops: bool,
/// Average delay a data packet is going to get delay at a single mixnode. /// Average delay a data packet is going to get delay at a single mixnode.
average_packet_delay: Duration, average_packet_delay: Duration,
@@ -108,6 +115,10 @@ pub(crate) struct Config {
/// Optional secondary predefined packet size used for the encapsulated messages. /// Optional secondary predefined packet size used for the encapsulated messages.
secondary_packet_size: Option<PacketSize>, secondary_packet_size: Option<PacketSize>,
/// Specify whether any constructed reply surbs should use the legacy format,
/// where the payload keys are explicitly attached rather than using the seeds
use_legacy_sphinx_format: bool,
} }
impl Config { impl Config {
@@ -117,6 +128,7 @@ impl Config {
average_packet_delay: Duration, average_packet_delay: Duration,
average_ack_delay: Duration, average_ack_delay: Duration,
deterministic_route_selection: bool, deterministic_route_selection: bool,
use_legacy_reply_surb_format: bool,
) -> Self { ) -> Self {
Config { Config {
ack_key, ack_key,
@@ -126,6 +138,8 @@ impl Config {
average_ack_delay, average_ack_delay,
primary_packet_size: PacketSize::default(), primary_packet_size: PacketSize::default(),
secondary_packet_size: None, secondary_packet_size: None,
use_legacy_sphinx_format: use_legacy_reply_surb_format,
disable_mix_hops: false,
} }
} }
@@ -140,6 +154,18 @@ impl Config {
self.secondary_packet_size = packet_size; self.secondary_packet_size = packet_size;
self self
} }
/// Configure whether messages senders using this config should use mix hops or not when sending messages.
pub fn disable_mix_hops(mut self, disable_mix_hops: bool) -> Self {
self.disable_mix_hops = disable_mix_hops;
self
}
}
#[derive(Clone)]
pub(crate) struct FragmentWithMaxRetransmissions {
pub(crate) fragment: Fragment,
pub(crate) max_retransmissions: MaxRetransmissions,
} }
#[derive(Clone)] #[derive(Clone)]
@@ -179,6 +205,8 @@ where
config.sender_address, config.sender_address,
config.average_packet_delay, config.average_packet_delay,
config.average_ack_delay, config.average_ack_delay,
config.use_legacy_sphinx_format,
config.disable_mix_hops,
); );
MessageHandler { MessageHandler {
config, config,
@@ -198,10 +226,10 @@ where
trace!("we already had sender tag for {recipient}"); trace!("we already had sender tag for {recipient}");
existing existing
} else { } else {
info!("creating new sender tag for {recipient}"); debug!("creating new sender tag for {recipient}");
let new_tag = AnonymousSenderTag::new_random(&mut self.rng); let new_tag = AnonymousSenderTag::new_random(&mut self.rng);
self.tag_storage.insert_new(recipient, new_tag); self.tag_storage.insert_new(recipient, new_tag);
info!("we'll be using {new_tag} for all anonymous messages sent to {recipient}"); info!("using {new_tag} for all anonymous messages sent to {recipient}");
new_tag new_tag
} }
} }
@@ -247,9 +275,11 @@ where
let topology_permit = self.topology_access.get_read_permit().await; let topology_permit = self.topology_access.get_read_permit().await;
let topology = self.get_topology(&topology_permit)?; let topology = self.get_topology(&topology_permit)?;
let reply_surbs = self let reply_surbs = self.message_preparer.generate_reply_surbs(
.message_preparer self.config.use_legacy_sphinx_format,
.generate_reply_surbs(amount, topology)?; amount,
topology,
)?;
let reply_keys = reply_surbs let reply_keys = reply_surbs
.iter() .iter()
@@ -268,7 +298,7 @@ where
) -> Result<(), SurbWrappedPreparationError> { ) -> Result<(), SurbWrappedPreparationError> {
let msg = NymMessage::new_reply(message); let msg = NymMessage::new_reply(message);
let packet_size = self.optimal_packet_size(&msg); let packet_size = self.optimal_packet_size(&msg);
debug!("Using {packet_size} packets for {msg}"); trace!("Using {packet_size} packets for {msg}");
let mut fragment = self let mut fragment = self
.message_preparer .message_preparer
@@ -294,8 +324,14 @@ where
Some(chunk.fragment_identifier()), Some(chunk.fragment_identifier()),
); );
let delay = prepared_fragment.total_delay; let delay = prepared_fragment.total_delay;
let pending_ack = let max_retransmissions = None;
PendingAcknowledgement::new_anonymous(chunk, delay, target, is_extra_surb_request); let pending_ack = PendingAcknowledgement::new_anonymous(
chunk,
delay,
target,
is_extra_surb_request,
max_retransmissions,
);
let lane = if is_extra_surb_request { let lane = if is_extra_surb_request {
TransmissionLane::ReplySurbRequest TransmissionLane::ReplySurbRequest
@@ -326,7 +362,7 @@ where
pub(crate) fn split_reply_message(&mut self, message: Vec<u8>) -> Vec<Fragment> { pub(crate) fn split_reply_message(&mut self, message: Vec<u8>) -> Vec<Fragment> {
let msg = NymMessage::new_reply(ReplyMessage::new_data_message(message)); let msg = NymMessage::new_reply(ReplyMessage::new_data_message(message));
let packet_size = self.optimal_packet_size(&msg); let packet_size = self.optimal_packet_size(&msg);
debug!("Using {packet_size} packets for {msg}"); trace!("Using {packet_size} packets for {msg}");
self.message_preparer self.message_preparer
.pad_and_split_message(msg, packet_size) .pad_and_split_message(msg, packet_size)
@@ -350,7 +386,7 @@ where
pub(crate) async fn try_send_reply_chunks_on_lane( pub(crate) async fn try_send_reply_chunks_on_lane(
&mut self, &mut self,
target: AnonymousSenderTag, target: AnonymousSenderTag,
fragments: Vec<Fragment>, fragments: Vec<FragmentWithMaxRetransmissions>,
reply_surbs: Vec<ReplySurb>, reply_surbs: Vec<ReplySurb>,
lane: TransmissionLane, lane: TransmissionLane,
) -> Result<(), SurbWrappedPreparationError> { ) -> Result<(), SurbWrappedPreparationError> {
@@ -367,12 +403,12 @@ where
pub(crate) async fn try_send_reply_chunks( pub(crate) async fn try_send_reply_chunks(
&mut self, &mut self,
target: AnonymousSenderTag, target: AnonymousSenderTag,
fragments: Vec<(TransmissionLane, Fragment)>, fragments: Vec<(TransmissionLane, FragmentWithMaxRetransmissions)>,
reply_surbs: Vec<ReplySurb>, reply_surbs: Vec<ReplySurb>,
) -> Result<(), SurbWrappedPreparationError> { ) -> Result<(), SurbWrappedPreparationError> {
let prepared_fragments = self let prepared_fragments = self
.prepare_reply_chunks_for_sending( .prepare_reply_chunks_for_sending(
fragments.iter().map(|(_, f)| f.clone()).collect(), fragments.iter().map(|(_, f)| f.fragment.clone()).collect(),
reply_surbs, reply_surbs,
) )
.await?; .await?;
@@ -382,12 +418,21 @@ where
for (raw, prepared) in fragments.into_iter().zip(prepared_fragments.into_iter()) { for (raw, prepared) in fragments.into_iter().zip(prepared_fragments.into_iter()) {
let lane = raw.0; let lane = raw.0;
let fragment = raw.1; let FragmentWithMaxRetransmissions {
fragment,
max_retransmissions,
} = raw.1;
let real_message = let real_message =
RealMessage::new(prepared.mix_packet, Some(prepared.fragment_identifier)); RealMessage::new(prepared.mix_packet, Some(prepared.fragment_identifier));
let delay = prepared.total_delay; let delay = prepared.total_delay;
let pending_ack = PendingAcknowledgement::new_anonymous(fragment, delay, target, false); let pending_ack = PendingAcknowledgement::new_anonymous(
fragment,
delay,
target,
false,
max_retransmissions,
);
let entry = to_forward.entry(lane).or_default(); let entry = to_forward.entry(lane).or_default();
entry.push(real_message); entry.push(real_message);
@@ -416,10 +461,17 @@ where
message: Vec<u8>, message: Vec<u8>,
lane: TransmissionLane, lane: TransmissionLane,
packet_type: PacketType, packet_type: PacketType,
max_retransmissions: Option<u32>,
) -> Result<(), PreparationError> { ) -> Result<(), PreparationError> {
let message = NymMessage::new_plain(message); let message = NymMessage::new_plain(message);
self.try_split_and_send_non_reply_message(message, recipient, lane, packet_type) self.try_split_and_send_non_reply_message(
.await message,
recipient,
lane,
packet_type,
max_retransmissions,
)
.await
} }
pub(crate) async fn try_split_and_send_non_reply_message( pub(crate) async fn try_split_and_send_non_reply_message(
@@ -428,6 +480,7 @@ where
recipient: Recipient, recipient: Recipient,
lane: TransmissionLane, lane: TransmissionLane,
packet_type: PacketType, packet_type: PacketType,
max_retransmissions: Option<u32>,
) -> Result<(), PreparationError> { ) -> Result<(), PreparationError> {
debug!("Sending non-reply message with packet type {packet_type}"); debug!("Sending non-reply message with packet type {packet_type}");
// TODO: I really dislike existence of this assertion, it implies code has to be re-organised // TODO: I really dislike existence of this assertion, it implies code has to be re-organised
@@ -442,7 +495,7 @@ where
} else { } else {
self.optimal_packet_size(&message) self.optimal_packet_size(&message)
}; };
debug!("Using {packet_size} packets for {message}"); trace!("Using {packet_size} packets for {message}");
let fragments = self let fragments = self
.message_preparer .message_preparer
.pad_and_split_message(message, packet_size); .pad_and_split_message(message, packet_size);
@@ -467,7 +520,8 @@ where
Some(fragment.fragment_identifier()), Some(fragment.fragment_identifier()),
); );
let delay = prepared_fragment.total_delay; let delay = prepared_fragment.total_delay;
let pending_ack = PendingAcknowledgement::new_known(fragment, delay, recipient); let pending_ack =
PendingAcknowledgement::new_known(fragment, delay, recipient, max_retransmissions);
real_messages.push(real_message); real_messages.push(real_message);
pending_acks.push(pending_ack); pending_acks.push(pending_ack);
@@ -491,15 +545,20 @@ where
self.generate_reply_surbs_with_keys(amount as usize).await?; self.generate_reply_surbs_with_keys(amount as usize).await?;
let message = NymMessage::new_repliable(RepliableMessage::new_additional_surbs( let message = NymMessage::new_repliable(RepliableMessage::new_additional_surbs(
self.config.use_legacy_sphinx_format,
sender_tag, sender_tag,
reply_surbs, reply_surbs,
)); ));
// When sending SURBs we want to retransmit
let max_retransmissions = None;
self.try_split_and_send_non_reply_message( self.try_split_and_send_non_reply_message(
message, message,
recipient, recipient,
TransmissionLane::AdditionalReplySurbs, TransmissionLane::AdditionalReplySurbs,
packet_type, packet_type,
max_retransmissions,
) )
.await?; .await?;
@@ -516,6 +575,7 @@ where
num_reply_surbs: u32, num_reply_surbs: u32,
lane: TransmissionLane, lane: TransmissionLane,
packet_type: PacketType, packet_type: PacketType,
max_retransmissions: Option<u32>,
) -> Result<(), SurbWrappedPreparationError> { ) -> Result<(), SurbWrappedPreparationError> {
debug!("Sending message with reply SURBs with packet type {packet_type}"); debug!("Sending message with reply SURBs with packet type {packet_type}");
let sender_tag = self.get_or_create_sender_tag(&recipient); let sender_tag = self.get_or_create_sender_tag(&recipient);
@@ -523,11 +583,21 @@ where
.generate_reply_surbs_with_keys(num_reply_surbs as usize) .generate_reply_surbs_with_keys(num_reply_surbs as usize)
.await?; .await?;
let message = let message = NymMessage::new_repliable(RepliableMessage::new_data(
NymMessage::new_repliable(RepliableMessage::new_data(message, sender_tag, reply_surbs)); self.config.use_legacy_sphinx_format,
message,
sender_tag,
reply_surbs,
));
self.try_split_and_send_non_reply_message(message, recipient, lane, packet_type) self.try_split_and_send_non_reply_message(
.await?; message,
recipient,
lane,
packet_type,
max_retransmissions,
)
.await?;
log::trace!("storing {} reply keys", reply_keys.len()); log::trace!("storing {} reply keys", reply_keys.len());
self.reply_key_storage.insert_multiple(reply_keys); self.reply_key_storage.insert_multiple(reply_keys);
@@ -99,9 +99,11 @@ impl<'a> From<&'a Config> for message_handler::Config {
cfg.traffic.average_packet_delay, cfg.traffic.average_packet_delay,
cfg.acks.average_ack_delay, cfg.acks.average_ack_delay,
cfg.traffic.deterministic_route_selection, cfg.traffic.deterministic_route_selection,
cfg.traffic.use_legacy_sphinx_format,
) )
.with_custom_primary_packet_size(cfg.traffic.primary_packet_size) .with_custom_primary_packet_size(cfg.traffic.primary_packet_size)
.with_custom_secondary_packet_size(cfg.traffic.secondary_packet_size) .with_custom_secondary_packet_size(cfg.traffic.secondary_packet_size)
.disable_mix_hops(cfg.traffic.disable_mix_hops)
} }
} }
@@ -153,7 +155,7 @@ impl RealMessagesController<OsRng> {
let rng = OsRng; let rng = OsRng;
// create channels for inter-task communication // create channels for inter-task communication
let (real_message_sender, real_message_receiver) = tokio::sync::mpsc::channel(1); let (real_message_sender, real_message_receiver) = tokio::sync::mpsc::channel(8);
let (sent_notifier_tx, sent_notifier_rx) = mpsc::unbounded(); let (sent_notifier_tx, sent_notifier_rx) = mpsc::unbounded();
let (ack_action_tx, ack_action_rx) = mpsc::unbounded(); let (ack_action_tx, ack_action_rx) = mpsc::unbounded();
let ack_controller_connectors = AcknowledgementControllerConnectors::new( let ack_controller_connectors = AcknowledgementControllerConnectors::new(
@@ -252,6 +252,7 @@ where
( (
generate_loop_cover_packet( generate_loop_cover_packet(
&mut self.rng, &mut self.rng,
self.config.traffic.use_legacy_sphinx_format,
topology_ref, topology_ref,
&self.config.ack_key, &self.config.ack_key,
&self.config.our_full_destination, &self.config.our_full_destination,
@@ -9,7 +9,7 @@ use futures::channel::mpsc;
use futures::lock::Mutex; use futures::lock::Mutex;
use futures::StreamExt; use futures::StreamExt;
use log::*; use log::*;
use nym_crypto::asymmetric::encryption; use nym_crypto::asymmetric::x25519;
use nym_crypto::Digest; use nym_crypto::Digest;
use nym_gateway_client::MixnetMessageReceiver; use nym_gateway_client::MixnetMessageReceiver;
use nym_sphinx::anonymous_replies::requests::{ use nym_sphinx::anonymous_replies::requests::{
@@ -23,6 +23,10 @@ use nym_statistics_common::clients::{packet_statistics::PacketStatisticsEvent, C
use nym_task::TaskClient; use nym_task::TaskClient;
use std::collections::HashSet; use std::collections::HashSet;
use std::sync::Arc; use std::sync::Arc;
use std::time::{Duration, Instant};
// The interval at which we check for stale buffers
const STALE_BUFFER_CHECK_INTERVAL: Duration = Duration::from_secs(10);
// Buffer Requests to say "hey, send any reconstructed messages to this channel" // 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" // or to say "hey, I'm going offline, don't send anything more to me. Just buffer them instead"
@@ -35,7 +39,7 @@ pub type ReconstructedMessagesReceiver = mpsc::UnboundedReceiver<Vec<Reconstruct
struct ReceivedMessagesBufferInner<R: MessageReceiver> { struct ReceivedMessagesBufferInner<R: MessageReceiver> {
messages: Vec<ReconstructedMessage>, messages: Vec<ReconstructedMessage>,
local_encryption_keypair: Arc<encryption::KeyPair>, local_encryption_keypair: Arc<x25519::KeyPair>,
// TODO: looking how it 'looks' here, perhaps `MessageReceiver` should be renamed to something // TODO: looking how it 'looks' here, perhaps `MessageReceiver` should be renamed to something
// else instead. // else instead.
@@ -48,6 +52,9 @@ struct ReceivedMessagesBufferInner<R: MessageReceiver> {
recently_reconstructed: HashSet<i32>, recently_reconstructed: HashSet<i32>,
stats_tx: ClientStatsSender, stats_tx: ClientStatsSender,
// Periodically check for stale buffers to clean up
last_stale_check: Instant,
} }
impl<R: MessageReceiver> ReceivedMessagesBufferInner<R> { impl<R: MessageReceiver> ReceivedMessagesBufferInner<R> {
@@ -96,9 +103,10 @@ impl<R: MessageReceiver> ReceivedMessagesBufferInner<R> {
} }
None None
} }
_ => unreachable!( _ => {
"no other error kind should have been returned here! If so, it's a bug!" error!("unexpected error occurred during message reconstruction: {err}");
), None
}
}, },
Ok(reconstruction_result) => match reconstruction_result { Ok(reconstruction_result) => match reconstruction_result {
Some((reconstructed_message, used_sets)) => { Some((reconstructed_message, used_sets)) => {
@@ -144,6 +152,16 @@ impl<R: MessageReceiver> ReceivedMessagesBufferInner<R> {
self.recover_from_fragment(fragment_data, raw_fragment_size) self.recover_from_fragment(fragment_data, raw_fragment_size)
} }
fn cleanup_stale_buffers(&mut self) {
let now = Instant::now();
if now - self.last_stale_check > STALE_BUFFER_CHECK_INTERVAL {
self.last_stale_check = now;
self.message_receiver
.reconstructor()
.cleanup_stale_buffers();
}
}
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -158,7 +176,7 @@ struct ReceivedMessagesBuffer<R: MessageReceiver> {
impl<R: MessageReceiver> ReceivedMessagesBuffer<R> { impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
fn new( fn new(
local_encryption_keypair: Arc<encryption::KeyPair>, local_encryption_keypair: Arc<x25519::KeyPair>,
reply_key_storage: SentReplyKeys, reply_key_storage: SentReplyKeys,
reply_controller_sender: ReplyControllerSender, reply_controller_sender: ReplyControllerSender,
stats_tx: ClientStatsSender, stats_tx: ClientStatsSender,
@@ -172,6 +190,7 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
message_sender: None, message_sender: None,
recently_reconstructed: HashSet::new(), recently_reconstructed: HashSet::new(),
stats_tx, stats_tx,
last_stale_check: Instant::now(),
})), })),
reply_key_storage, reply_key_storage,
reply_controller_sender, reply_controller_sender,
@@ -231,10 +250,10 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
let mut reconstructed = Vec::new(); let mut reconstructed = Vec::new();
for msg in msgs { for msg in msgs {
let (reply_surbs, from_surb_request) = match msg.content { let (reply_surbs, from_surb_request) = match msg.content {
RepliableMessageContent::Data { RepliableMessageContent::Data(content) => {
message, let reply_surbs = content.reply_surbs;
reply_surbs, let message = content.message;
} => {
trace!( trace!(
"received message that also contained additional {} reply surbs from {:?}!", "received message that also contained additional {} reply surbs from {:?}!",
reply_surbs.len(), reply_surbs.len(),
@@ -245,7 +264,9 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
(reply_surbs, false) (reply_surbs, false)
} }
RepliableMessageContent::AdditionalSurbs { reply_surbs } => { RepliableMessageContent::AdditionalSurbs(content) => {
let reply_surbs = content.reply_surbs;
trace!( trace!(
"received additional {} reply surbs from {:?}!", "received additional {} reply surbs from {:?}!",
reply_surbs.len(), reply_surbs.len(),
@@ -253,9 +274,37 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
); );
(reply_surbs, true) (reply_surbs, true)
} }
RepliableMessageContent::Heartbeat { RepliableMessageContent::Heartbeat(content) => {
additional_reply_surbs, let additional_reply_surbs = content.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)
}
RepliableMessageContent::DataV2(content) => {
let reply_surbs = content.reply_surbs;
let message = content.message;
trace!(
"received message that also contained additional {} reply surbs from {:?}!",
reply_surbs.len(),
msg.sender_tag
);
reconstructed.push(ReconstructedMessage::new(message, msg.sender_tag));
(reply_surbs, false)
}
RepliableMessageContent::AdditionalSurbsV2(content) => {
let reply_surbs = content.reply_surbs;
trace!(
"received additional {} reply surbs from {:?}!",
reply_surbs.len(),
msg.sender_tag
);
(reply_surbs, true)
}
RepliableMessageContent::HeartbeatV2(content) => {
let additional_reply_surbs = content.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)"); 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) (additional_reply_surbs, false)
} }
@@ -392,6 +441,11 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
} }
} }
// Cleanup stale buffers, if there are any fragments that simply never arrived.
// We do this here as part of handling new received fragments so that we can keep the event
// loop focused on processing new messages.
inner_guard.cleanup_stale_buffers();
drop(inner_guard); drop(inner_guard);
if !completed_messages.is_empty() { if !completed_messages.is_empty() {
@@ -512,7 +566,7 @@ pub(crate) struct ReceivedMessagesBufferController<R: MessageReceiver> {
impl<R: MessageReceiver + Clone + Send + 'static> ReceivedMessagesBufferController<R> { impl<R: MessageReceiver + Clone + Send + 'static> ReceivedMessagesBufferController<R> {
pub(crate) fn new( pub(crate) fn new(
local_encryption_keypair: Arc<encryption::KeyPair>, local_encryption_keypair: Arc<x25519::KeyPair>,
query_receiver: ReceivedBufferRequestReceiver, query_receiver: ReceivedBufferRequestReceiver,
mixnet_packet_receiver: MixnetMessageReceiver, mixnet_packet_receiver: MixnetMessageReceiver,
reply_key_storage: SentReplyKeys, reply_key_storage: SentReplyKeys,
@@ -2,7 +2,9 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::client::real_messages_control::acknowledgement_control::PendingAcknowledgement; use crate::client::real_messages_control::acknowledgement_control::PendingAcknowledgement;
use crate::client::real_messages_control::message_handler::{MessageHandler, PreparationError}; use crate::client::real_messages_control::message_handler::{
FragmentWithMaxRetransmissions, MessageHandler, PreparationError,
};
use crate::client::replies::reply_storage::CombinedReplyStorage; use crate::client::replies::reply_storage::CombinedReplyStorage;
use futures::channel::oneshot; use futures::channel::oneshot;
use futures::StreamExt; use futures::StreamExt;
@@ -10,7 +12,7 @@ use log::{debug, error, info, trace, warn};
use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::addressing::clients::Recipient;
use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag;
use nym_sphinx::anonymous_replies::ReplySurb; use nym_sphinx::anonymous_replies::ReplySurb;
use nym_sphinx::chunking::fragment::{Fragment, FragmentIdentifier}; use nym_sphinx::chunking::fragment::FragmentIdentifier;
use nym_task::connections::{ConnectionId, TransmissionLane}; use nym_task::connections::{ConnectionId, TransmissionLane};
use nym_task::TaskClient; use nym_task::TaskClient;
use rand::{CryptoRng, Rng}; use rand::{CryptoRng, Rng};
@@ -49,6 +51,8 @@ impl Config {
// - replies to "give additional surbs" requests // - replies to "give additional surbs" requests
// - will reply to future heartbeats // - will reply to future heartbeats
pub type MaxRetransmissions = Option<u32>;
// TODO: this should be split into ingress and egress controllers // TODO: this should be split into ingress and egress controllers
// because currently its trying to perform two distinct jobs // because currently its trying to perform two distinct jobs
pub struct ReplyController<R> { pub struct ReplyController<R> {
@@ -59,7 +63,8 @@ pub struct ReplyController<R> {
// of surbs required to send the message through // of surbs required to send the message through
// expected_reliability: f32, // expected_reliability: f32,
request_receiver: ReplyControllerReceiver, request_receiver: ReplyControllerReceiver,
pending_replies: HashMap<AnonymousSenderTag, TransmissionBuffer<Fragment>>, pending_replies:
HashMap<AnonymousSenderTag, TransmissionBuffer<FragmentWithMaxRetransmissions>>,
/// Retransmission packets that have already timed out and are waiting for additional reply SURBs /// 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. /// so that they could be sent back to the network. Once we receive more SURBs, we should send them ASAP.
@@ -96,7 +101,7 @@ where
} }
} }
fn insert_pending_replies<I: IntoIterator<Item = Fragment>>( fn insert_pending_replies<I: IntoIterator<Item = FragmentWithMaxRetransmissions>>(
&mut self, &mut self,
recipient: &AnonymousSenderTag, recipient: &AnonymousSenderTag,
fragments: I, fragments: I,
@@ -112,7 +117,7 @@ where
fn re_insert_pending_replies( fn re_insert_pending_replies(
&mut self, &mut self,
recipient: &AnonymousSenderTag, recipient: &AnonymousSenderTag,
fragments: Vec<(TransmissionLane, Fragment)>, fragments: Vec<(TransmissionLane, FragmentWithMaxRetransmissions)>,
) { ) {
trace!("re-inserting pending replies for {recipient}"); trace!("re-inserting pending replies for {recipient}");
// the buffer should ALWAYS exist at this point, if it doesn't, it's a bug... // the buffer should ALWAYS exist at this point, if it doesn't, it's a bug...
@@ -205,6 +210,7 @@ where
recipient_tag: AnonymousSenderTag, recipient_tag: AnonymousSenderTag,
data: Vec<u8>, data: Vec<u8>,
lane: TransmissionLane, lane: TransmissionLane,
max_retransmissions: Option<u32>,
) { ) {
if !self if !self
.full_reply_storage .full_reply_storage
@@ -242,7 +248,14 @@ where
.get_reply_surbs(&recipient_tag, max_to_send); .get_reply_surbs(&recipient_tag, max_to_send);
if let Some(reply_surbs) = surbs { if let Some(reply_surbs) = surbs {
let to_send = fragments.drain(..max_to_send).collect::<Vec<_>>(); let to_send = fragments
.drain(..max_to_send)
.map(|f| FragmentWithMaxRetransmissions {
fragment: f,
max_retransmissions,
})
.collect::<Vec<_>>();
if let Err(err) = self if let Err(err) = self
.message_handler .message_handler
.try_send_reply_chunks_on_lane( .try_send_reply_chunks_on_lane(
@@ -276,6 +289,13 @@ where
"buffering {no_fragments} fragments for {recipient_tag}", "buffering {no_fragments} fragments for {recipient_tag}",
no_fragments = fragments.len() no_fragments = fragments.len()
); );
let fragments: Vec<_> = fragments
.into_iter()
.map(|fragment| FragmentWithMaxRetransmissions {
fragment,
max_retransmissions,
})
.collect();
self.insert_pending_replies(&recipient_tag, fragments, lane); self.insert_pending_replies(&recipient_tag, fragments, lane);
} }
@@ -409,7 +429,7 @@ where
&mut self, &mut self,
from: &AnonymousSenderTag, from: &AnonymousSenderTag,
amount: usize, amount: usize,
) -> Option<Vec<(TransmissionLane, Fragment)>> { ) -> Option<Vec<(TransmissionLane, FragmentWithMaxRetransmissions)>> {
// if possible, pop all pending replies, if not, pop only entries for which we'd have a reply surb // if possible, pop all pending replies, if not, pop only entries for which we'd have a reply surb
let total = self.pending_replies.get(from)?.total_size(); let total = self.pending_replies.get(from)?.total_size();
trace!("pending queue has {total} elements"); trace!("pending queue has {total} elements");
@@ -689,7 +709,11 @@ where
recipient, recipient,
message, message,
lane, lane,
} => self.handle_send_reply(recipient, message, lane).await, max_retransmissions,
} => {
self.handle_send_reply(recipient, message, lane, max_retransmissions)
.await
}
ReplyControllerMessage::AdditionalSurbs { ReplyControllerMessage::AdditionalSurbs {
sender_tag, sender_tag,
reply_surbs, reply_surbs,
@@ -66,12 +66,14 @@ impl ReplyControllerSender {
recipient: AnonymousSenderTag, recipient: AnonymousSenderTag,
message: Vec<u8>, message: Vec<u8>,
lane: TransmissionLane, lane: TransmissionLane,
max_retransmissions: Option<u32>,
) -> Result<(), ReplyControllerSenderError> { ) -> Result<(), ReplyControllerSenderError> {
self.0 self.0
.unbounded_send(ReplyControllerMessage::SendReply { .unbounded_send(ReplyControllerMessage::SendReply {
recipient, recipient,
message, message,
lane, lane,
max_retransmissions,
}) })
.map_err(ReplyControllerSenderError::SendReply) .map_err(ReplyControllerSenderError::SendReply)
} }
@@ -160,6 +162,7 @@ pub enum ReplyControllerMessage {
recipient: AnonymousSenderTag, recipient: AnonymousSenderTag,
message: Vec<u8>, message: Vec<u8>,
lane: TransmissionLane, lane: TransmissionLane,
max_retransmissions: Option<u32>,
}, },
AdditionalSurbs { AdditionalSurbs {
@@ -1,214 +0,0 @@
use crate::config::GroupBy;
use log::{debug, error};
use nym_explorer_client::{ExplorerClient, PrettyDetailedMixNodeBond};
use nym_network_defaults::var_names::EXPLORER_API;
use nym_topology::{
provider_trait::{async_trait, TopologyProvider},
NymTopology,
};
use nym_validator_client::client::NodeId;
use rand::{prelude::SliceRandom, thread_rng};
use std::collections::HashMap;
use tap::TapOptional;
use url::Url;
pub use nym_country_group::CountryGroup;
fn create_explorer_client() -> Option<ExplorerClient> {
let Ok(explorer_api_url) = std::env::var(EXPLORER_API) else {
error!("Missing EXPLORER_API");
return None;
};
let Ok(explorer_api_url) = explorer_api_url.parse() else {
error!("Failed to parse EXPLORER_API");
return None;
};
log::debug!("Using explorer-api url: {}", explorer_api_url);
let Ok(client) = nym_explorer_client::ExplorerClient::new(explorer_api_url) else {
error!("Failed to create explorer-api client");
return None;
};
Some(client)
}
fn group_mixnodes_by_country_code(
mixnodes: Vec<PrettyDetailedMixNodeBond>,
) -> HashMap<CountryGroup, Vec<NodeId>> {
mixnodes
.into_iter()
.fold(HashMap::<CountryGroup, Vec<NodeId>>::new(), |mut acc, m| {
if let Some(ref location) = m.location {
let country_code = location.two_letter_iso_country_code.clone();
let group_code = CountryGroup::new(country_code.as_str());
let mixnodes = acc.entry(group_code).or_default();
mixnodes.push(m.mix_id);
}
acc
})
}
fn log_mixnode_distribution(mixnodes: &HashMap<CountryGroup, Vec<NodeId>>) {
let mixnode_distribution = mixnodes
.iter()
.map(|(k, v)| format!("{}: {}", k, v.len()))
.collect::<Vec<_>>()
.join(", ");
debug!("Mixnode distribution - {}", mixnode_distribution);
}
fn check_layer_integrity(topology: NymTopology) -> Result<(), ()> {
if topology.ensure_minimally_routable().is_err() {
error!("Layer is missing in topology!");
return Err(());
}
Ok(())
}
#[deprecated(note = "use NymApiTopologyProvider instead as explorer API will soon be removed")]
pub struct GeoAwareTopologyProvider {
validator_client: nym_validator_client::client::NymApiClient,
filter_on: GroupBy,
}
#[allow(deprecated)]
impl GeoAwareTopologyProvider {
pub fn new(mut nym_api_urls: Vec<Url>, filter_on: GroupBy) -> GeoAwareTopologyProvider {
log::info!(
"Creating geo-aware topology provider with filter on {}",
filter_on
);
nym_api_urls.shuffle(&mut thread_rng());
GeoAwareTopologyProvider {
validator_client: nym_validator_client::client::NymApiClient::new(
nym_api_urls[0].clone(),
),
filter_on,
}
}
async fn get_topology(&self) -> Option<NymTopology> {
let rewarded_set = self
.validator_client
.get_current_rewarded_set()
.await
.inspect_err(|err| error!("failed to get current rewarded set: {err}"))
.ok()?;
let mut topology = NymTopology::new_empty(rewarded_set);
let mixnodes = match self
.validator_client
.get_all_basic_active_mixing_assigned_nodes()
.await
{
Err(err) => {
error!("failed to get network mixnodes - {err}");
return None;
}
Ok(mixes) => mixes,
};
let gateways = match self
.validator_client
.get_all_basic_entry_assigned_nodes()
.await
{
Err(err) => {
error!("failed to get network gateways - {err}");
return None;
}
Ok(gateways) => gateways,
};
// Also fetch mixnodes cached by explorer-api, with the purpose of getting their
// geolocation.
debug!("Fetching mixnodes from explorer-api...");
let explorer_client = create_explorer_client()?;
let Ok(mixnodes_from_explorer_api) = explorer_client.get_mixnodes().await else {
error!("failed to get mixnodes from explorer-api");
return None;
};
debug!("Fetching gateways from explorer-api...");
let Ok(gateways_from_explorer_api) = explorer_client.get_gateways().await else {
error!("failed to get mixnodes from explorer-api");
return None;
};
// Determine what we should filter around
let filter_on = match self.filter_on {
GroupBy::CountryGroup(group) => group,
GroupBy::NymAddress(recipient) => {
// Convert recipient into a country group by extracting out the gateway part and
// using that as the country code.
let gateway = recipient.gateway().to_base58_string();
// Lookup the location of this gateway by using the location data from the
// explorer-api
let gateway_location = gateways_from_explorer_api
.iter()
.find(|g| g.gateway.identity_key == gateway)
.and_then(|g| g.location.clone())
.map(|location| location.two_letter_iso_country_code)
.tap_none(|| error!("No location found for the gateway: {}", gateway))?;
debug!(
"Filtering on nym-address: {}, with location: {}",
recipient, gateway_location
);
CountryGroup::new(&gateway_location)
}
};
debug!("Filter group: {}", filter_on);
// Partition mixnodes_from_explorer_api according to the value of
// two_letter_iso_country_code.
// NOTE: we construct the full distribution here, but only use the one we're interested in.
// The reason we this instead of a straight filter is that this opens up the possibility to
// complement a small grouping with mixnodes from adjecent countries.
let mixnode_distribution = group_mixnodes_by_country_code(mixnodes_from_explorer_api);
log_mixnode_distribution(&mixnode_distribution);
let Some(filtered_mixnode_ids) = mixnode_distribution.get(&filter_on) else {
error!("no mixnodes found for: {}", filter_on);
return None;
};
let mixnodes = mixnodes
.into_iter()
.filter(|m| filtered_mixnode_ids.contains(&m.node_id))
.collect::<Vec<_>>();
topology.add_skimmed_nodes(&mixnodes);
topology.add_skimmed_nodes(&gateways);
// TODO: return real error type
check_layer_integrity(topology.clone()).ok()?;
Some(topology)
}
}
#[allow(deprecated)]
#[cfg(not(target_arch = "wasm32"))]
#[async_trait]
impl TopologyProvider for GeoAwareTopologyProvider {
// this will be manually refreshed on a timer specified inside mixnet client config
async fn get_new_topology(&mut self) -> Option<NymTopology> {
self.get_topology().await
}
}
#[allow(deprecated)]
#[cfg(target_arch = "wasm32")]
#[async_trait(?Send)]
impl TopologyProvider for GeoAwareTopologyProvider {
// this will be manually refreshed on a timer specified inside mixnet client config
async fn get_new_topology(&mut self) -> Option<NymTopology> {
self.get_topology().await
}
}
@@ -17,11 +17,8 @@ use tokio::time::sleep;
use wasmtimer::tokio::sleep; use wasmtimer::tokio::sleep;
mod accessor; mod accessor;
pub mod geo_aware_provider;
pub mod nym_api_provider; pub mod nym_api_provider;
#[allow(deprecated)]
pub use geo_aware_provider::GeoAwareTopologyProvider;
pub use nym_api_provider::{Config as NymApiTopologyProviderConfig, NymApiTopologyProvider}; pub use nym_api_provider::{Config as NymApiTopologyProviderConfig, NymApiTopologyProvider};
pub use nym_topology::provider_trait::TopologyProvider; pub use nym_topology::provider_trait::TopologyProvider;
+1 -1
View File
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use crate::client::mix_traffic::transceiver::ErasedGatewayError; use crate::client::mix_traffic::transceiver::ErasedGatewayError;
use nym_crypto::asymmetric::identity::Ed25519RecoveryError; use nym_crypto::asymmetric::ed25519::Ed25519RecoveryError;
use nym_gateway_client::error::GatewayClientError; use nym_gateway_client::error::GatewayClientError;
use nym_topology::node::RoutingNodeError; use nym_topology::node::RoutingNodeError;
use nym_topology::{NodeId, NymTopologyError}; use nym_topology::{NodeId, NymTopologyError};
+16 -8
View File
@@ -5,12 +5,14 @@ use crate::error::ClientCoreError;
use crate::init::types::RegistrationResult; use crate::init::types::RegistrationResult;
use futures::{SinkExt, StreamExt}; use futures::{SinkExt, StreamExt};
use log::{debug, info, trace, warn}; use log::{debug, info, trace, warn};
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use nym_gateway_client::GatewayClient; use nym_gateway_client::GatewayClient;
use nym_topology::node::RoutingNode; use nym_topology::node::RoutingNode;
use nym_validator_client::client::IdentityKeyRef; use nym_validator_client::client::IdentityKeyRef;
use nym_validator_client::UserAgent; use nym_validator_client::UserAgent;
use rand::{seq::SliceRandom, Rng}; use rand::{seq::SliceRandom, Rng};
#[cfg(unix)]
use std::os::fd::RawFd;
use std::{sync::Arc, time::Duration}; use std::{sync::Arc, time::Duration};
use tungstenite::Message; use tungstenite::Message;
use url::Url; use url::Url;
@@ -50,7 +52,7 @@ const PING_TIMEOUT: Duration = Duration::from_millis(1000);
// The abstraction that some of these helpers use // The abstraction that some of these helpers use
pub trait ConnectableGateway { pub trait ConnectableGateway {
fn node_id(&self) -> NodeId; fn node_id(&self) -> NodeId;
fn identity(&self) -> identity::PublicKey; fn identity(&self) -> ed25519::PublicKey;
fn clients_address(&self, prefer_ipv6: bool) -> Option<String>; fn clients_address(&self, prefer_ipv6: bool) -> Option<String>;
fn is_wss(&self) -> bool; fn is_wss(&self) -> bool;
} }
@@ -60,7 +62,7 @@ impl ConnectableGateway for RoutingNode {
self.node_id self.node_id
} }
fn identity(&self) -> identity::PublicKey { fn identity(&self) -> ed25519::PublicKey {
self.identity_key self.identity_key
} }
@@ -285,7 +287,7 @@ pub(super) fn get_specified_gateway(
must_use_tls: bool, must_use_tls: bool,
) -> Result<RoutingNode, ClientCoreError> { ) -> Result<RoutingNode, ClientCoreError> {
log::debug!("Requesting specified gateway: {}", gateway_identity); log::debug!("Requesting specified gateway: {}", gateway_identity);
let user_gateway = identity::PublicKey::from_base58_string(gateway_identity) let user_gateway = ed25519::PublicKey::from_base58_string(gateway_identity)
.map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?; .map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?;
let gateway = gateways let gateway = gateways
@@ -310,12 +312,18 @@ pub(super) fn get_specified_gateway(
} }
pub(super) async fn register_with_gateway( pub(super) async fn register_with_gateway(
gateway_id: identity::PublicKey, gateway_id: ed25519::PublicKey,
gateway_listener: Url, gateway_listener: Url,
our_identity: Arc<identity::KeyPair>, our_identity: Arc<ed25519::KeyPair>,
#[cfg(unix)] connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
) -> Result<RegistrationResult, ClientCoreError> { ) -> Result<RegistrationResult, ClientCoreError> {
let mut gateway_client = let mut gateway_client = GatewayClient::new_init(
GatewayClient::new_init(gateway_listener, gateway_id, our_identity.clone()); gateway_listener,
gateway_id,
our_identity.clone(),
#[cfg(unix)]
connection_fd_callback,
);
gateway_client.establish_connection().await.map_err(|err| { gateway_client.establish_connection().await.map_err(|err| {
log::warn!("Failed to establish connection with gateway!"); log::warn!("Failed to establish connection with gateway!");
+22 -4
View File
@@ -23,6 +23,8 @@ use nym_topology::node::RoutingNode;
use rand::rngs::OsRng; use rand::rngs::OsRng;
use rand::{CryptoRng, RngCore}; use rand::{CryptoRng, RngCore};
use serde::Serialize; use serde::Serialize;
#[cfg(unix)]
use std::{os::fd::RawFd, sync::Arc};
pub mod helpers; pub mod helpers;
pub mod types; pub mod types;
@@ -53,6 +55,7 @@ async fn setup_new_gateway<K, D>(
details_store: &D, details_store: &D,
selection_specification: GatewaySelectionSpecification, selection_specification: GatewaySelectionSpecification,
available_gateways: Vec<RoutingNode>, available_gateways: Vec<RoutingNode>,
#[cfg(unix)] connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
) -> Result<InitialisationResult, ClientCoreError> ) -> Result<InitialisationResult, ClientCoreError>
where where
K: KeyStore, K: KeyStore,
@@ -108,9 +111,14 @@ where
// if we're using a 'normal' gateway setup, do register // if we're using a 'normal' gateway setup, do register
let our_identity = client_keys.identity_keypair(); let our_identity = client_keys.identity_keypair();
let registration = let registration = helpers::register_with_gateway(
helpers::register_with_gateway(gateway_id, gateway_listener.clone(), our_identity) gateway_id,
.await?; gateway_listener.clone(),
our_identity,
#[cfg(unix)]
connection_fd_callback,
)
.await?;
( (
GatewayDetails::new_remote( GatewayDetails::new_remote(
gateway_id, gateway_id,
@@ -203,9 +211,19 @@ where
GatewaySetup::New { GatewaySetup::New {
specification, specification,
available_gateways, available_gateways,
#[cfg(unix)]
connection_fd_callback,
} => { } => {
log::debug!("GatewaySetup::New with spec: {specification:?}"); log::debug!("GatewaySetup::New with spec: {specification:?}");
setup_new_gateway(key_store, details_store, specification, available_gateways).await setup_new_gateway(
key_store,
details_store,
specification,
available_gateways,
#[cfg(unix)]
connection_fd_callback,
)
.await
} }
GatewaySetup::ReuseConnection { GatewaySetup::ReuseConnection {
authenticated_ephemeral_client, authenticated_ephemeral_client,
+17 -7
View File
@@ -9,7 +9,7 @@ use crate::init::{setup_gateway, use_loaded_gateway_details};
use nym_client_core_gateways_storage::{ use nym_client_core_gateways_storage::{
GatewayRegistration, GatewaysDetailsStore, RemoteGatewayDetails, GatewayRegistration, GatewaysDetailsStore, RemoteGatewayDetails,
}; };
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use nym_gateway_client::client::InitGatewayClient; use nym_gateway_client::client::InitGatewayClient;
use nym_gateway_requests::shared_key::SharedGatewayKey; use nym_gateway_requests::shared_key::SharedGatewayKey;
use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::addressing::clients::Recipient;
@@ -18,20 +18,22 @@ use nym_validator_client::client::IdentityKey;
use nym_validator_client::nyxd::AccountId; use nym_validator_client::nyxd::AccountId;
use serde::Serialize; use serde::Serialize;
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display};
#[cfg(unix)]
use std::os::fd::RawFd;
use std::sync::Arc; use std::sync::Arc;
use time::OffsetDateTime; use time::OffsetDateTime;
use url::Url; use url::Url;
pub enum SelectedGateway { pub enum SelectedGateway {
Remote { Remote {
gateway_id: identity::PublicKey, gateway_id: ed25519::PublicKey,
gateway_owner_address: Option<AccountId>, gateway_owner_address: Option<AccountId>,
gateway_listener: Url, gateway_listener: Url,
}, },
Custom { Custom {
gateway_id: identity::PublicKey, gateway_id: ed25519::PublicKey,
additional_data: Option<Vec<u8>>, additional_data: Option<Vec<u8>>,
}, },
} }
@@ -75,7 +77,7 @@ impl SelectedGateway {
gateway_id: String, gateway_id: String,
additional_data: Option<Vec<u8>>, additional_data: Option<Vec<u8>>,
) -> Result<Self, ClientCoreError> { ) -> Result<Self, ClientCoreError> {
let gateway_id = identity::PublicKey::from_base58_string(&gateway_id) let gateway_id = ed25519::PublicKey::from_base58_string(&gateway_id)
.map_err(|source| ClientCoreError::MalformedGatewayIdentity { gateway_id, source })?; .map_err(|source| ClientCoreError::MalformedGatewayIdentity { gateway_id, source })?;
Ok(SelectedGateway::Custom { Ok(SelectedGateway::Custom {
@@ -84,7 +86,7 @@ impl SelectedGateway {
}) })
} }
pub fn gateway_id(&self) -> &identity::PublicKey { pub fn gateway_id(&self) -> &ed25519::PublicKey {
match self { match self {
SelectedGateway::Remote { gateway_id, .. } => gateway_id, SelectedGateway::Remote { gateway_id, .. } => gateway_id,
SelectedGateway::Custom { gateway_id, .. } => gateway_id, SelectedGateway::Custom { gateway_id, .. } => gateway_id,
@@ -140,7 +142,7 @@ impl InitialisationResult {
) )
} }
pub fn gateway_id(&self) -> identity::PublicKey { pub fn gateway_id(&self) -> ed25519::PublicKey {
self.gateway_registration.details.gateway_id() self.gateway_registration.details.gateway_id()
} }
} }
@@ -208,6 +210,10 @@ pub enum GatewaySetup {
// TODO: seems to be a bit inefficient to pass them by value // TODO: seems to be a bit inefficient to pass them by value
available_gateways: Vec<RoutingNode>, available_gateways: Vec<RoutingNode>,
/// Callback useful for allowing initial connection to gateway
#[cfg(unix)]
connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
}, },
ReuseConnection { ReuseConnection {
@@ -231,6 +237,8 @@ impl Debug for GatewaySetup {
GatewaySetup::New { GatewaySetup::New {
specification, specification,
available_gateways, available_gateways,
#[cfg(unix)]
connection_fd_callback: _,
} => f } => f
.debug_struct("GatewaySetup::New") .debug_struct("GatewaySetup::New")
.field("specification", specification) .field("specification", specification)
@@ -263,13 +271,15 @@ impl GatewaySetup {
} }
/// new gateway setup performed by each client that's inbuilt in a gateway (like NR or IPR) /// new gateway setup performed by each client that's inbuilt in a gateway (like NR or IPR)
pub fn new_inbuilt(identity: identity::PublicKey) -> Self { pub fn new_inbuilt(identity: ed25519::PublicKey) -> Self {
GatewaySetup::New { GatewaySetup::New {
specification: GatewaySelectionSpecification::Custom { specification: GatewaySelectionSpecification::Custom {
gateway_identity: identity.to_base58_string(), gateway_identity: identity.to_base58_string(),
additional_data: None, additional_data: None,
}, },
available_gateways: vec![], available_gateways: vec![],
#[cfg(unix)]
connection_fd_callback: None,
} }
} }
@@ -17,7 +17,7 @@ use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCred
use nym_credential_storage::storage::Storage as CredentialStorage; use nym_credential_storage::storage::Storage as CredentialStorage;
use nym_credentials::CredentialSpendingData; use nym_credentials::CredentialSpendingData;
use nym_credentials_interface::TicketType; use nym_credentials_interface::TicketType;
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use nym_gateway_requests::registration::handshake::client_handshake; use nym_gateway_requests::registration::handshake::client_handshake;
use nym_gateway_requests::{ use nym_gateway_requests::{
BinaryRequest, ClientControlRequest, ClientRequest, GatewayProtocolVersionExt, BinaryRequest, ClientControlRequest, ClientRequest, GatewayProtocolVersionExt,
@@ -57,7 +57,7 @@ pub(crate) mod websockets;
use websockets::connect_async; use websockets::connect_async;
pub struct GatewayConfig { pub struct GatewayConfig {
pub gateway_identity: identity::PublicKey, pub gateway_identity: ed25519::PublicKey,
// currently a dead field // currently a dead field
pub gateway_owner: Option<String>, pub gateway_owner: Option<String>,
@@ -67,7 +67,7 @@ pub struct GatewayConfig {
impl GatewayConfig { impl GatewayConfig {
pub fn new( pub fn new(
gateway_identity: identity::PublicKey, gateway_identity: ed25519::PublicKey,
gateway_owner: Option<String>, gateway_owner: Option<String>,
gateway_listener: String, gateway_listener: String,
) -> Self { ) -> Self {
@@ -93,8 +93,8 @@ pub struct GatewayClient<C, St = EphemeralCredentialStorage> {
authenticated: bool, authenticated: bool,
bandwidth: ClientBandwidth, bandwidth: ClientBandwidth,
gateway_address: String, gateway_address: String,
gateway_identity: identity::PublicKey, gateway_identity: ed25519::PublicKey,
local_identity: Arc<identity::KeyPair>, local_identity: Arc<ed25519::KeyPair>,
shared_key: Option<Arc<SharedGatewayKey>>, shared_key: Option<Arc<SharedGatewayKey>>,
connection: SocketState, connection: SocketState,
packet_router: PacketRouter, packet_router: PacketRouter,
@@ -117,7 +117,7 @@ impl<C, St> GatewayClient<C, St> {
pub fn new( pub fn new(
cfg: GatewayClientConfig, cfg: GatewayClientConfig,
gateway_config: GatewayConfig, gateway_config: GatewayConfig,
local_identity: Arc<identity::KeyPair>, local_identity: Arc<ed25519::KeyPair>,
// TODO: make it mandatory. if you don't want to pass it, use `new_init` // TODO: make it mandatory. if you don't want to pass it, use `new_init`
shared_key: Option<Arc<SharedGatewayKey>>, shared_key: Option<Arc<SharedGatewayKey>>,
packet_router: PacketRouter, packet_router: PacketRouter,
@@ -145,7 +145,7 @@ impl<C, St> GatewayClient<C, St> {
} }
} }
pub fn gateway_identity(&self) -> identity::PublicKey { pub fn gateway_identity(&self) -> ed25519::PublicKey {
self.gateway_identity self.gateway_identity
} }
@@ -1063,8 +1063,9 @@ impl GatewayClient<InitOnly, EphemeralCredentialStorage> {
// for initialisation we do not need credential storage. Though it's still a bit weird we have to set the generic... // for initialisation we do not need credential storage. Though it's still a bit weird we have to set the generic...
pub fn new_init( pub fn new_init(
gateway_listener: Url, gateway_listener: Url,
gateway_identity: identity::PublicKey, gateway_identity: ed25519::PublicKey,
local_identity: Arc<identity::KeyPair>, local_identity: Arc<ed25519::KeyPair>,
#[cfg(unix)] connection_fd_callback: Option<Arc<dyn Fn(RawFd) + Send + Sync>>,
) -> Self { ) -> Self {
log::trace!("Initialising gateway client"); log::trace!("Initialising gateway client");
use futures::channel::mpsc; use futures::channel::mpsc;
@@ -1090,7 +1091,7 @@ impl GatewayClient<InitOnly, EphemeralCredentialStorage> {
stats_reporter: ClientStatsSender::new(None, task_client.clone()), stats_reporter: ClientStatsSender::new(None, task_client.clone()),
negotiated_protocol: None, negotiated_protocol: None,
#[cfg(unix)] #[cfg(unix)]
connection_fd_callback: None, connection_fd_callback,
task_client, task_client,
} }
} }
@@ -24,10 +24,10 @@ use tracing::*;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Config { pub struct Config {
initial_reconnection_backoff: Duration, pub initial_reconnection_backoff: Duration,
maximum_reconnection_backoff: Duration, pub maximum_reconnection_backoff: Duration,
initial_connection_timeout: Duration, pub initial_connection_timeout: Duration,
maximum_connection_buffer_size: usize, pub maximum_connection_buffer_size: usize,
} }
impl Config { impl Config {
@@ -50,7 +50,7 @@ pub trait SendWithoutResponse {
// Without response in this context means we will not listen for anything we might get back (not // Without response in this context means we will not listen for anything we might get back (not
// that we should get anything), including any possible io errors // that we should get anything), including any possible io errors
fn send_without_response( fn send_without_response(
&mut self, &self,
address: NymNodeRoutingAddress, address: NymNodeRoutingAddress,
packet: NymPacket, packet: NymPacket,
packet_type: PacketType, packet_type: PacketType,
@@ -196,7 +196,7 @@ impl Client {
} }
} }
fn make_connection(&mut self, address: NymNodeRoutingAddress, pending_packet: FramedNymPacket) { fn make_connection(&self, address: NymNodeRoutingAddress, pending_packet: FramedNymPacket) {
let (sender, receiver) = mpsc::channel(self.config.maximum_connection_buffer_size); let (sender, receiver) = mpsc::channel(self.config.maximum_connection_buffer_size);
// this CAN'T fail because we just created the channel which has a non-zero capacity // this CAN'T fail because we just created the channel which has a non-zero capacity
@@ -247,7 +247,7 @@ impl Client {
impl SendWithoutResponse for Client { impl SendWithoutResponse for Client {
fn send_without_response( fn send_without_response(
&mut self, &self,
address: NymNodeRoutingAddress, address: NymNodeRoutingAddress,
packet: NymPacket, packet: NymPacket,
packet_type: PacketType, packet_type: PacketType,
@@ -16,14 +16,13 @@ nym-coconut-dkg-common = { path = "../../cosmwasm-smart-contracts/coconut-dkg" }
nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" } nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" }
nym-mixnet-contract-common = { path = "../../cosmwasm-smart-contracts/mixnet-contract" } nym-mixnet-contract-common = { path = "../../cosmwasm-smart-contracts/mixnet-contract" }
nym-vesting-contract-common = { path = "../../cosmwasm-smart-contracts/vesting-contract" } nym-vesting-contract-common = { path = "../../cosmwasm-smart-contracts/vesting-contract" }
nym-coconut-bandwidth-contract-common = { path = "../../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
nym-ecash-contract-common = { path = "../../cosmwasm-smart-contracts/ecash-contract" } nym-ecash-contract-common = { path = "../../cosmwasm-smart-contracts/ecash-contract" }
nym-multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" } nym-multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" }
nym-group-contract-common = { path = "../../cosmwasm-smart-contracts/group-contract" } nym-group-contract-common = { path = "../../cosmwasm-smart-contracts/group-contract" }
nym-serde-helpers = { path = "../../serde-helpers", features = ["hex", "base64"] } nym-serde-helpers = { path = "../../serde-helpers", features = ["hex", "base64"] }
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true } serde_json = { workspace = true }
nym-http-api-client = { path = "../../../common/http-api-client" } nym-http-api-client = { path = "../../../common/http-api-client", features = ["bincode"] }
thiserror = { workspace = true } thiserror = { workspace = true }
tracing = { workspace = true } tracing = { workspace = true }
url = { workspace = true, features = ["serde"] } url = { workspace = true, features = ["serde"] }
@@ -56,7 +55,7 @@ cw4 = { workspace = true }
cw-controllers = { workspace = true } cw-controllers = { workspace = true }
prost = { workspace = true, default-features = false } prost = { workspace = true, default-features = false }
flate2 = { workspace = true } flate2 = { workspace = true }
sha2 = { version = "0.9.5" } sha2 = { workspace = true }
itertools = { workspace = true } itertools = { workspace = true }
zeroize = { workspace = true, features = ["zeroize_derive"] } zeroize = { workspace = true, features = ["zeroize_derive"] }
cosmwasm-std = { workspace = true } cosmwasm-std = { workspace = true }
@@ -11,7 +11,9 @@ use crate::{
use nym_api_requests::ecash::models::{ use nym_api_requests::ecash::models::{
AggregatedCoinIndicesSignatureResponse, AggregatedExpirationDateSignatureResponse, AggregatedCoinIndicesSignatureResponse, AggregatedExpirationDateSignatureResponse,
BatchRedeemTicketsBody, EcashBatchTicketRedemptionResponse, EcashTicketVerificationResponse, BatchRedeemTicketsBody, EcashBatchTicketRedemptionResponse, EcashTicketVerificationResponse,
IssuedTicketbooksChallengeResponse, IssuedTicketbooksForResponse, VerifyEcashTicketBody, IssuedTicketbooksChallengeCommitmentRequest, IssuedTicketbooksChallengeCommitmentResponse,
IssuedTicketbooksDataRequest, IssuedTicketbooksDataResponse, IssuedTicketbooksForCountResponse,
IssuedTicketbooksForResponse, VerifyEcashTicketBody,
}; };
use nym_api_requests::ecash::{ use nym_api_requests::ecash::{
BlindSignRequestBody, BlindedSignatureResponse, PartialCoinIndicesSignatureResponse, BlindSignRequestBody, BlindedSignatureResponse, PartialCoinIndicesSignatureResponse,
@@ -25,15 +27,14 @@ use nym_api_requests::models::{
use nym_api_requests::models::{LegacyDescribedGateway, MixNodeBondAnnotated}; use nym_api_requests::models::{LegacyDescribedGateway, MixNodeBondAnnotated};
use nym_api_requests::nym_nodes::{NodesByAddressesResponse, SkimmedNode}; use nym_api_requests::nym_nodes::{NodesByAddressesResponse, SkimmedNode};
use nym_coconut_dkg_common::types::EpochId; use nym_coconut_dkg_common::types::EpochId;
use nym_ecash_contract_common::deposit::DepositId;
use nym_http_api_client::UserAgent; use nym_http_api_client::UserAgent;
use nym_mixnet_contract_common::EpochRewardedSet;
use nym_network_defaults::NymNetworkDetails; use nym_network_defaults::NymNetworkDetails;
use std::net::IpAddr; use std::net::IpAddr;
use time::Date; use time::Date;
use url::Url; use url::Url;
pub use crate::nym_api::NymApiClientExt; pub use crate::nym_api::NymApiClientExt;
use nym_mixnet_contract_common::EpochRewardedSet;
pub use nym_mixnet_contract_common::{ pub use nym_mixnet_contract_common::{
mixnode::MixNodeDetails, GatewayBond, IdentityKey, IdentityKeyRef, NodeId, NymNodeDetails, mixnode::MixNodeDetails, GatewayBond, IdentityKey, IdentityKeyRef, NodeId, NymNodeDetails,
}; };
@@ -344,25 +345,47 @@ impl<C, S> Client<C, S> {
#[derive(Clone)] #[derive(Clone)]
pub struct NymApiClient { pub struct NymApiClient {
pub use_bincode: bool,
pub nym_api: nym_api::Client, pub nym_api: nym_api::Client,
// TODO: perhaps if we really need it at some (currently I don't see any reasons for it) // TODO: perhaps if we really need it at some (currently I don't see any reasons for it)
// we could re-implement the communication with the REST API on port 1317 // we could re-implement the communication with the REST API on port 1317
} }
impl From<nym_api::Client> for NymApiClient {
fn from(nym_api: nym_api::Client) -> Self {
NymApiClient {
use_bincode: false,
nym_api,
}
}
}
// we have to allow the use of deprecated method here as they're calling the deprecated trait methods // we have to allow the use of deprecated method here as they're calling the deprecated trait methods
#[allow(deprecated)] #[allow(deprecated)]
impl NymApiClient { impl NymApiClient {
pub fn new(api_url: Url) -> Self { pub fn new(api_url: Url) -> Self {
let nym_api = nym_api::Client::new(api_url, None); let nym_api = nym_api::Client::new(api_url, None);
NymApiClient { nym_api } NymApiClient {
use_bincode: false,
nym_api,
}
} }
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
pub fn new_with_timeout(api_url: Url, timeout: std::time::Duration) -> Self { pub fn new_with_timeout(api_url: Url, timeout: std::time::Duration) -> Self {
let nym_api = nym_api::Client::new(api_url, Some(timeout)); let nym_api = nym_api::Client::new(api_url, Some(timeout));
NymApiClient { nym_api } NymApiClient {
use_bincode: false,
nym_api,
}
}
#[must_use]
pub fn with_bincode(mut self, use_bincode: bool) -> Self {
self.use_bincode = use_bincode;
self
} }
pub fn new_with_user_agent(api_url: Url, user_agent: impl Into<UserAgent>) -> Self { pub fn new_with_user_agent(api_url: Url, user_agent: impl Into<UserAgent>) -> Self {
@@ -372,7 +395,10 @@ impl NymApiClient {
.build::<ValidatorClientError>() .build::<ValidatorClientError>()
.expect("failed to build nym api client"); .expect("failed to build nym api client");
NymApiClient { nym_api } NymApiClient {
use_bincode: false,
nym_api,
}
} }
pub fn api_url(&self) -> &Url { pub fn api_url(&self) -> &Url {
@@ -409,7 +435,7 @@ impl NymApiClient {
loop { loop {
let mut res = self let mut res = self
.nym_api .nym_api
.get_basic_entry_assigned_nodes(false, Some(page), None) .get_basic_entry_assigned_nodes(false, Some(page), None, self.use_bincode)
.await?; .await?;
nodes.append(&mut res.nodes.data); nodes.append(&mut res.nodes.data);
@@ -435,7 +461,7 @@ impl NymApiClient {
loop { loop {
let mut res = self let mut res = self
.nym_api .nym_api
.get_basic_active_mixing_assigned_nodes(false, Some(page), None) .get_basic_active_mixing_assigned_nodes(false, Some(page), None, self.use_bincode)
.await?; .await?;
nodes.append(&mut res.nodes.data); nodes.append(&mut res.nodes.data);
@@ -461,7 +487,7 @@ impl NymApiClient {
loop { loop {
let mut res = self let mut res = self
.nym_api .nym_api
.get_basic_mixing_capable_nodes(false, Some(page), None) .get_basic_mixing_capable_nodes(false, Some(page), None, self.use_bincode)
.await?; .await?;
nodes.append(&mut res.nodes.data); nodes.append(&mut res.nodes.data);
@@ -484,7 +510,7 @@ impl NymApiClient {
loop { loop {
let mut res = self let mut res = self
.nym_api .nym_api
.get_basic_nodes(false, Some(page), None) .get_basic_nodes(false, Some(page), None, self.use_bincode)
.await?; .await?;
nodes.append(&mut res.nodes.data); nodes.append(&mut res.nodes.data);
@@ -701,17 +727,33 @@ impl NymApiClient {
Ok(self.nym_api.issued_ticketbooks_for(expiration_date).await?) Ok(self.nym_api.issued_ticketbooks_for(expiration_date).await?)
} }
pub async fn issued_ticketbooks_challenge( pub async fn issued_ticketbooks_for_count(
&self, &self,
expiration_date: Date, expiration_date: Date,
deposits: Vec<DepositId>, ) -> Result<IssuedTicketbooksForCountResponse, ValidatorClientError> {
) -> Result<IssuedTicketbooksChallengeResponse, ValidatorClientError> {
Ok(self Ok(self
.nym_api .nym_api
.issued_ticketbooks_challenge(expiration_date, deposits) .issued_ticketbooks_for_count(expiration_date)
.await?) .await?)
} }
pub async fn issued_ticketbooks_challenge_commitment(
&self,
request: &IssuedTicketbooksChallengeCommitmentRequest,
) -> Result<IssuedTicketbooksChallengeCommitmentResponse, ValidatorClientError> {
Ok(self
.nym_api
.issued_ticketbooks_challenge_commitment(request)
.await?)
}
pub async fn issued_ticketbooks_data(
&self,
request: &IssuedTicketbooksDataRequest,
) -> Result<IssuedTicketbooksDataResponse, ValidatorClientError> {
Ok(self.nym_api.issued_ticketbooks_data(request).await?)
}
pub async fn nodes_by_addresses( pub async fn nodes_by_addresses(
&self, &self,
addresses: Vec<IpAddr>, addresses: Vec<IpAddr>,
@@ -7,7 +7,8 @@ use async_trait::async_trait;
use nym_api_requests::ecash::models::{ use nym_api_requests::ecash::models::{
AggregatedCoinIndicesSignatureResponse, AggregatedExpirationDateSignatureResponse, AggregatedCoinIndicesSignatureResponse, AggregatedExpirationDateSignatureResponse,
BatchRedeemTicketsBody, EcashBatchTicketRedemptionResponse, EcashTicketVerificationResponse, BatchRedeemTicketsBody, EcashBatchTicketRedemptionResponse, EcashTicketVerificationResponse,
IssuedTicketbooksChallengeRequest, IssuedTicketbooksChallengeResponse, IssuedTicketbooksChallengeCommitmentRequest, IssuedTicketbooksChallengeCommitmentResponse,
IssuedTicketbooksDataRequest, IssuedTicketbooksDataResponse, IssuedTicketbooksForCountResponse,
IssuedTicketbooksForResponse, VerifyEcashTicketBody, IssuedTicketbooksForResponse, VerifyEcashTicketBody,
}; };
use nym_api_requests::ecash::VerificationKeyResponse; use nym_api_requests::ecash::VerificationKeyResponse;
@@ -36,10 +37,7 @@ pub use nym_api_requests::{
nym_nodes::{CachedNodesResponse, SkimmedNode}, nym_nodes::{CachedNodesResponse, SkimmedNode},
NymNetworkDetailsResponse, NymNetworkDetailsResponse,
}; };
pub use nym_coconut_dkg_common::types::EpochId;
use nym_contracts_common::IdentityKey; use nym_contracts_common::IdentityKey;
use nym_ecash_contract_common::deposit::DepositId;
pub use nym_http_api_client::Client;
use nym_http_api_client::{ApiClient, NO_PARAMS}; use nym_http_api_client::{ApiClient, NO_PARAMS};
use nym_mixnet_contract_common::mixnode::MixNodeDetails; use nym_mixnet_contract_common::mixnode::MixNodeDetails;
use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, NodeId, NymNodeDetails}; use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, NodeId, NymNodeDetails};
@@ -48,6 +46,9 @@ use time::format_description::BorrowedFormatItem;
use time::Date; use time::Date;
use tracing::instrument; use tracing::instrument;
pub use nym_coconut_dkg_common::types::EpochId;
pub use nym_http_api_client::Client;
pub mod error; pub mod error;
pub mod routes; pub mod routes;
@@ -317,6 +318,7 @@ pub trait NymApiClientExt: ApiClient {
no_legacy: bool, no_legacy: bool,
page: Option<u32>, page: Option<u32>,
per_page: Option<u32>, per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponse<SkimmedNode>, NymAPIError> { ) -> Result<PaginatedCachedNodesResponse<SkimmedNode>, NymAPIError> {
let mut params = Vec::new(); let mut params = Vec::new();
@@ -332,7 +334,11 @@ pub trait NymApiClientExt: ApiClient {
params.push(("per_page", per_page.to_string())) params.push(("per_page", per_page.to_string()))
} }
self.get_json( if use_bincode {
params.push(("output", "bincode".to_string()))
}
self.get_response(
&[ &[
routes::API_VERSION, routes::API_VERSION,
"unstable", "unstable",
@@ -354,6 +360,7 @@ pub trait NymApiClientExt: ApiClient {
no_legacy: bool, no_legacy: bool,
page: Option<u32>, page: Option<u32>,
per_page: Option<u32>, per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponse<SkimmedNode>, NymAPIError> { ) -> Result<PaginatedCachedNodesResponse<SkimmedNode>, NymAPIError> {
let mut params = Vec::new(); let mut params = Vec::new();
@@ -369,7 +376,11 @@ pub trait NymApiClientExt: ApiClient {
params.push(("per_page", per_page.to_string())) params.push(("per_page", per_page.to_string()))
} }
self.get_json( if use_bincode {
params.push(("output", "bincode".to_string()))
}
self.get_response(
&[ &[
routes::API_VERSION, routes::API_VERSION,
"unstable", "unstable",
@@ -391,6 +402,7 @@ pub trait NymApiClientExt: ApiClient {
no_legacy: bool, no_legacy: bool,
page: Option<u32>, page: Option<u32>,
per_page: Option<u32>, per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponse<SkimmedNode>, NymAPIError> { ) -> Result<PaginatedCachedNodesResponse<SkimmedNode>, NymAPIError> {
let mut params = Vec::new(); let mut params = Vec::new();
@@ -406,7 +418,11 @@ pub trait NymApiClientExt: ApiClient {
params.push(("per_page", per_page.to_string())) params.push(("per_page", per_page.to_string()))
} }
self.get_json( if use_bincode {
params.push(("output", "bincode".to_string()))
}
self.get_response(
&[ &[
routes::API_VERSION, routes::API_VERSION,
"unstable", "unstable",
@@ -426,6 +442,7 @@ pub trait NymApiClientExt: ApiClient {
no_legacy: bool, no_legacy: bool,
page: Option<u32>, page: Option<u32>,
per_page: Option<u32>, per_page: Option<u32>,
use_bincode: bool,
) -> Result<PaginatedCachedNodesResponse<SkimmedNode>, NymAPIError> { ) -> Result<PaginatedCachedNodesResponse<SkimmedNode>, NymAPIError> {
let mut params = Vec::new(); let mut params = Vec::new();
@@ -441,7 +458,11 @@ pub trait NymApiClientExt: ApiClient {
params.push(("per_page", per_page.to_string())) params.push(("per_page", per_page.to_string()))
} }
self.get_json( if use_bincode {
params.push(("output", "bincode".to_string()))
}
self.get_response(
&[ &[
routes::API_VERSION, routes::API_VERSION,
"unstable", "unstable",
@@ -1012,22 +1033,52 @@ pub trait NymApiClientExt: ApiClient {
} }
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
async fn issued_ticketbooks_challenge( async fn issued_ticketbooks_for_count(
&self, &self,
expiration_date: Date, expiration_date: Date,
deposits: Vec<DepositId>, ) -> Result<IssuedTicketbooksForCountResponse, NymAPIError> {
) -> Result<IssuedTicketbooksChallengeResponse, NymAPIError> { self.get_json(
&[
routes::API_VERSION,
routes::ECASH_ROUTES,
routes::ECASH_ISSUED_TICKETBOOKS_FOR_COUNT,
&expiration_date.to_string(),
],
NO_PARAMS,
)
.await
}
#[instrument(level = "debug", skip(self))]
async fn issued_ticketbooks_challenge_commitment(
&self,
request: &IssuedTicketbooksChallengeCommitmentRequest,
) -> Result<IssuedTicketbooksChallengeCommitmentResponse, NymAPIError> {
self.post_json( self.post_json(
&[ &[
routes::API_VERSION, routes::API_VERSION,
routes::ECASH_ROUTES, routes::ECASH_ROUTES,
routes::ECASH_ISSUED_TICKETBOOKS_CHALLENGE, routes::ECASH_ISSUED_TICKETBOOKS_CHALLENGE_COMMITMENT,
], ],
NO_PARAMS, NO_PARAMS,
&IssuedTicketbooksChallengeRequest { request,
expiration_date, )
deposits, .await
}, }
#[instrument(level = "debug", skip(self))]
async fn issued_ticketbooks_data(
&self,
request: &IssuedTicketbooksDataRequest,
) -> Result<IssuedTicketbooksDataResponse, NymAPIError> {
self.post_json(
&[
routes::API_VERSION,
routes::ECASH_ROUTES,
routes::ECASH_ISSUED_TICKETBOOKS_DATA,
],
NO_PARAMS,
request,
) )
.await .await
} }
@@ -26,7 +26,12 @@ pub mod ecash {
pub const GLOBAL_COIN_INDICES_SIGNATURES: &str = "aggregated-coin-indices-signatures"; pub const GLOBAL_COIN_INDICES_SIGNATURES: &str = "aggregated-coin-indices-signatures";
pub const MASTER_VERIFICATION_KEY: &str = "master-verification-key"; pub const MASTER_VERIFICATION_KEY: &str = "master-verification-key";
pub const ECASH_ISSUED_TICKETBOOKS_FOR: &str = "issued-ticketbooks-for"; pub const ECASH_ISSUED_TICKETBOOKS_FOR: &str = "issued-ticketbooks-for";
pub const ECASH_ISSUED_TICKETBOOKS_CHALLENGE: &str = "issued-ticketbooks-challenge"; pub const ECASH_ISSUED_TICKETBOOKS_COUNT: &str = "issued-ticketbooks-count";
pub const ECASH_ISSUED_TICKETBOOKS_FOR_COUNT: &str = "issued-ticketbooks-for-count";
pub const ECASH_ISSUED_TICKETBOOKS_ON_COUNT: &str = "issued-ticketbooks-on-count";
pub const ECASH_ISSUED_TICKETBOOKS_CHALLENGE_COMMITMENT: &str =
"issued-ticketbooks-challenge-commitment";
pub const ECASH_ISSUED_TICKETBOOKS_DATA: &str = "issued-ticketbooks-data";
pub const EXPIRATION_DATE_PARAM: &str = "expiration_date"; pub const EXPIRATION_DATE_PARAM: &str = "expiration_date";
pub const EPOCH_ID_PARAM: &str = "epoch_id"; pub const EPOCH_ID_PARAM: &str = "epoch_id";
@@ -48,7 +48,7 @@ impl Div<GasPrice> for &Coin {
panic!("attempted to divide by zero!") panic!("attempted to divide by zero!")
}; };
let implicit_gas_limit = gas_price_inv * Uint128::new(self.amount); let implicit_gas_limit = Uint128::new(self.amount).mul_floor(gas_price_inv);
if implicit_gas_limit.u128() >= u64::MAX as u128 { if implicit_gas_limit.u128() >= u64::MAX as u128 {
u64::MAX u64::MAX
} else { } else {
@@ -169,13 +169,7 @@ impl CoinConverter for CosmosCoin {
type Target = CosmWasmCoin; type Target = CosmWasmCoin;
fn convert_coin(&self) -> Self::Target { fn convert_coin(&self) -> Self::Target {
CosmWasmCoin::new( CosmWasmCoin::new(self.amount, self.denom.to_string())
self.amount
.to_string()
.parse()
.expect("cosmos coin had an invalid amount assigned"),
self.denom.to_string(),
)
} }
} }
@@ -7,10 +7,10 @@ use crate::nyxd::error::NyxdError;
use crate::nyxd::{Coin, Fee, SigningCosmWasmClient}; use crate::nyxd::{Coin, Fee, SigningCosmWasmClient};
use crate::signing::signer::OfflineSigner; use crate::signing::signer::OfflineSigner;
use async_trait::async_trait; use async_trait::async_trait;
use cosmwasm_std::{to_binary, CosmosMsg, WasmMsg}; use cosmwasm_std::{CosmosMsg, Empty};
use cw3::Vote; use cw3::Vote;
use cw4::{MemberChangedHookMsg, MemberDiff}; use cw4::{MemberChangedHookMsg, MemberDiff};
use nym_coconut_bandwidth_contract_common::msg::ExecuteMsg as CoconutBandwidthExecuteMsg; use cw_utils::Expiration;
use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg; use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg;
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
@@ -24,35 +24,23 @@ pub trait MultisigSigningClient: NymContractsProvider {
funds: Vec<Coin>, funds: Vec<Coin>,
) -> Result<ExecuteResult, NyxdError>; ) -> Result<ExecuteResult, NyxdError>;
async fn propose_release_funds( async fn propose(
&self, &self,
title: String, title: String,
blinded_serial_number: String, description: String,
voucher_value: Coin, msgs: Vec<CosmosMsg<Empty>>,
latest: Option<Expiration>,
fee: Option<Fee>, fee: Option<Fee>,
) -> Result<ExecuteResult, NyxdError> { ) -> Result<ExecuteResult, NyxdError> {
let ecash_contract_address = self
.ecash_contract_address()
.ok_or_else(|| NyxdError::unavailable_contract_address("coconut bandwidth contract"))?;
let release_funds_req = CoconutBandwidthExecuteMsg::ReleaseFunds {
funds: voucher_value.into(),
};
let release_funds_msg = CosmosMsg::Wasm(WasmMsg::Execute {
contract_addr: ecash_contract_address.to_string(),
msg: to_binary(&release_funds_req)?,
funds: vec![],
});
let req = MultisigExecuteMsg::Propose {
title,
description: blinded_serial_number,
msgs: vec![release_funds_msg],
latest: None,
};
self.execute_multisig_contract( self.execute_multisig_contract(
fee, fee,
req, MultisigExecuteMsg::Propose {
"Multisig::Propose::Execute::ReleaseFunds".to_string(), title,
description,
msgs,
latest,
},
"Multisig::Propose".to_string(),
vec![], vec![],
) )
.await .await
@@ -161,7 +149,7 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::nyxd::contract_traits::tests::{mock_coin, IgnoreValue}; use crate::nyxd::contract_traits::tests::IgnoreValue;
// it's enough that this compiles and clippy is happy about it // it's enough that this compiles and clippy is happy about it
#[allow(dead_code)] #[allow(dead_code)]
@@ -171,9 +159,12 @@ mod tests {
) { ) {
match msg { match msg {
MultisigExecuteMsg::Propose { MultisigExecuteMsg::Propose {
title, description, .. title,
description,
msgs,
latest,
} => client } => client
.propose_release_funds(title, description, mock_coin(), None) .propose(title, description, msgs, latest, None)
.ignore(), .ignore(),
MultisigExecuteMsg::Vote { proposal_id, vote } => { MultisigExecuteMsg::Vote { proposal_id, vote } => {
client.vote(proposal_id, vote, None).ignore() client.vote(proposal_id, vote, None).ignore()
@@ -27,7 +27,7 @@ impl Mul<Gas> for &GasPrice {
fn mul(self, gas_limit: Gas) -> Self::Output { fn mul(self, gas_limit: Gas) -> Self::Output {
let limit_uint128 = Uint128::from(gas_limit); let limit_uint128 = Uint128::from(gas_limit);
let mut amount = self.amount * limit_uint128; let mut amount = limit_uint128.mul_floor(self.amount);
let gas_price_numerator = self.amount.numerator(); let gas_price_numerator = self.amount.numerator();
let gas_price_denominator = self.amount.denominator(); let gas_price_denominator = self.amount.denominator();
@@ -35,7 +35,7 @@ impl Mul<Gas> for &GasPrice {
// gas price is a fraction of the smallest fee token unit, so we must ensure that // gas price is a fraction of the smallest fee token unit, so we must ensure that
// for any multiplication, we have rounded up // for any multiplication, we have rounded up
// //
// I don't really like the this solution as it has a theoretical chance of // I don't really like this solution as it has a theoretical chance of
// overflowing (internally cosmwasm uses U256 to avoid that) // overflowing (internally cosmwasm uses U256 to avoid that)
// however, realistically that is impossible to happen as the resultant value // however, realistically that is impossible to happen as the resultant value
// would have to be way higher than our token limit of 10^15 (1 billion of tokens * 1 million for denomination) // would have to be way higher than our token limit of 10^15 (1 billion of tokens * 1 million for denomination)
@@ -15,7 +15,7 @@ use nym_credentials::{
AggregatedCoinIndicesSignatures, AggregatedExpirationDateSignatures, EpochVerificationKey, AggregatedCoinIndicesSignatures, AggregatedExpirationDateSignatures, EpochVerificationKey,
}; };
use nym_credentials_interface::TicketType; use nym_credentials_interface::TicketType;
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use tempfile::NamedTempFile; use tempfile::NamedTempFile;
@@ -83,7 +83,7 @@ async fn issue_client_ticketbook(
); );
let persistent_storage = initialise_persistent_storage(credentials_store).await; let persistent_storage = initialise_persistent_storage(credentials_store).await;
let private_id_key: identity::PrivateKey = nym_pemstore::load_key(private_id_key)?; let private_id_key: ed25519::PrivateKey = nym_pemstore::load_key(private_id_key)?;
utils::issue_credential( utils::issue_credential(
&client, &client,
&persistent_storage, &persistent_storage,
@@ -155,7 +155,7 @@ async fn fetch_delegation_data(
match event.event.kind { match event.event.kind {
// If a pending undelegate tx is found, remove it from delegation map // If a pending undelegate tx is found, remove it from delegation map
PendingEpochEventKind::Undelegate { owner, node_id, .. } => { PendingEpochEventKind::Undelegate { owner, node_id, .. } => {
if owner == address.as_ref() if owner.as_str() == address.as_ref()
&& existing_delegation_map.contains_key(&node_id.to_string()) && existing_delegation_map.contains_key(&node_id.to_string())
{ {
existing_delegation_map.remove(&node_id.to_string()); existing_delegation_map.remove(&node_id.to_string());
@@ -169,7 +169,7 @@ async fn fetch_delegation_data(
amount, amount,
.. ..
} => { } => {
if owner == address.as_ref() { if owner.as_str() == address.as_ref() {
let mut amount = Coin::from(amount); let mut amount = Coin::from(amount);
if let Some(pending_record) = pending_delegation_map.get(&node_id.to_string()) { if let Some(pending_record) = pending_delegation_map.get(&node_id.to_string()) {
amount.amount += pending_record.amount; amount.amount += pending_record.amount;
@@ -1,6 +1,6 @@
use clap::{Args, Parser, Subcommand}; use clap::{Args, Parser, Subcommand};
use nym_bin_common::output_format::OutputFormat; use nym_bin_common::output_format::OutputFormat;
use nym_crypto::asymmetric::identity; use nym_crypto::asymmetric::ed25519;
use nym_types::helpers::ConsoleSigningOutput; use nym_types::helpers::ConsoleSigningOutput;
use nym_validator_client::nyxd::error::NyxdError; use nym_validator_client::nyxd::error::NyxdError;
use std::path::PathBuf; use std::path::PathBuf;
@@ -34,14 +34,14 @@ pub struct SignArgs {
pub async fn sign(args: SignArgs) -> Result<(), NyxdError> { pub async fn sign(args: SignArgs) -> Result<(), NyxdError> {
eprintln!(">>> loading: {}", args.private_key.display()); eprintln!(">>> loading: {}", args.private_key.display());
let private_identity_key: identity::PrivateKey = let private_identity_key: ed25519::PrivateKey =
nym_pemstore::load_key(args.private_key).expect("failed to load key"); nym_pemstore::load_key(args.private_key).expect("failed to load key");
print_signed_msg(&private_identity_key, &args.base58_msg, args.output); print_signed_msg(&private_identity_key, &args.base58_msg, args.output);
Ok(()) Ok(())
} }
fn print_signed_msg(private_key: &identity::PrivateKey, raw_msg: &str, output: OutputFormat) { fn print_signed_msg(private_key: &ed25519::PrivateKey, raw_msg: &str, output: OutputFormat) {
let trimmed = raw_msg.trim(); let trimmed = raw_msg.trim();
eprintln!(">>> attempting to sign: {trimmed}"); eprintln!(">>> attempting to sign: {trimmed}");

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